kinto
Version:
An Offline-First JavaScript client for Kinto.
18,622 lines • 1.56 MB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Kinto = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
(function (global){
"use strict";
require("core-js/es6");
require("core-js/fn/array/includes");
require("core-js/fn/string/pad-start");
require("core-js/fn/string/pad-end");
require("core-js/fn/symbol/async-iterator");
require("core-js/fn/object/get-own-property-descriptors");
require("core-js/fn/object/values");
require("core-js/fn/object/entries");
require("core-js/fn/promise/finally");
require("core-js/web");
require("regenerator-runtime/runtime");
if (global._babelPolyfill && typeof console !== "undefined" && console.warn) {
console.warn("@babel/polyfill is loaded more than once on this page. This is probably not desirable/intended " + "and may have consequences if different versions of the polyfills are applied sequentially. " + "If you do need to load the polyfill more than once, use @babel/polyfill/noConflict " + "instead to bypass the warning.");
}
global._babelPolyfill = true;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"core-js/es6":2,"core-js/fn/array/includes":3,"core-js/fn/object/entries":4,"core-js/fn/object/get-own-property-descriptors":5,"core-js/fn/object/values":6,"core-js/fn/promise/finally":7,"core-js/fn/string/pad-end":8,"core-js/fn/string/pad-start":9,"core-js/fn/symbol/async-iterator":10,"core-js/web":275,"regenerator-runtime/runtime":276}],2:[function(require,module,exports){
require('../modules/es6.symbol');
require('../modules/es6.object.create');
require('../modules/es6.object.define-property');
require('../modules/es6.object.define-properties');
require('../modules/es6.object.get-own-property-descriptor');
require('../modules/es6.object.get-prototype-of');
require('../modules/es6.object.keys');
require('../modules/es6.object.get-own-property-names');
require('../modules/es6.object.freeze');
require('../modules/es6.object.seal');
require('../modules/es6.object.prevent-extensions');
require('../modules/es6.object.is-frozen');
require('../modules/es6.object.is-sealed');
require('../modules/es6.object.is-extensible');
require('../modules/es6.object.assign');
require('../modules/es6.object.is');
require('../modules/es6.object.set-prototype-of');
require('../modules/es6.object.to-string');
require('../modules/es6.function.bind');
require('../modules/es6.function.name');
require('../modules/es6.function.has-instance');
require('../modules/es6.parse-int');
require('../modules/es6.parse-float');
require('../modules/es6.number.constructor');
require('../modules/es6.number.to-fixed');
require('../modules/es6.number.to-precision');
require('../modules/es6.number.epsilon');
require('../modules/es6.number.is-finite');
require('../modules/es6.number.is-integer');
require('../modules/es6.number.is-nan');
require('../modules/es6.number.is-safe-integer');
require('../modules/es6.number.max-safe-integer');
require('../modules/es6.number.min-safe-integer');
require('../modules/es6.number.parse-float');
require('../modules/es6.number.parse-int');
require('../modules/es6.math.acosh');
require('../modules/es6.math.asinh');
require('../modules/es6.math.atanh');
require('../modules/es6.math.cbrt');
require('../modules/es6.math.clz32');
require('../modules/es6.math.cosh');
require('../modules/es6.math.expm1');
require('../modules/es6.math.fround');
require('../modules/es6.math.hypot');
require('../modules/es6.math.imul');
require('../modules/es6.math.log10');
require('../modules/es6.math.log1p');
require('../modules/es6.math.log2');
require('../modules/es6.math.sign');
require('../modules/es6.math.sinh');
require('../modules/es6.math.tanh');
require('../modules/es6.math.trunc');
require('../modules/es6.string.from-code-point');
require('../modules/es6.string.raw');
require('../modules/es6.string.trim');
require('../modules/es6.string.iterator');
require('../modules/es6.string.code-point-at');
require('../modules/es6.string.ends-with');
require('../modules/es6.string.includes');
require('../modules/es6.string.repeat');
require('../modules/es6.string.starts-with');
require('../modules/es6.string.anchor');
require('../modules/es6.string.big');
require('../modules/es6.string.blink');
require('../modules/es6.string.bold');
require('../modules/es6.string.fixed');
require('../modules/es6.string.fontcolor');
require('../modules/es6.string.fontsize');
require('../modules/es6.string.italics');
require('../modules/es6.string.link');
require('../modules/es6.string.small');
require('../modules/es6.string.strike');
require('../modules/es6.string.sub');
require('../modules/es6.string.sup');
require('../modules/es6.date.now');
require('../modules/es6.date.to-json');
require('../modules/es6.date.to-iso-string');
require('../modules/es6.date.to-string');
require('../modules/es6.date.to-primitive');
require('../modules/es6.array.is-array');
require('../modules/es6.array.from');
require('../modules/es6.array.of');
require('../modules/es6.array.join');
require('../modules/es6.array.slice');
require('../modules/es6.array.sort');
require('../modules/es6.array.for-each');
require('../modules/es6.array.map');
require('../modules/es6.array.filter');
require('../modules/es6.array.some');
require('../modules/es6.array.every');
require('../modules/es6.array.reduce');
require('../modules/es6.array.reduce-right');
require('../modules/es6.array.index-of');
require('../modules/es6.array.last-index-of');
require('../modules/es6.array.copy-within');
require('../modules/es6.array.fill');
require('../modules/es6.array.find');
require('../modules/es6.array.find-index');
require('../modules/es6.array.species');
require('../modules/es6.array.iterator');
require('../modules/es6.regexp.constructor');
require('../modules/es6.regexp.to-string');
require('../modules/es6.regexp.flags');
require('../modules/es6.regexp.match');
require('../modules/es6.regexp.replace');
require('../modules/es6.regexp.search');
require('../modules/es6.regexp.split');
require('../modules/es6.promise');
require('../modules/es6.map');
require('../modules/es6.set');
require('../modules/es6.weak-map');
require('../modules/es6.weak-set');
require('../modules/es6.typed.array-buffer');
require('../modules/es6.typed.data-view');
require('../modules/es6.typed.int8-array');
require('../modules/es6.typed.uint8-array');
require('../modules/es6.typed.uint8-clamped-array');
require('../modules/es6.typed.int16-array');
require('../modules/es6.typed.uint16-array');
require('../modules/es6.typed.int32-array');
require('../modules/es6.typed.uint32-array');
require('../modules/es6.typed.float32-array');
require('../modules/es6.typed.float64-array');
require('../modules/es6.reflect.apply');
require('../modules/es6.reflect.construct');
require('../modules/es6.reflect.define-property');
require('../modules/es6.reflect.delete-property');
require('../modules/es6.reflect.enumerate');
require('../modules/es6.reflect.get');
require('../modules/es6.reflect.get-own-property-descriptor');
require('../modules/es6.reflect.get-prototype-of');
require('../modules/es6.reflect.has');
require('../modules/es6.reflect.is-extensible');
require('../modules/es6.reflect.own-keys');
require('../modules/es6.reflect.prevent-extensions');
require('../modules/es6.reflect.set');
require('../modules/es6.reflect.set-prototype-of');
module.exports = require('../modules/_core');
},{"../modules/_core":29,"../modules/es6.array.copy-within":127,"../modules/es6.array.every":128,"../modules/es6.array.fill":129,"../modules/es6.array.filter":130,"../modules/es6.array.find":132,"../modules/es6.array.find-index":131,"../modules/es6.array.for-each":133,"../modules/es6.array.from":134,"../modules/es6.array.index-of":135,"../modules/es6.array.is-array":136,"../modules/es6.array.iterator":137,"../modules/es6.array.join":138,"../modules/es6.array.last-index-of":139,"../modules/es6.array.map":140,"../modules/es6.array.of":141,"../modules/es6.array.reduce":143,"../modules/es6.array.reduce-right":142,"../modules/es6.array.slice":144,"../modules/es6.array.some":145,"../modules/es6.array.sort":146,"../modules/es6.array.species":147,"../modules/es6.date.now":148,"../modules/es6.date.to-iso-string":149,"../modules/es6.date.to-json":150,"../modules/es6.date.to-primitive":151,"../modules/es6.date.to-string":152,"../modules/es6.function.bind":153,"../modules/es6.function.has-instance":154,"../modules/es6.function.name":155,"../modules/es6.map":156,"../modules/es6.math.acosh":157,"../modules/es6.math.asinh":158,"../modules/es6.math.atanh":159,"../modules/es6.math.cbrt":160,"../modules/es6.math.clz32":161,"../modules/es6.math.cosh":162,"../modules/es6.math.expm1":163,"../modules/es6.math.fround":164,"../modules/es6.math.hypot":165,"../modules/es6.math.imul":166,"../modules/es6.math.log10":167,"../modules/es6.math.log1p":168,"../modules/es6.math.log2":169,"../modules/es6.math.sign":170,"../modules/es6.math.sinh":171,"../modules/es6.math.tanh":172,"../modules/es6.math.trunc":173,"../modules/es6.number.constructor":174,"../modules/es6.number.epsilon":175,"../modules/es6.number.is-finite":176,"../modules/es6.number.is-integer":177,"../modules/es6.number.is-nan":178,"../modules/es6.number.is-safe-integer":179,"../modules/es6.number.max-safe-integer":180,"../modules/es6.number.min-safe-integer":181,"../modules/es6.number.parse-float":182,"../modules/es6.number.parse-int":183,"../modules/es6.number.to-fixed":184,"../modules/es6.number.to-precision":185,"../modules/es6.object.assign":186,"../modules/es6.object.create":187,"../modules/es6.object.define-properties":188,"../modules/es6.object.define-property":189,"../modules/es6.object.freeze":190,"../modules/es6.object.get-own-property-descriptor":191,"../modules/es6.object.get-own-property-names":192,"../modules/es6.object.get-prototype-of":193,"../modules/es6.object.is":197,"../modules/es6.object.is-extensible":194,"../modules/es6.object.is-frozen":195,"../modules/es6.object.is-sealed":196,"../modules/es6.object.keys":198,"../modules/es6.object.prevent-extensions":199,"../modules/es6.object.seal":200,"../modules/es6.object.set-prototype-of":201,"../modules/es6.object.to-string":202,"../modules/es6.parse-float":203,"../modules/es6.parse-int":204,"../modules/es6.promise":205,"../modules/es6.reflect.apply":206,"../modules/es6.reflect.construct":207,"../modules/es6.reflect.define-property":208,"../modules/es6.reflect.delete-property":209,"../modules/es6.reflect.enumerate":210,"../modules/es6.reflect.get":213,"../modules/es6.reflect.get-own-property-descriptor":211,"../modules/es6.reflect.get-prototype-of":212,"../modules/es6.reflect.has":214,"../modules/es6.reflect.is-extensible":215,"../modules/es6.reflect.own-keys":216,"../modules/es6.reflect.prevent-extensions":217,"../modules/es6.reflect.set":219,"../modules/es6.reflect.set-prototype-of":218,"../modules/es6.regexp.constructor":220,"../modules/es6.regexp.flags":221,"../modules/es6.regexp.match":222,"../modules/es6.regexp.replace":223,"../modules/es6.regexp.search":224,"../modules/es6.regexp.split":225,"../modules/es6.regexp.to-string":226,"../modules/es6.set":227,"../modules/es6.string.anchor":228,"../modules/es6.string.big":229,"../modules/es6.string.blink":230,"../modules/es6.string.bold":231,"../modules/es6.string.code-point-at":232,"../modules/es6.string.ends-with":233,"../modules/es6.string.fixed":234,"../modules/es6.string.fontcolor":235,"../modules/es6.string.fontsize":236,"../modules/es6.string.from-code-point":237,"../modules/es6.string.includes":238,"../modules/es6.string.italics":239,"../modules/es6.string.iterator":240,"../modules/es6.string.link":241,"../modules/es6.string.raw":242,"../modules/es6.string.repeat":243,"../modules/es6.string.small":244,"../modules/es6.string.starts-with":245,"../modules/es6.string.strike":246,"../modules/es6.string.sub":247,"../modules/es6.string.sup":248,"../modules/es6.string.trim":249,"../modules/es6.symbol":250,"../modules/es6.typed.array-buffer":251,"../modules/es6.typed.data-view":252,"../modules/es6.typed.float32-array":253,"../modules/es6.typed.float64-array":254,"../modules/es6.typed.int16-array":255,"../modules/es6.typed.int32-array":256,"../modules/es6.typed.int8-array":257,"../modules/es6.typed.uint16-array":258,"../modules/es6.typed.uint32-array":259,"../modules/es6.typed.uint8-array":260,"../modules/es6.typed.uint8-clamped-array":261,"../modules/es6.weak-map":262,"../modules/es6.weak-set":263}],3:[function(require,module,exports){
require('../../modules/es7.array.includes');
module.exports = require('../../modules/_core').Array.includes;
},{"../../modules/_core":29,"../../modules/es7.array.includes":264}],4:[function(require,module,exports){
require('../../modules/es7.object.entries');
module.exports = require('../../modules/_core').Object.entries;
},{"../../modules/_core":29,"../../modules/es7.object.entries":265}],5:[function(require,module,exports){
require('../../modules/es7.object.get-own-property-descriptors');
module.exports = require('../../modules/_core').Object.getOwnPropertyDescriptors;
},{"../../modules/_core":29,"../../modules/es7.object.get-own-property-descriptors":266}],6:[function(require,module,exports){
require('../../modules/es7.object.values');
module.exports = require('../../modules/_core').Object.values;
},{"../../modules/_core":29,"../../modules/es7.object.values":267}],7:[function(require,module,exports){
'use strict';
require('../../modules/es6.promise');
require('../../modules/es7.promise.finally');
module.exports = require('../../modules/_core').Promise['finally'];
},{"../../modules/_core":29,"../../modules/es6.promise":205,"../../modules/es7.promise.finally":268}],8:[function(require,module,exports){
require('../../modules/es7.string.pad-end');
module.exports = require('../../modules/_core').String.padEnd;
},{"../../modules/_core":29,"../../modules/es7.string.pad-end":269}],9:[function(require,module,exports){
require('../../modules/es7.string.pad-start');
module.exports = require('../../modules/_core').String.padStart;
},{"../../modules/_core":29,"../../modules/es7.string.pad-start":270}],10:[function(require,module,exports){
require('../../modules/es7.symbol.async-iterator');
module.exports = require('../../modules/_wks-ext').f('asyncIterator');
},{"../../modules/_wks-ext":124,"../../modules/es7.symbol.async-iterator":271}],11:[function(require,module,exports){
module.exports = function (it) {
if (typeof it != 'function') throw TypeError(it + ' is not a function!');
return it;
};
},{}],12:[function(require,module,exports){
var cof = require('./_cof');
module.exports = function (it, msg) {
if (typeof it != 'number' && cof(it) != 'Number') throw TypeError(msg);
return +it;
};
},{"./_cof":25}],13:[function(require,module,exports){
// 22.1.3.31 Array.prototype[@@unscopables]
var UNSCOPABLES = require('./_wks')('unscopables');
var ArrayProto = Array.prototype;
if (ArrayProto[UNSCOPABLES] == undefined) require('./_hide')(ArrayProto, UNSCOPABLES, {});
module.exports = function (key) {
ArrayProto[UNSCOPABLES][key] = true;
};
},{"./_hide":47,"./_wks":125}],14:[function(require,module,exports){
module.exports = function (it, Constructor, name, forbiddenField) {
if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) {
throw TypeError(name + ': incorrect invocation!');
} return it;
};
},{}],15:[function(require,module,exports){
var isObject = require('./_is-object');
module.exports = function (it) {
if (!isObject(it)) throw TypeError(it + ' is not an object!');
return it;
};
},{"./_is-object":56}],16:[function(require,module,exports){
// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
'use strict';
var toObject = require('./_to-object');
var toAbsoluteIndex = require('./_to-absolute-index');
var toLength = require('./_to-length');
module.exports = [].copyWithin || function copyWithin(target /* = 0 */, start /* = 0, end = @length */) {
var O = toObject(this);
var len = toLength(O.length);
var to = toAbsoluteIndex(target, len);
var from = toAbsoluteIndex(start, len);
var end = arguments.length > 2 ? arguments[2] : undefined;
var count = Math.min((end === undefined ? len : toAbsoluteIndex(end, len)) - from, len - to);
var inc = 1;
if (from < to && to < from + count) {
inc = -1;
from += count - 1;
to += count - 1;
}
while (count-- > 0) {
if (from in O) O[to] = O[from];
else delete O[to];
to += inc;
from += inc;
} return O;
};
},{"./_to-absolute-index":110,"./_to-length":114,"./_to-object":115}],17:[function(require,module,exports){
// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
'use strict';
var toObject = require('./_to-object');
var toAbsoluteIndex = require('./_to-absolute-index');
var toLength = require('./_to-length');
module.exports = function fill(value /* , start = 0, end = @length */) {
var O = toObject(this);
var length = toLength(O.length);
var aLen = arguments.length;
var index = toAbsoluteIndex(aLen > 1 ? arguments[1] : undefined, length);
var end = aLen > 2 ? arguments[2] : undefined;
var endPos = end === undefined ? length : toAbsoluteIndex(end, length);
while (endPos > index) O[index++] = value;
return O;
};
},{"./_to-absolute-index":110,"./_to-length":114,"./_to-object":115}],18:[function(require,module,exports){
// false -> Array#indexOf
// true -> Array#includes
var toIObject = require('./_to-iobject');
var toLength = require('./_to-length');
var toAbsoluteIndex = require('./_to-absolute-index');
module.exports = function (IS_INCLUDES) {
return function ($this, el, fromIndex) {
var O = toIObject($this);
var length = toLength(O.length);
var index = toAbsoluteIndex(fromIndex, length);
var value;
// Array#includes uses SameValueZero equality algorithm
// eslint-disable-next-line no-self-compare
if (IS_INCLUDES && el != el) while (length > index) {
value = O[index++];
// eslint-disable-next-line no-self-compare
if (value != value) return true;
// Array#indexOf ignores holes, Array#includes - not
} else for (;length > index; index++) if (IS_INCLUDES || index in O) {
if (O[index] === el) return IS_INCLUDES || index || 0;
} return !IS_INCLUDES && -1;
};
};
},{"./_to-absolute-index":110,"./_to-iobject":113,"./_to-length":114}],19:[function(require,module,exports){
// 0 -> Array#forEach
// 1 -> Array#map
// 2 -> Array#filter
// 3 -> Array#some
// 4 -> Array#every
// 5 -> Array#find
// 6 -> Array#findIndex
var ctx = require('./_ctx');
var IObject = require('./_iobject');
var toObject = require('./_to-object');
var toLength = require('./_to-length');
var asc = require('./_array-species-create');
module.exports = function (TYPE, $create) {
var IS_MAP = TYPE == 1;
var IS_FILTER = TYPE == 2;
var IS_SOME = TYPE == 3;
var IS_EVERY = TYPE == 4;
var IS_FIND_INDEX = TYPE == 6;
var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
var create = $create || asc;
return function ($this, callbackfn, that) {
var O = toObject($this);
var self = IObject(O);
var f = ctx(callbackfn, that, 3);
var length = toLength(self.length);
var index = 0;
var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;
var val, res;
for (;length > index; index++) if (NO_HOLES || index in self) {
val = self[index];
res = f(val, index, O);
if (TYPE) {
if (IS_MAP) result[index] = res; // map
else if (res) switch (TYPE) {
case 3: return true; // some
case 5: return val; // find
case 6: return index; // findIndex
case 2: result.push(val); // filter
} else if (IS_EVERY) return false; // every
}
}
return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;
};
};
},{"./_array-species-create":22,"./_ctx":31,"./_iobject":52,"./_to-length":114,"./_to-object":115}],20:[function(require,module,exports){
var aFunction = require('./_a-function');
var toObject = require('./_to-object');
var IObject = require('./_iobject');
var toLength = require('./_to-length');
module.exports = function (that, callbackfn, aLen, memo, isRight) {
aFunction(callbackfn);
var O = toObject(that);
var self = IObject(O);
var length = toLength(O.length);
var index = isRight ? length - 1 : 0;
var i = isRight ? -1 : 1;
if (aLen < 2) for (;;) {
if (index in self) {
memo = self[index];
index += i;
break;
}
index += i;
if (isRight ? index < 0 : length <= index) {
throw TypeError('Reduce of empty array with no initial value');
}
}
for (;isRight ? index >= 0 : length > index; index += i) if (index in self) {
memo = callbackfn(memo, self[index], index, O);
}
return memo;
};
},{"./_a-function":11,"./_iobject":52,"./_to-length":114,"./_to-object":115}],21:[function(require,module,exports){
var isObject = require('./_is-object');
var isArray = require('./_is-array');
var SPECIES = require('./_wks')('species');
module.exports = function (original) {
var C;
if (isArray(original)) {
C = original.constructor;
// cross-realm fallback
if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
if (isObject(C)) {
C = C[SPECIES];
if (C === null) C = undefined;
}
} return C === undefined ? Array : C;
};
},{"./_is-array":54,"./_is-object":56,"./_wks":125}],22:[function(require,module,exports){
// 9.4.2.3 ArraySpeciesCreate(originalArray, length)
var speciesConstructor = require('./_array-species-constructor');
module.exports = function (original, length) {
return new (speciesConstructor(original))(length);
};
},{"./_array-species-constructor":21}],23:[function(require,module,exports){
'use strict';
var aFunction = require('./_a-function');
var isObject = require('./_is-object');
var invoke = require('./_invoke');
var arraySlice = [].slice;
var factories = {};
var construct = function (F, len, args) {
if (!(len in factories)) {
for (var n = [], i = 0; i < len; i++) n[i] = 'a[' + i + ']';
// eslint-disable-next-line no-new-func
factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')');
} return factories[len](F, args);
};
module.exports = Function.bind || function bind(that /* , ...args */) {
var fn = aFunction(this);
var partArgs = arraySlice.call(arguments, 1);
var bound = function (/* args... */) {
var args = partArgs.concat(arraySlice.call(arguments));
return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that);
};
if (isObject(fn.prototype)) bound.prototype = fn.prototype;
return bound;
};
},{"./_a-function":11,"./_invoke":51,"./_is-object":56}],24:[function(require,module,exports){
// getting tag from 19.1.3.6 Object.prototype.toString()
var cof = require('./_cof');
var TAG = require('./_wks')('toStringTag');
// ES3 wrong here
var ARG = cof(function () { return arguments; }()) == 'Arguments';
// fallback for IE11 Script Access Denied error
var tryGet = function (it, key) {
try {
return it[key];
} catch (e) { /* empty */ }
};
module.exports = function (it) {
var O, T, B;
return it === undefined ? 'Undefined' : it === null ? 'Null'
// @@toStringTag case
: typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
// builtinTag case
: ARG ? cof(O)
// ES3 arguments fallback
: (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
};
},{"./_cof":25,"./_wks":125}],25:[function(require,module,exports){
var toString = {}.toString;
module.exports = function (it) {
return toString.call(it).slice(8, -1);
};
},{}],26:[function(require,module,exports){
'use strict';
var dP = require('./_object-dp').f;
var create = require('./_object-create');
var redefineAll = require('./_redefine-all');
var ctx = require('./_ctx');
var anInstance = require('./_an-instance');
var forOf = require('./_for-of');
var $iterDefine = require('./_iter-define');
var step = require('./_iter-step');
var setSpecies = require('./_set-species');
var DESCRIPTORS = require('./_descriptors');
var fastKey = require('./_meta').fastKey;
var validate = require('./_validate-collection');
var SIZE = DESCRIPTORS ? '_s' : 'size';
var getEntry = function (that, key) {
// fast case
var index = fastKey(key);
var entry;
if (index !== 'F') return that._i[index];
// frozen object case
for (entry = that._f; entry; entry = entry.n) {
if (entry.k == key) return entry;
}
};
module.exports = {
getConstructor: function (wrapper, NAME, IS_MAP, ADDER) {
var C = wrapper(function (that, iterable) {
anInstance(that, C, NAME, '_i');
that._t = NAME; // collection type
that._i = create(null); // index
that._f = undefined; // first entry
that._l = undefined; // last entry
that[SIZE] = 0; // size
if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);
});
redefineAll(C.prototype, {
// 23.1.3.1 Map.prototype.clear()
// 23.2.3.2 Set.prototype.clear()
clear: function clear() {
for (var that = validate(this, NAME), data = that._i, entry = that._f; entry; entry = entry.n) {
entry.r = true;
if (entry.p) entry.p = entry.p.n = undefined;
delete data[entry.i];
}
that._f = that._l = undefined;
that[SIZE] = 0;
},
// 23.1.3.3 Map.prototype.delete(key)
// 23.2.3.4 Set.prototype.delete(value)
'delete': function (key) {
var that = validate(this, NAME);
var entry = getEntry(that, key);
if (entry) {
var next = entry.n;
var prev = entry.p;
delete that._i[entry.i];
entry.r = true;
if (prev) prev.n = next;
if (next) next.p = prev;
if (that._f == entry) that._f = next;
if (that._l == entry) that._l = prev;
that[SIZE]--;
} return !!entry;
},
// 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
// 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
forEach: function forEach(callbackfn /* , that = undefined */) {
validate(this, NAME);
var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);
var entry;
while (entry = entry ? entry.n : this._f) {
f(entry.v, entry.k, this);
// revert to the last existing entry
while (entry && entry.r) entry = entry.p;
}
},
// 23.1.3.7 Map.prototype.has(key)
// 23.2.3.7 Set.prototype.has(value)
has: function has(key) {
return !!getEntry(validate(this, NAME), key);
}
});
if (DESCRIPTORS) dP(C.prototype, 'size', {
get: function () {
return validate(this, NAME)[SIZE];
}
});
return C;
},
def: function (that, key, value) {
var entry = getEntry(that, key);
var prev, index;
// change existing entry
if (entry) {
entry.v = value;
// create new entry
} else {
that._l = entry = {
i: index = fastKey(key, true), // <- index
k: key, // <- key
v: value, // <- value
p: prev = that._l, // <- previous entry
n: undefined, // <- next entry
r: false // <- removed
};
if (!that._f) that._f = entry;
if (prev) prev.n = entry;
that[SIZE]++;
// add to index
if (index !== 'F') that._i[index] = entry;
} return that;
},
getEntry: getEntry,
setStrong: function (C, NAME, IS_MAP) {
// add .keys, .values, .entries, [@@iterator]
// 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
$iterDefine(C, NAME, function (iterated, kind) {
this._t = validate(iterated, NAME); // target
this._k = kind; // kind
this._l = undefined; // previous
}, function () {
var that = this;
var kind = that._k;
var entry = that._l;
// revert to the last existing entry
while (entry && entry.r) entry = entry.p;
// get next entry
if (!that._t || !(that._l = entry = entry ? entry.n : that._t._f)) {
// or finish the iteration
that._t = undefined;
return step(1);
}
// return step by kind
if (kind == 'keys') return step(0, entry.k);
if (kind == 'values') return step(0, entry.v);
return step(0, [entry.k, entry.v]);
}, IS_MAP ? 'entries' : 'values', !IS_MAP, true);
// add [@@species], 23.1.2.2, 23.2.2.2
setSpecies(NAME);
}
};
},{"./_an-instance":14,"./_ctx":31,"./_descriptors":35,"./_for-of":44,"./_iter-define":60,"./_iter-step":62,"./_meta":69,"./_object-create":73,"./_object-dp":74,"./_redefine-all":92,"./_set-species":96,"./_validate-collection":122}],27:[function(require,module,exports){
'use strict';
var redefineAll = require('./_redefine-all');
var getWeak = require('./_meta').getWeak;
var anObject = require('./_an-object');
var isObject = require('./_is-object');
var anInstance = require('./_an-instance');
var forOf = require('./_for-of');
var createArrayMethod = require('./_array-methods');
var $has = require('./_has');
var validate = require('./_validate-collection');
var arrayFind = createArrayMethod(5);
var arrayFindIndex = createArrayMethod(6);
var id = 0;
// fallback for uncaught frozen keys
var uncaughtFrozenStore = function (that) {
return that._l || (that._l = new UncaughtFrozenStore());
};
var UncaughtFrozenStore = function () {
this.a = [];
};
var findUncaughtFrozen = function (store, key) {
return arrayFind(store.a, function (it) {
return it[0] === key;
});
};
UncaughtFrozenStore.prototype = {
get: function (key) {
var entry = findUncaughtFrozen(this, key);
if (entry) return entry[1];
},
has: function (key) {
return !!findUncaughtFrozen(this, key);
},
set: function (key, value) {
var entry = findUncaughtFrozen(this, key);
if (entry) entry[1] = value;
else this.a.push([key, value]);
},
'delete': function (key) {
var index = arrayFindIndex(this.a, function (it) {
return it[0] === key;
});
if (~index) this.a.splice(index, 1);
return !!~index;
}
};
module.exports = {
getConstructor: function (wrapper, NAME, IS_MAP, ADDER) {
var C = wrapper(function (that, iterable) {
anInstance(that, C, NAME, '_i');
that._t = NAME; // collection type
that._i = id++; // collection id
that._l = undefined; // leak store for uncaught frozen objects
if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);
});
redefineAll(C.prototype, {
// 23.3.3.2 WeakMap.prototype.delete(key)
// 23.4.3.3 WeakSet.prototype.delete(value)
'delete': function (key) {
if (!isObject(key)) return false;
var data = getWeak(key);
if (data === true) return uncaughtFrozenStore(validate(this, NAME))['delete'](key);
return data && $has(data, this._i) && delete data[this._i];
},
// 23.3.3.4 WeakMap.prototype.has(key)
// 23.4.3.4 WeakSet.prototype.has(value)
has: function has(key) {
if (!isObject(key)) return false;
var data = getWeak(key);
if (data === true) return uncaughtFrozenStore(validate(this, NAME)).has(key);
return data && $has(data, this._i);
}
});
return C;
},
def: function (that, key, value) {
var data = getWeak(anObject(key), true);
if (data === true) uncaughtFrozenStore(that).set(key, value);
else data[that._i] = value;
return that;
},
ufstore: uncaughtFrozenStore
};
},{"./_an-instance":14,"./_an-object":15,"./_array-methods":19,"./_for-of":44,"./_has":46,"./_is-object":56,"./_meta":69,"./_redefine-all":92,"./_validate-collection":122}],28:[function(require,module,exports){
'use strict';
var global = require('./_global');
var $export = require('./_export');
var redefine = require('./_redefine');
var redefineAll = require('./_redefine-all');
var meta = require('./_meta');
var forOf = require('./_for-of');
var anInstance = require('./_an-instance');
var isObject = require('./_is-object');
var fails = require('./_fails');
var $iterDetect = require('./_iter-detect');
var setToStringTag = require('./_set-to-string-tag');
var inheritIfRequired = require('./_inherit-if-required');
module.exports = function (NAME, wrapper, methods, common, IS_MAP, IS_WEAK) {
var Base = global[NAME];
var C = Base;
var ADDER = IS_MAP ? 'set' : 'add';
var proto = C && C.prototype;
var O = {};
var fixMethod = function (KEY) {
var fn = proto[KEY];
redefine(proto, KEY,
KEY == 'delete' ? function (a) {
return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
} : KEY == 'has' ? function has(a) {
return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
} : KEY == 'get' ? function get(a) {
return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);
} : KEY == 'add' ? function add(a) { fn.call(this, a === 0 ? 0 : a); return this; }
: function set(a, b) { fn.call(this, a === 0 ? 0 : a, b); return this; }
);
};
if (typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function () {
new C().entries().next();
}))) {
// create collection constructor
C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);
redefineAll(C.prototype, methods);
meta.NEED = true;
} else {
var instance = new C();
// early implementations not supports chaining
var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;
// V8 ~ Chromium 40- weak-collections throws on primitives, but should return false
var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });
// most early implementations doesn't supports iterables, most modern - not close it correctly
var ACCEPT_ITERABLES = $iterDetect(function (iter) { new C(iter); }); // eslint-disable-line no-new
// for early implementations -0 and +0 not the same
var BUGGY_ZERO = !IS_WEAK && fails(function () {
// V8 ~ Chromium 42- fails only with 5+ elements
var $instance = new C();
var index = 5;
while (index--) $instance[ADDER](index, index);
return !$instance.has(-0);
});
if (!ACCEPT_ITERABLES) {
C = wrapper(function (target, iterable) {
anInstance(target, C, NAME);
var that = inheritIfRequired(new Base(), target, C);
if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);
return that;
});
C.prototype = proto;
proto.constructor = C;
}
if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {
fixMethod('delete');
fixMethod('has');
IS_MAP && fixMethod('get');
}
if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);
// weak collections should not contains .clear method
if (IS_WEAK && proto.clear) delete proto.clear;
}
setToStringTag(C, NAME);
O[NAME] = C;
$export($export.G + $export.W + $export.F * (C != Base), O);
if (!IS_WEAK) common.setStrong(C, NAME, IS_MAP);
return C;
};
},{"./_an-instance":14,"./_export":39,"./_fails":41,"./_for-of":44,"./_global":45,"./_inherit-if-required":50,"./_is-object":56,"./_iter-detect":61,"./_meta":69,"./_redefine":93,"./_redefine-all":92,"./_set-to-string-tag":97}],29:[function(require,module,exports){
var core = module.exports = { version: '2.5.7' };
if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
},{}],30:[function(require,module,exports){
'use strict';
var $defineProperty = require('./_object-dp');
var createDesc = require('./_property-desc');
module.exports = function (object, index, value) {
if (index in object) $defineProperty.f(object, index, createDesc(0, value));
else object[index] = value;
};
},{"./_object-dp":74,"./_property-desc":91}],31:[function(require,module,exports){
// optional / simple context binding
var aFunction = require('./_a-function');
module.exports = function (fn, that, length) {
aFunction(fn);
if (that === undefined) return fn;
switch (length) {
case 1: return function (a) {
return fn.call(that, a);
};
case 2: return function (a, b) {
return fn.call(that, a, b);
};
case 3: return function (a, b, c) {
return fn.call(that, a, b, c);
};
}
return function (/* ...args */) {
return fn.apply(that, arguments);
};
};
},{"./_a-function":11}],32:[function(require,module,exports){
'use strict';
// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()
var fails = require('./_fails');
var getTime = Date.prototype.getTime;
var $toISOString = Date.prototype.toISOString;
var lz = function (num) {
return num > 9 ? num : '0' + num;
};
// PhantomJS / old WebKit has a broken implementations
module.exports = (fails(function () {
return $toISOString.call(new Date(-5e13 - 1)) != '0385-07-25T07:06:39.999Z';
}) || !fails(function () {
$toISOString.call(new Date(NaN));
})) ? function toISOString() {
if (!isFinite(getTime.call(this))) throw RangeError('Invalid time value');
var d = this;
var y = d.getUTCFullYear();
var m = d.getUTCMilliseconds();
var s = y < 0 ? '-' : y > 9999 ? '+' : '';
return s + ('00000' + Math.abs(y)).slice(s ? -6 : -4) +
'-' + lz(d.getUTCMonth() + 1) + '-' + lz(d.getUTCDate()) +
'T' + lz(d.getUTCHours()) + ':' + lz(d.getUTCMinutes()) +
':' + lz(d.getUTCSeconds()) + '.' + (m > 99 ? m : '0' + lz(m)) + 'Z';
} : $toISOString;
},{"./_fails":41}],33:[function(require,module,exports){
'use strict';
var anObject = require('./_an-object');
var toPrimitive = require('./_to-primitive');
var NUMBER = 'number';
module.exports = function (hint) {
if (hint !== 'string' && hint !== NUMBER && hint !== 'default') throw TypeError('Incorrect hint');
return toPrimitive(anObject(this), hint != NUMBER);
};
},{"./_an-object":15,"./_to-primitive":116}],34:[function(require,module,exports){
// 7.2.1 RequireObjectCoercible(argument)
module.exports = function (it) {
if (it == undefined) throw TypeError("Can't call method on " + it);
return it;
};
},{}],35:[function(require,module,exports){
// Thank's IE8 for his funny defineProperty
module.exports = !require('./_fails')(function () {
return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
});
},{"./_fails":41}],36:[function(require,module,exports){
var isObject = require('./_is-object');
var document = require('./_global').document;
// typeof document.createElement is 'object' in old IE
var is = isObject(document) && isObject(document.createElement);
module.exports = function (it) {
return is ? document.createElement(it) : {};
};
},{"./_global":45,"./_is-object":56}],37:[function(require,module,exports){
// IE 8- don't enum bug keys
module.exports = (
'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
).split(',');
},{}],38:[function(require,module,exports){
// all enumerable object keys, includes symbols
var getKeys = require('./_object-keys');
var gOPS = require('./_object-gops');
var pIE = require('./_object-pie');
module.exports = function (it) {
var result = getKeys(it);
var getSymbols = gOPS.f;
if (getSymbols) {
var symbols = getSymbols(it);
var isEnum = pIE.f;
var i = 0;
var key;
while (symbols.length > i) if (isEnum.call(it, key = symbols[i++])) result.push(key);
} return result;
};
},{"./_object-gops":79,"./_object-keys":82,"./_object-pie":83}],39:[function(require,module,exports){
var global = require('./_global');
var core = require('./_core');
var hide = require('./_hide');
var redefine = require('./_redefine');
var ctx = require('./_ctx');
var PROTOTYPE = 'prototype';
var $export = function (type, name, source) {
var IS_FORCED = type & $export.F;
var IS_GLOBAL = type & $export.G;
var IS_STATIC = type & $export.S;
var IS_PROTO = type & $export.P;
var IS_BIND = type & $export.B;
var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE];
var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});
var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});
var key, own, out, exp;
if (IS_GLOBAL) source = name;
for (key in source) {
// contains in native
own = !IS_FORCED && target && target[key] !== undefined;
// export native or passed
out = (own ? target : source)[key];
// bind timers to global for call from export context
exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
// extend global
if (target) redefine(target, key, out, type & $export.U);
// export
if (exports[key] != out) hide(exports, key, exp);
if (IS_PROTO && expProto[key] != out) expProto[key] = out;
}
};
global.core = core;
// type bitmap
$export.F = 1; // forced
$export.G = 2; // global
$export.S = 4; // static
$export.P = 8; // proto
$export.B = 16; // bind
$export.W = 32; // wrap
$export.U = 64; // safe
$export.R = 128; // real proto method for `library`
module.exports = $export;
},{"./_core":29,"./_ctx":31,"./_global":45,"./_hide":47,"./_redefine":93}],40:[function(require,module,exports){
var MATCH = require('./_wks')('match');
module.exports = function (KEY) {
var re = /./;
try {
'/./'[KEY](re);
} catch (e) {
try {
re[MATCH] = false;
return !'/./'[KEY](re);
} catch (f) { /* empty */ }
} return true;
};
},{"./_wks":125}],41:[function(require,module,exports){
module.exports = function (exec) {
try {
return !!exec();
} catch (e) {
return true;
}
};
},{}],42:[function(require,module,exports){
'use strict';
var hide = require('./_hide');
var redefine = require('./_redefine');
var fails = require('./_fails');
var defined = require('./_defined');
var wks = require('./_wks');
module.exports = function (KEY, length, exec) {
var SYMBOL = wks(KEY);
var fns = exec(defined, SYMBOL, ''[KEY]);
var strfn = fns[0];
var rxfn = fns[1];
if (fails(function () {
var O = {};
O[SYMBOL] = function () { return 7; };
return ''[KEY](O) != 7;
})) {
redefine(String.prototype, KEY, strfn);
hide(RegExp.prototype, SYMBOL, length == 2
// 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
// 21.2.5.11 RegExp.prototype[@@split](string, limit)
? function (string, arg) { return rxfn.call(string, this, arg); }
// 21.2.5.6 RegExp.prototype[@@match](string)
// 21.2.5.9 RegExp.prototype[@@search](string)
: function (string) { return rxfn.call(string, this); }
);
}
};
},{"./_defined":34,"./_fails":41,"./_hide":47,"./_redefine":93,"./_wks":125}],43:[function(require,module,exports){
'use strict';
// 21.2.5.3 get RegExp.prototype.flags
var anObject = require('./_an-object');
module.exports = function () {
var that = anObject(this);
var result = '';
if (that.global) result += 'g';
if (that.ignoreCase) result += 'i';
if (that.multiline) result += 'm';
if (that.unicode) result += 'u';
if (that.sticky) result += 'y';
return result;
};
},{"./_an-object":15}],44:[function(require,module,exports){
var ctx = require('./_ctx');
var call = require('./_iter-call');
var isArrayIter = require('./_is-array-iter');
var anObject = require('./_an-object');
var toLength = require('./_to-length');
var getIterFn = require('./core.get-iterator-method');
var BREAK = {};
var RETURN = {};
var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {
var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable);
var f = ctx(fn, that, entries ? 2 : 1);
var index = 0;
var length, step, iterator, result;
if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');
// fast case for arrays with default iterator
if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {
result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
if (result === BREAK || result === RETURN) return result;
} else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {
result = call(iterator, f, step.value, entries);
if (result === BREAK || result === RETURN) return result;
}
};
exports.BREAK = BREAK;
exports.RETURN = RETURN;
},{"./_an-object":15,"./_ctx":31,"./_is-array-iter":53,"./_iter-call":58,"./_to-length":114,"./core.get-iterator-method":126}],45:[function(require,module,exports){
// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
var global = module.exports = typeof window != 'undefined' && window.Math == Math
? window : typeof self != 'undefined' && self.Math == Math ? self
// eslint-disable-next-line no-new-func
: Function('return this')();
if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
},{}],46:[function(require,module,exports){
var hasOwnProperty = {}.hasOwnProperty;
module.exports = function (it, key) {
return hasOwnProperty.call(it, key);
};
},{}],47:[function(require,module,exports){
var dP = require('./_object-dp');
var createDesc = require('./_property-desc');
module.exports = require('./_descriptors') ? function (object, key, value) {
return dP.f(object, key, createDesc(1, value));
} : function (object, key, value) {
object[key] = value;
return object;
};
},{"./_descriptors":35,"./_object-dp":74,"./_property-desc":91}],48:[function(require,module,exports){
var document = require('./_global').document;
module.exports = document && document.documentElement;
},{"./_global":45}],49:[function(require,module,exports){
module.exports = !require('./_descriptors') && !require('./_fails')(function () {
return Object.defineProperty(require('./_dom-create')('div'), 'a', { get: function () { return 7; } }).a != 7;
});
},{"./_descriptors":35,"./_dom-create":36,"./_fails":41}],50:[function(require,module,exports){
var isObject = require('./_is-object');
var setPrototypeOf = require('./_set-proto').set;
module.exports = function (that, target, C) {
var S = target.constructor;
var P;
if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf) {
setPrototypeOf(that, P);
} return that;
};
},{"./_is-object":56,"./_set-proto":95}],51:[function(require,module,exports){
// fast apply, http://jsperf.lnkit.com/fast-apply/5
module.exports = function (fn, args, that) {
var un = that === undefined;
switch (args.length) {
case 0: return un ? fn()
: fn.call(that);
case 1: return un ? fn(args[0])
: fn.call(that, args[0]);
case 2: return un ? fn(args[0], args[1])
: fn.call(that, args[0], args[1]);
case 3: return un ? fn(args[0], args[1], args[2])
: fn.call(that, args[0], args[1], args[2]);
case 4: return un ? fn(args[0], args[1], args[2], args[3])
: fn.call(that, args[0], args[1], args[2], args[3]);
} return fn.apply(that, args);
};
},{}],52:[function(require,module,exports){
// fallback for non-array-like ES3 and non-enumerable old V8 strings
var cof = require('./_cof');
// eslint-disable-next-line no-prototype-builtins
module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
return cof(it) == 'String' ? it.split('') : Object(it);
};
},{"./_cof":25}],53:[function(require,module,exports){
// check on default Array iterator
var Iterators = require('./_iterators');
var ITERATOR = require('./_wks')('iterator');
var ArrayProto = Array.prototype;
module.exports = function (it) {
return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);
};
},{"./_iterators":63,"./_wks":125}],54:[function(require,module,exports){
// 7.2.2 IsArray(argument)
var cof = require('./_cof');
module.exports = Array.isArray || function isArray(arg) {
return cof(arg) == 'Array';
};
},{"./_cof":25}],55:[function(require,module,exports){
// 20.1.2.3 Number.isInteger(number)
var isObject = require('./_is-object');
var floor = Math.floor;
module.exports = function isInteger(it) {
return !isObject(it) && isFinite(it) && floor(it) === it;
};
},{"./_is-object":56}],56:[function(require,module,exports){
module.exports = function (it) {
return typeof it === 'object' ? it !== null : typeof it === 'function';
};
},{}],57:[function(require,module,exports){
// 7.2.8 IsRegExp(argument)
var isObject = require('./_is-object');
var cof = require('./_cof');
var MATCH = require('./_wks')('match');
module.exports = function (it) {
var isRegExp;
return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');
};
},{"./_cof":25,"./_is-object":56,"./_wks":125}],58:[function(require,module,exports){
// call something on iterator step with safe closing on error
var anObject = require('./_an-object');
module.exports = function (iterator, fn, value, entries) {
try {
return entries ? fn(anObject(value)[0], value[1]) : fn(value);
// 7.4.6 IteratorClose(iterator, completion)
} catch (e) {
var ret = iterator['return'];
if (ret !== undefined) anObject(ret.call(iterator));
throw e;
}
};
},{"./_an-object":15}],59:[function(require,module,exports){
'use strict';
var create = require('./_object-create');
var descriptor = require('./_property-desc');
var setToStringTag = require('./_set-to-string-tag');
var IteratorPrototype = {};
// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
require('./_hide')(IteratorPrototype, require('./_wks')('iterator'), function () { return this; });
module.exports = function (Constructor, NAME, next) {
Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });
setToStringTag(Constructor, NAME + ' Iterator');
};
},{"./_hide":47,"./_object-create":73,"./_property-desc":91,"./_set-to-string-tag":97,"./_wks":125}],60:[function(require,module,exports){
'use strict';
var LIBRARY = require('./_library');
var $export = require('./_export');
var redefine = require('./_redefine');
var hide = require('./_hide');
var Iterators = require('./_iterators');
var $iterCreate = require('./_iter-create');
var setToStringTag = require('./_set-to-string-tag');
var getPrototypeOf = require('./_object-gpo');
var ITERATOR = require('./_wks')('iterator');
var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`
var FF_ITERATOR = '@@iterator';
var KEYS = 'keys';
var VALUES = 'values';
var returnThis = function () { return this; };
module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
$iterCreate(Constructor, NAME, next);
var getMethod = function (kind) {
if (!BUGGY && kind in proto) return proto[kind];
switch (kind) {
case KEYS: return function keys() { return new Constructor(this, kind); };
case VALUES: return function values() { return new Constructor(this, kind); };
} return function entries() { return new Constructor(this, kind); };
};
var TAG = NAME + ' Iterator';
var DEF_VALUES = DEFAULT == VALUES;
var VALUES_BUG = false;
var proto = Base.prototype;
var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];
var $default = $native || getMethod(DEFAULT);
var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;
var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;
var methods, key, IteratorPrototype;
// Fix native
if ($anyNative) {
IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));
if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {
// Set @@toStringTag to native iterators
setToStringTag(IteratorPrototype, TAG, true);
// fix for some old engines
if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis);
}
}
// fix Array#{values, @@iterator}.name in V8 / FF
if (DEF_VALUES && $native && $native.name !== VALUES) {
VALUES_BUG = true;
$default = function values() { return $native.call(this); };
}
// Define iterator
if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {
hide(proto, ITERATOR, $default);
}
// Plug for library
Iterators[NAME] = $default;
Iterators[TAG] = returnThis;
if (DEFAULT) {
methods = {
values: DEF_VALUES ? $default : getMethod(VALUES),
keys: IS_SET ? $default : getMethod(KEYS),
entries: $entries
};
if (FORCED) for (key in methods) {
if (!(key in proto)) redefine(proto, key, methods[key]);
} else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);
}
return methods;
};
},{"./_export":39,"./_hide":47,"./_iter-create":59,"./_iterators":63,"./_library":64,"./_object-gpo":80,"./_redefine":93,"./_set-to-string-tag":97,"./_wks":125}],61:[function(require,module,exports){
var ITERATOR = require('./_wks')('iterator');
var SAFE_CLOSING = false;
try {
var riter = [7][ITERATOR]();
riter['return'] = function () { SAFE_CLOSING = true; };
// eslint-disable-next-line no-throw-literal
Array.from(riter, function () { throw 2; });
} catch (e) { /* empty */ }
module.exports = function (exec, skipClosing) {
if (!skipClosing && !SAFE_CLOSING) return false;
var safe = false;
try {
var arr = [7];
var iter = arr[ITERATOR]();
iter.next = function () { return { done: safe = true }; };
arr[ITERATOR] = function () { return iter; };
exec(arr);
} catch (e) { /* empty */ }
return safe;
};
},{"./_wks":125}],62:[function(require,module,exports){
module.exports = function (done, value) {
return { value: value, done: !!done };
};
},{}],63:[function(require,module,exports){
module.exports = {};
},{}],64:[function(require,module,exports){
module.exports = false;
},{}],65:[function(require,module,exports){
// 20.2.2.14 Math.expm1(x)
var $expm1 = Math.expm1;
module.exports = (!$expm1
// Old FF bug
|| $expm1(10) > 22025.465794806719 || $expm1(10) < 22025.4657948067165168
// Tor Browser bug
|| $expm1(-2e-17) != -2e-17
) ? function expm1(x) {
return (x = +x) == 0 ? x : x > -1e-6 && x < 1e-6 ? x + x * x / 2 : Math.exp(x) - 1;
} : $expm1;
},{}],66:[function(require,module,exports){
// 20.2.2.16 Math.fround(x)
var sign = require('./_math-sign');
var pow = Math.pow;
var EPSILON = pow(2, -52);
var EPSILON32 = pow(2, -23);
var MAX32 = pow(2, 127) * (2 - EPSILON32);
var MIN32 = pow(2, -126);
var roundTiesToEven = function (n) {
return n + 1 / EPSILON - 1 / EPSILON;
};
module.exports = Math.fround || function fround(x) {
var $abs = Math.abs(x);
var $sign = sign(x);
var a, result;
if ($abs < MIN32) return $sign * roundTiesToEven($abs / MIN32 / EPSILON32) * MIN32 * EPSILON32;
a = (1 + EPSILON32 / EPSILON) * $abs;
result = a - (a - $abs);
// eslint-disable-next-line no-self-compare
if (result > MAX32 || result != result) return $sign * Infinity;
return $sign * result;
};
},{"./_math-sign":68}],67:[function(require,module,exports){
// 20.2.2.20 Math.log1p(x)
module.exports = Math.log1p || function log1p(x) {
return (x = +x) > -1e-8 && x < 1e-8 ? x - x * x / 2 : Math.log(1 + x);
};
},{}],68:[function(require,module,exports){
// 20.2.2.28 Math.sign(x)
module.exports = Math.sign || function sign(x) {
// eslint-disable-next-line no-self-compare
return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1;
};
},{}],69:[function(require,module,exports){
var META = require('./_uid')('meta');
var isObject = require('./_is-object');
var has = require('./_has');
var setDesc = require('./_object-dp').f;
var id = 0;
var isExtensible = Object.isExtensible || function () {
return true;
};
var FREEZE = !require('./_fails')(function () {
return isExtensible(Object.preventExtensions({}));
});
var setMeta = function (it) {
setDesc(it, META, { value: {
i: 'O' + ++id, // object ID
w: {} // weak collections IDs
} });
};
var fastKey = function (it, create) {
// return primitive with prefix
if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
if (!has(it, META)) {
// can't set metadata to uncaught frozen object
if (!isExtensible(it)) return 'F';
// not necessary to add metadata
if (!create) return 'E';
// add missing metadata
setMeta(it);
// return object ID
} return it[META].i;
};
var getWeak = function (it, create) {
if (!has(it, META)) {
// can't set metadata to uncaught frozen object
if (!isExtensible(it)) return true;
// not necessary to add metadata
if (!create) return false;
// add missing metadata
setMeta(it);
// return hash weak collections IDs
} return it[META].w;
};
// add metadata on freeze-family methods calling
var onFreeze = function (it) {
if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it);
return it;
};
var meta = module.exports = {
KEY: META,
NEED: false,
fastKey: fastKey,
getWeak: getWeak,
onFreeze: onFreeze
};
},{"./_fails":41,"./_has":46,"./_is-object":56,"./_object-dp":74,"./_uid":120}],70:[function(require,module,exports){
var global = require('./_global');
var macrotask = require('./_task').set;
var Observer = global.MutationObserver || global.WebKitMutationObserver;
var process = global.process;
var Promise = global.Promise;
var isNode = require('./_cof')(process) == 'process';
module.exports = function () {
var head, last, notify;
var flush = function () {
var parent, fn;
if (isNode && (parent = process.domain)) parent.exit();
while (head) {
fn = head.fn;
head = head.next;
try {
fn();
} catch (e) {
if (head) notify();
else last = undefined;
throw e;
}
} last = undefined;
if (parent) parent.enter();
};
// Node.js
if (isNode) {
notify = function () {
process.nextTick(flush);
};
// browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339
} else if (Observer && !(global.navigator && global.navigator.standalone)) {
var toggle = true;
var node = document.createTextNode('');
new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new
notify = function () {
node.data = toggle = !toggle;
};
// environments with maybe non-completely correct, but existent Promise
} else if (Promise && Promise.resolve) {
// Promise.resolve without an argument throws an error in LG WebOS 2
var promise = Promise.resolve(undefined);
notify = function () {
promise.then(flush);
};
// for other environments - macrotask based on:
// - setImmediate
// - MessageChannel
// - window.postMessag
// - onreadystatechange
// - setTimeout
} else {
notify = function () {
// strange IE + webpack dev server bug - use .call(global)
macrotask.call(global, flush);
};
}
return function (fn) {
var task = { fn: fn, next: undefined };
if (last) last.next = task;
if (!head) {
head = task;
notify();
} last = task;
};
};
},{"./_cof":25,"./_global":45,"./_task":109}],71:[function(require,module,exports){
'use strict';
// 25.4.1.5 NewPromiseCapability(C)
var aFunction = require('./_a-function');
function PromiseCapability(C) {
var resolve, reject;
this.promise = new C(function ($$resolve, $$reject) {
if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
resolve = $$resolve;
reject = $$reject;
});
this.resolve = aFunction(resolve);
this.reject = aFunction(reject);
}
module.exports.f = function (C) {
return new PromiseCapability(C);
};
},{"./_a-function":11}],72:[function(require,module,exports){
'use strict';
// 19.1.2.1 Object.assign(target, source, ...)
var getKeys = require('./_object-keys');
var gOPS = require('./_object-gops');
var pIE = require('./_object-pie');
var toObject = require('./_to-object');
var IObject = require('./_iobject');
var $assign = Object.assign;
// should work with symbols and should have deterministic property order (V8 bug)
module.exports = !$assign || require('./_fails')(function () {
var A = {};
var B = {};
// eslint-disable-next-line no-undef
var S = Symbol();
var K = 'abcdefghijklmnopqrst';
A[S] = 7;
K.split('').forEach(function (k) { B[k] = k; });
return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
}) ? function assign(target, source) { // eslint-disable-line no-unused-vars
var T = toObject(target);
var aLen = arguments.length;
var index = 1;
var getSymbols = gOPS.f;
var isEnum = pIE.f;
while (aLen > index) {
var S = IObject(arguments[index++]);
var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S);
var length = keys.length;
var j = 0;
var key;
while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key];
} return T;
} : $assign;
},{"./_fails":41,"./_iobject":52,"./_object-gops":79,"./_object-keys":82,"./_object-pie":83,"./_to-object":115}],73:[function(require,module,exports){
// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
var anObject = require('./_an-object');
var dPs = require('./_object-dps');
var enumBugKeys = require('./_enum-bug-keys');
var IE_PROTO = require('./_shared-key')('IE_PROTO');
var Empty = function () { /* empty */ };
var PROTOTYPE = 'prototype';
// Create object with fake `null` prototype: use iframe Object with cleared prototype
var createDict = function () {
// Thrash, waste and sodomy: IE GC bug
var iframe = require('./_dom-create')('iframe');
var i = enumBugKeys.length;
var lt = '<';
var gt = '>';
var iframeDocument;
iframe.style.display = 'none';
require('./_html').appendChild(iframe);
iframe.src = 'javascript:'; // eslint-disable-line no-script-url
// createDict = iframe.contentWindow.Object;
// html.removeChild(iframe);
iframeDocument = iframe.contentWindow.document;
iframeDocument.open();
iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
iframeDocument.close();
createDict = iframeDocument.F;
while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];
return createDict();
};
module.exports = Object.create || function create(O, Properties) {
var result;
if (O !== null) {
Empty[PROTOTYPE] = anObject(O);
result = new Empty();
Empty[PROTOTYPE] = null;
// add "__proto__" for Object.getPrototypeOf polyfill
result[IE_PROTO] = O;
} else result = createDict();
return Properties === undefined ? result : dPs(result, Properties);
};
},{"./_an-object":15,"./_dom-create":36,"./_enum-bug-keys":37,"./_html":48,"./_object-dps":75,"./_shared-key":98}],74:[function(require,module,exports){
var anObject = require('./_an-object');
var IE8_DOM_DEFINE = require('./_ie8-dom-define');
var toPrimitive = require('./_to-primitive');
var dP = Object.defineProperty;
exports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes) {
anObject(O);
P = toPrimitive(P, true);
anObject(Attributes);
if (IE8_DOM_DEFINE) try {
return dP(O, P, Attributes);
} catch (e) { /* empty */ }
if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
if ('value' in Attributes) O[P] = Attributes.value;
return O;
};
},{"./_an-object":15,"./_descriptors":35,"./_ie8-dom-define":49,"./_to-primitive":116}],75:[function(require,module,exports){
var dP = require('./_object-dp');
var anObject = require('./_an-object');
var getKeys = require('./_object-keys');
module.exports = require('./_descriptors') ? Object.defineProperties : function defineProperties(O, Properties) {
anObject(O);
var keys = getKeys(Properties);
var length = keys.length;
var i = 0;
var P;
while (length > i) dP.f(O, P = keys[i++], Properties[P]);
return O;
};
},{"./_an-object":15,"./_descriptors":35,"./_object-dp":74,"./_object-keys":82}],76:[function(require,module,exports){
var pIE = require('./_object-pie');
var createDesc = require('./_property-desc');
var toIObject = require('./_to-iobject');
var toPrimitive = require('./_to-primitive');
var has = require('./_has');
var IE8_DOM_DEFINE = require('./_ie8-dom-define');
var gOPD = Object.getOwnPropertyDescriptor;
exports.f = require('./_descriptors') ? gOPD : function getOwnPropertyDescriptor(O, P) {
O = toIObject(O);
P = toPrimitive(P, true);
if (IE8_DOM_DEFINE) try {
return gOPD(O, P);
} catch (e) { /* empty */ }
if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]);
};
},{"./_descriptors":35,"./_has":46,"./_ie8-dom-define":49,"./_object-pie":83,"./_property-desc":91,"./_to-iobject":113,"./_to-primitive":116}],77:[function(require,module,exports){
// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
var toIObject = require('./_to-iobject');
var gOPN = require('./_object-gopn').f;
var toString = {}.toString;
var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
? Object.getOwnPropertyNames(window) : [];
var getWindowNames = function (it) {
try {
return gOPN(it);
} catch (e) {
return windowNames.slice();
}
};
module.exports.f = function getOwnPropertyNames(it) {
return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it));
};
},{"./_object-gopn":78,"./_to-iobject":113}],78:[function(require,module,exports){
// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)
var $keys = require('./_object-keys-internal');
var hiddenKeys = require('./_enum-bug-keys').concat('length', 'prototype');
exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
return $keys(O, hiddenKeys);
};
},{"./_enum-bug-keys":37,"./_object-keys-internal":81}],79:[function(require,module,exports){
exports.f = Object.getOwnPropertySymbols;
},{}],80:[function(require,module,exports){
// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
var has = require('./_has');
var toObject = require('./_to-object');
var IE_PROTO = require('./_shared-key')('IE_PROTO');
var ObjectProto = Object.prototype;
module.exports = Object.getPrototypeOf || function (O) {
O = toObject(O);
if (has(O, IE_PROTO)) return O[IE_PROTO];
if (typeof O.constructor == 'function' && O instanceof O.constructor) {
return O.constructor.prototype;
} return O instanceof Object ? ObjectProto : null;
};
},{"./_has":46,"./_shared-key":98,"./_to-object":115}],81:[function(require,module,exports){
var has = require('./_has');
var toIObject = require('./_to-iobject');
var arrayIndexOf = require('./_array-includes')(false);
var IE_PROTO = require('./_shared-key')('IE_PROTO');
module.exports = function (object, names) {
var O = toIObject(object);
var i = 0;
var result = [];
var key;
for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key);
// Don't enum bug & hidden keys
while (names.length > i) if (has(O, key = names[i++])) {
~arrayIndexOf(result, key) || result.push(key);
}
return result;
};
},{"./_array-includes":18,"./_has":46,"./_shared-key":98,"./_to-iobject":113}],82:[function(require,module,exports){
// 19.1.2.14 / 15.2.3.14 Object.keys(O)
var $keys = require('./_object-keys-internal');
var enumBugKeys = require('./_enum-bug-keys');
module.exports = Object.keys || function keys(O) {
return $keys(O, enumBugKeys);
};
},{"./_enum-bug-keys":37,"./_object-keys-internal":81}],83:[function(require,module,exports){
exports.f = {}.propertyIsEnumerable;
},{}],84:[function(require,module,exports){
// most Object methods by ES6 should accept primitives
var $export = require('./_export');
var core = require('./_core');
var fails = require('./_fails');
module.exports = function (KEY, exec) {
var fn = (core.Object || {})[KEY] || Object[KEY];
var exp = {};
exp[KEY] = exec(fn);
$export($export.S + $export.F * fails(function () { fn(1); }), 'Object', exp);
};
},{"./_core":29,"./_export":39,"./_fails":41}],85:[function(require,module,exports){
var getKeys = require('./_object-keys');
var toIObject = require('./_to-iobject');
var isEnum = require('./_object-pie').f;
module.exports = function (isEntries) {
return function (it) {
var O = toIObject(it);
var keys = getKeys(O);
var length = keys.length;
var i = 0;
var result = [];
var key;
while (length > i) if (isEnum.call(O, key = keys[i++])) {
result.push(isEntries ? [key, O[key]] : O[key]);
} return result;
};
};
},{"./_object-keys":82,"./_object-pie":83,"./_to-iobject":113}],86:[function(require,module,exports){
// all object keys, includes non-enumerable and symbols
var gOPN = require('./_object-gopn');
var gOPS = require('./_object-gops');
var anObject = require('./_an-object');
var Reflect = require('./_global').Reflect;
module.exports = Reflect && Reflect.ownKeys || function ownKeys(it) {
var keys = gOPN.f(anObject(it));
var getSymbols = gOPS.f;
return getSymbols ? keys.concat(getSymbols(it)) : keys;
};
},{"./_an-object":15,"./_global":45,"./_object-gopn":78,"./_object-gops":79}],87:[function(require,module,exports){
var $parseFloat = require('./_global').parseFloat;
var $trim = require('./_string-trim').trim;
module.exports = 1 / $parseFloat(require('./_string-ws') + '-0') !== -Infinity ? function parseFloat(str) {
var string = $trim(String(str), 3);
var result = $parseFloat(string);
return result === 0 && string.charAt(0) == '-' ? -0 : result;
} : $parseFloat;
},{"./_global":45,"./_string-trim":107,"./_string-ws":108}],88:[function(require,module,exports){
var $parseInt = require('./_global').parseInt;
var $trim = require('./_string-trim').trim;
var ws = require('./_string-ws');
var hex = /^[-+]?0[xX]/;
module.exports = $parseInt(ws + '08') !== 8 || $parseInt(ws + '0x16') !== 22 ? function parseInt(str, radix) {
var string = $trim(String(str), 3);
return $parseInt(string, (radix >>> 0) || (hex.test(string) ? 16 : 10));
} : $parseInt;
},{"./_global":45,"./_string-trim":107,"./_string-ws":108}],89:[function(require,module,exports){
module.exports = function (exec) {
try {
return { e: false, v: exec() };
} catch (e) {
return { e: true, v: e };
}
};
},{}],90:[function(require,module,exports){
var anObject = require('./_an-object');
var isObject = require('./_is-object');
var newPromiseCapability = require('./_new-promise-capability');
module.exports = function (C, x) {
anObject(C);
if (isObject(x) && x.constructor === C) return x;
var promiseCapability = newPromiseCapability.f(C);
var resolve = promiseCapability.resolve;
resolve(x);
return promiseCapability.promise;
};
},{"./_an-object":15,"./_is-object":56,"./_new-promise-capability":71}],91:[function(require,module,exports){
module.exports = function (bitmap, value) {
return {
enumerable: !(bitmap & 1),
configurable: !(bitmap & 2),
writable: !(bitmap & 4),
value: value
};
};
},{}],92:[function(require,module,exports){
var redefine = require('./_redefine');
module.exports = function (target, src, safe) {
for (var key in src) redefine(target, key, src[key], safe);
return target;
};
},{"./_redefine":93}],93:[function(require,module,exports){
var global = require('./_global');
var hide = require('./_hide');
var has = require('./_has');
var SRC = require('./_uid')('src');
var TO_STRING = 'toString';
var $toString = Function[TO_STRING];
var TPL = ('' + $toString).split(TO_STRING);
require('./_core').inspectSource = function (it) {
return $toString.call(it);
};
(module.exports = function (O, key, val, safe) {
var isFunction = typeof val == 'function';
if (isFunction) has(val, 'name') || hide(val, 'name', key);
if (O[key] === val) return;
if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
if (O === global) {
O[key] = val;
} else if (!safe) {
delete O[key];
hide(O, key, val);
} else if (O[key]) {
O[key] = val;
} else {
hide(O, key, val);
}
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, TO_STRING, function toString() {
return typeof this == 'function' && this[SRC] || $toString.call(this);
});
},{"./_core":29,"./_global":45,"./_has":46,"./_hide":47,"./_uid":120}],94:[function(require,module,exports){
// 7.2.9 SameValue(x, y)
module.exports = Object.is || function is(x, y) {
// eslint-disable-next-line no-self-compare
return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;
};
},{}],95:[function(require,module,exports){
// Works with __proto__ only. Old v8 can't work with null proto objects.
/* eslint-disable no-proto */
var isObject = require('./_is-object');
var anObject = require('./_an-object');
var check = function (O, proto) {
anObject(O);
if (!isObject(proto) && proto !== null) throw TypeError(proto + ": can't set as prototype!");
};
module.exports = {
set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
function (test, buggy, set) {
try {
set = require('./_ctx')(Function.call, require('./_object-gopd').f(Object.prototype, '__proto__').set, 2);
set(test, []);
buggy = !(test instanceof Array);
} catch (e) { buggy = true; }
return function setPrototypeOf(O, proto) {
check(O, proto);
if (buggy) O.__proto__ = proto;
else set(O, proto);
return O;
};
}({}, false) : undefined),
check: check
};
},{"./_an-object":15,"./_ctx":31,"./_is-object":56,"./_object-gopd":76}],96:[function(require,module,exports){
'use strict';
var global = require('./_global');
var dP = require('./_object-dp');
var DESCRIPTORS = require('./_descriptors');
var SPECIES = require('./_wks')('species');
module.exports = function (KEY) {
var C = global[KEY];
if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, {
configurable: true,
get: function () { return this; }
});
};
},{"./_descriptors":35,"./_global":45,"./_object-dp":74,"./_wks":125}],97:[function(require,module,exports){
var def = require('./_object-dp').f;
var has = require('./_has');
var TAG = require('./_wks')('toStringTag');
module.exports = function (it, tag, stat) {
if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });
};
},{"./_has":46,"./_object-dp":74,"./_wks":125}],98:[function(require,module,exports){
var shared = require('./_shared')('keys');
var uid = require('./_uid');
module.exports = function (key) {
return shared[key] || (shared[key] = uid(key));
};
},{"./_shared":99,"./_uid":120}],99:[function(require,module,exports){
var core = require('./_core');
var global = require('./_global');
var SHARED = '__core-js_shared__';
var store = global[SHARED] || (global[SHARED] = {});
(module.exports = function (key, value) {
return store[key] || (store[key] = value !== undefined ? value : {});
})('versions', []).push({
version: core.version,
mode: require('./_library') ? 'pure' : 'global',
copyright: '© 2018 Denis Pushkarev (zloirock.ru)'
});
},{"./_core":29,"./_global":45,"./_library":64}],100:[function(require,module,exports){
// 7.3.20 SpeciesConstructor(O, defaultConstructor)
var anObject = require('./_an-object');
var aFunction = require('./_a-function');
var SPECIES = require('./_wks')('species');
module.exports = function (O, D) {
var C = anObject(O).constructor;
var S;
return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);
};
},{"./_a-function":11,"./_an-object":15,"./_wks":125}],101:[function(require,module,exports){
'use strict';
var fails = require('./_fails');
module.exports = function (method, arg) {
return !!method && fails(function () {
// eslint-disable-next-line no-useless-call
arg ? method.call(null, function () { /* empty */ }, 1) : method.call(null);
});
};
},{"./_fails":41}],102:[function(require,module,exports){
var toInteger = require('./_to-integer');
var defined = require('./_defined');
// true -> String#at
// false -> String#codePointAt
module.exports = function (TO_STRING) {
return function (that, pos) {
var s = String(defined(that));
var i = toInteger(pos);
var l = s.length;
var a, b;
if (i < 0 || i >= l) return TO_STRING ? '' : undefined;
a = s.charCodeAt(i);
return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
? TO_STRING ? s.charAt(i) : a
: TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
};
};
},{"./_defined":34,"./_to-integer":112}],103:[function(require,module,exports){
// helper for String#{startsWith, endsWith, includes}
var isRegExp = require('./_is-regexp');
var defined = require('./_defined');
module.exports = function (that, searchString, NAME) {
if (isRegExp(searchString)) throw TypeError('String#' + NAME + " doesn't accept regex!");
return String(defined(that));
};
},{"./_defined":34,"./_is-regexp":57}],104:[function(require,module,exports){
var $export = require('./_export');
var fails = require('./_fails');
var defined = require('./_defined');
var quot = /"/g;
// B.2.3.2.1 CreateHTML(string, tag, attribute, value)
var createHTML = function (string, tag, attribute, value) {
var S = String(defined(string));
var p1 = '<' + tag;
if (attribute !== '') p1 += ' ' + attribute + '="' + String(value).replace(quot, '"') + '"';
return p1 + '>' + S + '</' + tag + '>';
};
module.exports = function (NAME, exec) {
var O = {};
O[NAME] = exec(createHTML);
$export($export.P + $export.F * fails(function () {
var test = ''[NAME]('"');
return test !== test.toLowerCase() || test.split('"').length > 3;
}), 'String', O);
};
},{"./_defined":34,"./_export":39,"./_fails":41}],105:[function(require,module,exports){
// https://github.com/tc39/proposal-string-pad-start-end
var toLength = require('./_to-length');
var repeat = require('./_string-repeat');
var defined = require('./_defined');
module.exports = function (that, maxLength, fillString, left) {
var S = String(defined(that));
var stringLength = S.length;
var fillStr = fillString === undefined ? ' ' : String(fillString);
var intMaxLength = toLength(maxLength);
if (intMaxLength <= stringLength || fillStr == '') return S;
var fillLen = intMaxLength - stringLength;
var stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));
if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen);
return left ? stringFiller + S : S + stringFiller;
};
},{"./_defined":34,"./_string-repeat":106,"./_to-length":114}],106:[function(require,module,exports){
'use strict';
var toInteger = require('./_to-integer');
var defined = require('./_defined');
module.exports = function repeat(count) {
var str = String(defined(this));
var res = '';
var n = toInteger(count);
if (n < 0 || n == Infinity) throw RangeError("Count can't be negative");
for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) res += str;
return res;
};
},{"./_defined":34,"./_to-integer":112}],107:[function(require,module,exports){
var $export = require('./_export');
var defined = require('./_defined');
var fails = require('./_fails');
var spaces = require('./_string-ws');
var space = '[' + spaces + ']';
var non = '\u200b\u0085';
var ltrim = RegExp('^' + space + space + '*');
var rtrim = RegExp(space + space + '*$');
var exporter = function (KEY, exec, ALIAS) {
var exp = {};
var FORCE = fails(function () {
return !!spaces[KEY]() || non[KEY]() != non;
});
var fn = exp[KEY] = FORCE ? exec(trim) : spaces[KEY];
if (ALIAS) exp[ALIAS] = fn;
$export($export.P + $export.F * FORCE, 'String', exp);
};
// 1 -> String#trimLeft
// 2 -> String#trimRight
// 3 -> String#trim
var trim = exporter.trim = function (string, TYPE) {
string = String(defined(string));
if (TYPE & 1) string = string.replace(ltrim, '');
if (TYPE & 2) string = string.replace(rtrim, '');
return string;
};
module.exports = exporter;
},{"./_defined":34,"./_export":39,"./_fails":41,"./_string-ws":108}],108:[function(require,module,exports){
module.exports = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
'\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';
},{}],109:[function(require,module,exports){
var ctx = require('./_ctx');
var invoke = require('./_invoke');
var html = require('./_html');
var cel = require('./_dom-create');
var global = require('./_global');
var process = global.process;
var setTask = global.setImmediate;
var clearTask = global.clearImmediate;
var MessageChannel = global.MessageChannel;
var Dispatch = global.Dispatch;
var counter = 0;
var queue = {};
var ONREADYSTATECHANGE = 'onreadystatechange';
var defer, channel, port;
var run = function () {
var id = +this;
// eslint-disable-next-line no-prototype-builtins
if (queue.hasOwnProperty(id)) {
var fn = queue[id];
delete queue[id];
fn();
}
};
var listener = function (event) {
run.call(event.data);
};
// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
if (!setTask || !clearTask) {
setTask = function setImmediate(fn) {
var args = [];
var i = 1;
while (arguments.length > i) args.push(arguments[i++]);
queue[++counter] = function () {
// eslint-disable-next-line no-new-func
invoke(typeof fn == 'function' ? fn : Function(fn), args);
};
defer(counter);
return counter;
};
clearTask = function clearImmediate(id) {
delete queue[id];
};
// Node.js 0.8-
if (require('./_cof')(process) == 'process') {
defer = function (id) {
process.nextTick(ctx(run, id, 1));
};
// Sphere (JS game engine) Dispatch API
} else if (Dispatch && Dispatch.now) {
defer = function (id) {
Dispatch.now(ctx(run, id, 1));
};
// Browsers with MessageChannel, includes WebWorkers
} else if (MessageChannel) {
channel = new MessageChannel();
port = channel.port2;
channel.port1.onmessage = listener;
defer = ctx(port.postMessage, port, 1);
// Browsers with postMessage, skip WebWorkers
// IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
} else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) {
defer = function (id) {
global.postMessage(id + '', '*');
};
global.addEventListener('message', listener, false);
// IE8-
} else if (ONREADYSTATECHANGE in cel('script')) {
defer = function (id) {
html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () {
html.removeChild(this);
run.call(id);
};
};
// Rest old browsers
} else {
defer = function (id) {
setTimeout(ctx(run, id, 1), 0);
};
}
}
module.exports = {
set: setTask,
clear: clearTask
};
},{"./_cof":25,"./_ctx":31,"./_dom-create":36,"./_global":45,"./_html":48,"./_invoke":51}],110:[function(require,module,exports){
var toInteger = require('./_to-integer');
var max = Math.max;
var min = Math.min;
module.exports = function (index, length) {
index = toInteger(index);
return index < 0 ? max(index + length, 0) : min(index, length);
};
},{"./_to-integer":112}],111:[function(require,module,exports){
// https://tc39.github.io/ecma262/#sec-toindex
var toInteger = require('./_to-integer');
var toLength = require('./_to-length');
module.exports = function (it) {
if (it === undefined) return 0;
var number = toInteger(it);
var length = toLength(number);
if (number !== length) throw RangeError('Wrong length!');
return length;
};
},{"./_to-integer":112,"./_to-length":114}],112:[function(require,module,exports){
// 7.1.4 ToInteger
var ceil = Math.ceil;
var floor = Math.floor;
module.exports = function (it) {
return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
};
},{}],113:[function(require,module,exports){
// to indexed object, toObject with fallback for non-array-like ES3 strings
var IObject = require('./_iobject');
var defined = require('./_defined');
module.exports = function (it) {
return IObject(defined(it));
};
},{"./_defined":34,"./_iobject":52}],114:[function(require,module,exports){
// 7.1.15 ToLength
var toInteger = require('./_to-integer');
var min = Math.min;
module.exports = function (it) {
return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
};
},{"./_to-integer":112}],115:[function(require,module,exports){
// 7.1.13 ToObject(argument)
var defined = require('./_defined');
module.exports = function (it) {
return Object(defined(it));
};
},{"./_defined":34}],116:[function(require,module,exports){
// 7.1.1 ToPrimitive(input [, PreferredType])
var isObject = require('./_is-object');
// instead of the ES6 spec version, we didn't implement @@toPrimitive case
// and the second argument - flag - preferred type is a string
module.exports = function (it, S) {
if (!isObject(it)) return it;
var fn, val;
if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;
if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
throw TypeError("Can't convert object to primitive value");
};
},{"./_is-object":56}],117:[function(require,module,exports){
'use strict';
if (require('./_descriptors')) {
var LIBRARY = require('./_library');
var global = require('./_global');
var fails = require('./_fails');
var $export = require('./_export');
var $typed = require('./_typed');
var $buffer = require('./_typed-buffer');
var ctx = require('./_ctx');
var anInstance = require('./_an-instance');
var propertyDesc = require('./_property-desc');
var hide = require('./_hide');
var redefineAll = require('./_redefine-all');
var toInteger = require('./_to-integer');
var toLength = require('./_to-length');
var toIndex = require('./_to-index');
var toAbsoluteIndex = require('./_to-absolute-index');
var toPrimitive = require('./_to-primitive');
var has = require('./_has');
var classof = require('./_classof');
var isObject = require('./_is-object');
var toObject = require('./_to-object');
var isArrayIter = require('./_is-array-iter');
var create = require('./_object-create');
var getPrototypeOf = require('./_object-gpo');
var gOPN = require('./_object-gopn').f;
var getIterFn = require('./core.get-iterator-method');
var uid = require('./_uid');
var wks = require('./_wks');
var createArrayMethod = require('./_array-methods');
var createArrayIncludes = require('./_array-includes');
var speciesConstructor = require('./_species-constructor');
var ArrayIterators = require('./es6.array.iterator');
var Iterators = require('./_iterators');
var $iterDetect = require('./_iter-detect');
var setSpecies = require('./_set-species');
var arrayFill = require('./_array-fill');
var arrayCopyWithin = require('./_array-copy-within');
var $DP = require('./_object-dp');
var $GOPD = require('./_object-gopd');
var dP = $DP.f;
var gOPD = $GOPD.f;
var RangeError = global.RangeError;
var TypeError = global.TypeError;
var Uint8Array = global.Uint8Array;
var ARRAY_BUFFER = 'ArrayBuffer';
var SHARED_BUFFER = 'Shared' + ARRAY_BUFFER;
var BYTES_PER_ELEMENT = 'BYTES_PER_ELEMENT';
var PROTOTYPE = 'prototype';
var ArrayProto = Array[PROTOTYPE];
var $ArrayBuffer = $buffer.ArrayBuffer;
var $DataView = $buffer.DataView;
var arrayForEach = createArrayMethod(0);
var arrayFilter = createArrayMethod(2);
var arraySome = createArrayMethod(3);
var arrayEvery = createArrayMethod(4);
var arrayFind = createArrayMethod(5);
var arrayFindIndex = createArrayMethod(6);
var arrayIncludes = createArrayIncludes(true);
var arrayIndexOf = createArrayIncludes(false);
var arrayValues = ArrayIterators.values;
var arrayKeys = ArrayIterators.keys;
var arrayEntries = ArrayIterators.entries;
var arrayLastIndexOf = ArrayProto.lastIndexOf;
var arrayReduce = ArrayProto.reduce;
var arrayReduceRight = ArrayProto.reduceRight;
var arrayJoin = ArrayProto.join;
var arraySort = ArrayProto.sort;
var arraySlice = ArrayProto.slice;
var arrayToString = ArrayProto.toString;
var arrayToLocaleString = ArrayProto.toLocaleString;
var ITERATOR = wks('iterator');
var TAG = wks('toStringTag');
var TYPED_CONSTRUCTOR = uid('typed_constructor');
var DEF_CONSTRUCTOR = uid('def_constructor');
var ALL_CONSTRUCTORS = $typed.CONSTR;
var TYPED_ARRAY = $typed.TYPED;
var VIEW = $typed.VIEW;
var WRONG_LENGTH = 'Wrong length!';
var $map = createArrayMethod(1, function (O, length) {
return allocate(speciesConstructor(O, O[DEF_CONSTRUCTOR]), length);
});
var LITTLE_ENDIAN = fails(function () {
// eslint-disable-next-line no-undef
return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
});
var FORCED_SET = !!Uint8Array && !!Uint8Array[PROTOTYPE].set && fails(function () {
new Uint8Array(1).set({});
});
var toOffset = function (it, BYTES) {
var offset = toInteger(it);
if (offset < 0 || offset % BYTES) throw RangeError('Wrong offset!');
return offset;
};
var validate = function (it) {
if (isObject(it) && TYPED_ARRAY in it) return it;
throw TypeError(it + ' is not a typed array!');
};
var allocate = function (C, length) {
if (!(isObject(C) && TYPED_CONSTRUCTOR in C)) {
throw TypeError('It is not a typed array constructor!');
} return new C(length);
};
var speciesFromList = function (O, list) {
return fromList(speciesConstructor(O, O[DEF_CONSTRUCTOR]), list);
};
var fromList = function (C, list) {
var index = 0;
var length = list.length;
var result = allocate(C, length);
while (length > index) result[index] = list[index++];
return result;
};
var addGetter = function (it, key, internal) {
dP(it, key, { get: function () { return this._d[internal]; } });
};
var $from = function from(source /* , mapfn, thisArg */) {
var O = toObject(source);
var aLen = arguments.length;
var mapfn = aLen > 1 ? arguments[1] : undefined;
var mapping = mapfn !== undefined;
var iterFn = getIterFn(O);
var i, length, values, result, step, iterator;
if (iterFn != undefined && !isArrayIter(iterFn)) {
for (iterator = iterFn.call(O), values = [], i = 0; !(step = iterator.next()).done; i++) {
values.push(step.value);
} O = values;
}
if (mapping && aLen > 2) mapfn = ctx(mapfn, arguments[2], 2);
for (i = 0, length = toLength(O.length), result = allocate(this, length); length > i; i++) {
result[i] = mapping ? mapfn(O[i], i) : O[i];
}
return result;
};
var $of = function of(/* ...items */) {
var index = 0;
var length = arguments.length;
var result = allocate(this, length);
while (length > index) result[index] = arguments[index++];
return result;
};
// iOS Safari 6.x fails here
var TO_LOCALE_BUG = !!Uint8Array && fails(function () { arrayToLocaleString.call(new Uint8Array(1)); });
var $toLocaleString = function toLocaleString() {
return arrayToLocaleString.apply(TO_LOCALE_BUG ? arraySlice.call(validate(this)) : validate(this), arguments);
};
var proto = {
copyWithin: function copyWithin(target, start /* , end */) {
return arrayCopyWithin.call(validate(this), target, start, arguments.length > 2 ? arguments[2] : undefined);
},
every: function every(callbackfn /* , thisArg */) {
return arrayEvery(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
},
fill: function fill(value /* , start, end */) { // eslint-disable-line no-unused-vars
return arrayFill.apply(validate(this), arguments);
},
filter: function filter(callbackfn /* , thisArg */) {
return speciesFromList(this, arrayFilter(validate(this), callbackfn,
arguments.length > 1 ? arguments[1] : undefined));
},
find: function find(predicate /* , thisArg */) {
return arrayFind(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
},
findIndex: function findIndex(predicate /* , thisArg */) {
return arrayFindIndex(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
},
forEach: function forEach(callbackfn /* , thisArg */) {
arrayForEach(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
},
indexOf: function indexOf(searchElement /* , fromIndex */) {
return arrayIndexOf(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
},
includes: function includes(searchElement /* , fromIndex */) {
return arrayIncludes(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
},
join: function join(separator) { // eslint-disable-line no-unused-vars
return arrayJoin.apply(validate(this), arguments);
},
lastIndexOf: function lastIndexOf(searchElement /* , fromIndex */) { // eslint-disable-line no-unused-vars
return arrayLastIndexOf.apply(validate(this), arguments);
},
map: function map(mapfn /* , thisArg */) {
return $map(validate(this), mapfn, arguments.length > 1 ? arguments[1] : undefined);
},
reduce: function reduce(callbackfn /* , initialValue */) { // eslint-disable-line no-unused-vars
return arrayReduce.apply(validate(this), arguments);
},
reduceRight: function reduceRight(callbackfn /* , initialValue */) { // eslint-disable-line no-unused-vars
return arrayReduceRight.apply(validate(this), arguments);
},
reverse: function reverse() {
var that = this;
var length = validate(that).length;
var middle = Math.floor(length / 2);
var index = 0;
var value;
while (index < middle) {
value = that[index];
that[index++] = that[--length];
that[length] = value;
} return that;
},
some: function some(callbackfn /* , thisArg */) {
return arraySome(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
},
sort: function sort(comparefn) {
return arraySort.call(validate(this), comparefn);
},
subarray: function subarray(begin, end) {
var O = validate(this);
var length = O.length;
var $begin = toAbsoluteIndex(begin, length);
return new (speciesConstructor(O, O[DEF_CONSTRUCTOR]))(
O.buffer,
O.byteOffset + $begin * O.BYTES_PER_ELEMENT,
toLength((end === undefined ? length : toAbsoluteIndex(end, length)) - $begin)
);
}
};
var $slice = function slice(start, end) {
return speciesFromList(this, arraySlice.call(validate(this), start, end));
};
var $set = function set(arrayLike /* , offset */) {
validate(this);
var offset = toOffset(arguments[1], 1);
var length = this.length;
var src = toObject(arrayLike);
var len = toLength(src.length);
var index = 0;
if (len + offset > length) throw RangeError(WRONG_LENGTH);
while (index < len) this[offset + index] = src[index++];
};
var $iterators = {
entries: function entries() {
return arrayEntries.call(validate(this));
},
keys: function keys() {
return arrayKeys.call(validate(this));
},
values: function values() {
return arrayValues.call(validate(this));
}
};
var isTAIndex = function (target, key) {
return isObject(target)
&& target[TYPED_ARRAY]
&& typeof key != 'symbol'
&& key in target
&& String(+key) == String(key);
};
var $getDesc = function getOwnPropertyDescriptor(target, key) {
return isTAIndex(target, key = toPrimitive(key, true))
? propertyDesc(2, target[key])
: gOPD(target, key);
};
var $setDesc = function defineProperty(target, key, desc) {
if (isTAIndex(target, key = toPrimitive(key, true))
&& isObject(desc)
&& has(desc, 'value')
&& !has(desc, 'get')
&& !has(desc, 'set')
// TODO: add validation descriptor w/o calling accessors
&& !desc.configurable
&& (!has(desc, 'writable') || desc.writable)
&& (!has(desc, 'enumerable') || desc.enumerable)
) {
target[key] = desc.value;
return target;
} return dP(target, key, desc);
};
if (!ALL_CONSTRUCTORS) {
$GOPD.f = $getDesc;
$DP.f = $setDesc;
}
$export($export.S + $export.F * !ALL_CONSTRUCTORS, 'Object', {
getOwnPropertyDescriptor: $getDesc,
defineProperty: $setDesc
});
if (fails(function () { arrayToString.call({}); })) {
arrayToString = arrayToLocaleString = function toString() {
return arrayJoin.call(this);
};
}
var $TypedArrayPrototype$ = redefineAll({}, proto);
redefineAll($TypedArrayPrototype$, $iterators);
hide($TypedArrayPrototype$, ITERATOR, $iterators.values);
redefineAll($TypedArrayPrototype$, {
slice: $slice,
set: $set,
constructor: function () { /* noop */ },
toString: arrayToString,
toLocaleString: $toLocaleString
});
addGetter($TypedArrayPrototype$, 'buffer', 'b');
addGetter($TypedArrayPrototype$, 'byteOffset', 'o');
addGetter($TypedArrayPrototype$, 'byteLength', 'l');
addGetter($TypedArrayPrototype$, 'length', 'e');
dP($TypedArrayPrototype$, TAG, {
get: function () { return this[TYPED_ARRAY]; }
});
// eslint-disable-next-line max-statements
module.exports = function (KEY, BYTES, wrapper, CLAMPED) {
CLAMPED = !!CLAMPED;
var NAME = KEY + (CLAMPED ? 'Clamped' : '') + 'Array';
var GETTER = 'get' + KEY;
var SETTER = 'set' + KEY;
var TypedArray = global[NAME];
var Base = TypedArray || {};
var TAC = TypedArray && getPrototypeOf(TypedArray);
var FORCED = !TypedArray || !$typed.ABV;
var O = {};
var TypedArrayPrototype = TypedArray && TypedArray[PROTOTYPE];
var getter = function (that, index) {
var data = that._d;
return data.v[GETTER](index * BYTES + data.o, LITTLE_ENDIAN);
};
var setter = function (that, index, value) {
var data = that._d;
if (CLAMPED) value = (value = Math.round(value)) < 0 ? 0 : value > 0xff ? 0xff : value & 0xff;
data.v[SETTER](index * BYTES + data.o, value, LITTLE_ENDIAN);
};
var addElement = function (that, index) {
dP(that, index, {
get: function () {
return getter(this, index);
},
set: function (value) {
return setter(this, index, value);
},
enumerable: true
});
};
if (FORCED) {
TypedArray = wrapper(function (that, data, $offset, $length) {
anInstance(that, TypedArray, NAME, '_d');
var index = 0;
var offset = 0;
var buffer, byteLength, length, klass;
if (!isObject(data)) {
length = toIndex(data);
byteLength = length * BYTES;
buffer = new $ArrayBuffer(byteLength);
} else if (data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER) {
buffer = data;
offset = toOffset($offset, BYTES);
var $len = data.byteLength;
if ($length === undefined) {
if ($len % BYTES) throw RangeError(WRONG_LENGTH);
byteLength = $len - offset;
if (byteLength < 0) throw RangeError(WRONG_LENGTH);
} else {
byteLength = toLength($length) * BYTES;
if (byteLength + offset > $len) throw RangeError(WRONG_LENGTH);
}
length = byteLength / BYTES;
} else if (TYPED_ARRAY in data) {
return fromList(TypedArray, data);
} else {
return $from.call(TypedArray, data);
}
hide(that, '_d', {
b: buffer,
o: offset,
l: byteLength,
e: length,
v: new $DataView(buffer)
});
while (index < length) addElement(that, index++);
});
TypedArrayPrototype = TypedArray[PROTOTYPE] = create($TypedArrayPrototype$);
hide(TypedArrayPrototype, 'constructor', TypedArray);
} else if (!fails(function () {
TypedArray(1);
}) || !fails(function () {
new TypedArray(-1); // eslint-disable-line no-new
}) || !$iterDetect(function (iter) {
new TypedArray(); // eslint-disable-line no-new
new TypedArray(null); // eslint-disable-line no-new
new TypedArray(1.5); // eslint-disable-line no-new
new TypedArray(iter); // eslint-disable-line no-new
}, true)) {
TypedArray = wrapper(function (that, data, $offset, $length) {
anInstance(that, TypedArray, NAME);
var klass;
// `ws` module bug, temporarily remove validation length for Uint8Array
// https://github.com/websockets/ws/pull/645
if (!isObject(data)) return new Base(toIndex(data));
if (data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER) {
return $length !== undefined
? new Base(data, toOffset($offset, BYTES), $length)
: $offset !== undefined
? new Base(data, toOffset($offset, BYTES))
: new Base(data);
}
if (TYPED_ARRAY in data) return fromList(TypedArray, data);
return $from.call(TypedArray, data);
});
arrayForEach(TAC !== Function.prototype ? gOPN(Base).concat(gOPN(TAC)) : gOPN(Base), function (key) {
if (!(key in TypedArray)) hide(TypedArray, key, Base[key]);
});
TypedArray[PROTOTYPE] = TypedArrayPrototype;
if (!LIBRARY) TypedArrayPrototype.constructor = TypedArray;
}
var $nativeIterator = TypedArrayPrototype[ITERATOR];
var CORRECT_ITER_NAME = !!$nativeIterator
&& ($nativeIterator.name == 'values' || $nativeIterator.name == undefined);
var $iterator = $iterators.values;
hide(TypedArray, TYPED_CONSTRUCTOR, true);
hide(TypedArrayPrototype, TYPED_ARRAY, NAME);
hide(TypedArrayPrototype, VIEW, true);
hide(TypedArrayPrototype, DEF_CONSTRUCTOR, TypedArray);
if (CLAMPED ? new TypedArray(1)[TAG] != NAME : !(TAG in TypedArrayPrototype)) {
dP(TypedArrayPrototype, TAG, {
get: function () { return NAME; }
});
}
O[NAME] = TypedArray;
$export($export.G + $export.W + $export.F * (TypedArray != Base), O);
$export($export.S, NAME, {
BYTES_PER_ELEMENT: BYTES
});
$export($export.S + $export.F * fails(function () { Base.of.call(TypedArray, 1); }), NAME, {
from: $from,
of: $of
});
if (!(BYTES_PER_ELEMENT in TypedArrayPrototype)) hide(TypedArrayPrototype, BYTES_PER_ELEMENT, BYTES);
$export($export.P, NAME, proto);
setSpecies(NAME);
$export($export.P + $export.F * FORCED_SET, NAME, { set: $set });
$export($export.P + $export.F * !CORRECT_ITER_NAME, NAME, $iterators);
if (!LIBRARY && TypedArrayPrototype.toString != arrayToString) TypedArrayPrototype.toString = arrayToString;
$export($export.P + $export.F * fails(function () {
new TypedArray(1).slice();
}), NAME, { slice: $slice });
$export($export.P + $export.F * (fails(function () {
return [1, 2].toLocaleString() != new TypedArray([1, 2]).toLocaleString();
}) || !fails(function () {
TypedArrayPrototype.toLocaleString.call([1, 2]);
})), NAME, { toLocaleString: $toLocaleString });
Iterators[NAME] = CORRECT_ITER_NAME ? $nativeIterator : $iterator;
if (!LIBRARY && !CORRECT_ITER_NAME) hide(TypedArrayPrototype, ITERATOR, $iterator);
};
} else module.exports = function () { /* empty */ };
},{"./_an-instance":14,"./_array-copy-within":16,"./_array-fill":17,"./_array-includes":18,"./_array-methods":19,"./_classof":24,"./_ctx":31,"./_descriptors":35,"./_export":39,"./_fails":41,"./_global":45,"./_has":46,"./_hide":47,"./_is-array-iter":53,"./_is-object":56,"./_iter-detect":61,"./_iterators":63,"./_library":64,"./_object-create":73,"./_object-dp":74,"./_object-gopd":76,"./_object-gopn":78,"./_object-gpo":80,"./_property-desc":91,"./_redefine-all":92,"./_set-species":96,"./_species-constructor":100,"./_to-absolute-index":110,"./_to-index":111,"./_to-integer":112,"./_to-length":114,"./_to-object":115,"./_to-primitive":116,"./_typed":119,"./_typed-buffer":118,"./_uid":120,"./_wks":125,"./core.get-iterator-method":126,"./es6.array.iterator":137}],118:[function(require,module,exports){
'use strict';
var global = require('./_global');
var DESCRIPTORS = require('./_descriptors');
var LIBRARY = require('./_library');
var $typed = require('./_typed');
var hide = require('./_hide');
var redefineAll = require('./_redefine-all');
var fails = require('./_fails');
var anInstance = require('./_an-instance');
var toInteger = require('./_to-integer');
var toLength = require('./_to-length');
var toIndex = require('./_to-index');
var gOPN = require('./_object-gopn').f;
var dP = require('./_object-dp').f;
var arrayFill = require('./_array-fill');
var setToStringTag = require('./_set-to-string-tag');
var ARRAY_BUFFER = 'ArrayBuffer';
var DATA_VIEW = 'DataView';
var PROTOTYPE = 'prototype';
var WRONG_LENGTH = 'Wrong length!';
var WRONG_INDEX = 'Wrong index!';
var $ArrayBuffer = global[ARRAY_BUFFER];
var $DataView = global[DATA_VIEW];
var Math = global.Math;
var RangeError = global.RangeError;
// eslint-disable-next-line no-shadow-restricted-names
var Infinity = global.Infinity;
var BaseBuffer = $ArrayBuffer;
var abs = Math.abs;
var pow = Math.pow;
var floor = Math.floor;
var log = Math.log;
var LN2 = Math.LN2;
var BUFFER = 'buffer';
var BYTE_LENGTH = 'byteLength';
var BYTE_OFFSET = 'byteOffset';
var $BUFFER = DESCRIPTORS ? '_b' : BUFFER;
var $LENGTH = DESCRIPTORS ? '_l' : BYTE_LENGTH;
var $OFFSET = DESCRIPTORS ? '_o' : BYTE_OFFSET;
// IEEE754 conversions based on https://github.com/feross/ieee754
function packIEEE754(value, mLen, nBytes) {
var buffer = new Array(nBytes);
var eLen = nBytes * 8 - mLen - 1;
var eMax = (1 << eLen) - 1;
var eBias = eMax >> 1;
var rt = mLen === 23 ? pow(2, -24) - pow(2, -77) : 0;
var i = 0;
var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0;
var e, m, c;
value = abs(value);
// eslint-disable-next-line no-self-compare
if (value != value || value === Infinity) {
// eslint-disable-next-line no-self-compare
m = value != value ? 1 : 0;
e = eMax;
} else {
e = floor(log(value) / LN2);
if (value * (c = pow(2, -e)) < 1) {
e--;
c *= 2;
}
if (e + eBias >= 1) {
value += rt / c;
} else {
value += rt * 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) * pow(2, mLen);
e = e + eBias;
} else {
m = value * pow(2, eBias - 1) * pow(2, mLen);
e = 0;
}
}
for (; mLen >= 8; buffer[i++] = m & 255, m /= 256, mLen -= 8);
e = e << mLen | m;
eLen += mLen;
for (; eLen > 0; buffer[i++] = e & 255, e /= 256, eLen -= 8);
buffer[--i] |= s * 128;
return buffer;
}
function unpackIEEE754(buffer, mLen, nBytes) {
var eLen = nBytes * 8 - mLen - 1;
var eMax = (1 << eLen) - 1;
var eBias = eMax >> 1;
var nBits = eLen - 7;
var i = nBytes - 1;
var s = buffer[i--];
var e = s & 127;
var m;
s >>= 7;
for (; nBits > 0; e = e * 256 + buffer[i], i--, nBits -= 8);
m = e & (1 << -nBits) - 1;
e >>= -nBits;
nBits += mLen;
for (; nBits > 0; m = m * 256 + buffer[i], i--, nBits -= 8);
if (e === 0) {
e = 1 - eBias;
} else if (e === eMax) {
return m ? NaN : s ? -Infinity : Infinity;
} else {
m = m + pow(2, mLen);
e = e - eBias;
} return (s ? -1 : 1) * m * pow(2, e - mLen);
}
function unpackI32(bytes) {
return bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
}
function packI8(it) {
return [it & 0xff];
}
function packI16(it) {
return [it & 0xff, it >> 8 & 0xff];
}
function packI32(it) {
return [it & 0xff, it >> 8 & 0xff, it >> 16 & 0xff, it >> 24 & 0xff];
}
function packF64(it) {
return packIEEE754(it, 52, 8);
}
function packF32(it) {
return packIEEE754(it, 23, 4);
}
function addGetter(C, key, internal) {
dP(C[PROTOTYPE], key, { get: function () { return this[internal]; } });
}
function get(view, bytes, index, isLittleEndian) {
var numIndex = +index;
var intIndex = toIndex(numIndex);
if (intIndex + bytes > view[$LENGTH]) throw RangeError(WRONG_INDEX);
var store = view[$BUFFER]._b;
var start = intIndex + view[$OFFSET];
var pack = store.slice(start, start + bytes);
return isLittleEndian ? pack : pack.reverse();
}
function set(view, bytes, index, conversion, value, isLittleEndian) {
var numIndex = +index;
var intIndex = toIndex(numIndex);
if (intIndex + bytes > view[$LENGTH]) throw RangeError(WRONG_INDEX);
var store = view[$BUFFER]._b;
var start = intIndex + view[$OFFSET];
var pack = conversion(+value);
for (var i = 0; i < bytes; i++) store[start + i] = pack[isLittleEndian ? i : bytes - i - 1];
}
if (!$typed.ABV) {
$ArrayBuffer = function ArrayBuffer(length) {
anInstance(this, $ArrayBuffer, ARRAY_BUFFER);
var byteLength = toIndex(length);
this._b = arrayFill.call(new Array(byteLength), 0);
this[$LENGTH] = byteLength;
};
$DataView = function DataView(buffer, byteOffset, byteLength) {
anInstance(this, $DataView, DATA_VIEW);
anInstance(buffer, $ArrayBuffer, DATA_VIEW);
var bufferLength = buffer[$LENGTH];
var offset = toInteger(byteOffset);
if (offset < 0 || offset > bufferLength) throw RangeError('Wrong offset!');
byteLength = byteLength === undefined ? bufferLength - offset : toLength(byteLength);
if (offset + byteLength > bufferLength) throw RangeError(WRONG_LENGTH);
this[$BUFFER] = buffer;
this[$OFFSET] = offset;
this[$LENGTH] = byteLength;
};
if (DESCRIPTORS) {
addGetter($ArrayBuffer, BYTE_LENGTH, '_l');
addGetter($DataView, BUFFER, '_b');
addGetter($DataView, BYTE_LENGTH, '_l');
addGetter($DataView, BYTE_OFFSET, '_o');
}
redefineAll($DataView[PROTOTYPE], {
getInt8: function getInt8(byteOffset) {
return get(this, 1, byteOffset)[0] << 24 >> 24;
},
getUint8: function getUint8(byteOffset) {
return get(this, 1, byteOffset)[0];
},
getInt16: function getInt16(byteOffset /* , littleEndian */) {
var bytes = get(this, 2, byteOffset, arguments[1]);
return (bytes[1] << 8 | bytes[0]) << 16 >> 16;
},
getUint16: function getUint16(byteOffset /* , littleEndian */) {
var bytes = get(this, 2, byteOffset, arguments[1]);
return bytes[1] << 8 | bytes[0];
},
getInt32: function getInt32(byteOffset /* , littleEndian */) {
return unpackI32(get(this, 4, byteOffset, arguments[1]));
},
getUint32: function getUint32(byteOffset /* , littleEndian */) {
return unpackI32(get(this, 4, byteOffset, arguments[1])) >>> 0;
},
getFloat32: function getFloat32(byteOffset /* , littleEndian */) {
return unpackIEEE754(get(this, 4, byteOffset, arguments[1]), 23, 4);
},
getFloat64: function getFloat64(byteOffset /* , littleEndian */) {
return unpackIEEE754(get(this, 8, byteOffset, arguments[1]), 52, 8);
},
setInt8: function setInt8(byteOffset, value) {
set(this, 1, byteOffset, packI8, value);
},
setUint8: function setUint8(byteOffset, value) {
set(this, 1, byteOffset, packI8, value);
},
setInt16: function setInt16(byteOffset, value /* , littleEndian */) {
set(this, 2, byteOffset, packI16, value, arguments[2]);
},
setUint16: function setUint16(byteOffset, value /* , littleEndian */) {
set(this, 2, byteOffset, packI16, value, arguments[2]);
},
setInt32: function setInt32(byteOffset, value /* , littleEndian */) {
set(this, 4, byteOffset, packI32, value, arguments[2]);
},
setUint32: function setUint32(byteOffset, value /* , littleEndian */) {
set(this, 4, byteOffset, packI32, value, arguments[2]);
},
setFloat32: function setFloat32(byteOffset, value /* , littleEndian */) {
set(this, 4, byteOffset, packF32, value, arguments[2]);
},
setFloat64: function setFloat64(byteOffset, value /* , littleEndian */) {
set(this, 8, byteOffset, packF64, value, arguments[2]);
}
});
} else {
if (!fails(function () {
$ArrayBuffer(1);
}) || !fails(function () {
new $ArrayBuffer(-1); // eslint-disable-line no-new
}) || fails(function () {
new $ArrayBuffer(); // eslint-disable-line no-new
new $ArrayBuffer(1.5); // eslint-disable-line no-new
new $ArrayBuffer(NaN); // eslint-disable-line no-new
return $ArrayBuffer.name != ARRAY_BUFFER;
})) {
$ArrayBuffer = function ArrayBuffer(length) {
anInstance(this, $ArrayBuffer);
return new BaseBuffer(toIndex(length));
};
var ArrayBufferProto = $ArrayBuffer[PROTOTYPE] = BaseBuffer[PROTOTYPE];
for (var keys = gOPN(BaseBuffer), j = 0, key; keys.length > j;) {
if (!((key = keys[j++]) in $ArrayBuffer)) hide($ArrayBuffer, key, BaseBuffer[key]);
}
if (!LIBRARY) ArrayBufferProto.constructor = $ArrayBuffer;
}
// iOS Safari 7.x bug
var view = new $DataView(new $ArrayBuffer(2));
var $setInt8 = $DataView[PROTOTYPE].setInt8;
view.setInt8(0, 2147483648);
view.setInt8(1, 2147483649);
if (view.getInt8(0) || !view.getInt8(1)) redefineAll($DataView[PROTOTYPE], {
setInt8: function setInt8(byteOffset, value) {
$setInt8.call(this, byteOffset, value << 24 >> 24);
},
setUint8: function setUint8(byteOffset, value) {
$setInt8.call(this, byteOffset, value << 24 >> 24);
}
}, true);
}
setToStringTag($ArrayBuffer, ARRAY_BUFFER);
setToStringTag($DataView, DATA_VIEW);
hide($DataView[PROTOTYPE], $typed.VIEW, true);
exports[ARRAY_BUFFER] = $ArrayBuffer;
exports[DATA_VIEW] = $DataView;
},{"./_an-instance":14,"./_array-fill":17,"./_descriptors":35,"./_fails":41,"./_global":45,"./_hide":47,"./_library":64,"./_object-dp":74,"./_object-gopn":78,"./_redefine-all":92,"./_set-to-string-tag":97,"./_to-index":111,"./_to-integer":112,"./_to-length":114,"./_typed":119}],119:[function(require,module,exports){
var global = require('./_global');
var hide = require('./_hide');
var uid = require('./_uid');
var TYPED = uid('typed_array');
var VIEW = uid('view');
var ABV = !!(global.ArrayBuffer && global.DataView);
var CONSTR = ABV;
var i = 0;
var l = 9;
var Typed;
var TypedArrayConstructors = (
'Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array'
).split(',');
while (i < l) {
if (Typed = global[TypedArrayConstructors[i++]]) {
hide(Typed.prototype, TYPED, true);
hide(Typed.prototype, VIEW, true);
} else CONSTR = false;
}
module.exports = {
ABV: ABV,
CONSTR: CONSTR,
TYPED: TYPED,
VIEW: VIEW
};
},{"./_global":45,"./_hide":47,"./_uid":120}],120:[function(require,module,exports){
var id = 0;
var px = Math.random();
module.exports = function (key) {
return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
};
},{}],121:[function(require,module,exports){
var global = require('./_global');
var navigator = global.navigator;
module.exports = navigator && navigator.userAgent || '';
},{"./_global":45}],122:[function(require,module,exports){
var isObject = require('./_is-object');
module.exports = function (it, TYPE) {
if (!isObject(it) || it._t !== TYPE) throw TypeError('Incompatible receiver, ' + TYPE + ' required!');
return it;
};
},{"./_is-object":56}],123:[function(require,module,exports){
var global = require('./_global');
var core = require('./_core');
var LIBRARY = require('./_library');
var wksExt = require('./_wks-ext');
var defineProperty = require('./_object-dp').f;
module.exports = function (name) {
var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {});
if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty($Symbol, name, { value: wksExt.f(name) });
};
},{"./_core":29,"./_global":45,"./_library":64,"./_object-dp":74,"./_wks-ext":124}],124:[function(require,module,exports){
exports.f = require('./_wks');
},{"./_wks":125}],125:[function(require,module,exports){
var store = require('./_shared')('wks');
var uid = require('./_uid');
var Symbol = require('./_global').Symbol;
var USE_SYMBOL = typeof Symbol == 'function';
var $exports = module.exports = function (name) {
return store[name] || (store[name] =
USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));
};
$exports.store = store;
},{"./_global":45,"./_shared":99,"./_uid":120}],126:[function(require,module,exports){
var classof = require('./_classof');
var ITERATOR = require('./_wks')('iterator');
var Iterators = require('./_iterators');
module.exports = require('./_core').getIteratorMethod = function (it) {
if (it != undefined) return it[ITERATOR]
|| it['@@iterator']
|| Iterators[classof(it)];
};
},{"./_classof":24,"./_core":29,"./_iterators":63,"./_wks":125}],127:[function(require,module,exports){
// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
var $export = require('./_export');
$export($export.P, 'Array', { copyWithin: require('./_array-copy-within') });
require('./_add-to-unscopables')('copyWithin');
},{"./_add-to-unscopables":13,"./_array-copy-within":16,"./_export":39}],128:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $every = require('./_array-methods')(4);
$export($export.P + $export.F * !require('./_strict-method')([].every, true), 'Array', {
// 22.1.3.5 / 15.4.4.16 Array.prototype.every(callbackfn [, thisArg])
every: function every(callbackfn /* , thisArg */) {
return $every(this, callbackfn, arguments[1]);
}
});
},{"./_array-methods":19,"./_export":39,"./_strict-method":101}],129:[function(require,module,exports){
// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
var $export = require('./_export');
$export($export.P, 'Array', { fill: require('./_array-fill') });
require('./_add-to-unscopables')('fill');
},{"./_add-to-unscopables":13,"./_array-fill":17,"./_export":39}],130:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $filter = require('./_array-methods')(2);
$export($export.P + $export.F * !require('./_strict-method')([].filter, true), 'Array', {
// 22.1.3.7 / 15.4.4.20 Array.prototype.filter(callbackfn [, thisArg])
filter: function filter(callbackfn /* , thisArg */) {
return $filter(this, callbackfn, arguments[1]);
}
});
},{"./_array-methods":19,"./_export":39,"./_strict-method":101}],131:[function(require,module,exports){
'use strict';
// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined)
var $export = require('./_export');
var $find = require('./_array-methods')(6);
var KEY = 'findIndex';
var forced = true;
// Shouldn't skip holes
if (KEY in []) Array(1)[KEY](function () { forced = false; });
$export($export.P + $export.F * forced, 'Array', {
findIndex: function findIndex(callbackfn /* , that = undefined */) {
return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
}
});
require('./_add-to-unscopables')(KEY);
},{"./_add-to-unscopables":13,"./_array-methods":19,"./_export":39}],132:[function(require,module,exports){
'use strict';
// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)
var $export = require('./_export');
var $find = require('./_array-methods')(5);
var KEY = 'find';
var forced = true;
// Shouldn't skip holes
if (KEY in []) Array(1)[KEY](function () { forced = false; });
$export($export.P + $export.F * forced, 'Array', {
find: function find(callbackfn /* , that = undefined */) {
return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
}
});
require('./_add-to-unscopables')(KEY);
},{"./_add-to-unscopables":13,"./_array-methods":19,"./_export":39}],133:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $forEach = require('./_array-methods')(0);
var STRICT = require('./_strict-method')([].forEach, true);
$export($export.P + $export.F * !STRICT, 'Array', {
// 22.1.3.10 / 15.4.4.18 Array.prototype.forEach(callbackfn [, thisArg])
forEach: function forEach(callbackfn /* , thisArg */) {
return $forEach(this, callbackfn, arguments[1]);
}
});
},{"./_array-methods":19,"./_export":39,"./_strict-method":101}],134:[function(require,module,exports){
'use strict';
var ctx = require('./_ctx');
var $export = require('./_export');
var toObject = require('./_to-object');
var call = require('./_iter-call');
var isArrayIter = require('./_is-array-iter');
var toLength = require('./_to-length');
var createProperty = require('./_create-property');
var getIterFn = require('./core.get-iterator-method');
$export($export.S + $export.F * !require('./_iter-detect')(function (iter) { Array.from(iter); }), 'Array', {
// 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
var O = toObject(arrayLike);
var C = typeof this == 'function' ? this : Array;
var aLen = arguments.length;
var mapfn = aLen > 1 ? arguments[1] : undefined;
var mapping = mapfn !== undefined;
var index = 0;
var iterFn = getIterFn(O);
var length, result, step, iterator;
if (mapping) mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
// if object isn't iterable or it's array with default iterator - use simple case
if (iterFn != undefined && !(C == Array && isArrayIter(iterFn))) {
for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) {
createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value);
}
} else {
length = toLength(O.length);
for (result = new C(length); length > index; index++) {
createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
}
}
result.length = index;
return result;
}
});
},{"./_create-property":30,"./_ctx":31,"./_export":39,"./_is-array-iter":53,"./_iter-call":58,"./_iter-detect":61,"./_to-length":114,"./_to-object":115,"./core.get-iterator-method":126}],135:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $indexOf = require('./_array-includes')(false);
var $native = [].indexOf;
var NEGATIVE_ZERO = !!$native && 1 / [1].indexOf(1, -0) < 0;
$export($export.P + $export.F * (NEGATIVE_ZERO || !require('./_strict-method')($native)), 'Array', {
// 22.1.3.11 / 15.4.4.14 Array.prototype.indexOf(searchElement [, fromIndex])
indexOf: function indexOf(searchElement /* , fromIndex = 0 */) {
return NEGATIVE_ZERO
// convert -0 to +0
? $native.apply(this, arguments) || 0
: $indexOf(this, searchElement, arguments[1]);
}
});
},{"./_array-includes":18,"./_export":39,"./_strict-method":101}],136:[function(require,module,exports){
// 22.1.2.2 / 15.4.3.2 Array.isArray(arg)
var $export = require('./_export');
$export($export.S, 'Array', { isArray: require('./_is-array') });
},{"./_export":39,"./_is-array":54}],137:[function(require,module,exports){
'use strict';
var addToUnscopables = require('./_add-to-unscopables');
var step = require('./_iter-step');
var Iterators = require('./_iterators');
var toIObject = require('./_to-iobject');
// 22.1.3.4 Array.prototype.entries()
// 22.1.3.13 Array.prototype.keys()
// 22.1.3.29 Array.prototype.values()
// 22.1.3.30 Array.prototype[@@iterator]()
module.exports = require('./_iter-define')(Array, 'Array', function (iterated, kind) {
this._t = toIObject(iterated); // target
this._i = 0; // next index
this._k = kind; // kind
// 22.1.5.2.1 %ArrayIteratorPrototype%.next()
}, function () {
var O = this._t;
var kind = this._k;
var index = this._i++;
if (!O || index >= O.length) {
this._t = undefined;
return step(1);
}
if (kind == 'keys') return step(0, index);
if (kind == 'values') return step(0, O[index]);
return step(0, [index, O[index]]);
}, 'values');
// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
Iterators.Arguments = Iterators.Array;
addToUnscopables('keys');
addToUnscopables('values');
addToUnscopables('entries');
},{"./_add-to-unscopables":13,"./_iter-define":60,"./_iter-step":62,"./_iterators":63,"./_to-iobject":113}],138:[function(require,module,exports){
'use strict';
// 22.1.3.13 Array.prototype.join(separator)
var $export = require('./_export');
var toIObject = require('./_to-iobject');
var arrayJoin = [].join;
// fallback for not array-like strings
$export($export.P + $export.F * (require('./_iobject') != Object || !require('./_strict-method')(arrayJoin)), 'Array', {
join: function join(separator) {
return arrayJoin.call(toIObject(this), separator === undefined ? ',' : separator);
}
});
},{"./_export":39,"./_iobject":52,"./_strict-method":101,"./_to-iobject":113}],139:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var toIObject = require('./_to-iobject');
var toInteger = require('./_to-integer');
var toLength = require('./_to-length');
var $native = [].lastIndexOf;
var NEGATIVE_ZERO = !!$native && 1 / [1].lastIndexOf(1, -0) < 0;
$export($export.P + $export.F * (NEGATIVE_ZERO || !require('./_strict-method')($native)), 'Array', {
// 22.1.3.14 / 15.4.4.15 Array.prototype.lastIndexOf(searchElement [, fromIndex])
lastIndexOf: function lastIndexOf(searchElement /* , fromIndex = @[*-1] */) {
// convert -0 to +0
if (NEGATIVE_ZERO) return $native.apply(this, arguments) || 0;
var O = toIObject(this);
var length = toLength(O.length);
var index = length - 1;
if (arguments.length > 1) index = Math.min(index, toInteger(arguments[1]));
if (index < 0) index = length + index;
for (;index >= 0; index--) if (index in O) if (O[index] === searchElement) return index || 0;
return -1;
}
});
},{"./_export":39,"./_strict-method":101,"./_to-integer":112,"./_to-iobject":113,"./_to-length":114}],140:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $map = require('./_array-methods')(1);
$export($export.P + $export.F * !require('./_strict-method')([].map, true), 'Array', {
// 22.1.3.15 / 15.4.4.19 Array.prototype.map(callbackfn [, thisArg])
map: function map(callbackfn /* , thisArg */) {
return $map(this, callbackfn, arguments[1]);
}
});
},{"./_array-methods":19,"./_export":39,"./_strict-method":101}],141:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var createProperty = require('./_create-property');
// WebKit Array.of isn't generic
$export($export.S + $export.F * require('./_fails')(function () {
function F() { /* empty */ }
return !(Array.of.call(F) instanceof F);
}), 'Array', {
// 22.1.2.3 Array.of( ...items)
of: function of(/* ...args */) {
var index = 0;
var aLen = arguments.length;
var result = new (typeof this == 'function' ? this : Array)(aLen);
while (aLen > index) createProperty(result, index, arguments[index++]);
result.length = aLen;
return result;
}
});
},{"./_create-property":30,"./_export":39,"./_fails":41}],142:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $reduce = require('./_array-reduce');
$export($export.P + $export.F * !require('./_strict-method')([].reduceRight, true), 'Array', {
// 22.1.3.19 / 15.4.4.22 Array.prototype.reduceRight(callbackfn [, initialValue])
reduceRight: function reduceRight(callbackfn /* , initialValue */) {
return $reduce(this, callbackfn, arguments.length, arguments[1], true);
}
});
},{"./_array-reduce":20,"./_export":39,"./_strict-method":101}],143:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $reduce = require('./_array-reduce');
$export($export.P + $export.F * !require('./_strict-method')([].reduce, true), 'Array', {
// 22.1.3.18 / 15.4.4.21 Array.prototype.reduce(callbackfn [, initialValue])
reduce: function reduce(callbackfn /* , initialValue */) {
return $reduce(this, callbackfn, arguments.length, arguments[1], false);
}
});
},{"./_array-reduce":20,"./_export":39,"./_strict-method":101}],144:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var html = require('./_html');
var cof = require('./_cof');
var toAbsoluteIndex = require('./_to-absolute-index');
var toLength = require('./_to-length');
var arraySlice = [].slice;
// fallback for not array-like ES3 strings and DOM objects
$export($export.P + $export.F * require('./_fails')(function () {
if (html) arraySlice.call(html);
}), 'Array', {
slice: function slice(begin, end) {
var len = toLength(this.length);
var klass = cof(this);
end = end === undefined ? len : end;
if (klass == 'Array') return arraySlice.call(this, begin, end);
var start = toAbsoluteIndex(begin, len);
var upTo = toAbsoluteIndex(end, len);
var size = toLength(upTo - start);
var cloned = new Array(size);
var i = 0;
for (; i < size; i++) cloned[i] = klass == 'String'
? this.charAt(start + i)
: this[start + i];
return cloned;
}
});
},{"./_cof":25,"./_export":39,"./_fails":41,"./_html":48,"./_to-absolute-index":110,"./_to-length":114}],145:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $some = require('./_array-methods')(3);
$export($export.P + $export.F * !require('./_strict-method')([].some, true), 'Array', {
// 22.1.3.23 / 15.4.4.17 Array.prototype.some(callbackfn [, thisArg])
some: function some(callbackfn /* , thisArg */) {
return $some(this, callbackfn, arguments[1]);
}
});
},{"./_array-methods":19,"./_export":39,"./_strict-method":101}],146:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var aFunction = require('./_a-function');
var toObject = require('./_to-object');
var fails = require('./_fails');
var $sort = [].sort;
var test = [1, 2, 3];
$export($export.P + $export.F * (fails(function () {
// IE8-
test.sort(undefined);
}) || !fails(function () {
// V8 bug
test.sort(null);
// Old WebKit
}) || !require('./_strict-method')($sort)), 'Array', {
// 22.1.3.25 Array.prototype.sort(comparefn)
sort: function sort(comparefn) {
return comparefn === undefined
? $sort.call(toObject(this))
: $sort.call(toObject(this), aFunction(comparefn));
}
});
},{"./_a-function":11,"./_export":39,"./_fails":41,"./_strict-method":101,"./_to-object":115}],147:[function(require,module,exports){
require('./_set-species')('Array');
},{"./_set-species":96}],148:[function(require,module,exports){
// 20.3.3.1 / 15.9.4.4 Date.now()
var $export = require('./_export');
$export($export.S, 'Date', { now: function () { return new Date().getTime(); } });
},{"./_export":39}],149:[function(require,module,exports){
// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()
var $export = require('./_export');
var toISOString = require('./_date-to-iso-string');
// PhantomJS / old WebKit has a broken implementations
$export($export.P + $export.F * (Date.prototype.toISOString !== toISOString), 'Date', {
toISOString: toISOString
});
},{"./_date-to-iso-string":32,"./_export":39}],150:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var toObject = require('./_to-object');
var toPrimitive = require('./_to-primitive');
$export($export.P + $export.F * require('./_fails')(function () {
return new Date(NaN).toJSON() !== null
|| Date.prototype.toJSON.call({ toISOString: function () { return 1; } }) !== 1;
}), 'Date', {
// eslint-disable-next-line no-unused-vars
toJSON: function toJSON(key) {
var O = toObject(this);
var pv = toPrimitive(O);
return typeof pv == 'number' && !isFinite(pv) ? null : O.toISOString();
}
});
},{"./_export":39,"./_fails":41,"./_to-object":115,"./_to-primitive":116}],151:[function(require,module,exports){
var TO_PRIMITIVE = require('./_wks')('toPrimitive');
var proto = Date.prototype;
if (!(TO_PRIMITIVE in proto)) require('./_hide')(proto, TO_PRIMITIVE, require('./_date-to-primitive'));
},{"./_date-to-primitive":33,"./_hide":47,"./_wks":125}],152:[function(require,module,exports){
var DateProto = Date.prototype;
var INVALID_DATE = 'Invalid Date';
var TO_STRING = 'toString';
var $toString = DateProto[TO_STRING];
var getTime = DateProto.getTime;
if (new Date(NaN) + '' != INVALID_DATE) {
require('./_redefine')(DateProto, TO_STRING, function toString() {
var value = getTime.call(this);
// eslint-disable-next-line no-self-compare
return value === value ? $toString.call(this) : INVALID_DATE;
});
}
},{"./_redefine":93}],153:[function(require,module,exports){
// 19.2.3.2 / 15.3.4.5 Function.prototype.bind(thisArg, args...)
var $export = require('./_export');
$export($export.P, 'Function', { bind: require('./_bind') });
},{"./_bind":23,"./_export":39}],154:[function(require,module,exports){
'use strict';
var isObject = require('./_is-object');
var getPrototypeOf = require('./_object-gpo');
var HAS_INSTANCE = require('./_wks')('hasInstance');
var FunctionProto = Function.prototype;
// 19.2.3.6 Function.prototype[@@hasInstance](V)
if (!(HAS_INSTANCE in FunctionProto)) require('./_object-dp').f(FunctionProto, HAS_INSTANCE, { value: function (O) {
if (typeof this != 'function' || !isObject(O)) return false;
if (!isObject(this.prototype)) return O instanceof this;
// for environment w/o native `@@hasInstance` logic enough `instanceof`, but add this:
while (O = getPrototypeOf(O)) if (this.prototype === O) return true;
return false;
} });
},{"./_is-object":56,"./_object-dp":74,"./_object-gpo":80,"./_wks":125}],155:[function(require,module,exports){
var dP = require('./_object-dp').f;
var FProto = Function.prototype;
var nameRE = /^\s*function ([^ (]*)/;
var NAME = 'name';
// 19.2.4.2 name
NAME in FProto || require('./_descriptors') && dP(FProto, NAME, {
configurable: true,
get: function () {
try {
return ('' + this).match(nameRE)[1];
} catch (e) {
return '';
}
}
});
},{"./_descriptors":35,"./_object-dp":74}],156:[function(require,module,exports){
'use strict';
var strong = require('./_collection-strong');
var validate = require('./_validate-collection');
var MAP = 'Map';
// 23.1 Map Objects
module.exports = require('./_collection')(MAP, function (get) {
return function Map() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
// 23.1.3.6 Map.prototype.get(key)
get: function get(key) {
var entry = strong.getEntry(validate(this, MAP), key);
return entry && entry.v;
},
// 23.1.3.9 Map.prototype.set(key, value)
set: function set(key, value) {
return strong.def(validate(this, MAP), key === 0 ? 0 : key, value);
}
}, strong, true);
},{"./_collection":28,"./_collection-strong":26,"./_validate-collection":122}],157:[function(require,module,exports){
// 20.2.2.3 Math.acosh(x)
var $export = require('./_export');
var log1p = require('./_math-log1p');
var sqrt = Math.sqrt;
var $acosh = Math.acosh;
$export($export.S + $export.F * !($acosh
// V8 bug: https://code.google.com/p/v8/issues/detail?id=3509
&& Math.floor($acosh(Number.MAX_VALUE)) == 710
// Tor Browser bug: Math.acosh(Infinity) -> NaN
&& $acosh(Infinity) == Infinity
), 'Math', {
acosh: function acosh(x) {
return (x = +x) < 1 ? NaN : x > 94906265.62425156
? Math.log(x) + Math.LN2
: log1p(x - 1 + sqrt(x - 1) * sqrt(x + 1));
}
});
},{"./_export":39,"./_math-log1p":67}],158:[function(require,module,exports){
// 20.2.2.5 Math.asinh(x)
var $export = require('./_export');
var $asinh = Math.asinh;
function asinh(x) {
return !isFinite(x = +x) || x == 0 ? x : x < 0 ? -asinh(-x) : Math.log(x + Math.sqrt(x * x + 1));
}
// Tor Browser bug: Math.asinh(0) -> -0
$export($export.S + $export.F * !($asinh && 1 / $asinh(0) > 0), 'Math', { asinh: asinh });
},{"./_export":39}],159:[function(require,module,exports){
// 20.2.2.7 Math.atanh(x)
var $export = require('./_export');
var $atanh = Math.atanh;
// Tor Browser bug: Math.atanh(-0) -> 0
$export($export.S + $export.F * !($atanh && 1 / $atanh(-0) < 0), 'Math', {
atanh: function atanh(x) {
return (x = +x) == 0 ? x : Math.log((1 + x) / (1 - x)) / 2;
}
});
},{"./_export":39}],160:[function(require,module,exports){
// 20.2.2.9 Math.cbrt(x)
var $export = require('./_export');
var sign = require('./_math-sign');
$export($export.S, 'Math', {
cbrt: function cbrt(x) {
return sign(x = +x) * Math.pow(Math.abs(x), 1 / 3);
}
});
},{"./_export":39,"./_math-sign":68}],161:[function(require,module,exports){
// 20.2.2.11 Math.clz32(x)
var $export = require('./_export');
$export($export.S, 'Math', {
clz32: function clz32(x) {
return (x >>>= 0) ? 31 - Math.floor(Math.log(x + 0.5) * Math.LOG2E) : 32;
}
});
},{"./_export":39}],162:[function(require,module,exports){
// 20.2.2.12 Math.cosh(x)
var $export = require('./_export');
var exp = Math.exp;
$export($export.S, 'Math', {
cosh: function cosh(x) {
return (exp(x = +x) + exp(-x)) / 2;
}
});
},{"./_export":39}],163:[function(require,module,exports){
// 20.2.2.14 Math.expm1(x)
var $export = require('./_export');
var $expm1 = require('./_math-expm1');
$export($export.S + $export.F * ($expm1 != Math.expm1), 'Math', { expm1: $expm1 });
},{"./_export":39,"./_math-expm1":65}],164:[function(require,module,exports){
// 20.2.2.16 Math.fround(x)
var $export = require('./_export');
$export($export.S, 'Math', { fround: require('./_math-fround') });
},{"./_export":39,"./_math-fround":66}],165:[function(require,module,exports){
// 20.2.2.17 Math.hypot([value1[, value2[, … ]]])
var $export = require('./_export');
var abs = Math.abs;
$export($export.S, 'Math', {
hypot: function hypot(value1, value2) { // eslint-disable-line no-unused-vars
var sum = 0;
var i = 0;
var aLen = arguments.length;
var larg = 0;
var arg, div;
while (i < aLen) {
arg = abs(arguments[i++]);
if (larg < arg) {
div = larg / arg;
sum = sum * div * div + 1;
larg = arg;
} else if (arg > 0) {
div = arg / larg;
sum += div * div;
} else sum += arg;
}
return larg === Infinity ? Infinity : larg * Math.sqrt(sum);
}
});
},{"./_export":39}],166:[function(require,module,exports){
// 20.2.2.18 Math.imul(x, y)
var $export = require('./_export');
var $imul = Math.imul;
// some WebKit versions fails with big numbers, some has wrong arity
$export($export.S + $export.F * require('./_fails')(function () {
return $imul(0xffffffff, 5) != -5 || $imul.length != 2;
}), 'Math', {
imul: function imul(x, y) {
var UINT16 = 0xffff;
var xn = +x;
var yn = +y;
var xl = UINT16 & xn;
var yl = UINT16 & yn;
return 0 | xl * yl + ((UINT16 & xn >>> 16) * yl + xl * (UINT16 & yn >>> 16) << 16 >>> 0);
}
});
},{"./_export":39,"./_fails":41}],167:[function(require,module,exports){
// 20.2.2.21 Math.log10(x)
var $export = require('./_export');
$export($export.S, 'Math', {
log10: function log10(x) {
return Math.log(x) * Math.LOG10E;
}
});
},{"./_export":39}],168:[function(require,module,exports){
// 20.2.2.20 Math.log1p(x)
var $export = require('./_export');
$export($export.S, 'Math', { log1p: require('./_math-log1p') });
},{"./_export":39,"./_math-log1p":67}],169:[function(require,module,exports){
// 20.2.2.22 Math.log2(x)
var $export = require('./_export');
$export($export.S, 'Math', {
log2: function log2(x) {
return Math.log(x) / Math.LN2;
}
});
},{"./_export":39}],170:[function(require,module,exports){
// 20.2.2.28 Math.sign(x)
var $export = require('./_export');
$export($export.S, 'Math', { sign: require('./_math-sign') });
},{"./_export":39,"./_math-sign":68}],171:[function(require,module,exports){
// 20.2.2.30 Math.sinh(x)
var $export = require('./_export');
var expm1 = require('./_math-expm1');
var exp = Math.exp;
// V8 near Chromium 38 has a problem with very small numbers
$export($export.S + $export.F * require('./_fails')(function () {
return !Math.sinh(-2e-17) != -2e-17;
}), 'Math', {
sinh: function sinh(x) {
return Math.abs(x = +x) < 1
? (expm1(x) - expm1(-x)) / 2
: (exp(x - 1) - exp(-x - 1)) * (Math.E / 2);
}
});
},{"./_export":39,"./_fails":41,"./_math-expm1":65}],172:[function(require,module,exports){
// 20.2.2.33 Math.tanh(x)
var $export = require('./_export');
var expm1 = require('./_math-expm1');
var exp = Math.exp;
$export($export.S, 'Math', {
tanh: function tanh(x) {
var a = expm1(x = +x);
var b = expm1(-x);
return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (exp(x) + exp(-x));
}
});
},{"./_export":39,"./_math-expm1":65}],173:[function(require,module,exports){
// 20.2.2.34 Math.trunc(x)
var $export = require('./_export');
$export($export.S, 'Math', {
trunc: function trunc(it) {
return (it > 0 ? Math.floor : Math.ceil)(it);
}
});
},{"./_export":39}],174:[function(require,module,exports){
'use strict';
var global = require('./_global');
var has = require('./_has');
var cof = require('./_cof');
var inheritIfRequired = require('./_inherit-if-required');
var toPrimitive = require('./_to-primitive');
var fails = require('./_fails');
var gOPN = require('./_object-gopn').f;
var gOPD = require('./_object-gopd').f;
var dP = require('./_object-dp').f;
var $trim = require('./_string-trim').trim;
var NUMBER = 'Number';
var $Number = global[NUMBER];
var Base = $Number;
var proto = $Number.prototype;
// Opera ~12 has broken Object#toString
var BROKEN_COF = cof(require('./_object-create')(proto)) == NUMBER;
var TRIM = 'trim' in String.prototype;
// 7.1.3 ToNumber(argument)
var toNumber = function (argument) {
var it = toPrimitive(argument, false);
if (typeof it == 'string' && it.length > 2) {
it = TRIM ? it.trim() : $trim(it, 3);
var first = it.charCodeAt(0);
var third, radix, maxCode;
if (first === 43 || first === 45) {
third = it.charCodeAt(2);
if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix
} else if (first === 48) {
switch (it.charCodeAt(1)) {
case 66: case 98: radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i
case 79: case 111: radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i
default: return +it;
}
for (var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++) {
code = digits.charCodeAt(i);
// parseInt parses a string to a first unavailable symbol
// but ToNumber should return NaN if a string contains unavailable symbols
if (code < 48 || code > maxCode) return NaN;
} return parseInt(digits, radix);
}
} return +it;
};
if (!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')) {
$Number = function Number(value) {
var it = arguments.length < 1 ? 0 : value;
var that = this;
return that instanceof $Number
// check on 1..constructor(foo) case
&& (BROKEN_COF ? fails(function () { proto.valueOf.call(that); }) : cof(that) != NUMBER)
? inheritIfRequired(new Base(toNumber(it)), that, $Number) : toNumber(it);
};
for (var keys = require('./_descriptors') ? gOPN(Base) : (
// ES3:
'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +
// ES6 (in case, if modules with ES6 Number statics required before):
'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +
'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'
).split(','), j = 0, key; keys.length > j; j++) {
if (has(Base, key = keys[j]) && !has($Number, key)) {
dP($Number, key, gOPD(Base, key));
}
}
$Number.prototype = proto;
proto.constructor = $Number;
require('./_redefine')(global, NUMBER, $Number);
}
},{"./_cof":25,"./_descriptors":35,"./_fails":41,"./_global":45,"./_has":46,"./_inherit-if-required":50,"./_object-create":73,"./_object-dp":74,"./_object-gopd":76,"./_object-gopn":78,"./_redefine":93,"./_string-trim":107,"./_to-primitive":116}],175:[function(require,module,exports){
// 20.1.2.1 Number.EPSILON
var $export = require('./_export');
$export($export.S, 'Number', { EPSILON: Math.pow(2, -52) });
},{"./_export":39}],176:[function(require,module,exports){
// 20.1.2.2 Number.isFinite(number)
var $export = require('./_export');
var _isFinite = require('./_global').isFinite;
$export($export.S, 'Number', {
isFinite: function isFinite(it) {
return typeof it == 'number' && _isFinite(it);
}
});
},{"./_export":39,"./_global":45}],177:[function(require,module,exports){
// 20.1.2.3 Number.isInteger(number)
var $export = require('./_export');
$export($export.S, 'Number', { isInteger: require('./_is-integer') });
},{"./_export":39,"./_is-integer":55}],178:[function(require,module,exports){
// 20.1.2.4 Number.isNaN(number)
var $export = require('./_export');
$export($export.S, 'Number', {
isNaN: function isNaN(number) {
// eslint-disable-next-line no-self-compare
return number != number;
}
});
},{"./_export":39}],179:[function(require,module,exports){
// 20.1.2.5 Number.isSafeInteger(number)
var $export = require('./_export');
var isInteger = require('./_is-integer');
var abs = Math.abs;
$export($export.S, 'Number', {
isSafeInteger: function isSafeInteger(number) {
return isInteger(number) && abs(number) <= 0x1fffffffffffff;
}
});
},{"./_export":39,"./_is-integer":55}],180:[function(require,module,exports){
// 20.1.2.6 Number.MAX_SAFE_INTEGER
var $export = require('./_export');
$export($export.S, 'Number', { MAX_SAFE_INTEGER: 0x1fffffffffffff });
},{"./_export":39}],181:[function(require,module,exports){
// 20.1.2.10 Number.MIN_SAFE_INTEGER
var $export = require('./_export');
$export($export.S, 'Number', { MIN_SAFE_INTEGER: -0x1fffffffffffff });
},{"./_export":39}],182:[function(require,module,exports){
var $export = require('./_export');
var $parseFloat = require('./_parse-float');
// 20.1.2.12 Number.parseFloat(string)
$export($export.S + $export.F * (Number.parseFloat != $parseFloat), 'Number', { parseFloat: $parseFloat });
},{"./_export":39,"./_parse-float":87}],183:[function(require,module,exports){
var $export = require('./_export');
var $parseInt = require('./_parse-int');
// 20.1.2.13 Number.parseInt(string, radix)
$export($export.S + $export.F * (Number.parseInt != $parseInt), 'Number', { parseInt: $parseInt });
},{"./_export":39,"./_parse-int":88}],184:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var toInteger = require('./_to-integer');
var aNumberValue = require('./_a-number-value');
var repeat = require('./_string-repeat');
var $toFixed = 1.0.toFixed;
var floor = Math.floor;
var data = [0, 0, 0, 0, 0, 0];
var ERROR = 'Number.toFixed: incorrect invocation!';
var ZERO = '0';
var multiply = function (n, c) {
var i = -1;
var c2 = c;
while (++i < 6) {
c2 += n * data[i];
data[i] = c2 % 1e7;
c2 = floor(c2 / 1e7);
}
};
var divide = function (n) {
var i = 6;
var c = 0;
while (--i >= 0) {
c += data[i];
data[i] = floor(c / n);
c = (c % n) * 1e7;
}
};
var numToString = function () {
var i = 6;
var s = '';
while (--i >= 0) {
if (s !== '' || i === 0 || data[i] !== 0) {
var t = String(data[i]);
s = s === '' ? t : s + repeat.call(ZERO, 7 - t.length) + t;
}
} return s;
};
var pow = function (x, n, acc) {
return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc);
};
var log = function (x) {
var n = 0;
var x2 = x;
while (x2 >= 4096) {
n += 12;
x2 /= 4096;
}
while (x2 >= 2) {
n += 1;
x2 /= 2;
} return n;
};
$export($export.P + $export.F * (!!$toFixed && (
0.00008.toFixed(3) !== '0.000' ||
0.9.toFixed(0) !== '1' ||
1.255.toFixed(2) !== '1.25' ||
1000000000000000128.0.toFixed(0) !== '1000000000000000128'
) || !require('./_fails')(function () {
// V8 ~ Android 4.3-
$toFixed.call({});
})), 'Number', {
toFixed: function toFixed(fractionDigits) {
var x = aNumberValue(this, ERROR);
var f = toInteger(fractionDigits);
var s = '';
var m = ZERO;
var e, z, j, k;
if (f < 0 || f > 20) throw RangeError(ERROR);
// eslint-disable-next-line no-self-compare
if (x != x) return 'NaN';
if (x <= -1e21 || x >= 1e21) return String(x);
if (x < 0) {
s = '-';
x = -x;
}
if (x > 1e-21) {
e = log(x * pow(2, 69, 1)) - 69;
z = e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1);
z *= 0x10000000000000;
e = 52 - e;
if (e > 0) {
multiply(0, z);
j = f;
while (j >= 7) {
multiply(1e7, 0);
j -= 7;
}
multiply(pow(10, j, 1), 0);
j = e - 1;
while (j >= 23) {
divide(1 << 23);
j -= 23;
}
divide(1 << j);
multiply(1, 1);
divide(2);
m = numToString();
} else {
multiply(0, z);
multiply(1 << -e, 0);
m = numToString() + repeat.call(ZERO, f);
}
}
if (f > 0) {
k = m.length;
m = s + (k <= f ? '0.' + repeat.call(ZERO, f - k) + m : m.slice(0, k - f) + '.' + m.slice(k - f));
} else {
m = s + m;
} return m;
}
});
},{"./_a-number-value":12,"./_export":39,"./_fails":41,"./_string-repeat":106,"./_to-integer":112}],185:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $fails = require('./_fails');
var aNumberValue = require('./_a-number-value');
var $toPrecision = 1.0.toPrecision;
$export($export.P + $export.F * ($fails(function () {
// IE7-
return $toPrecision.call(1, undefined) !== '1';
}) || !$fails(function () {
// V8 ~ Android 4.3-
$toPrecision.call({});
})), 'Number', {
toPrecision: function toPrecision(precision) {
var that = aNumberValue(this, 'Number#toPrecision: incorrect invocation!');
return precision === undefined ? $toPrecision.call(that) : $toPrecision.call(that, precision);
}
});
},{"./_a-number-value":12,"./_export":39,"./_fails":41}],186:[function(require,module,exports){
// 19.1.3.1 Object.assign(target, source)
var $export = require('./_export');
$export($export.S + $export.F, 'Object', { assign: require('./_object-assign') });
},{"./_export":39,"./_object-assign":72}],187:[function(require,module,exports){
var $export = require('./_export');
// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
$export($export.S, 'Object', { create: require('./_object-create') });
},{"./_export":39,"./_object-create":73}],188:[function(require,module,exports){
var $export = require('./_export');
// 19.1.2.3 / 15.2.3.7 Object.defineProperties(O, Properties)
$export($export.S + $export.F * !require('./_descriptors'), 'Object', { defineProperties: require('./_object-dps') });
},{"./_descriptors":35,"./_export":39,"./_object-dps":75}],189:[function(require,module,exports){
var $export = require('./_export');
// 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes)
$export($export.S + $export.F * !require('./_descriptors'), 'Object', { defineProperty: require('./_object-dp').f });
},{"./_descriptors":35,"./_export":39,"./_object-dp":74}],190:[function(require,module,exports){
// 19.1.2.5 Object.freeze(O)
var isObject = require('./_is-object');
var meta = require('./_meta').onFreeze;
require('./_object-sap')('freeze', function ($freeze) {
return function freeze(it) {
return $freeze && isObject(it) ? $freeze(meta(it)) : it;
};
});
},{"./_is-object":56,"./_meta":69,"./_object-sap":84}],191:[function(require,module,exports){
// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
var toIObject = require('./_to-iobject');
var $getOwnPropertyDescriptor = require('./_object-gopd').f;
require('./_object-sap')('getOwnPropertyDescriptor', function () {
return function getOwnPropertyDescriptor(it, key) {
return $getOwnPropertyDescriptor(toIObject(it), key);
};
});
},{"./_object-gopd":76,"./_object-sap":84,"./_to-iobject":113}],192:[function(require,module,exports){
// 19.1.2.7 Object.getOwnPropertyNames(O)
require('./_object-sap')('getOwnPropertyNames', function () {
return require('./_object-gopn-ext').f;
});
},{"./_object-gopn-ext":77,"./_object-sap":84}],193:[function(require,module,exports){
// 19.1.2.9 Object.getPrototypeOf(O)
var toObject = require('./_to-object');
var $getPrototypeOf = require('./_object-gpo');
require('./_object-sap')('getPrototypeOf', function () {
return function getPrototypeOf(it) {
return $getPrototypeOf(toObject(it));
};
});
},{"./_object-gpo":80,"./_object-sap":84,"./_to-object":115}],194:[function(require,module,exports){
// 19.1.2.11 Object.isExtensible(O)
var isObject = require('./_is-object');
require('./_object-sap')('isExtensible', function ($isExtensible) {
return function isExtensible(it) {
return isObject(it) ? $isExtensible ? $isExtensible(it) : true : false;
};
});
},{"./_is-object":56,"./_object-sap":84}],195:[function(require,module,exports){
// 19.1.2.12 Object.isFrozen(O)
var isObject = require('./_is-object');
require('./_object-sap')('isFrozen', function ($isFrozen) {
return function isFrozen(it) {
return isObject(it) ? $isFrozen ? $isFrozen(it) : false : true;
};
});
},{"./_is-object":56,"./_object-sap":84}],196:[function(require,module,exports){
// 19.1.2.13 Object.isSealed(O)
var isObject = require('./_is-object');
require('./_object-sap')('isSealed', function ($isSealed) {
return function isSealed(it) {
return isObject(it) ? $isSealed ? $isSealed(it) : false : true;
};
});
},{"./_is-object":56,"./_object-sap":84}],197:[function(require,module,exports){
// 19.1.3.10 Object.is(value1, value2)
var $export = require('./_export');
$export($export.S, 'Object', { is: require('./_same-value') });
},{"./_export":39,"./_same-value":94}],198:[function(require,module,exports){
// 19.1.2.14 Object.keys(O)
var toObject = require('./_to-object');
var $keys = require('./_object-keys');
require('./_object-sap')('keys', function () {
return function keys(it) {
return $keys(toObject(it));
};
});
},{"./_object-keys":82,"./_object-sap":84,"./_to-object":115}],199:[function(require,module,exports){
// 19.1.2.15 Object.preventExtensions(O)
var isObject = require('./_is-object');
var meta = require('./_meta').onFreeze;
require('./_object-sap')('preventExtensions', function ($preventExtensions) {
return function preventExtensions(it) {
return $preventExtensions && isObject(it) ? $preventExtensions(meta(it)) : it;
};
});
},{"./_is-object":56,"./_meta":69,"./_object-sap":84}],200:[function(require,module,exports){
// 19.1.2.17 Object.seal(O)
var isObject = require('./_is-object');
var meta = require('./_meta').onFreeze;
require('./_object-sap')('seal', function ($seal) {
return function seal(it) {
return $seal && isObject(it) ? $seal(meta(it)) : it;
};
});
},{"./_is-object":56,"./_meta":69,"./_object-sap":84}],201:[function(require,module,exports){
// 19.1.3.19 Object.setPrototypeOf(O, proto)
var $export = require('./_export');
$export($export.S, 'Object', { setPrototypeOf: require('./_set-proto').set });
},{"./_export":39,"./_set-proto":95}],202:[function(require,module,exports){
'use strict';
// 19.1.3.6 Object.prototype.toString()
var classof = require('./_classof');
var test = {};
test[require('./_wks')('toStringTag')] = 'z';
if (test + '' != '[object z]') {
require('./_redefine')(Object.prototype, 'toString', function toString() {
return '[object ' + classof(this) + ']';
}, true);
}
},{"./_classof":24,"./_redefine":93,"./_wks":125}],203:[function(require,module,exports){
var $export = require('./_export');
var $parseFloat = require('./_parse-float');
// 18.2.4 parseFloat(string)
$export($export.G + $export.F * (parseFloat != $parseFloat), { parseFloat: $parseFloat });
},{"./_export":39,"./_parse-float":87}],204:[function(require,module,exports){
var $export = require('./_export');
var $parseInt = require('./_parse-int');
// 18.2.5 parseInt(string, radix)
$export($export.G + $export.F * (parseInt != $parseInt), { parseInt: $parseInt });
},{"./_export":39,"./_parse-int":88}],205:[function(require,module,exports){
'use strict';
var LIBRARY = require('./_library');
var global = require('./_global');
var ctx = require('./_ctx');
var classof = require('./_classof');
var $export = require('./_export');
var isObject = require('./_is-object');
var aFunction = require('./_a-function');
var anInstance = require('./_an-instance');
var forOf = require('./_for-of');
var speciesConstructor = require('./_species-constructor');
var task = require('./_task').set;
var microtask = require('./_microtask')();
var newPromiseCapabilityModule = require('./_new-promise-capability');
var perform = require('./_perform');
var userAgent = require('./_user-agent');
var promiseResolve = require('./_promise-resolve');
var PROMISE = 'Promise';
var TypeError = global.TypeError;
var process = global.process;
var versions = process && process.versions;
var v8 = versions && versions.v8 || '';
var $Promise = global[PROMISE];
var isNode = classof(process) == 'process';
var empty = function () { /* empty */ };
var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper;
var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f;
var USE_NATIVE = !!function () {
try {
// correct subclassing with @@species support
var promise = $Promise.resolve(1);
var FakePromise = (promise.constructor = {})[require('./_wks')('species')] = function (exec) {
exec(empty, empty);
};
// unhandled rejections tracking support, NodeJS Promise without it fails @@species test
return (isNode || typeof PromiseRejectionEvent == 'function')
&& promise.then(empty) instanceof FakePromise
// v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables
// https://bugs.chromium.org/p/chromium/issues/detail?id=830565
// we can't detect it synchronously, so just check versions
&& v8.indexOf('6.6') !== 0
&& userAgent.indexOf('Chrome/66') === -1;
} catch (e) { /* empty */ }
}();
// helpers
var isThenable = function (it) {
var then;
return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
};
var notify = function (promise, isReject) {
if (promise._n) return;
promise._n = true;
var chain = promise._c;
microtask(function () {
var value = promise._v;
var ok = promise._s == 1;
var i = 0;
var run = function (reaction) {
var handler = ok ? reaction.ok : reaction.fail;
var resolve = reaction.resolve;
var reject = reaction.reject;
var domain = reaction.domain;
var result, then, exited;
try {
if (handler) {
if (!ok) {
if (promise._h == 2) onHandleUnhandled(promise);
promise._h = 1;
}
if (handler === true) result = value;
else {
if (domain) domain.enter();
result = handler(value); // may throw
if (domain) {
domain.exit();
exited = true;
}
}
if (result === reaction.promise) {
reject(TypeError('Promise-chain cycle'));
} else if (then = isThenable(result)) {
then.call(result, resolve, reject);
} else resolve(result);
} else reject(value);
} catch (e) {
if (domain && !exited) domain.exit();
reject(e);
}
};
while (chain.length > i) run(chain[i++]); // variable length - can't use forEach
promise._c = [];
promise._n = false;
if (isReject && !promise._h) onUnhandled(promise);
});
};
var onUnhandled = function (promise) {
task.call(global, function () {
var value = promise._v;
var unhandled = isUnhandled(promise);
var result, handler, console;
if (unhandled) {
result = perform(function () {
if (isNode) {
process.emit('unhandledRejection', value, promise);
} else if (handler = global.onunhandledrejection) {
handler({ promise: promise, reason: value });
} else if ((console = global.console) && console.error) {
console.error('Unhandled promise rejection', value);
}
});
// Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
promise._h = isNode || isUnhandled(promise) ? 2 : 1;
} promise._a = undefined;
if (unhandled && result.e) throw result.v;
});
};
var isUnhandled = function (promise) {
return promise._h !== 1 && (promise._a || promise._c).length === 0;
};
var onHandleUnhandled = function (promise) {
task.call(global, function () {
var handler;
if (isNode) {
process.emit('rejectionHandled', promise);
} else if (handler = global.onrejectionhandled) {
handler({ promise: promise, reason: promise._v });
}
});
};
var $reject = function (value) {
var promise = this;
if (promise._d) return;
promise._d = true;
promise = promise._w || promise; // unwrap
promise._v = value;
promise._s = 2;
if (!promise._a) promise._a = promise._c.slice();
notify(promise, true);
};
var $resolve = function (value) {
var promise = this;
var then;
if (promise._d) return;
promise._d = true;
promise = promise._w || promise; // unwrap
try {
if (promise === value) throw TypeError("Promise can't be resolved itself");
if (then = isThenable(value)) {
microtask(function () {
var wrapper = { _w: promise, _d: false }; // wrap
try {
then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));
} catch (e) {
$reject.call(wrapper, e);
}
});
} else {
promise._v = value;
promise._s = 1;
notify(promise, false);
}
} catch (e) {
$reject.call({ _w: promise, _d: false }, e); // wrap
}
};
// constructor polyfill
if (!USE_NATIVE) {
// 25.4.3.1 Promise(executor)
$Promise = function Promise(executor) {
anInstance(this, $Promise, PROMISE, '_h');
aFunction(executor);
Internal.call(this);
try {
executor(ctx($resolve, this, 1), ctx($reject, this, 1));
} catch (err) {
$reject.call(this, err);
}
};
// eslint-disable-next-line no-unused-vars
Internal = function Promise(executor) {
this._c = []; // <- awaiting reactions
this._a = undefined; // <- checked in isUnhandled reactions
this._s = 0; // <- state
this._d = false; // <- done
this._v = undefined; // <- value
this._h = 0; // <- rejection state, 0 - default, 1 - handled, 2 - unhandled
this._n = false; // <- notify
};
Internal.prototype = require('./_redefine-all')($Promise.prototype, {
// 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)
then: function then(onFulfilled, onRejected) {
var reaction = newPromiseCapability(speciesConstructor(this, $Promise));
reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
reaction.fail = typeof onRejected == 'function' && onRejected;
reaction.domain = isNode ? process.domain : undefined;
this._c.push(reaction);
if (this._a) this._a.push(reaction);
if (this._s) notify(this, false);
return reaction.promise;
},
// 25.4.5.1 Promise.prototype.catch(onRejected)
'catch': function (onRejected) {
return this.then(undefined, onRejected);
}
});
OwnPromiseCapability = function () {
var promise = new Internal();
this.promise = promise;
this.resolve = ctx($resolve, promise, 1);
this.reject = ctx($reject, promise, 1);
};
newPromiseCapabilityModule.f = newPromiseCapability = function (C) {
return C === $Promise || C === Wrapper
? new OwnPromiseCapability(C)
: newGenericPromiseCapability(C);
};
}
$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });
require('./_set-to-string-tag')($Promise, PROMISE);
require('./_set-species')(PROMISE);
Wrapper = require('./_core')[PROMISE];
// statics
$export($export.S + $export.F * !USE_NATIVE, PROMISE, {
// 25.4.4.5 Promise.reject(r)
reject: function reject(r) {
var capability = newPromiseCapability(this);
var $$reject = capability.reject;
$$reject(r);
return capability.promise;
}
});
$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {
// 25.4.4.6 Promise.resolve(x)
resolve: function resolve(x) {
return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x);
}
});
$export($export.S + $export.F * !(USE_NATIVE && require('./_iter-detect')(function (iter) {
$Promise.all(iter)['catch'](empty);
})), PROMISE, {
// 25.4.4.1 Promise.all(iterable)
all: function all(iterable) {
var C = this;
var capability = newPromiseCapability(C);
var resolve = capability.resolve;
var reject = capability.reject;
var result = perform(function () {
var values = [];
var index = 0;
var remaining = 1;
forOf(iterable, false, function (promise) {
var $index = index++;
var alreadyCalled = false;
values.push(undefined);
remaining++;
C.resolve(promise).then(function (value) {
if (alreadyCalled) return;
alreadyCalled = true;
values[$index] = value;
--remaining || resolve(values);
}, reject);
});
--remaining || resolve(values);
});
if (result.e) reject(result.v);
return capability.promise;
},
// 25.4.4.4 Promise.race(iterable)
race: function race(iterable) {
var C = this;
var capability = newPromiseCapability(C);
var reject = capability.reject;
var result = perform(function () {
forOf(iterable, false, function (promise) {
C.resolve(promise).then(capability.resolve, reject);
});
});
if (result.e) reject(result.v);
return capability.promise;
}
});
},{"./_a-function":11,"./_an-instance":14,"./_classof":24,"./_core":29,"./_ctx":31,"./_export":39,"./_for-of":44,"./_global":45,"./_is-object":56,"./_iter-detect":61,"./_library":64,"./_microtask":70,"./_new-promise-capability":71,"./_perform":89,"./_promise-resolve":90,"./_redefine-all":92,"./_set-species":96,"./_set-to-string-tag":97,"./_species-constructor":100,"./_task":109,"./_user-agent":121,"./_wks":125}],206:[function(require,module,exports){
// 26.1.1 Reflect.apply(target, thisArgument, argumentsList)
var $export = require('./_export');
var aFunction = require('./_a-function');
var anObject = require('./_an-object');
var rApply = (require('./_global').Reflect || {}).apply;
var fApply = Function.apply;
// MS Edge argumentsList argument is optional
$export($export.S + $export.F * !require('./_fails')(function () {
rApply(function () { /* empty */ });
}), 'Reflect', {
apply: function apply(target, thisArgument, argumentsList) {
var T = aFunction(target);
var L = anObject(argumentsList);
return rApply ? rApply(T, thisArgument, L) : fApply.call(T, thisArgument, L);
}
});
},{"./_a-function":11,"./_an-object":15,"./_export":39,"./_fails":41,"./_global":45}],207:[function(require,module,exports){
// 26.1.2 Reflect.construct(target, argumentsList [, newTarget])
var $export = require('./_export');
var create = require('./_object-create');
var aFunction = require('./_a-function');
var anObject = require('./_an-object');
var isObject = require('./_is-object');
var fails = require('./_fails');
var bind = require('./_bind');
var rConstruct = (require('./_global').Reflect || {}).construct;
// MS Edge supports only 2 arguments and argumentsList argument is optional
// FF Nightly sets third argument as `new.target`, but does not create `this` from it
var NEW_TARGET_BUG = fails(function () {
function F() { /* empty */ }
return !(rConstruct(function () { /* empty */ }, [], F) instanceof F);
});
var ARGS_BUG = !fails(function () {
rConstruct(function () { /* empty */ });
});
$export($export.S + $export.F * (NEW_TARGET_BUG || ARGS_BUG), 'Reflect', {
construct: function construct(Target, args /* , newTarget */) {
aFunction(Target);
anObject(args);
var newTarget = arguments.length < 3 ? Target : aFunction(arguments[2]);
if (ARGS_BUG && !NEW_TARGET_BUG) return rConstruct(Target, args, newTarget);
if (Target == newTarget) {
// w/o altered newTarget, optimization for 0-4 arguments
switch (args.length) {
case 0: return new Target();
case 1: return new Target(args[0]);
case 2: return new Target(args[0], args[1]);
case 3: return new Target(args[0], args[1], args[2]);
case 4: return new Target(args[0], args[1], args[2], args[3]);
}
// w/o altered newTarget, lot of arguments case
var $args = [null];
$args.push.apply($args, args);
return new (bind.apply(Target, $args))();
}
// with altered newTarget, not support built-in constructors
var proto = newTarget.prototype;
var instance = create(isObject(proto) ? proto : Object.prototype);
var result = Function.apply.call(Target, instance, args);
return isObject(result) ? result : instance;
}
});
},{"./_a-function":11,"./_an-object":15,"./_bind":23,"./_export":39,"./_fails":41,"./_global":45,"./_is-object":56,"./_object-create":73}],208:[function(require,module,exports){
// 26.1.3 Reflect.defineProperty(target, propertyKey, attributes)
var dP = require('./_object-dp');
var $export = require('./_export');
var anObject = require('./_an-object');
var toPrimitive = require('./_to-primitive');
// MS Edge has broken Reflect.defineProperty - throwing instead of returning false
$export($export.S + $export.F * require('./_fails')(function () {
// eslint-disable-next-line no-undef
Reflect.defineProperty(dP.f({}, 1, { value: 1 }), 1, { value: 2 });
}), 'Reflect', {
defineProperty: function defineProperty(target, propertyKey, attributes) {
anObject(target);
propertyKey = toPrimitive(propertyKey, true);
anObject(attributes);
try {
dP.f(target, propertyKey, attributes);
return true;
} catch (e) {
return false;
}
}
});
},{"./_an-object":15,"./_export":39,"./_fails":41,"./_object-dp":74,"./_to-primitive":116}],209:[function(require,module,exports){
// 26.1.4 Reflect.deleteProperty(target, propertyKey)
var $export = require('./_export');
var gOPD = require('./_object-gopd').f;
var anObject = require('./_an-object');
$export($export.S, 'Reflect', {
deleteProperty: function deleteProperty(target, propertyKey) {
var desc = gOPD(anObject(target), propertyKey);
return desc && !desc.configurable ? false : delete target[propertyKey];
}
});
},{"./_an-object":15,"./_export":39,"./_object-gopd":76}],210:[function(require,module,exports){
'use strict';
// 26.1.5 Reflect.enumerate(target)
var $export = require('./_export');
var anObject = require('./_an-object');
var Enumerate = function (iterated) {
this._t = anObject(iterated); // target
this._i = 0; // next index
var keys = this._k = []; // keys
var key;
for (key in iterated) keys.push(key);
};
require('./_iter-create')(Enumerate, 'Object', function () {
var that = this;
var keys = that._k;
var key;
do {
if (that._i >= keys.length) return { value: undefined, done: true };
} while (!((key = keys[that._i++]) in that._t));
return { value: key, done: false };
});
$export($export.S, 'Reflect', {
enumerate: function enumerate(target) {
return new Enumerate(target);
}
});
},{"./_an-object":15,"./_export":39,"./_iter-create":59}],211:[function(require,module,exports){
// 26.1.7 Reflect.getOwnPropertyDescriptor(target, propertyKey)
var gOPD = require('./_object-gopd');
var $export = require('./_export');
var anObject = require('./_an-object');
$export($export.S, 'Reflect', {
getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, propertyKey) {
return gOPD.f(anObject(target), propertyKey);
}
});
},{"./_an-object":15,"./_export":39,"./_object-gopd":76}],212:[function(require,module,exports){
// 26.1.8 Reflect.getPrototypeOf(target)
var $export = require('./_export');
var getProto = require('./_object-gpo');
var anObject = require('./_an-object');
$export($export.S, 'Reflect', {
getPrototypeOf: function getPrototypeOf(target) {
return getProto(anObject(target));
}
});
},{"./_an-object":15,"./_export":39,"./_object-gpo":80}],213:[function(require,module,exports){
// 26.1.6 Reflect.get(target, propertyKey [, receiver])
var gOPD = require('./_object-gopd');
var getPrototypeOf = require('./_object-gpo');
var has = require('./_has');
var $export = require('./_export');
var isObject = require('./_is-object');
var anObject = require('./_an-object');
function get(target, propertyKey /* , receiver */) {
var receiver = arguments.length < 3 ? target : arguments[2];
var desc, proto;
if (anObject(target) === receiver) return target[propertyKey];
if (desc = gOPD.f(target, propertyKey)) return has(desc, 'value')
? desc.value
: desc.get !== undefined
? desc.get.call(receiver)
: undefined;
if (isObject(proto = getPrototypeOf(target))) return get(proto, propertyKey, receiver);
}
$export($export.S, 'Reflect', { get: get });
},{"./_an-object":15,"./_export":39,"./_has":46,"./_is-object":56,"./_object-gopd":76,"./_object-gpo":80}],214:[function(require,module,exports){
// 26.1.9 Reflect.has(target, propertyKey)
var $export = require('./_export');
$export($export.S, 'Reflect', {
has: function has(target, propertyKey) {
return propertyKey in target;
}
});
},{"./_export":39}],215:[function(require,module,exports){
// 26.1.10 Reflect.isExtensible(target)
var $export = require('./_export');
var anObject = require('./_an-object');
var $isExtensible = Object.isExtensible;
$export($export.S, 'Reflect', {
isExtensible: function isExtensible(target) {
anObject(target);
return $isExtensible ? $isExtensible(target) : true;
}
});
},{"./_an-object":15,"./_export":39}],216:[function(require,module,exports){
// 26.1.11 Reflect.ownKeys(target)
var $export = require('./_export');
$export($export.S, 'Reflect', { ownKeys: require('./_own-keys') });
},{"./_export":39,"./_own-keys":86}],217:[function(require,module,exports){
// 26.1.12 Reflect.preventExtensions(target)
var $export = require('./_export');
var anObject = require('./_an-object');
var $preventExtensions = Object.preventExtensions;
$export($export.S, 'Reflect', {
preventExtensions: function preventExtensions(target) {
anObject(target);
try {
if ($preventExtensions) $preventExtensions(target);
return true;
} catch (e) {
return false;
}
}
});
},{"./_an-object":15,"./_export":39}],218:[function(require,module,exports){
// 26.1.14 Reflect.setPrototypeOf(target, proto)
var $export = require('./_export');
var setProto = require('./_set-proto');
if (setProto) $export($export.S, 'Reflect', {
setPrototypeOf: function setPrototypeOf(target, proto) {
setProto.check(target, proto);
try {
setProto.set(target, proto);
return true;
} catch (e) {
return false;
}
}
});
},{"./_export":39,"./_set-proto":95}],219:[function(require,module,exports){
// 26.1.13 Reflect.set(target, propertyKey, V [, receiver])
var dP = require('./_object-dp');
var gOPD = require('./_object-gopd');
var getPrototypeOf = require('./_object-gpo');
var has = require('./_has');
var $export = require('./_export');
var createDesc = require('./_property-desc');
var anObject = require('./_an-object');
var isObject = require('./_is-object');
function set(target, propertyKey, V /* , receiver */) {
var receiver = arguments.length < 4 ? target : arguments[3];
var ownDesc = gOPD.f(anObject(target), propertyKey);
var existingDescriptor, proto;
if (!ownDesc) {
if (isObject(proto = getPrototypeOf(target))) {
return set(proto, propertyKey, V, receiver);
}
ownDesc = createDesc(0);
}
if (has(ownDesc, 'value')) {
if (ownDesc.writable === false || !isObject(receiver)) return false;
if (existingDescriptor = gOPD.f(receiver, propertyKey)) {
if (existingDescriptor.get || existingDescriptor.set || existingDescriptor.writable === false) return false;
existingDescriptor.value = V;
dP.f(receiver, propertyKey, existingDescriptor);
} else dP.f(receiver, propertyKey, createDesc(0, V));
return true;
}
return ownDesc.set === undefined ? false : (ownDesc.set.call(receiver, V), true);
}
$export($export.S, 'Reflect', { set: set });
},{"./_an-object":15,"./_export":39,"./_has":46,"./_is-object":56,"./_object-dp":74,"./_object-gopd":76,"./_object-gpo":80,"./_property-desc":91}],220:[function(require,module,exports){
var global = require('./_global');
var inheritIfRequired = require('./_inherit-if-required');
var dP = require('./_object-dp').f;
var gOPN = require('./_object-gopn').f;
var isRegExp = require('./_is-regexp');
var $flags = require('./_flags');
var $RegExp = global.RegExp;
var Base = $RegExp;
var proto = $RegExp.prototype;
var re1 = /a/g;
var re2 = /a/g;
// "new" creates a new object, old webkit buggy here
var CORRECT_NEW = new $RegExp(re1) !== re1;
if (require('./_descriptors') && (!CORRECT_NEW || require('./_fails')(function () {
re2[require('./_wks')('match')] = false;
// RegExp constructor can alter flags and IsRegExp works correct with @@match
return $RegExp(re1) != re1 || $RegExp(re2) == re2 || $RegExp(re1, 'i') != '/a/i';
}))) {
$RegExp = function RegExp(p, f) {
var tiRE = this instanceof $RegExp;
var piRE = isRegExp(p);
var fiU = f === undefined;
return !tiRE && piRE && p.constructor === $RegExp && fiU ? p
: inheritIfRequired(CORRECT_NEW
? new Base(piRE && !fiU ? p.source : p, f)
: Base((piRE = p instanceof $RegExp) ? p.source : p, piRE && fiU ? $flags.call(p) : f)
, tiRE ? this : proto, $RegExp);
};
var proxy = function (key) {
key in $RegExp || dP($RegExp, key, {
configurable: true,
get: function () { return Base[key]; },
set: function (it) { Base[key] = it; }
});
};
for (var keys = gOPN(Base), i = 0; keys.length > i;) proxy(keys[i++]);
proto.constructor = $RegExp;
$RegExp.prototype = proto;
require('./_redefine')(global, 'RegExp', $RegExp);
}
require('./_set-species')('RegExp');
},{"./_descriptors":35,"./_fails":41,"./_flags":43,"./_global":45,"./_inherit-if-required":50,"./_is-regexp":57,"./_object-dp":74,"./_object-gopn":78,"./_redefine":93,"./_set-species":96,"./_wks":125}],221:[function(require,module,exports){
// 21.2.5.3 get RegExp.prototype.flags()
if (require('./_descriptors') && /./g.flags != 'g') require('./_object-dp').f(RegExp.prototype, 'flags', {
configurable: true,
get: require('./_flags')
});
},{"./_descriptors":35,"./_flags":43,"./_object-dp":74}],222:[function(require,module,exports){
// @@match logic
require('./_fix-re-wks')('match', 1, function (defined, MATCH, $match) {
// 21.1.3.11 String.prototype.match(regexp)
return [function match(regexp) {
'use strict';
var O = defined(this);
var fn = regexp == undefined ? undefined : regexp[MATCH];
return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
}, $match];
});
},{"./_fix-re-wks":42}],223:[function(require,module,exports){
// @@replace logic
require('./_fix-re-wks')('replace', 2, function (defined, REPLACE, $replace) {
// 21.1.3.14 String.prototype.replace(searchValue, replaceValue)
return [function replace(searchValue, replaceValue) {
'use strict';
var O = defined(this);
var fn = searchValue == undefined ? undefined : searchValue[REPLACE];
return fn !== undefined
? fn.call(searchValue, O, replaceValue)
: $replace.call(String(O), searchValue, replaceValue);
}, $replace];
});
},{"./_fix-re-wks":42}],224:[function(require,module,exports){
// @@search logic
require('./_fix-re-wks')('search', 1, function (defined, SEARCH, $search) {
// 21.1.3.15 String.prototype.search(regexp)
return [function search(regexp) {
'use strict';
var O = defined(this);
var fn = regexp == undefined ? undefined : regexp[SEARCH];
return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));
}, $search];
});
},{"./_fix-re-wks":42}],225:[function(require,module,exports){
// @@split logic
require('./_fix-re-wks')('split', 2, function (defined, SPLIT, $split) {
'use strict';
var isRegExp = require('./_is-regexp');
var _split = $split;
var $push = [].push;
var $SPLIT = 'split';
var LENGTH = 'length';
var LAST_INDEX = 'lastIndex';
if (
'abbc'[$SPLIT](/(b)*/)[1] == 'c' ||
'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 ||
'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 ||
'.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 ||
'.'[$SPLIT](/()()/)[LENGTH] > 1 ||
''[$SPLIT](/.?/)[LENGTH]
) {
var NPCG = /()??/.exec('')[1] === undefined; // nonparticipating capturing group
// based on es5-shim implementation, need to rework it
$split = function (separator, limit) {
var string = String(this);
if (separator === undefined && limit === 0) return [];
// If `separator` is not a regex, use native split
if (!isRegExp(separator)) return _split.call(string, separator, limit);
var output = [];
var flags = (separator.ignoreCase ? 'i' : '') +
(separator.multiline ? 'm' : '') +
(separator.unicode ? 'u' : '') +
(separator.sticky ? 'y' : '');
var lastLastIndex = 0;
var splitLimit = limit === undefined ? 4294967295 : limit >>> 0;
// Make `global` and avoid `lastIndex` issues by working with a copy
var separatorCopy = new RegExp(separator.source, flags + 'g');
var separator2, match, lastIndex, lastLength, i;
// Doesn't need flags gy, but they don't hurt
if (!NPCG) separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
while (match = separatorCopy.exec(string)) {
// `separatorCopy.lastIndex` is not reliable cross-browser
lastIndex = match.index + match[0][LENGTH];
if (lastIndex > lastLastIndex) {
output.push(string.slice(lastLastIndex, match.index));
// Fix browsers whose `exec` methods don't consistently return `undefined` for NPCG
// eslint-disable-next-line no-loop-func
if (!NPCG && match[LENGTH] > 1) match[0].replace(separator2, function () {
for (i = 1; i < arguments[LENGTH] - 2; i++) if (arguments[i] === undefined) match[i] = undefined;
});
if (match[LENGTH] > 1 && match.index < string[LENGTH]) $push.apply(output, match.slice(1));
lastLength = match[0][LENGTH];
lastLastIndex = lastIndex;
if (output[LENGTH] >= splitLimit) break;
}
if (separatorCopy[LAST_INDEX] === match.index) separatorCopy[LAST_INDEX]++; // Avoid an infinite loop
}
if (lastLastIndex === string[LENGTH]) {
if (lastLength || !separatorCopy.test('')) output.push('');
} else output.push(string.slice(lastLastIndex));
return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;
};
// Chakra, V8
} else if ('0'[$SPLIT](undefined, 0)[LENGTH]) {
$split = function (separator, limit) {
return separator === undefined && limit === 0 ? [] : _split.call(this, separator, limit);
};
}
// 21.1.3.17 String.prototype.split(separator, limit)
return [function split(separator, limit) {
var O = defined(this);
var fn = separator == undefined ? undefined : separator[SPLIT];
return fn !== undefined ? fn.call(separator, O, limit) : $split.call(String(O), separator, limit);
}, $split];
});
},{"./_fix-re-wks":42,"./_is-regexp":57}],226:[function(require,module,exports){
'use strict';
require('./es6.regexp.flags');
var anObject = require('./_an-object');
var $flags = require('./_flags');
var DESCRIPTORS = require('./_descriptors');
var TO_STRING = 'toString';
var $toString = /./[TO_STRING];
var define = function (fn) {
require('./_redefine')(RegExp.prototype, TO_STRING, fn, true);
};
// 21.2.5.14 RegExp.prototype.toString()
if (require('./_fails')(function () { return $toString.call({ source: 'a', flags: 'b' }) != '/a/b'; })) {
define(function toString() {
var R = anObject(this);
return '/'.concat(R.source, '/',
'flags' in R ? R.flags : !DESCRIPTORS && R instanceof RegExp ? $flags.call(R) : undefined);
});
// FF44- RegExp#toString has a wrong name
} else if ($toString.name != TO_STRING) {
define(function toString() {
return $toString.call(this);
});
}
},{"./_an-object":15,"./_descriptors":35,"./_fails":41,"./_flags":43,"./_redefine":93,"./es6.regexp.flags":221}],227:[function(require,module,exports){
'use strict';
var strong = require('./_collection-strong');
var validate = require('./_validate-collection');
var SET = 'Set';
// 23.2 Set Objects
module.exports = require('./_collection')(SET, function (get) {
return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
// 23.2.3.1 Set.prototype.add(value)
add: function add(value) {
return strong.def(validate(this, SET), value = value === 0 ? 0 : value, value);
}
}, strong);
},{"./_collection":28,"./_collection-strong":26,"./_validate-collection":122}],228:[function(require,module,exports){
'use strict';
// B.2.3.2 String.prototype.anchor(name)
require('./_string-html')('anchor', function (createHTML) {
return function anchor(name) {
return createHTML(this, 'a', 'name', name);
};
});
},{"./_string-html":104}],229:[function(require,module,exports){
'use strict';
// B.2.3.3 String.prototype.big()
require('./_string-html')('big', function (createHTML) {
return function big() {
return createHTML(this, 'big', '', '');
};
});
},{"./_string-html":104}],230:[function(require,module,exports){
'use strict';
// B.2.3.4 String.prototype.blink()
require('./_string-html')('blink', function (createHTML) {
return function blink() {
return createHTML(this, 'blink', '', '');
};
});
},{"./_string-html":104}],231:[function(require,module,exports){
'use strict';
// B.2.3.5 String.prototype.bold()
require('./_string-html')('bold', function (createHTML) {
return function bold() {
return createHTML(this, 'b', '', '');
};
});
},{"./_string-html":104}],232:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $at = require('./_string-at')(false);
$export($export.P, 'String', {
// 21.1.3.3 String.prototype.codePointAt(pos)
codePointAt: function codePointAt(pos) {
return $at(this, pos);
}
});
},{"./_export":39,"./_string-at":102}],233:[function(require,module,exports){
// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition])
'use strict';
var $export = require('./_export');
var toLength = require('./_to-length');
var context = require('./_string-context');
var ENDS_WITH = 'endsWith';
var $endsWith = ''[ENDS_WITH];
$export($export.P + $export.F * require('./_fails-is-regexp')(ENDS_WITH), 'String', {
endsWith: function endsWith(searchString /* , endPosition = @length */) {
var that = context(this, searchString, ENDS_WITH);
var endPosition = arguments.length > 1 ? arguments[1] : undefined;
var len = toLength(that.length);
var end = endPosition === undefined ? len : Math.min(toLength(endPosition), len);
var search = String(searchString);
return $endsWith
? $endsWith.call(that, search, end)
: that.slice(end - search.length, end) === search;
}
});
},{"./_export":39,"./_fails-is-regexp":40,"./_string-context":103,"./_to-length":114}],234:[function(require,module,exports){
'use strict';
// B.2.3.6 String.prototype.fixed()
require('./_string-html')('fixed', function (createHTML) {
return function fixed() {
return createHTML(this, 'tt', '', '');
};
});
},{"./_string-html":104}],235:[function(require,module,exports){
'use strict';
// B.2.3.7 String.prototype.fontcolor(color)
require('./_string-html')('fontcolor', function (createHTML) {
return function fontcolor(color) {
return createHTML(this, 'font', 'color', color);
};
});
},{"./_string-html":104}],236:[function(require,module,exports){
'use strict';
// B.2.3.8 String.prototype.fontsize(size)
require('./_string-html')('fontsize', function (createHTML) {
return function fontsize(size) {
return createHTML(this, 'font', 'size', size);
};
});
},{"./_string-html":104}],237:[function(require,module,exports){
var $export = require('./_export');
var toAbsoluteIndex = require('./_to-absolute-index');
var fromCharCode = String.fromCharCode;
var $fromCodePoint = String.fromCodePoint;
// length should be 1, old FF problem
$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {
// 21.1.2.2 String.fromCodePoint(...codePoints)
fromCodePoint: function fromCodePoint(x) { // eslint-disable-line no-unused-vars
var res = [];
var aLen = arguments.length;
var i = 0;
var code;
while (aLen > i) {
code = +arguments[i++];
if (toAbsoluteIndex(code, 0x10ffff) !== code) throw RangeError(code + ' is not a valid code point');
res.push(code < 0x10000
? fromCharCode(code)
: fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)
);
} return res.join('');
}
});
},{"./_export":39,"./_to-absolute-index":110}],238:[function(require,module,exports){
// 21.1.3.7 String.prototype.includes(searchString, position = 0)
'use strict';
var $export = require('./_export');
var context = require('./_string-context');
var INCLUDES = 'includes';
$export($export.P + $export.F * require('./_fails-is-regexp')(INCLUDES), 'String', {
includes: function includes(searchString /* , position = 0 */) {
return !!~context(this, searchString, INCLUDES)
.indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);
}
});
},{"./_export":39,"./_fails-is-regexp":40,"./_string-context":103}],239:[function(require,module,exports){
'use strict';
// B.2.3.9 String.prototype.italics()
require('./_string-html')('italics', function (createHTML) {
return function italics() {
return createHTML(this, 'i', '', '');
};
});
},{"./_string-html":104}],240:[function(require,module,exports){
'use strict';
var $at = require('./_string-at')(true);
// 21.1.3.27 String.prototype[@@iterator]()
require('./_iter-define')(String, 'String', function (iterated) {
this._t = String(iterated); // target
this._i = 0; // next index
// 21.1.5.2.1 %StringIteratorPrototype%.next()
}, function () {
var O = this._t;
var index = this._i;
var point;
if (index >= O.length) return { value: undefined, done: true };
point = $at(O, index);
this._i += point.length;
return { value: point, done: false };
});
},{"./_iter-define":60,"./_string-at":102}],241:[function(require,module,exports){
'use strict';
// B.2.3.10 String.prototype.link(url)
require('./_string-html')('link', function (createHTML) {
return function link(url) {
return createHTML(this, 'a', 'href', url);
};
});
},{"./_string-html":104}],242:[function(require,module,exports){
var $export = require('./_export');
var toIObject = require('./_to-iobject');
var toLength = require('./_to-length');
$export($export.S, 'String', {
// 21.1.2.4 String.raw(callSite, ...substitutions)
raw: function raw(callSite) {
var tpl = toIObject(callSite.raw);
var len = toLength(tpl.length);
var aLen = arguments.length;
var res = [];
var i = 0;
while (len > i) {
res.push(String(tpl[i++]));
if (i < aLen) res.push(String(arguments[i]));
} return res.join('');
}
});
},{"./_export":39,"./_to-iobject":113,"./_to-length":114}],243:[function(require,module,exports){
var $export = require('./_export');
$export($export.P, 'String', {
// 21.1.3.13 String.prototype.repeat(count)
repeat: require('./_string-repeat')
});
},{"./_export":39,"./_string-repeat":106}],244:[function(require,module,exports){
'use strict';
// B.2.3.11 String.prototype.small()
require('./_string-html')('small', function (createHTML) {
return function small() {
return createHTML(this, 'small', '', '');
};
});
},{"./_string-html":104}],245:[function(require,module,exports){
// 21.1.3.18 String.prototype.startsWith(searchString [, position ])
'use strict';
var $export = require('./_export');
var toLength = require('./_to-length');
var context = require('./_string-context');
var STARTS_WITH = 'startsWith';
var $startsWith = ''[STARTS_WITH];
$export($export.P + $export.F * require('./_fails-is-regexp')(STARTS_WITH), 'String', {
startsWith: function startsWith(searchString /* , position = 0 */) {
var that = context(this, searchString, STARTS_WITH);
var index = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length));
var search = String(searchString);
return $startsWith
? $startsWith.call(that, search, index)
: that.slice(index, index + search.length) === search;
}
});
},{"./_export":39,"./_fails-is-regexp":40,"./_string-context":103,"./_to-length":114}],246:[function(require,module,exports){
'use strict';
// B.2.3.12 String.prototype.strike()
require('./_string-html')('strike', function (createHTML) {
return function strike() {
return createHTML(this, 'strike', '', '');
};
});
},{"./_string-html":104}],247:[function(require,module,exports){
'use strict';
// B.2.3.13 String.prototype.sub()
require('./_string-html')('sub', function (createHTML) {
return function sub() {
return createHTML(this, 'sub', '', '');
};
});
},{"./_string-html":104}],248:[function(require,module,exports){
'use strict';
// B.2.3.14 String.prototype.sup()
require('./_string-html')('sup', function (createHTML) {
return function sup() {
return createHTML(this, 'sup', '', '');
};
});
},{"./_string-html":104}],249:[function(require,module,exports){
'use strict';
// 21.1.3.25 String.prototype.trim()
require('./_string-trim')('trim', function ($trim) {
return function trim() {
return $trim(this, 3);
};
});
},{"./_string-trim":107}],250:[function(require,module,exports){
'use strict';
// ECMAScript 6 symbols shim
var global = require('./_global');
var has = require('./_has');
var DESCRIPTORS = require('./_descriptors');
var $export = require('./_export');
var redefine = require('./_redefine');
var META = require('./_meta').KEY;
var $fails = require('./_fails');
var shared = require('./_shared');
var setToStringTag = require('./_set-to-string-tag');
var uid = require('./_uid');
var wks = require('./_wks');
var wksExt = require('./_wks-ext');
var wksDefine = require('./_wks-define');
var enumKeys = require('./_enum-keys');
var isArray = require('./_is-array');
var anObject = require('./_an-object');
var isObject = require('./_is-object');
var toIObject = require('./_to-iobject');
var toPrimitive = require('./_to-primitive');
var createDesc = require('./_property-desc');
var _create = require('./_object-create');
var gOPNExt = require('./_object-gopn-ext');
var $GOPD = require('./_object-gopd');
var $DP = require('./_object-dp');
var $keys = require('./_object-keys');
var gOPD = $GOPD.f;
var dP = $DP.f;
var gOPN = gOPNExt.f;
var $Symbol = global.Symbol;
var $JSON = global.JSON;
var _stringify = $JSON && $JSON.stringify;
var PROTOTYPE = 'prototype';
var HIDDEN = wks('_hidden');
var TO_PRIMITIVE = wks('toPrimitive');
var isEnum = {}.propertyIsEnumerable;
var SymbolRegistry = shared('symbol-registry');
var AllSymbols = shared('symbols');
var OPSymbols = shared('op-symbols');
var ObjectProto = Object[PROTOTYPE];
var USE_NATIVE = typeof $Symbol == 'function';
var QObject = global.QObject;
// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;
// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
var setSymbolDesc = DESCRIPTORS && $fails(function () {
return _create(dP({}, 'a', {
get: function () { return dP(this, 'a', { value: 7 }).a; }
})).a != 7;
}) ? function (it, key, D) {
var protoDesc = gOPD(ObjectProto, key);
if (protoDesc) delete ObjectProto[key];
dP(it, key, D);
if (protoDesc && it !== ObjectProto) dP(ObjectProto, key, protoDesc);
} : dP;
var wrap = function (tag) {
var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]);
sym._k = tag;
return sym;
};
var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function (it) {
return typeof it == 'symbol';
} : function (it) {
return it instanceof $Symbol;
};
var $defineProperty = function defineProperty(it, key, D) {
if (it === ObjectProto) $defineProperty(OPSymbols, key, D);
anObject(it);
key = toPrimitive(key, true);
anObject(D);
if (has(AllSymbols, key)) {
if (!D.enumerable) {
if (!has(it, HIDDEN)) dP(it, HIDDEN, createDesc(1, {}));
it[HIDDEN][key] = true;
} else {
if (has(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false;
D = _create(D, { enumerable: createDesc(0, false) });
} return setSymbolDesc(it, key, D);
} return dP(it, key, D);
};
var $defineProperties = function defineProperties(it, P) {
anObject(it);
var keys = enumKeys(P = toIObject(P));
var i = 0;
var l = keys.length;
var key;
while (l > i) $defineProperty(it, key = keys[i++], P[key]);
return it;
};
var $create = function create(it, P) {
return P === undefined ? _create(it) : $defineProperties(_create(it), P);
};
var $propertyIsEnumerable = function propertyIsEnumerable(key) {
var E = isEnum.call(this, key = toPrimitive(key, true));
if (this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return false;
return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true;
};
var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key) {
it = toIObject(it);
key = toPrimitive(key, true);
if (it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return;
var D = gOPD(it, key);
if (D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) D.enumerable = true;
return D;
};
var $getOwnPropertyNames = function getOwnPropertyNames(it) {
var names = gOPN(toIObject(it));
var result = [];
var i = 0;
var key;
while (names.length > i) {
if (!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META) result.push(key);
} return result;
};
var $getOwnPropertySymbols = function getOwnPropertySymbols(it) {
var IS_OP = it === ObjectProto;
var names = gOPN(IS_OP ? OPSymbols : toIObject(it));
var result = [];
var i = 0;
var key;
while (names.length > i) {
if (has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true)) result.push(AllSymbols[key]);
} return result;
};
// 19.4.1.1 Symbol([description])
if (!USE_NATIVE) {
$Symbol = function Symbol() {
if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor!');
var tag = uid(arguments.length > 0 ? arguments[0] : undefined);
var $set = function (value) {
if (this === ObjectProto) $set.call(OPSymbols, value);
if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;
setSymbolDesc(this, tag, createDesc(1, value));
};
if (DESCRIPTORS && setter) setSymbolDesc(ObjectProto, tag, { configurable: true, set: $set });
return wrap(tag);
};
redefine($Symbol[PROTOTYPE], 'toString', function toString() {
return this._k;
});
$GOPD.f = $getOwnPropertyDescriptor;
$DP.f = $defineProperty;
require('./_object-gopn').f = gOPNExt.f = $getOwnPropertyNames;
require('./_object-pie').f = $propertyIsEnumerable;
require('./_object-gops').f = $getOwnPropertySymbols;
if (DESCRIPTORS && !require('./_library')) {
redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
}
wksExt.f = function (name) {
return wrap(wks(name));
};
}
$export($export.G + $export.W + $export.F * !USE_NATIVE, { Symbol: $Symbol });
for (var es6Symbols = (
// 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14
'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'
).split(','), j = 0; es6Symbols.length > j;)wks(es6Symbols[j++]);
for (var wellKnownSymbols = $keys(wks.store), k = 0; wellKnownSymbols.length > k;) wksDefine(wellKnownSymbols[k++]);
$export($export.S + $export.F * !USE_NATIVE, 'Symbol', {
// 19.4.2.1 Symbol.for(key)
'for': function (key) {
return has(SymbolRegistry, key += '')
? SymbolRegistry[key]
: SymbolRegistry[key] = $Symbol(key);
},
// 19.4.2.5 Symbol.keyFor(sym)
keyFor: function keyFor(sym) {
if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol!');
for (var key in SymbolRegistry) if (SymbolRegistry[key] === sym) return key;
},
useSetter: function () { setter = true; },
useSimple: function () { setter = false; }
});
$export($export.S + $export.F * !USE_NATIVE, 'Object', {
// 19.1.2.2 Object.create(O [, Properties])
create: $create,
// 19.1.2.4 Object.defineProperty(O, P, Attributes)
defineProperty: $defineProperty,
// 19.1.2.3 Object.defineProperties(O, Properties)
defineProperties: $defineProperties,
// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
// 19.1.2.7 Object.getOwnPropertyNames(O)
getOwnPropertyNames: $getOwnPropertyNames,
// 19.1.2.8 Object.getOwnPropertySymbols(O)
getOwnPropertySymbols: $getOwnPropertySymbols
});
// 24.3.2 JSON.stringify(value [, replacer [, space]])
$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function () {
var S = $Symbol();
// MS Edge converts symbol values to JSON as {}
// WebKit converts symbol values to JSON as null
// V8 throws on boxed symbols
return _stringify([S]) != '[null]' || _stringify({ a: S }) != '{}' || _stringify(Object(S)) != '{}';
})), 'JSON', {
stringify: function stringify(it) {
var args = [it];
var i = 1;
var replacer, $replacer;
while (arguments.length > i) args.push(arguments[i++]);
$replacer = replacer = args[1];
if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined
if (!isArray(replacer)) replacer = function (key, value) {
if (typeof $replacer == 'function') value = $replacer.call(this, key, value);
if (!isSymbol(value)) return value;
};
args[1] = replacer;
return _stringify.apply($JSON, args);
}
});
// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)
$Symbol[PROTOTYPE][TO_PRIMITIVE] || require('./_hide')($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);
// 19.4.3.5 Symbol.prototype[@@toStringTag]
setToStringTag($Symbol, 'Symbol');
// 20.2.1.9 Math[@@toStringTag]
setToStringTag(Math, 'Math', true);
// 24.3.3 JSON[@@toStringTag]
setToStringTag(global.JSON, 'JSON', true);
},{"./_an-object":15,"./_descriptors":35,"./_enum-keys":38,"./_export":39,"./_fails":41,"./_global":45,"./_has":46,"./_hide":47,"./_is-array":54,"./_is-object":56,"./_library":64,"./_meta":69,"./_object-create":73,"./_object-dp":74,"./_object-gopd":76,"./_object-gopn":78,"./_object-gopn-ext":77,"./_object-gops":79,"./_object-keys":82,"./_object-pie":83,"./_property-desc":91,"./_redefine":93,"./_set-to-string-tag":97,"./_shared":99,"./_to-iobject":113,"./_to-primitive":116,"./_uid":120,"./_wks":125,"./_wks-define":123,"./_wks-ext":124}],251:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $typed = require('./_typed');
var buffer = require('./_typed-buffer');
var anObject = require('./_an-object');
var toAbsoluteIndex = require('./_to-absolute-index');
var toLength = require('./_to-length');
var isObject = require('./_is-object');
var ArrayBuffer = require('./_global').ArrayBuffer;
var speciesConstructor = require('./_species-constructor');
var $ArrayBuffer = buffer.ArrayBuffer;
var $DataView = buffer.DataView;
var $isView = $typed.ABV && ArrayBuffer.isView;
var $slice = $ArrayBuffer.prototype.slice;
var VIEW = $typed.VIEW;
var ARRAY_BUFFER = 'ArrayBuffer';
$export($export.G + $export.W + $export.F * (ArrayBuffer !== $ArrayBuffer), { ArrayBuffer: $ArrayBuffer });
$export($export.S + $export.F * !$typed.CONSTR, ARRAY_BUFFER, {
// 24.1.3.1 ArrayBuffer.isView(arg)
isView: function isView(it) {
return $isView && $isView(it) || isObject(it) && VIEW in it;
}
});
$export($export.P + $export.U + $export.F * require('./_fails')(function () {
return !new $ArrayBuffer(2).slice(1, undefined).byteLength;
}), ARRAY_BUFFER, {
// 24.1.4.3 ArrayBuffer.prototype.slice(start, end)
slice: function slice(start, end) {
if ($slice !== undefined && end === undefined) return $slice.call(anObject(this), start); // FF fix
var len = anObject(this).byteLength;
var first = toAbsoluteIndex(start, len);
var fin = toAbsoluteIndex(end === undefined ? len : end, len);
var result = new (speciesConstructor(this, $ArrayBuffer))(toLength(fin - first));
var viewS = new $DataView(this);
var viewT = new $DataView(result);
var index = 0;
while (first < fin) {
viewT.setUint8(index++, viewS.getUint8(first++));
} return result;
}
});
require('./_set-species')(ARRAY_BUFFER);
},{"./_an-object":15,"./_export":39,"./_fails":41,"./_global":45,"./_is-object":56,"./_set-species":96,"./_species-constructor":100,"./_to-absolute-index":110,"./_to-length":114,"./_typed":119,"./_typed-buffer":118}],252:[function(require,module,exports){
var $export = require('./_export');
$export($export.G + $export.W + $export.F * !require('./_typed').ABV, {
DataView: require('./_typed-buffer').DataView
});
},{"./_export":39,"./_typed":119,"./_typed-buffer":118}],253:[function(require,module,exports){
require('./_typed-array')('Float32', 4, function (init) {
return function Float32Array(data, byteOffset, length) {
return init(this, data, byteOffset, length);
};
});
},{"./_typed-array":117}],254:[function(require,module,exports){
require('./_typed-array')('Float64', 8, function (init) {
return function Float64Array(data, byteOffset, length) {
return init(this, data, byteOffset, length);
};
});
},{"./_typed-array":117}],255:[function(require,module,exports){
require('./_typed-array')('Int16', 2, function (init) {
return function Int16Array(data, byteOffset, length) {
return init(this, data, byteOffset, length);
};
});
},{"./_typed-array":117}],256:[function(require,module,exports){
require('./_typed-array')('Int32', 4, function (init) {
return function Int32Array(data, byteOffset, length) {
return init(this, data, byteOffset, length);
};
});
},{"./_typed-array":117}],257:[function(require,module,exports){
require('./_typed-array')('Int8', 1, function (init) {
return function Int8Array(data, byteOffset, length) {
return init(this, data, byteOffset, length);
};
});
},{"./_typed-array":117}],258:[function(require,module,exports){
require('./_typed-array')('Uint16', 2, function (init) {
return function Uint16Array(data, byteOffset, length) {
return init(this, data, byteOffset, length);
};
});
},{"./_typed-array":117}],259:[function(require,module,exports){
require('./_typed-array')('Uint32', 4, function (init) {
return function Uint32Array(data, byteOffset, length) {
return init(this, data, byteOffset, length);
};
});
},{"./_typed-array":117}],260:[function(require,module,exports){
require('./_typed-array')('Uint8', 1, function (init) {
return function Uint8Array(data, byteOffset, length) {
return init(this, data, byteOffset, length);
};
});
},{"./_typed-array":117}],261:[function(require,module,exports){
require('./_typed-array')('Uint8', 1, function (init) {
return function Uint8ClampedArray(data, byteOffset, length) {
return init(this, data, byteOffset, length);
};
}, true);
},{"./_typed-array":117}],262:[function(require,module,exports){
'use strict';
var each = require('./_array-methods')(0);
var redefine = require('./_redefine');
var meta = require('./_meta');
var assign = require('./_object-assign');
var weak = require('./_collection-weak');
var isObject = require('./_is-object');
var fails = require('./_fails');
var validate = require('./_validate-collection');
var WEAK_MAP = 'WeakMap';
var getWeak = meta.getWeak;
var isExtensible = Object.isExtensible;
var uncaughtFrozenStore = weak.ufstore;
var tmp = {};
var InternalMap;
var wrapper = function (get) {
return function WeakMap() {
return get(this, arguments.length > 0 ? arguments[0] : undefined);
};
};
var methods = {
// 23.3.3.3 WeakMap.prototype.get(key)
get: function get(key) {
if (isObject(key)) {
var data = getWeak(key);
if (data === true) return uncaughtFrozenStore(validate(this, WEAK_MAP)).get(key);
return data ? data[this._i] : undefined;
}
},
// 23.3.3.5 WeakMap.prototype.set(key, value)
set: function set(key, value) {
return weak.def(validate(this, WEAK_MAP), key, value);
}
};
// 23.3 WeakMap Objects
var $WeakMap = module.exports = require('./_collection')(WEAK_MAP, wrapper, methods, weak, true, true);
// IE11 WeakMap frozen keys fix
if (fails(function () { return new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7; })) {
InternalMap = weak.getConstructor(wrapper, WEAK_MAP);
assign(InternalMap.prototype, methods);
meta.NEED = true;
each(['delete', 'has', 'get', 'set'], function (key) {
var proto = $WeakMap.prototype;
var method = proto[key];
redefine(proto, key, function (a, b) {
// store frozen objects on internal weakmap shim
if (isObject(a) && !isExtensible(a)) {
if (!this._f) this._f = new InternalMap();
var result = this._f[key](a, b);
return key == 'set' ? this : result;
// store all the rest on native weakmap
} return method.call(this, a, b);
});
});
}
},{"./_array-methods":19,"./_collection":28,"./_collection-weak":27,"./_fails":41,"./_is-object":56,"./_meta":69,"./_object-assign":72,"./_redefine":93,"./_validate-collection":122}],263:[function(require,module,exports){
'use strict';
var weak = require('./_collection-weak');
var validate = require('./_validate-collection');
var WEAK_SET = 'WeakSet';
// 23.4 WeakSet Objects
require('./_collection')(WEAK_SET, function (get) {
return function WeakSet() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
// 23.4.3.1 WeakSet.prototype.add(value)
add: function add(value) {
return weak.def(validate(this, WEAK_SET), value, true);
}
}, weak, false, true);
},{"./_collection":28,"./_collection-weak":27,"./_validate-collection":122}],264:[function(require,module,exports){
'use strict';
// https://github.com/tc39/Array.prototype.includes
var $export = require('./_export');
var $includes = require('./_array-includes')(true);
$export($export.P, 'Array', {
includes: function includes(el /* , fromIndex = 0 */) {
return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
}
});
require('./_add-to-unscopables')('includes');
},{"./_add-to-unscopables":13,"./_array-includes":18,"./_export":39}],265:[function(require,module,exports){
// https://github.com/tc39/proposal-object-values-entries
var $export = require('./_export');
var $entries = require('./_object-to-array')(true);
$export($export.S, 'Object', {
entries: function entries(it) {
return $entries(it);
}
});
},{"./_export":39,"./_object-to-array":85}],266:[function(require,module,exports){
// https://github.com/tc39/proposal-object-getownpropertydescriptors
var $export = require('./_export');
var ownKeys = require('./_own-keys');
var toIObject = require('./_to-iobject');
var gOPD = require('./_object-gopd');
var createProperty = require('./_create-property');
$export($export.S, 'Object', {
getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object) {
var O = toIObject(object);
var getDesc = gOPD.f;
var keys = ownKeys(O);
var result = {};
var i = 0;
var key, desc;
while (keys.length > i) {
desc = getDesc(O, key = keys[i++]);
if (desc !== undefined) createProperty(result, key, desc);
}
return result;
}
});
},{"./_create-property":30,"./_export":39,"./_object-gopd":76,"./_own-keys":86,"./_to-iobject":113}],267:[function(require,module,exports){
// https://github.com/tc39/proposal-object-values-entries
var $export = require('./_export');
var $values = require('./_object-to-array')(false);
$export($export.S, 'Object', {
values: function values(it) {
return $values(it);
}
});
},{"./_export":39,"./_object-to-array":85}],268:[function(require,module,exports){
// https://github.com/tc39/proposal-promise-finally
'use strict';
var $export = require('./_export');
var core = require('./_core');
var global = require('./_global');
var speciesConstructor = require('./_species-constructor');
var promiseResolve = require('./_promise-resolve');
$export($export.P + $export.R, 'Promise', { 'finally': function (onFinally) {
var C = speciesConstructor(this, core.Promise || global.Promise);
var isFunction = typeof onFinally == 'function';
return this.then(
isFunction ? function (x) {
return promiseResolve(C, onFinally()).then(function () { return x; });
} : onFinally,
isFunction ? function (e) {
return promiseResolve(C, onFinally()).then(function () { throw e; });
} : onFinally
);
} });
},{"./_core":29,"./_export":39,"./_global":45,"./_promise-resolve":90,"./_species-constructor":100}],269:[function(require,module,exports){
'use strict';
// https://github.com/tc39/proposal-string-pad-start-end
var $export = require('./_export');
var $pad = require('./_string-pad');
var userAgent = require('./_user-agent');
// https://github.com/zloirock/core-js/issues/280
$export($export.P + $export.F * /Version\/10\.\d+(\.\d+)? Safari\//.test(userAgent), 'String', {
padEnd: function padEnd(maxLength /* , fillString = ' ' */) {
return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false);
}
});
},{"./_export":39,"./_string-pad":105,"./_user-agent":121}],270:[function(require,module,exports){
'use strict';
// https://github.com/tc39/proposal-string-pad-start-end
var $export = require('./_export');
var $pad = require('./_string-pad');
var userAgent = require('./_user-agent');
// https://github.com/zloirock/core-js/issues/280
$export($export.P + $export.F * /Version\/10\.\d+(\.\d+)? Safari\//.test(userAgent), 'String', {
padStart: function padStart(maxLength /* , fillString = ' ' */) {
return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);
}
});
},{"./_export":39,"./_string-pad":105,"./_user-agent":121}],271:[function(require,module,exports){
require('./_wks-define')('asyncIterator');
},{"./_wks-define":123}],272:[function(require,module,exports){
var $iterators = require('./es6.array.iterator');
var getKeys = require('./_object-keys');
var redefine = require('./_redefine');
var global = require('./_global');
var hide = require('./_hide');
var Iterators = require('./_iterators');
var wks = require('./_wks');
var ITERATOR = wks('iterator');
var TO_STRING_TAG = wks('toStringTag');
var ArrayValues = Iterators.Array;
var DOMIterables = {
CSSRuleList: true, // TODO: Not spec compliant, should be false.
CSSStyleDeclaration: false,
CSSValueList: false,
ClientRectList: false,
DOMRectList: false,
DOMStringList: false,
DOMTokenList: true,
DataTransferItemList: false,
FileList: false,
HTMLAllCollection: false,
HTMLCollection: false,
HTMLFormElement: false,
HTMLSelectElement: false,
MediaList: true, // TODO: Not spec compliant, should be false.
MimeTypeArray: false,
NamedNodeMap: false,
NodeList: true,
PaintRequestList: false,
Plugin: false,
PluginArray: false,
SVGLengthList: false,
SVGNumberList: false,
SVGPathSegList: false,
SVGPointList: false,
SVGStringList: false,
SVGTransformList: false,
SourceBufferList: false,
StyleSheetList: true, // TODO: Not spec compliant, should be false.
TextTrackCueList: false,
TextTrackList: false,
TouchList: false
};
for (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) {
var NAME = collections[i];
var explicit = DOMIterables[NAME];
var Collection = global[NAME];
var proto = Collection && Collection.prototype;
var key;
if (proto) {
if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);
if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);
Iterators[NAME] = ArrayValues;
if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);
}
}
},{"./_global":45,"./_hide":47,"./_iterators":63,"./_object-keys":82,"./_redefine":93,"./_wks":125,"./es6.array.iterator":137}],273:[function(require,module,exports){
var $export = require('./_export');
var $task = require('./_task');
$export($export.G + $export.B, {
setImmediate: $task.set,
clearImmediate: $task.clear
});
},{"./_export":39,"./_task":109}],274:[function(require,module,exports){
// ie9- setTimeout & setInterval additional parameters fix
var global = require('./_global');
var $export = require('./_export');
var userAgent = require('./_user-agent');
var slice = [].slice;
var MSIE = /MSIE .\./.test(userAgent); // <- dirty ie9- check
var wrap = function (set) {
return function (fn, time /* , ...args */) {
var boundArgs = arguments.length > 2;
var args = boundArgs ? slice.call(arguments, 2) : false;
return set(boundArgs ? function () {
// eslint-disable-next-line no-new-func
(typeof fn == 'function' ? fn : Function(fn)).apply(this, args);
} : fn, time);
};
};
$export($export.G + $export.B + $export.F * MSIE, {
setTimeout: wrap(global.setTimeout),
setInterval: wrap(global.setInterval)
});
},{"./_export":39,"./_global":45,"./_user-agent":121}],275:[function(require,module,exports){
require('../modules/web.timers');
require('../modules/web.immediate');
require('../modules/web.dom.iterable');
module.exports = require('../modules/_core');
},{"../modules/_core":29,"../modules/web.dom.iterable":272,"../modules/web.immediate":273,"../modules/web.timers":274}],276:[function(require,module,exports){
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
!(function(global) {
"use strict";
var Op = Object.prototype;
var hasOwn = Op.hasOwnProperty;
var undefined; // More compressible than void 0.
var $Symbol = typeof Symbol === "function" ? Symbol : {};
var iteratorSymbol = $Symbol.iterator || "@@iterator";
var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
var inModule = typeof module === "object";
var runtime = global.regeneratorRuntime;
if (runtime) {
if (inModule) {
// If regeneratorRuntime is defined globally and we're in a module,
// make the exports object identical to regeneratorRuntime.
module.exports = runtime;
}
// Don't bother evaluating the rest of this file if the runtime was
// already defined globally.
return;
}
// Define the runtime globally (as expected by generated code) as either
// module.exports (if we're in a module) or a new, empty object.
runtime = global.regeneratorRuntime = inModule ? module.exports : {};
function wrap(innerFn, outerFn, self, tryLocsList) {
// If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
var generator = Object.create(protoGenerator.prototype);
var context = new Context(tryLocsList || []);
// The ._invoke method unifies the implementations of the .next,
// .throw, and .return methods.
generator._invoke = makeInvokeMethod(innerFn, self, context);
return generator;
}
runtime.wrap = wrap;
// Try/catch helper to minimize deoptimizations. Returns a completion
// record like context.tryEntries[i].completion. This interface could
// have been (and was previously) designed to take a closure to be
// invoked without arguments, but in all the cases we care about we
// already have an existing method we want to call, so there's no need
// to create a new function object. We can even get away with assuming
// the method takes exactly one argument, since that happens to be true
// in every case, so we don't have to touch the arguments object. The
// only additional allocation required is the completion record, which
// has a stable shape and so hopefully should be cheap to allocate.
function tryCatch(fn, obj, arg) {
try {
return { type: "normal", arg: fn.call(obj, arg) };
} catch (err) {
return { type: "throw", arg: err };
}
}
var GenStateSuspendedStart = "suspendedStart";
var GenStateSuspendedYield = "suspendedYield";
var GenStateExecuting = "executing";
var GenStateCompleted = "completed";
// Returning this object from the innerFn has the same effect as
// breaking out of the dispatch switch statement.
var ContinueSentinel = {};
// Dummy constructor functions that we use as the .constructor and
// .constructor.prototype properties for functions that return Generator
// objects. For full spec compliance, you may wish to configure your
// minifier not to mangle the names of these two functions.
function Generator() {}
function GeneratorFunction() {}
function GeneratorFunctionPrototype() {}
// This is a polyfill for %IteratorPrototype% for environments that
// don't natively support it.
var IteratorPrototype = {};
IteratorPrototype[iteratorSymbol] = function () {
return this;
};
var getProto = Object.getPrototypeOf;
var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
if (NativeIteratorPrototype &&
NativeIteratorPrototype !== Op &&
hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
// This environment has a native %IteratorPrototype%; use it instead
// of the polyfill.
IteratorPrototype = NativeIteratorPrototype;
}
var Gp = GeneratorFunctionPrototype.prototype =
Generator.prototype = Object.create(IteratorPrototype);
GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
GeneratorFunctionPrototype.constructor = GeneratorFunction;
GeneratorFunctionPrototype[toStringTagSymbol] =
GeneratorFunction.displayName = "GeneratorFunction";
// Helper for defining the .next, .throw, and .return methods of the
// Iterator interface in terms of a single ._invoke method.
function defineIteratorMethods(prototype) {
["next", "throw", "return"].forEach(function(method) {
prototype[method] = function(arg) {
return this._invoke(method, arg);
};
});
}
runtime.isGeneratorFunction = function(genFun) {
var ctor = typeof genFun === "function" && genFun.constructor;
return ctor
? ctor === GeneratorFunction ||
// For the native GeneratorFunction constructor, the best we can
// do is to check its .name property.
(ctor.displayName || ctor.name) === "GeneratorFunction"
: false;
};
runtime.mark = function(genFun) {
if (Object.setPrototypeOf) {
Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
} else {
genFun.__proto__ = GeneratorFunctionPrototype;
if (!(toStringTagSymbol in genFun)) {
genFun[toStringTagSymbol] = "GeneratorFunction";
}
}
genFun.prototype = Object.create(Gp);
return genFun;
};
// Within the body of any async function, `await x` is transformed to
// `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
// `hasOwn.call(value, "__await")` to determine if the yielded value is
// meant to be awaited.
runtime.awrap = function(arg) {
return { __await: arg };
};
function AsyncIterator(generator) {
function invoke(method, arg, resolve, reject) {
var record = tryCatch(generator[method], generator, arg);
if (record.type === "throw") {
reject(record.arg);
} else {
var result = record.arg;
var value = result.value;
if (value &&
typeof value === "object" &&
hasOwn.call(value, "__await")) {
return Promise.resolve(value.__await).then(function(value) {
invoke("next", value, resolve, reject);
}, function(err) {
invoke("throw", err, resolve, reject);
});
}
return Promise.resolve(value).then(function(unwrapped) {
// When a yielded Promise is resolved, its final value becomes
// the .value of the Promise<{value,done}> result for the
// current iteration. If the Promise is rejected, however, the
// result for this iteration will be rejected with the same
// reason. Note that rejections of yielded Promises are not
// thrown back into the generator function, as is the case
// when an awaited Promise is rejected. This difference in
// behavior between yield and await is important, because it
// allows the consumer to decide what to do with the yielded
// rejection (swallow it and continue, manually .throw it back
// into the generator, abandon iteration, whatever). With
// await, by contrast, there is no opportunity to examine the
// rejection reason outside the generator function, so the
// only option is to throw it from the await expression, and
// let the generator function handle the exception.
result.value = unwrapped;
resolve(result);
}, reject);
}
}
var previousPromise;
function enqueue(method, arg) {
function callInvokeWithMethodAndArg() {
return new Promise(function(resolve, reject) {
invoke(method, arg, resolve, reject);
});
}
return previousPromise =
// If enqueue has been called before, then we want to wait until
// all previous Promises have been resolved before calling invoke,
// so that results are always delivered in the correct order. If
// enqueue has not been called before, then it is important to
// call invoke immediately, without waiting on a callback to fire,
// so that the async generator function has the opportunity to do
// any necessary setup in a predictable way. This predictability
// is why the Promise constructor synchronously invokes its
// executor callback, and why async functions synchronously
// execute code before the first await. Since we implement simple
// async functions in terms of async generators, it is especially
// important to get this right, even though it requires care.
previousPromise ? previousPromise.then(
callInvokeWithMethodAndArg,
// Avoid propagating failures to Promises returned by later
// invocations of the iterator.
callInvokeWithMethodAndArg
) : callInvokeWithMethodAndArg();
}
// Define the unified helper method that is used to implement .next,
// .throw, and .return (see defineIteratorMethods).
this._invoke = enqueue;
}
defineIteratorMethods(AsyncIterator.prototype);
AsyncIterator.prototype[asyncIteratorSymbol] = function () {
return this;
};
runtime.AsyncIterator = AsyncIterator;
// Note that simple async functions are implemented on top of
// AsyncIterator objects; they just return a Promise for the value of
// the final result produced by the iterator.
runtime.async = function(innerFn, outerFn, self, tryLocsList) {
var iter = new AsyncIterator(
wrap(innerFn, outerFn, self, tryLocsList)
);
return runtime.isGeneratorFunction(outerFn)
? iter // If outerFn is a generator, return the full iterator.
: iter.next().then(function(result) {
return result.done ? result.value : iter.next();
});
};
function makeInvokeMethod(innerFn, self, context) {
var state = GenStateSuspendedStart;
return function invoke(method, arg) {
if (state === GenStateExecuting) {
throw new Error("Generator is already running");
}
if (state === GenStateCompleted) {
if (method === "throw") {
throw arg;
}
// Be forgiving, per 25.3.3.3.3 of the spec:
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
return doneResult();
}
context.method = method;
context.arg = arg;
while (true) {
var delegate = context.delegate;
if (delegate) {
var delegateResult = maybeInvokeDelegate(delegate, context);
if (delegateResult) {
if (delegateResult === ContinueSentinel) continue;
return delegateResult;
}
}
if (context.method === "next") {
// Setting context._sent for legacy support of Babel's
// function.sent implementation.
context.sent = context._sent = context.arg;
} else if (context.method === "throw") {
if (state === GenStateSuspendedStart) {
state = GenStateCompleted;
throw context.arg;
}
context.dispatchException(context.arg);
} else if (context.method === "return") {
context.abrupt("return", context.arg);
}
state = GenStateExecuting;
var record = tryCatch(innerFn, self, context);
if (record.type === "normal") {
// If an exception is thrown from innerFn, we leave state ===
// GenStateExecuting and loop back for another invocation.
state = context.done
? GenStateCompleted
: GenStateSuspendedYield;
if (record.arg === ContinueSentinel) {
continue;
}
return {
value: record.arg,
done: context.done
};
} else if (record.type === "throw") {
state = GenStateCompleted;
// Dispatch the exception by looping back around to the
// context.dispatchException(context.arg) call above.
context.method = "throw";
context.arg = record.arg;
}
}
};
}
// Call delegate.iterator[context.method](context.arg) and handle the
// result, either by returning a { value, done } result from the
// delegate iterator, or by modifying context.method and context.arg,
// setting context.delegate to null, and returning the ContinueSentinel.
function maybeInvokeDelegate(delegate, context) {
var method = delegate.iterator[context.method];
if (method === undefined) {
// A .throw or .return when the delegate iterator has no .throw
// method always terminates the yield* loop.
context.delegate = null;
if (context.method === "throw") {
if (delegate.iterator.return) {
// If the delegate iterator has a return method, give it a
// chance to clean up.
context.method = "return";
context.arg = undefined;
maybeInvokeDelegate(delegate, context);
if (context.method === "throw") {
// If maybeInvokeDelegate(context) changed context.method from
// "return" to "throw", let that override the TypeError below.
return ContinueSentinel;
}
}
context.method = "throw";
context.arg = new TypeError(
"The iterator does not provide a 'throw' method");
}
return ContinueSentinel;
}
var record = tryCatch(method, delegate.iterator, context.arg);
if (record.type === "throw") {
context.method = "throw";
context.arg = record.arg;
context.delegate = null;
return ContinueSentinel;
}
var info = record.arg;
if (! info) {
context.method = "throw";
context.arg = new TypeError("iterator result is not an object");
context.delegate = null;
return ContinueSentinel;
}
if (info.done) {
// Assign the result of the finished delegate to the temporary
// variable specified by delegate.resultName (see delegateYield).
context[delegate.resultName] = info.value;
// Resume execution at the desired location (see delegateYield).
context.next = delegate.nextLoc;
// If context.method was "throw" but the delegate handled the
// exception, let the outer generator proceed normally. If
// context.method was "next", forget context.arg since it has been
// "consumed" by the delegate iterator. If context.method was
// "return", allow the original .return call to continue in the
// outer generator.
if (context.method !== "return") {
context.method = "next";
context.arg = undefined;
}
} else {
// Re-yield the result returned by the delegate method.
return info;
}
// The delegate iterator is finished, so forget it and continue with
// the outer generator.
context.delegate = null;
return ContinueSentinel;
}
// Define Generator.prototype.{next,throw,return} in terms of the
// unified ._invoke helper method.
defineIteratorMethods(Gp);
Gp[toStringTagSymbol] = "Generator";
// A Generator should always return itself as the iterator object when the
// @@iterator function is called on it. Some browsers' implementations of the
// iterator prototype chain incorrectly implement this, causing the Generator
// object to not be returned from this call. This ensures that doesn't happen.
// See https://github.com/facebook/regenerator/issues/274 for more details.
Gp[iteratorSymbol] = function() {
return this;
};
Gp.toString = function() {
return "[object Generator]";
};
function pushTryEntry(locs) {
var entry = { tryLoc: locs[0] };
if (1 in locs) {
entry.catchLoc = locs[1];
}
if (2 in locs) {
entry.finallyLoc = locs[2];
entry.afterLoc = locs[3];
}
this.tryEntries.push(entry);
}
function resetTryEntry(entry) {
var record = entry.completion || {};
record.type = "normal";
delete record.arg;
entry.completion = record;
}
function Context(tryLocsList) {
// The root entry object (effectively a try statement without a catch
// or a finally block) gives us a place to store values thrown from
// locations where there is no enclosing try statement.
this.tryEntries = [{ tryLoc: "root" }];
tryLocsList.forEach(pushTryEntry, this);
this.reset(true);
}
runtime.keys = function(object) {
var keys = [];
for (var key in object) {
keys.push(key);
}
keys.reverse();
// Rather than returning an object with a next method, we keep
// things simple and return the next function itself.
return function next() {
while (keys.length) {
var key = keys.pop();
if (key in object) {
next.value = key;
next.done = false;
return next;
}
}
// To avoid creating an additional object, we just hang the .value
// and .done properties off the next function object itself. This
// also ensures that the minifier will not anonymize the function.
next.done = true;
return next;
};
};
function values(iterable) {
if (iterable) {
var iteratorMethod = iterable[iteratorSymbol];
if (iteratorMethod) {
return iteratorMethod.call(iterable);
}
if (typeof iterable.next === "function") {
return iterable;
}
if (!isNaN(iterable.length)) {
var i = -1, next = function next() {
while (++i < iterable.length) {
if (hasOwn.call(iterable, i)) {
next.value = iterable[i];
next.done = false;
return next;
}
}
next.value = undefined;
next.done = true;
return next;
};
return next.next = next;
}
}
// Return an iterator with no values.
return { next: doneResult };
}
runtime.values = values;
function doneResult() {
return { value: undefined, done: true };
}
Context.prototype = {
constructor: Context,
reset: function(skipTempReset) {
this.prev = 0;
this.next = 0;
// Resetting context._sent for legacy support of Babel's
// function.sent implementation.
this.sent = this._sent = undefined;
this.done = false;
this.delegate = null;
this.method = "next";
this.arg = undefined;
this.tryEntries.forEach(resetTryEntry);
if (!skipTempReset) {
for (var name in this) {
// Not sure about the optimal order of these conditions:
if (name.charAt(0) === "t" &&
hasOwn.call(this, name) &&
!isNaN(+name.slice(1))) {
this[name] = undefined;
}
}
}
},
stop: function() {
this.done = true;
var rootEntry = this.tryEntries[0];
var rootRecord = rootEntry.completion;
if (rootRecord.type === "throw") {
throw rootRecord.arg;
}
return this.rval;
},
dispatchException: function(exception) {
if (this.done) {
throw exception;
}
var context = this;
function handle(loc, caught) {
record.type = "throw";
record.arg = exception;
context.next = loc;
if (caught) {
// If the dispatched exception was caught by a catch block,
// then let that catch block handle the exception normally.
context.method = "next";
context.arg = undefined;
}
return !! caught;
}
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
var record = entry.completion;
if (entry.tryLoc === "root") {
// Exception thrown outside of any try block that could handle
// it, so set the completion value of the entire function to
// throw the exception.
return handle("end");
}
if (entry.tryLoc <= this.prev) {
var hasCatch = hasOwn.call(entry, "catchLoc");
var hasFinally = hasOwn.call(entry, "finallyLoc");
if (hasCatch && hasFinally) {
if (this.prev < entry.catchLoc) {
return handle(entry.catchLoc, true);
} else if (this.prev < entry.finallyLoc) {
return handle(entry.finallyLoc);
}
} else if (hasCatch) {
if (this.prev < entry.catchLoc) {
return handle(entry.catchLoc, true);
}
} else if (hasFinally) {
if (this.prev < entry.finallyLoc) {
return handle(entry.finallyLoc);
}
} else {
throw new Error("try statement without catch or finally");
}
}
}
},
abrupt: function(type, arg) {
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
if (entry.tryLoc <= this.prev &&
hasOwn.call(entry, "finallyLoc") &&
this.prev < entry.finallyLoc) {
var finallyEntry = entry;
break;
}
}
if (finallyEntry &&
(type === "break" ||
type === "continue") &&
finallyEntry.tryLoc <= arg &&
arg <= finallyEntry.finallyLoc) {
// Ignore the finally entry if control is not jumping to a
// location outside the try/catch block.
finallyEntry = null;
}
var record = finallyEntry ? finallyEntry.completion : {};
record.type = type;
record.arg = arg;
if (finallyEntry) {
this.method = "next";
this.next = finallyEntry.finallyLoc;
return ContinueSentinel;
}
return this.complete(record);
},
complete: function(record, afterLoc) {
if (record.type === "throw") {
throw record.arg;
}
if (record.type === "break" ||
record.type === "continue") {
this.next = record.arg;
} else if (record.type === "return") {
this.rval = this.arg = record.arg;
this.method = "return";
this.next = "end";
} else if (record.type === "normal" && afterLoc) {
this.next = afterLoc;
}
return ContinueSentinel;
},
finish: function(finallyLoc) {
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
if (entry.finallyLoc === finallyLoc) {
this.complete(entry.completion, entry.afterLoc);
resetTryEntry(entry);
return ContinueSentinel;
}
}
},
"catch": function(tryLoc) {
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
if (entry.tryLoc === tryLoc) {
var record = entry.completion;
if (record.type === "throw") {
var thrown = record.arg;
resetTryEntry(entry);
}
return thrown;
}
}
// The context.catch method must only be called with a location
// argument that corresponds to a known catch block.
throw new Error("illegal catch attempt");
},
delegateYield: function(iterable, resultName, nextLoc) {
this.delegate = {
iterator: values(iterable),
resultName: resultName,
nextLoc: nextLoc
};
if (this.method === "next") {
// Deliberately forget the last sent value so that we don't
// accidentally pass it on to the delegate.
this.arg = undefined;
}
return ContinueSentinel;
}
};
})(
// In sloppy mode, unbound `this` refers to the global object, fallback to
// Function constructor if we're in global strict mode. That is sadly a form
// of indirect eval which violates Content Security Policy.
(function() { return this })() || Function("return this")()
);
},{}],277:[function(require,module,exports){
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function (key) {
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer) {
desc.writable = true;
}
desc = decorators.slice().reverse().reduce(function (desc, decorator) {
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0) {
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0) {
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
module.exports = _applyDecoratedDescriptor;
},{}],278:[function(require,module,exports){
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
module.exports = _arrayWithHoles;
},{}],279:[function(require,module,exports){
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
arr2[i] = arr[i];
}
return arr2;
}
}
module.exports = _arrayWithoutHoles;
},{}],280:[function(require,module,exports){
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
module.exports = _assertThisInitialized;
},{}],281:[function(require,module,exports){
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function () {
var self = this,
args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
module.exports = _asyncToGenerator;
},{}],282:[function(require,module,exports){
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
module.exports = _classCallCheck;
},{}],283:[function(require,module,exports){
var setPrototypeOf = require("./setPrototypeOf");
function isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _construct(Parent, args, Class) {
if (isNativeReflectConstruct()) {
module.exports = _construct = Reflect.construct;
} else {
module.exports = _construct = function _construct(Parent, args, Class) {
var a = [null];
a.push.apply(a, args);
var Constructor = Function.bind.apply(Parent, a);
var instance = new Constructor();
if (Class) setPrototypeOf(instance, Class.prototype);
return instance;
};
}
return _construct.apply(null, arguments);
}
module.exports = _construct;
},{"./setPrototypeOf":297}],284:[function(require,module,exports){
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
module.exports = _createClass;
},{}],285:[function(require,module,exports){
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
module.exports = _defineProperty;
},{}],286:[function(require,module,exports){
function _getPrototypeOf(o) {
module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
module.exports = _getPrototypeOf;
},{}],287:[function(require,module,exports){
var setPrototypeOf = require("./setPrototypeOf");
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) setPrototypeOf(subClass, superClass);
}
module.exports = _inherits;
},{"./setPrototypeOf":297}],288:[function(require,module,exports){
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
module.exports = _interopRequireDefault;
},{}],289:[function(require,module,exports){
function _interopRequireWildcard(obj) {
if (obj && obj.__esModule) {
return obj;
} else {
var newObj = {};
if (obj != null) {
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
if (desc.get || desc.set) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
}
newObj.default = obj;
return newObj;
}
}
module.exports = _interopRequireWildcard;
},{}],290:[function(require,module,exports){
function _isNativeFunction(fn) {
return Function.toString.call(fn).indexOf("[native code]") !== -1;
}
module.exports = _isNativeFunction;
},{}],291:[function(require,module,exports){
function _iterableToArray(iter) {
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
}
module.exports = _iterableToArray;
},{}],292:[function(require,module,exports){
function _iterableToArrayLimit(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
module.exports = _iterableToArrayLimit;
},{}],293:[function(require,module,exports){
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
module.exports = _nonIterableRest;
},{}],294:[function(require,module,exports){
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance");
}
module.exports = _nonIterableSpread;
},{}],295:[function(require,module,exports){
var defineProperty = require("./defineProperty");
function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === 'function') {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function (key) {
defineProperty(target, key, source[key]);
});
}
return target;
}
module.exports = _objectSpread;
},{"./defineProperty":285}],296:[function(require,module,exports){
var _typeof = require("../helpers/typeof");
var assertThisInitialized = require("./assertThisInitialized");
function _possibleConstructorReturn(self, call) {
if (call && (_typeof(call) === "object" || typeof call === "function")) {
return call;
}
return assertThisInitialized(self);
}
module.exports = _possibleConstructorReturn;
},{"../helpers/typeof":301,"./assertThisInitialized":280}],297:[function(require,module,exports){
function _setPrototypeOf(o, p) {
module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
module.exports = _setPrototypeOf;
},{}],298:[function(require,module,exports){
var arrayWithHoles = require("./arrayWithHoles");
var iterableToArrayLimit = require("./iterableToArrayLimit");
var nonIterableRest = require("./nonIterableRest");
function _slicedToArray(arr, i) {
return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || nonIterableRest();
}
module.exports = _slicedToArray;
},{"./arrayWithHoles":278,"./iterableToArrayLimit":292,"./nonIterableRest":293}],299:[function(require,module,exports){
var arrayWithHoles = require("./arrayWithHoles");
var iterableToArray = require("./iterableToArray");
var nonIterableRest = require("./nonIterableRest");
function _toArray(arr) {
return arrayWithHoles(arr) || iterableToArray(arr) || nonIterableRest();
}
module.exports = _toArray;
},{"./arrayWithHoles":278,"./iterableToArray":291,"./nonIterableRest":293}],300:[function(require,module,exports){
var arrayWithoutHoles = require("./arrayWithoutHoles");
var iterableToArray = require("./iterableToArray");
var nonIterableSpread = require("./nonIterableSpread");
function _toConsumableArray(arr) {
return arrayWithoutHoles(arr) || iterableToArray(arr) || nonIterableSpread();
}
module.exports = _toConsumableArray;
},{"./arrayWithoutHoles":279,"./iterableToArray":291,"./nonIterableSpread":294}],301:[function(require,module,exports){
function _typeof2(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof2(obj); }
function _typeof(obj) {
if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") {
module.exports = _typeof = function _typeof(obj) {
return _typeof2(obj);
};
} else {
module.exports = _typeof = function _typeof(obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj);
};
}
return _typeof(obj);
}
module.exports = _typeof;
},{}],302:[function(require,module,exports){
var getPrototypeOf = require("./getPrototypeOf");
var setPrototypeOf = require("./setPrototypeOf");
var isNativeFunction = require("./isNativeFunction");
var construct = require("./construct");
function _wrapNativeSuper(Class) {
var _cache = typeof Map === "function" ? new Map() : undefined;
module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) {
if (Class === null || !isNativeFunction(Class)) return Class;
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class)) return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {
return construct(Class, arguments, getPrototypeOf(this).constructor);
}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writable: true,
configurable: true
}
});
return setPrototypeOf(Wrapper, Class);
};
return _wrapNativeSuper(Class);
}
module.exports = _wrapNativeSuper;
},{"./construct":283,"./getPrototypeOf":286,"./isNativeFunction":290,"./setPrototypeOf":297}],303:[function(require,module,exports){
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// This method of obtaining a reference to the global object needs to be
// kept identical to the way it is obtained in runtime.js
var g = (function() {
return this || (typeof self === "object" && self);
})() || Function("return this")();
// Use `getOwnPropertyNames` because not all browsers support calling
// `hasOwnProperty` on the global `self` object in a worker. See #183.
var hadRuntime = g.regeneratorRuntime &&
Object.getOwnPropertyNames(g).indexOf("regeneratorRuntime") >= 0;
// Save the old regeneratorRuntime in case it needs to be restored later.
var oldRuntime = hadRuntime && g.regeneratorRuntime;
// Force reevalutation of runtime.js.
g.regeneratorRuntime = undefined;
module.exports = require("./runtime");
if (hadRuntime) {
// Restore the original runtime.
g.regeneratorRuntime = oldRuntime;
} else {
// Remove the global property added by runtime.js.
try {
delete g.regeneratorRuntime;
} catch(e) {
g.regeneratorRuntime = undefined;
}
}
},{"./runtime":304}],304:[function(require,module,exports){
/**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
!(function(global) {
"use strict";
var Op = Object.prototype;
var hasOwn = Op.hasOwnProperty;
var undefined; // More compressible than void 0.
var $Symbol = typeof Symbol === "function" ? Symbol : {};
var iteratorSymbol = $Symbol.iterator || "@@iterator";
var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
var inModule = typeof module === "object";
var runtime = global.regeneratorRuntime;
if (runtime) {
if (inModule) {
// If regeneratorRuntime is defined globally and we're in a module,
// make the exports object identical to regeneratorRuntime.
module.exports = runtime;
}
// Don't bother evaluating the rest of this file if the runtime was
// already defined globally.
return;
}
// Define the runtime globally (as expected by generated code) as either
// module.exports (if we're in a module) or a new, empty object.
runtime = global.regeneratorRuntime = inModule ? module.exports : {};
function wrap(innerFn, outerFn, self, tryLocsList) {
// If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
var generator = Object.create(protoGenerator.prototype);
var context = new Context(tryLocsList || []);
// The ._invoke method unifies the implementations of the .next,
// .throw, and .return methods.
generator._invoke = makeInvokeMethod(innerFn, self, context);
return generator;
}
runtime.wrap = wrap;
// Try/catch helper to minimize deoptimizations. Returns a completion
// record like context.tryEntries[i].completion. This interface could
// have been (and was previously) designed to take a closure to be
// invoked without arguments, but in all the cases we care about we
// already have an existing method we want to call, so there's no need
// to create a new function object. We can even get away with assuming
// the method takes exactly one argument, since that happens to be true
// in every case, so we don't have to touch the arguments object. The
// only additional allocation required is the completion record, which
// has a stable shape and so hopefully should be cheap to allocate.
function tryCatch(fn, obj, arg) {
try {
return { type: "normal", arg: fn.call(obj, arg) };
} catch (err) {
return { type: "throw", arg: err };
}
}
var GenStateSuspendedStart = "suspendedStart";
var GenStateSuspendedYield = "suspendedYield";
var GenStateExecuting = "executing";
var GenStateCompleted = "completed";
// Returning this object from the innerFn has the same effect as
// breaking out of the dispatch switch statement.
var ContinueSentinel = {};
// Dummy constructor functions that we use as the .constructor and
// .constructor.prototype properties for functions that return Generator
// objects. For full spec compliance, you may wish to configure your
// minifier not to mangle the names of these two functions.
function Generator() {}
function GeneratorFunction() {}
function GeneratorFunctionPrototype() {}
// This is a polyfill for %IteratorPrototype% for environments that
// don't natively support it.
var IteratorPrototype = {};
IteratorPrototype[iteratorSymbol] = function () {
return this;
};
var getProto = Object.getPrototypeOf;
var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
if (NativeIteratorPrototype &&
NativeIteratorPrototype !== Op &&
hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
// This environment has a native %IteratorPrototype%; use it instead
// of the polyfill.
IteratorPrototype = NativeIteratorPrototype;
}
var Gp = GeneratorFunctionPrototype.prototype =
Generator.prototype = Object.create(IteratorPrototype);
GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
GeneratorFunctionPrototype.constructor = GeneratorFunction;
GeneratorFunctionPrototype[toStringTagSymbol] =
GeneratorFunction.displayName = "GeneratorFunction";
// Helper for defining the .next, .throw, and .return methods of the
// Iterator interface in terms of a single ._invoke method.
function defineIteratorMethods(prototype) {
["next", "throw", "return"].forEach(function(method) {
prototype[method] = function(arg) {
return this._invoke(method, arg);
};
});
}
runtime.isGeneratorFunction = function(genFun) {
var ctor = typeof genFun === "function" && genFun.constructor;
return ctor
? ctor === GeneratorFunction ||
// For the native GeneratorFunction constructor, the best we can
// do is to check its .name property.
(ctor.displayName || ctor.name) === "GeneratorFunction"
: false;
};
runtime.mark = function(genFun) {
if (Object.setPrototypeOf) {
Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
} else {
genFun.__proto__ = GeneratorFunctionPrototype;
if (!(toStringTagSymbol in genFun)) {
genFun[toStringTagSymbol] = "GeneratorFunction";
}
}
genFun.prototype = Object.create(Gp);
return genFun;
};
// Within the body of any async function, `await x` is transformed to
// `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
// `hasOwn.call(value, "__await")` to determine if the yielded value is
// meant to be awaited.
runtime.awrap = function(arg) {
return { __await: arg };
};
function AsyncIterator(generator) {
function invoke(method, arg, resolve, reject) {
var record = tryCatch(generator[method], generator, arg);
if (record.type === "throw") {
reject(record.arg);
} else {
var result = record.arg;
var value = result.value;
if (value &&
typeof value === "object" &&
hasOwn.call(value, "__await")) {
return Promise.resolve(value.__await).then(function(value) {
invoke("next", value, resolve, reject);
}, function(err) {
invoke("throw", err, resolve, reject);
});
}
return Promise.resolve(value).then(function(unwrapped) {
// When a yielded Promise is resolved, its final value becomes
// the .value of the Promise<{value,done}> result for the
// current iteration.
result.value = unwrapped;
resolve(result);
}, function(error) {
// If a rejected Promise was yielded, throw the rejection back
// into the async generator function so it can be handled there.
return invoke("throw", error, resolve, reject);
});
}
}
var previousPromise;
function enqueue(method, arg) {
function callInvokeWithMethodAndArg() {
return new Promise(function(resolve, reject) {
invoke(method, arg, resolve, reject);
});
}
return previousPromise =
// If enqueue has been called before, then we want to wait until
// all previous Promises have been resolved before calling invoke,
// so that results are always delivered in the correct order. If
// enqueue has not been called before, then it is important to
// call invoke immediately, without waiting on a callback to fire,
// so that the async generator function has the opportunity to do
// any necessary setup in a predictable way. This predictability
// is why the Promise constructor synchronously invokes its
// executor callback, and why async functions synchronously
// execute code before the first await. Since we implement simple
// async functions in terms of async generators, it is especially
// important to get this right, even though it requires care.
previousPromise ? previousPromise.then(
callInvokeWithMethodAndArg,
// Avoid propagating failures to Promises returned by later
// invocations of the iterator.
callInvokeWithMethodAndArg
) : callInvokeWithMethodAndArg();
}
// Define the unified helper method that is used to implement .next,
// .throw, and .return (see defineIteratorMethods).
this._invoke = enqueue;
}
defineIteratorMethods(AsyncIterator.prototype);
AsyncIterator.prototype[asyncIteratorSymbol] = function () {
return this;
};
runtime.AsyncIterator = AsyncIterator;
// Note that simple async functions are implemented on top of
// AsyncIterator objects; they just return a Promise for the value of
// the final result produced by the iterator.
runtime.async = function(innerFn, outerFn, self, tryLocsList) {
var iter = new AsyncIterator(
wrap(innerFn, outerFn, self, tryLocsList)
);
return runtime.isGeneratorFunction(outerFn)
? iter // If outerFn is a generator, return the full iterator.
: iter.next().then(function(result) {
return result.done ? result.value : iter.next();
});
};
function makeInvokeMethod(innerFn, self, context) {
var state = GenStateSuspendedStart;
return function invoke(method, arg) {
if (state === GenStateExecuting) {
throw new Error("Generator is already running");
}
if (state === GenStateCompleted) {
if (method === "throw") {
throw arg;
}
// Be forgiving, per 25.3.3.3.3 of the spec:
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
return doneResult();
}
context.method = method;
context.arg = arg;
while (true) {
var delegate = context.delegate;
if (delegate) {
var delegateResult = maybeInvokeDelegate(delegate, context);
if (delegateResult) {
if (delegateResult === ContinueSentinel) continue;
return delegateResult;
}
}
if (context.method === "next") {
// Setting context._sent for legacy support of Babel's
// function.sent implementation.
context.sent = context._sent = context.arg;
} else if (context.method === "throw") {
if (state === GenStateSuspendedStart) {
state = GenStateCompleted;
throw context.arg;
}
context.dispatchException(context.arg);
} else if (context.method === "return") {
context.abrupt("return", context.arg);
}
state = GenStateExecuting;
var record = tryCatch(innerFn, self, context);
if (record.type === "normal") {
// If an exception is thrown from innerFn, we leave state ===
// GenStateExecuting and loop back for another invocation.
state = context.done
? GenStateCompleted
: GenStateSuspendedYield;
if (record.arg === ContinueSentinel) {
continue;
}
return {
value: record.arg,
done: context.done
};
} else if (record.type === "throw") {
state = GenStateCompleted;
// Dispatch the exception by looping back around to the
// context.dispatchException(context.arg) call above.
context.method = "throw";
context.arg = record.arg;
}
}
};
}
// Call delegate.iterator[context.method](context.arg) and handle the
// result, either by returning a { value, done } result from the
// delegate iterator, or by modifying context.method and context.arg,
// setting context.delegate to null, and returning the ContinueSentinel.
function maybeInvokeDelegate(delegate, context) {
var method = delegate.iterator[context.method];
if (method === undefined) {
// A .throw or .return when the delegate iterator has no .throw
// method always terminates the yield* loop.
context.delegate = null;
if (context.method === "throw") {
if (delegate.iterator.return) {
// If the delegate iterator has a return method, give it a
// chance to clean up.
context.method = "return";
context.arg = undefined;
maybeInvokeDelegate(delegate, context);
if (context.method === "throw") {
// If maybeInvokeDelegate(context) changed context.method from
// "return" to "throw", let that override the TypeError below.
return ContinueSentinel;
}
}
context.method = "throw";
context.arg = new TypeError(
"The iterator does not provide a 'throw' method");
}
return ContinueSentinel;
}
var record = tryCatch(method, delegate.iterator, context.arg);
if (record.type === "throw") {
context.method = "throw";
context.arg = record.arg;
context.delegate = null;
return ContinueSentinel;
}
var info = record.arg;
if (! info) {
context.method = "throw";
context.arg = new TypeError("iterator result is not an object");
context.delegate = null;
return ContinueSentinel;
}
if (info.done) {
// Assign the result of the finished delegate to the temporary
// variable specified by delegate.resultName (see delegateYield).
context[delegate.resultName] = info.value;
// Resume execution at the desired location (see delegateYield).
context.next = delegate.nextLoc;
// If context.method was "throw" but the delegate handled the
// exception, let the outer generator proceed normally. If
// context.method was "next", forget context.arg since it has been
// "consumed" by the delegate iterator. If context.method was
// "return", allow the original .return call to continue in the
// outer generator.
if (context.method !== "return") {
context.method = "next";
context.arg = undefined;
}
} else {
// Re-yield the result returned by the delegate method.
return info;
}
// The delegate iterator is finished, so forget it and continue with
// the outer generator.
context.delegate = null;
return ContinueSentinel;
}
// Define Generator.prototype.{next,throw,return} in terms of the
// unified ._invoke helper method.
defineIteratorMethods(Gp);
Gp[toStringTagSymbol] = "Generator";
// A Generator should always return itself as the iterator object when the
// @@iterator function is called on it. Some browsers' implementations of the
// iterator prototype chain incorrectly implement this, causing the Generator
// object to not be returned from this call. This ensures that doesn't happen.
// See https://github.com/facebook/regenerator/issues/274 for more details.
Gp[iteratorSymbol] = function() {
return this;
};
Gp.toString = function() {
return "[object Generator]";
};
function pushTryEntry(locs) {
var entry = { tryLoc: locs[0] };
if (1 in locs) {
entry.catchLoc = locs[1];
}
if (2 in locs) {
entry.finallyLoc = locs[2];
entry.afterLoc = locs[3];
}
this.tryEntries.push(entry);
}
function resetTryEntry(entry) {
var record = entry.completion || {};
record.type = "normal";
delete record.arg;
entry.completion = record;
}
function Context(tryLocsList) {
// The root entry object (effectively a try statement without a catch
// or a finally block) gives us a place to store values thrown from
// locations where there is no enclosing try statement.
this.tryEntries = [{ tryLoc: "root" }];
tryLocsList.forEach(pushTryEntry, this);
this.reset(true);
}
runtime.keys = function(object) {
var keys = [];
for (var key in object) {
keys.push(key);
}
keys.reverse();
// Rather than returning an object with a next method, we keep
// things simple and return the next function itself.
return function next() {
while (keys.length) {
var key = keys.pop();
if (key in object) {
next.value = key;
next.done = false;
return next;
}
}
// To avoid creating an additional object, we just hang the .value
// and .done properties off the next function object itself. This
// also ensures that the minifier will not anonymize the function.
next.done = true;
return next;
};
};
function values(iterable) {
if (iterable) {
var iteratorMethod = iterable[iteratorSymbol];
if (iteratorMethod) {
return iteratorMethod.call(iterable);
}
if (typeof iterable.next === "function") {
return iterable;
}
if (!isNaN(iterable.length)) {
var i = -1, next = function next() {
while (++i < iterable.length) {
if (hasOwn.call(iterable, i)) {
next.value = iterable[i];
next.done = false;
return next;
}
}
next.value = undefined;
next.done = true;
return next;
};
return next.next = next;
}
}
// Return an iterator with no values.
return { next: doneResult };
}
runtime.values = values;
function doneResult() {
return { value: undefined, done: true };
}
Context.prototype = {
constructor: Context,
reset: function(skipTempReset) {
this.prev = 0;
this.next = 0;
// Resetting context._sent for legacy support of Babel's
// function.sent implementation.
this.sent = this._sent = undefined;
this.done = false;
this.delegate = null;
this.method = "next";
this.arg = undefined;
this.tryEntries.forEach(resetTryEntry);
if (!skipTempReset) {
for (var name in this) {
// Not sure about the optimal order of these conditions:
if (name.charAt(0) === "t" &&
hasOwn.call(this, name) &&
!isNaN(+name.slice(1))) {
this[name] = undefined;
}
}
}
},
stop: function() {
this.done = true;
var rootEntry = this.tryEntries[0];
var rootRecord = rootEntry.completion;
if (rootRecord.type === "throw") {
throw rootRecord.arg;
}
return this.rval;
},
dispatchException: function(exception) {
if (this.done) {
throw exception;
}
var context = this;
function handle(loc, caught) {
record.type = "throw";
record.arg = exception;
context.next = loc;
if (caught) {
// If the dispatched exception was caught by a catch block,
// then let that catch block handle the exception normally.
context.method = "next";
context.arg = undefined;
}
return !! caught;
}
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
var record = entry.completion;
if (entry.tryLoc === "root") {
// Exception thrown outside of any try block that could handle
// it, so set the completion value of the entire function to
// throw the exception.
return handle("end");
}
if (entry.tryLoc <= this.prev) {
var hasCatch = hasOwn.call(entry, "catchLoc");
var hasFinally = hasOwn.call(entry, "finallyLoc");
if (hasCatch && hasFinally) {
if (this.prev < entry.catchLoc) {
return handle(entry.catchLoc, true);
} else if (this.prev < entry.finallyLoc) {
return handle(entry.finallyLoc);
}
} else if (hasCatch) {
if (this.prev < entry.catchLoc) {
return handle(entry.catchLoc, true);
}
} else if (hasFinally) {
if (this.prev < entry.finallyLoc) {
return handle(entry.finallyLoc);
}
} else {
throw new Error("try statement without catch or finally");
}
}
}
},
abrupt: function(type, arg) {
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
if (entry.tryLoc <= this.prev &&
hasOwn.call(entry, "finallyLoc") &&
this.prev < entry.finallyLoc) {
var finallyEntry = entry;
break;
}
}
if (finallyEntry &&
(type === "break" ||
type === "continue") &&
finallyEntry.tryLoc <= arg &&
arg <= finallyEntry.finallyLoc) {
// Ignore the finally entry if control is not jumping to a
// location outside the try/catch block.
finallyEntry = null;
}
var record = finallyEntry ? finallyEntry.completion : {};
record.type = type;
record.arg = arg;
if (finallyEntry) {
this.method = "next";
this.next = finallyEntry.finallyLoc;
return ContinueSentinel;
}
return this.complete(record);
},
complete: function(record, afterLoc) {
if (record.type === "throw") {
throw record.arg;
}
if (record.type === "break" ||
record.type === "continue") {
this.next = record.arg;
} else if (record.type === "return") {
this.rval = this.arg = record.arg;
this.method = "return";
this.next = "end";
} else if (record.type === "normal" && afterLoc) {
this.next = afterLoc;
}
return ContinueSentinel;
},
finish: function(finallyLoc) {
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
if (entry.finallyLoc === finallyLoc) {
this.complete(entry.completion, entry.afterLoc);
resetTryEntry(entry);
return ContinueSentinel;
}
}
},
"catch": function(tryLoc) {
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
if (entry.tryLoc === tryLoc) {
var record = entry.completion;
if (record.type === "throw") {
var thrown = record.arg;
resetTryEntry(entry);
}
return thrown;
}
}
// The context.catch method must only be called with a location
// argument that corresponds to a known catch block.
throw new Error("illegal catch attempt");
},
delegateYield: function(iterable, resultName, nextLoc) {
this.delegate = {
iterator: values(iterable),
resultName: resultName,
nextLoc: nextLoc
};
if (this.method === "next") {
// Deliberately forget the last sent value so that we don't
// accidentally pass it on to the delegate.
this.arg = undefined;
}
return ContinueSentinel;
}
};
})(
// In sloppy mode, unbound `this` refers to the global object, fallback to
// Function constructor if we're in global strict mode. That is sadly a form
// of indirect eval which violates Content Security Policy.
(function() {
return this || (typeof self === "object" && self);
})() || Function("return this")()
);
},{}],305:[function(require,module,exports){
module.exports = require("regenerator-runtime");
},{"regenerator-runtime":303}],306:[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 objectCreate = Object.create || objectCreatePolyfill
var objectKeys = Object.keys || objectKeysPolyfill
var bind = Function.prototype.bind || functionBindPolyfill
function EventEmitter() {
if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) {
this._events = objectCreate(null);
this._eventsCount = 0;
}
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.
var defaultMaxListeners = 10;
var hasDefineProperty;
try {
var o = {};
if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 });
hasDefineProperty = o.x === 0;
} catch (err) { hasDefineProperty = false }
if (hasDefineProperty) {
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
enumerable: true,
get: function() {
return defaultMaxListeners;
},
set: function(arg) {
// check whether the input is a positive number (whose value is zero or
// greater and not a NaN).
if (typeof arg !== 'number' || arg < 0 || arg !== arg)
throw new TypeError('"defaultMaxListeners" must be a positive number');
defaultMaxListeners = arg;
}
});
} else {
EventEmitter.defaultMaxListeners = defaultMaxListeners;
}
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
if (typeof n !== 'number' || n < 0 || isNaN(n))
throw new TypeError('"n" argument must be a positive number');
this._maxListeners = n;
return this;
};
function $getMaxListeners(that) {
if (that._maxListeners === undefined)
return EventEmitter.defaultMaxListeners;
return that._maxListeners;
}
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
return $getMaxListeners(this);
};
// These standalone emit* functions are used to optimize calling of event
// handlers for fast cases because emit() itself often has a variable number of
// arguments and can be deoptimized because of that. These functions always have
// the same number of arguments and thus do not get deoptimized, so the code
// inside them can execute faster.
function emitNone(handler, isFn, self) {
if (isFn)
handler.call(self);
else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
listeners[i].call(self);
}
}
function emitOne(handler, isFn, self, arg1) {
if (isFn)
handler.call(self, arg1);
else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
listeners[i].call(self, arg1);
}
}
function emitTwo(handler, isFn, self, arg1, arg2) {
if (isFn)
handler.call(self, arg1, arg2);
else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
listeners[i].call(self, arg1, arg2);
}
}
function emitThree(handler, isFn, self, arg1, arg2, arg3) {
if (isFn)
handler.call(self, arg1, arg2, arg3);
else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
listeners[i].call(self, arg1, arg2, arg3);
}
}
function emitMany(handler, isFn, self, args) {
if (isFn)
handler.apply(self, args);
else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
listeners[i].apply(self, args);
}
}
EventEmitter.prototype.emit = function emit(type) {
var er, handler, len, args, i, events;
var doError = (type === 'error');
events = this._events;
if (events)
doError = (doError && events.error == null);
else if (!doError)
return false;
// If there is no 'error' event listener then throw.
if (doError) {
if (arguments.length > 1)
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('Unhandled "error" event. (' + er + ')');
err.context = er;
throw err;
}
return false;
}
handler = events[type];
if (!handler)
return false;
var isFn = typeof handler === 'function';
len = arguments.length;
switch (len) {
// fast cases
case 1:
emitNone(handler, isFn, this);
break;
case 2:
emitOne(handler, isFn, this, arguments[1]);
break;
case 3:
emitTwo(handler, isFn, this, arguments[1], arguments[2]);
break;
case 4:
emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);
break;
// slower
default:
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
emitMany(handler, isFn, this, args);
}
return true;
};
function _addListener(target, type, listener, prepend) {
var m;
var events;
var existing;
if (typeof listener !== 'function')
throw new TypeError('"listener" argument must be a function');
events = target._events;
if (!events) {
events = target._events = objectCreate(null);
target._eventsCount = 0;
} else {
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (events.newListener) {
target.emit('newListener', type,
listener.listener ? listener.listener : listener);
// Re-assign `events` because a newListener handler could have caused the
// this._events to be assigned to a new object
events = target._events;
}
existing = events[type];
}
if (!existing) {
// Optimize the case of one listener. Don't need the extra array object.
existing = events[type] = listener;
++target._eventsCount;
} else {
if (typeof existing === 'function') {
// Adding the second element, need to change to array.
existing = events[type] =
prepend ? [listener, existing] : [existing, listener];
} else {
// If we've already got an array, just append.
if (prepend) {
existing.unshift(listener);
} else {
existing.push(listener);
}
}
// Check for listener leak
if (!existing.warned) {
m = $getMaxListeners(target);
if (m && m > 0 && existing.length > m) {
existing.warned = true;
var w = new Error('Possible EventEmitter memory leak detected. ' +
existing.length + ' "' + String(type) + '" listeners ' +
'added. Use emitter.setMaxListeners() to ' +
'increase limit.');
w.name = 'MaxListenersExceededWarning';
w.emitter = target;
w.type = type;
w.count = existing.length;
if (typeof console === 'object' && console.warn) {
console.warn('%s: %s', w.name, w.message);
}
}
}
}
return target;
}
EventEmitter.prototype.addListener = function addListener(type, listener) {
return _addListener(this, type, listener, false);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.prependListener =
function prependListener(type, listener) {
return _addListener(this, type, listener, true);
};
function onceWrapper() {
if (!this.fired) {
this.target.removeListener(this.type, this.wrapFn);
this.fired = true;
switch (arguments.length) {
case 0:
return this.listener.call(this.target);
case 1:
return this.listener.call(this.target, arguments[0]);
case 2:
return this.listener.call(this.target, arguments[0], arguments[1]);
case 3:
return this.listener.call(this.target, arguments[0], arguments[1],
arguments[2]);
default:
var args = new Array(arguments.length);
for (var i = 0; i < args.length; ++i)
args[i] = arguments[i];
this.listener.apply(this.target, args);
}
}
}
function _onceWrap(target, type, listener) {
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
var wrapped = bind.call(onceWrapper, state);
wrapped.listener = listener;
state.wrapFn = wrapped;
return wrapped;
}
EventEmitter.prototype.once = function once(type, listener) {
if (typeof listener !== 'function')
throw new TypeError('"listener" argument must be a function');
this.on(type, _onceWrap(this, type, listener));
return this;
};
EventEmitter.prototype.prependOnceListener =
function prependOnceListener(type, listener) {
if (typeof listener !== 'function')
throw new TypeError('"listener" argument must be a function');
this.prependListener(type, _onceWrap(this, type, listener));
return this;
};
// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener =
function removeListener(type, listener) {
var list, events, position, i, originalListener;
if (typeof listener !== 'function')
throw new TypeError('"listener" argument must be a function');
events = this._events;
if (!events)
return this;
list = events[type];
if (!list)
return this;
if (list === listener || list.listener === listener) {
if (--this._eventsCount === 0)
this._events = objectCreate(null);
else {
delete events[type];
if (events.removeListener)
this.emit('removeListener', type, list.listener || listener);
}
} else if (typeof list !== 'function') {
position = -1;
for (i = list.length - 1; i >= 0; i--) {
if (list[i] === listener || list[i].listener === listener) {
originalListener = list[i].listener;
position = i;
break;
}
}
if (position < 0)
return this;
if (position === 0)
list.shift();
else
spliceOne(list, position);
if (list.length === 1)
events[type] = list[0];
if (events.removeListener)
this.emit('removeListener', type, originalListener || listener);
}
return this;
};
EventEmitter.prototype.removeAllListeners =
function removeAllListeners(type) {
var listeners, events, i;
events = this._events;
if (!events)
return this;
// not listening for removeListener, no need to emit
if (!events.removeListener) {
if (arguments.length === 0) {
this._events = objectCreate(null);
this._eventsCount = 0;
} else if (events[type]) {
if (--this._eventsCount === 0)
this._events = objectCreate(null);
else
delete events[type];
}
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
var keys = objectKeys(events);
var key;
for (i = 0; i < keys.length; ++i) {
key = keys[i];
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = objectCreate(null);
this._eventsCount = 0;
return this;
}
listeners = events[type];
if (typeof listeners === 'function') {
this.removeListener(type, listeners);
} else if (listeners) {
// LIFO order
for (i = listeners.length - 1; i >= 0; i--) {
this.removeListener(type, listeners[i]);
}
}
return this;
};
function _listeners(target, type, unwrap) {
var events = target._events;
if (!events)
return [];
var evlistener = events[type];
if (!evlistener)
return [];
if (typeof evlistener === 'function')
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}
EventEmitter.prototype.listeners = function listeners(type) {
return _listeners(this, type, true);
};
EventEmitter.prototype.rawListeners = function rawListeners(type) {
return _listeners(this, type, false);
};
EventEmitter.listenerCount = function(emitter, type) {
if (typeof emitter.listenerCount === 'function') {
return emitter.listenerCount(type);
} else {
return listenerCount.call(emitter, type);
}
};
EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
var events = this._events;
if (events) {
var evlistener = events[type];
if (typeof evlistener === 'function') {
return 1;
} else if (evlistener) {
return evlistener.length;
}
}
return 0;
}
EventEmitter.prototype.eventNames = function eventNames() {
return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
};
// About 1.5x faster than the two-arg version of Array#splice().
function spliceOne(list, index) {
for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
list[i] = list[k];
list.pop();
}
function arrayClone(arr, n) {
var copy = new Array(n);
for (var i = 0; i < n; ++i)
copy[i] = arr[i];
return copy;
}
function unwrapListeners(arr) {
var ret = new Array(arr.length);
for (var i = 0; i < ret.length; ++i) {
ret[i] = arr[i].listener || arr[i];
}
return ret;
}
function objectCreatePolyfill(proto) {
var F = function() {};
F.prototype = proto;
return new F;
}
function objectKeysPolyfill(obj) {
var keys = [];
for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) {
keys.push(k);
}
return k;
}
function functionBindPolyfill(context) {
var fn = this;
return function () {
return fn.apply(context, arguments);
};
}
},{}],307:[function(require,module,exports){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.SUPPORTED_PROTOCOL_VERSION = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _applyDecoratedDescriptor2 = _interopRequireDefault(require("@babel/runtime/helpers/applyDecoratedDescriptor"));
var _utils = require("./utils");
var _http = _interopRequireDefault(require("./http"));
var _endpoint = _interopRequireDefault(require("./endpoint"));
var requests = _interopRequireWildcard(require("./requests"));
var _batch2 = require("./batch");
var _bucket = _interopRequireDefault(require("./bucket"));
var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _class;
/**
* Currently supported protocol version.
* @type {String}
*/
var SUPPORTED_PROTOCOL_VERSION = "v1";
/**
* High level HTTP client for the Kinto API.
*
* @example
* const client = new KintoClient("https://kinto.dev.mozaws.net/v1");
* client.bucket("default")
* .collection("my-blog")
* .createRecord({title: "First article"})
* .then(console.log.bind(console))
* .catch(console.error.bind(console));
*/
exports.SUPPORTED_PROTOCOL_VERSION = SUPPORTED_PROTOCOL_VERSION;
var KintoClientBase = (_dec = (0, _utils.nobatch)("This operation is not supported within a batch operation."), _dec2 = (0, _utils.nobatch)("This operation is not supported within a batch operation."), _dec3 = (0, _utils.nobatch)("This operation is not supported within a batch operation."), _dec4 = (0, _utils.nobatch)("This operation is not supported within a batch operation."), _dec5 = (0, _utils.nobatch)("Can't use batch within a batch!"), _dec6 = (0, _utils.capable)(["permissions_endpoint"]), _dec7 = (0, _utils.support)("1.4", "2.0"), (_class =
/*#__PURE__*/
function () {
/**
* Constructor.
*
* @param {String} remote The remote URL.
* @param {Object} [options={}] The options object.
* @param {Boolean} [options.safe=true] Adds concurrency headers to every requests.
* @param {EventEmitter} [options.events=EventEmitter] The events handler instance.
* @param {Object} [options.headers={}] The key-value headers to pass to each request.
* @param {Object} [options.retry=0] Number of retries when request fails (default: 0)
* @param {String} [options.bucket="default"] The default bucket to use.
* @param {String} [options.requestMode="cors"] The HTTP request mode (from ES6 fetch spec).
* @param {Number} [options.timeout=null] The request timeout in ms, if any.
*/
function KintoClientBase(remote) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _classCallCheck2.default)(this, KintoClientBase);
if (typeof remote !== "string" || !remote.length) {
throw new Error("Invalid remote URL: " + remote);
}
if (remote[remote.length - 1] === "/") {
remote = remote.slice(0, -1);
}
this._backoffReleaseTime = null;
this._requests = [];
this._isBatch = !!options.batch;
this._retry = options.retry || 0;
this._safe = !!options.safe;
this._headers = options.headers || {}; // public properties
/**
* The remote server base URL.
* @type {String}
*/
this.remote = remote;
/**
* Current server information.
* @ignore
* @type {Object|null}
*/
this.serverInfo = null;
/**
* The event emitter instance. Should comply with the `EventEmitter`
* interface.
* @ignore
* @type {Class}
*/
this.events = options.events;
var requestMode = options.requestMode,
timeout = options.timeout;
/**
* The HTTP instance.
* @ignore
* @type {HTTP}
*/
this.http = new _http.default(this.events, {
requestMode: requestMode,
timeout: timeout
});
this._registerHTTPEvents();
}
/**
* The remote endpoint base URL. Setting the value will also extract and
* validate the version.
* @type {String}
*/
(0, _createClass2.default)(KintoClientBase, [{
key: "_registerHTTPEvents",
/**
* Registers HTTP events.
* @private
*/
value: function _registerHTTPEvents() {
var _this = this;
// Prevent registering event from a batch client instance
if (!this._isBatch) {
this.events.on("backoff", function (backoffMs) {
_this._backoffReleaseTime = backoffMs;
});
}
}
/**
* Retrieve a bucket object to perform operations on it.
*
* @param {String} name The bucket name.
* @param {Object} [options={}] The request options.
* @param {Boolean} [options.safe] The resulting safe option.
* @param {Number} [options.retry] The resulting retry option.
* @param {Object} [options.headers] The extended headers object option.
* @return {Bucket}
*/
}, {
key: "bucket",
value: function bucket(name) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return new _bucket.default(this, name, {
batch: this._isBatch,
headers: this._getHeaders(options),
safe: this._getSafe(options),
retry: this._getRetry(options)
});
}
/**
* Set client "headers" for every request, updating previous headers (if any).
*
* @param {Object} headers The headers to merge with existing ones.
*/
}, {
key: "setHeaders",
value: function setHeaders(headers) {
this._headers = (0, _objectSpread2.default)({}, this._headers, headers);
this.serverInfo = null;
}
/**
* Get the value of "headers" for a given request, merging the
* per-request headers with our own "default" headers.
*
* Note that unlike other options, headers aren't overridden, but
* merged instead.
*
* @private
* @param {Object} options The options for a request.
* @returns {Object}
*/
}, {
key: "_getHeaders",
value: function _getHeaders(options) {
return (0, _objectSpread2.default)({}, this._headers, options.headers);
}
/**
* Get the value of "safe" for a given request, using the
* per-request option if present or falling back to our default
* otherwise.
*
* @private
* @param {Object} options The options for a request.
* @returns {Boolean}
*/
}, {
key: "_getSafe",
value: function _getSafe(options) {
return (0, _objectSpread2.default)({
safe: this._safe
}, options).safe;
}
/**
* As _getSafe, but for "retry".
*
* @private
*/
}, {
key: "_getRetry",
value: function _getRetry(options) {
return (0, _objectSpread2.default)({
retry: this._retry
}, options).retry;
}
/**
* Retrieves the server's "hello" endpoint. This endpoint reveals
* server capabilities and settings as well as telling the client
* "who they are" according to their given authorization headers.
*
* @private
* @param {Object} [options={}] The request options.
* @param {Object} [options.headers={}] Headers to use when making
* this request.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "_getHello",
value: function () {
var _getHello2 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee() {
var options,
path,
_ref,
json,
_args = arguments;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
path = this.remote + (0, _endpoint.default)("root");
_context.next = 4;
return this.http.request(path, {
headers: this._getHeaders(options)
}, {
retry: this._getRetry(options)
});
case 4:
_ref = _context.sent;
json = _ref.json;
return _context.abrupt("return", json);
case 7:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
return function _getHello() {
return _getHello2.apply(this, arguments);
};
}()
/**
* Retrieves server information and persist them locally. This operation is
* usually performed a single time during the instance lifecycle.
*
* @param {Object} [options={}] The request options.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "fetchServerInfo",
value: function () {
var _fetchServerInfo = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2() {
var options,
_args2 = arguments;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
options = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {};
if (!this.serverInfo) {
_context2.next = 3;
break;
}
return _context2.abrupt("return", this.serverInfo);
case 3:
_context2.next = 5;
return this._getHello({
retry: this._getRetry(options)
});
case 5:
this.serverInfo = _context2.sent;
return _context2.abrupt("return", this.serverInfo);
case 7:
case "end":
return _context2.stop();
}
}
}, _callee2, this);
}));
return function fetchServerInfo() {
return _fetchServerInfo.apply(this, arguments);
};
}()
/**
* Retrieves Kinto server settings.
*
* @param {Object} [options={}] The request options.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "fetchServerSettings",
value: function () {
var _fetchServerSettings = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee3(options) {
var _ref2, settings;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_context3.next = 2;
return this.fetchServerInfo(options);
case 2:
_ref2 = _context3.sent;
settings = _ref2.settings;
return _context3.abrupt("return", settings);
case 5:
case "end":
return _context3.stop();
}
}
}, _callee3, this);
}));
return function fetchServerSettings(_x) {
return _fetchServerSettings.apply(this, arguments);
};
}()
/**
* Retrieve server capabilities information.
*
* @param {Object} [options={}] The request options.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "fetchServerCapabilities",
value: function () {
var _fetchServerCapabilities = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee4() {
var options,
_ref3,
capabilities,
_args4 = arguments;
return _regenerator.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
options = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {};
_context4.next = 3;
return this.fetchServerInfo(options);
case 3:
_ref3 = _context4.sent;
capabilities = _ref3.capabilities;
return _context4.abrupt("return", capabilities);
case 6:
case "end":
return _context4.stop();
}
}
}, _callee4, this);
}));
return function fetchServerCapabilities() {
return _fetchServerCapabilities.apply(this, arguments);
};
}()
/**
* Retrieve authenticated user information.
*
* @param {Object} [options={}] The request options.
* @param {Object} [options.headers={}] Headers to use when making
* this request.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "fetchUser",
value: function () {
var _fetchUser = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee5() {
var options,
_ref4,
user,
_args5 = arguments;
return _regenerator.default.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
options = _args5.length > 0 && _args5[0] !== undefined ? _args5[0] : {};
_context5.next = 3;
return this._getHello(options);
case 3:
_ref4 = _context5.sent;
user = _ref4.user;
return _context5.abrupt("return", user);
case 6:
case "end":
return _context5.stop();
}
}
}, _callee5, this);
}));
return function fetchUser() {
return _fetchUser.apply(this, arguments);
};
}()
/**
* Retrieve authenticated user information.
*
* @param {Object} [options={}] The request options.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "fetchHTTPApiVersion",
value: function () {
var _fetchHTTPApiVersion = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee6() {
var options,
_ref5,
http_api_version,
_args6 = arguments;
return _regenerator.default.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
options = _args6.length > 0 && _args6[0] !== undefined ? _args6[0] : {};
_context6.next = 3;
return this.fetchServerInfo(options);
case 3:
_ref5 = _context6.sent;
http_api_version = _ref5.http_api_version;
return _context6.abrupt("return", http_api_version);
case 6:
case "end":
return _context6.stop();
}
}
}, _callee6, this);
}));
return function fetchHTTPApiVersion() {
return _fetchHTTPApiVersion.apply(this, arguments);
};
}()
/**
* Process batch requests, chunking them according to the batch_max_requests
* server setting when needed.
*
* @param {Array} requests The list of batch subrequests to perform.
* @param {Object} [options={}] The options object.
* @return {Promise<Object, Error>}
*/
}, {
key: "_batchRequests",
value: function () {
var _batchRequests2 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee7(requests) {
var _this2 = this;
var options,
headers,
serverSettings,
maxRequests,
chunks,
_ref6,
responses,
_args7 = arguments;
return _regenerator.default.wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
options = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {};
headers = this._getHeaders(options);
if (requests.length) {
_context7.next = 4;
break;
}
return _context7.abrupt("return", []);
case 4:
_context7.next = 6;
return this.fetchServerSettings({
retry: this._getRetry(options)
});
case 6:
serverSettings = _context7.sent;
maxRequests = serverSettings["batch_max_requests"];
if (!(maxRequests && requests.length > maxRequests)) {
_context7.next = 11;
break;
}
chunks = (0, _utils.partition)(requests, maxRequests);
return _context7.abrupt("return", (0, _utils.pMap)(chunks, function (chunk) {
return _this2._batchRequests(chunk, options);
}));
case 11:
_context7.next = 13;
return this.execute({
// FIXME: is this really necessary, since it's also present in
// the "defaults"?
headers: headers,
path: (0, _endpoint.default)("batch"),
method: "POST",
body: {
defaults: {
headers: headers
},
requests: requests
}
}, {
retry: this._getRetry(options)
});
case 13:
_ref6 = _context7.sent;
responses = _ref6.responses;
return _context7.abrupt("return", responses);
case 16:
case "end":
return _context7.stop();
}
}
}, _callee7, this);
}));
return function _batchRequests(_x2) {
return _batchRequests2.apply(this, arguments);
};
}()
/**
* Sends batch requests to the remote server.
*
* Note: Reserved for internal use only.
*
* @ignore
* @param {Function} fn The function to use for describing batch ops.
* @param {Object} [options={}] The options object.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.retry] The retry option.
* @param {String} [options.bucket] The bucket name option.
* @param {String} [options.collection] The collection name option.
* @param {Object} [options.headers] The headers object option.
* @param {Boolean} [options.aggregate=false] Produces an aggregated result object.
* @return {Promise<Object, Error>}
*/
}, {
key: "batch",
value: function () {
var _batch = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee8(fn) {
var options,
rootBatch,
bucketBatch,
collBatch,
batchClient,
responses,
_args8 = arguments;
return _regenerator.default.wrap(function _callee8$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
options = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {};
rootBatch = new KintoClientBase(this.remote, {
events: this.events,
batch: true,
safe: this._getSafe(options),
retry: this._getRetry(options)
});
if (options.bucket) {
bucketBatch = rootBatch.bucket(options.bucket);
if (options.collection) {
collBatch = bucketBatch.collection(options.collection);
}
}
batchClient = collBatch || bucketBatch || rootBatch;
fn(batchClient);
_context8.next = 7;
return this._batchRequests(rootBatch._requests, options);
case 7:
responses = _context8.sent;
if (!options.aggregate) {
_context8.next = 12;
break;
}
return _context8.abrupt("return", (0, _batch2.aggregate)(responses, rootBatch._requests));
case 12:
return _context8.abrupt("return", responses);
case 13:
case "end":
return _context8.stop();
}
}
}, _callee8, this);
}));
return function batch(_x3) {
return _batch.apply(this, arguments);
};
}()
/**
* Executes an atomic HTTP request.
*
* @private
* @param {Object} request The request object.
* @param {String} request.path The path to fetch, relative
* to the Kinto server root.
* @param {String} [request.method="GET"] The method to use in the
* request.
* @param {Body} [request.body] The request body.
* @param {Object} [request.headers={}] The request headers.
* @param {Object} [options={}] The options object.
* @param {Boolean} [options.raw=false] If true, resolve with full response
* @param {Boolean} [options.stringify=true] If true, serialize body data to
* @param {Number} [options.retry=0] The number of times to
* retry a request if the server responds with Retry-After.
* JSON.
* @return {Promise<Object, Error>}
*/
}, {
key: "execute",
value: function () {
var _execute = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee9(request) {
var options,
_options$raw,
raw,
_options$stringify,
stringify,
msg,
result,
_args9 = arguments;
return _regenerator.default.wrap(function _callee9$(_context9) {
while (1) {
switch (_context9.prev = _context9.next) {
case 0:
options = _args9.length > 1 && _args9[1] !== undefined ? _args9[1] : {};
_options$raw = options.raw, raw = _options$raw === void 0 ? false : _options$raw, _options$stringify = options.stringify, stringify = _options$stringify === void 0 ? true : _options$stringify; // If we're within a batch, add the request to the stack to send at once.
if (!this._isBatch) {
_context9.next = 6;
break;
}
this._requests.push(request); // Resolve with a message in case people attempt at consuming the result
// from within a batch operation.
msg = "This result is generated from within a batch " + "operation and should not be consumed.";
return _context9.abrupt("return", raw ? {
json: msg,
headers: {
get: function get() {}
}
} : msg);
case 6:
_context9.next = 8;
return this.http.request(this.remote + request.path, (0, _utils.cleanUndefinedProperties)({
// Limit requests to only those parts that would be allowed in
// a batch request -- don't pass through other fancy fetch()
// options like integrity, redirect, mode because they will
// break on a batch request. A batch request only allows
// headers, method, path (above), and body.
method: request.method,
headers: request.headers,
body: stringify ? JSON.stringify(request.body) : request.body
}), {
retry: this._getRetry(options)
});
case 8:
result = _context9.sent;
return _context9.abrupt("return", raw ? result : result.json);
case 10:
case "end":
return _context9.stop();
}
}
}, _callee9, this);
}));
return function execute(_x4) {
return _execute.apply(this, arguments);
};
}()
/**
* Fetch some pages from a paginated list, following the `next-page`
* header automatically until we have fetched the requested number
* of pages. Return a response with a `.next()` method that can be
* called to fetch more results.
*
* @private
* @param {String} path
* The path to make the request to.
* @param {Object} params
* The parameters to use when making the request.
* @param {String} [params.sort="-last_modified"]
* The sorting order to use when fetching.
* @param {Object} [params.filters={}]
* The filters to send in the request.
* @param {Number} [params.limit=undefined]
* The limit to send in the request. Undefined means no limit.
* @param {Number} [params.pages=undefined]
* The number of pages to fetch. Undefined means one page. Pass
* Infinity to fetch everything.
* @param {String} [params.since=undefined]
* The ETag from which to start fetching.
* @param {Object} [options={}]
* Additional request-level parameters to use in all requests.
* @param {Object} [options.headers={}]
* Headers to use during all requests.
* @param {Number} [options.retry=0]
* Number of times to retry each request if the server responds
* with Retry-After.
*/
}, {
key: "paginatedList",
value: function () {
var _paginatedList = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee13(path, params) {
var _this3 = this;
var options,
_sort$params,
sort,
filters,
limit,
pages,
since,
querystring,
results,
current,
next,
processNextPage,
pageResults,
handleResponse,
_args13 = arguments;
return _regenerator.default.wrap(function _callee13$(_context13) {
while (1) {
switch (_context13.prev = _context13.next) {
case 0:
options = _args13.length > 2 && _args13[2] !== undefined ? _args13[2] : {};
// FIXME: this is called even in batch requests, which doesn't
// make any sense (since all batch requests get a "dummy"
// response; see execute() above).
_sort$params = (0, _objectSpread2.default)({
sort: "-last_modified"
}, params), sort = _sort$params.sort, filters = _sort$params.filters, limit = _sort$params.limit, pages = _sort$params.pages, since = _sort$params.since; // Safety/Consistency check on ETag value.
if (!(since && typeof since !== "string")) {
_context13.next = 4;
break;
}
throw new Error("Invalid value for since (".concat(since, "), should be ETag value."));
case 4:
querystring = (0, _utils.qsify)((0, _objectSpread2.default)({}, filters, {
_sort: sort,
_limit: limit,
_since: since
}));
results = [], current = 0;
next =
/*#__PURE__*/
function () {
var _ref7 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee10(nextPage) {
return _regenerator.default.wrap(function _callee10$(_context10) {
while (1) {
switch (_context10.prev = _context10.next) {
case 0:
if (nextPage) {
_context10.next = 2;
break;
}
throw new Error("Pagination exhausted.");
case 2:
return _context10.abrupt("return", processNextPage(nextPage));
case 3:
case "end":
return _context10.stop();
}
}
}, _callee10, this);
}));
return function next(_x7) {
return _ref7.apply(this, arguments);
};
}();
processNextPage =
/*#__PURE__*/
function () {
var _ref8 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee11(nextPage) {
var headers;
return _regenerator.default.wrap(function _callee11$(_context11) {
while (1) {
switch (_context11.prev = _context11.next) {
case 0:
headers = options.headers;
_context11.t0 = handleResponse;
_context11.next = 4;
return _this3.http.request(nextPage, {
headers: headers
});
case 4:
_context11.t1 = _context11.sent;
return _context11.abrupt("return", (0, _context11.t0)(_context11.t1));
case 6:
case "end":
return _context11.stop();
}
}
}, _callee11, this);
}));
return function processNextPage(_x8) {
return _ref8.apply(this, arguments);
};
}();
pageResults = function pageResults(results, nextPage, etag, totalRecords) {
// ETag string is supposed to be opaque and stored «as-is».
// ETag header values are quoted (because of * and W/"foo").
return {
last_modified: etag ? etag.replace(/"/g, "") : etag,
data: results,
next: next.bind(null, nextPage),
hasNextPage: !!nextPage,
totalRecords: totalRecords
};
};
handleResponse =
/*#__PURE__*/
function () {
var _ref9 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee12(_ref10) {
var headers, json, nextPage, etag, totalRecords;
return _regenerator.default.wrap(function _callee12$(_context12) {
while (1) {
switch (_context12.prev = _context12.next) {
case 0:
headers = _ref10.headers, json = _ref10.json;
nextPage = headers.get("Next-Page");
etag = headers.get("ETag");
totalRecords = parseInt(headers.get("Total-Records"), 10);
if (pages) {
_context12.next = 6;
break;
}
return _context12.abrupt("return", pageResults(json.data, nextPage, etag, totalRecords));
case 6:
// Aggregate new results with previous ones
results = results.concat(json.data);
current += 1;
if (!(current >= pages || !nextPage)) {
_context12.next = 10;
break;
}
return _context12.abrupt("return", pageResults(results, nextPage, etag, totalRecords));
case 10:
return _context12.abrupt("return", processNextPage(nextPage));
case 11:
case "end":
return _context12.stop();
}
}
}, _callee12, this);
}));
return function handleResponse(_x9) {
return _ref9.apply(this, arguments);
};
}();
_context13.t0 = handleResponse;
_context13.next = 13;
return this.execute( // N.B.: This doesn't use _getHeaders, because all calls to
// `paginatedList` are assumed to come from calls that already
// have headers merged at e.g. the bucket or collection level.
{
headers: options.headers,
path: path + "?" + querystring
}, // N.B. This doesn't use _getRetry, because all calls to
// `paginatedList` are assumed to come from calls that already
// used `_getRetry` at e.g. the bucket or collection level.
{
raw: true,
retry: options.retry || 0
});
case 13:
_context13.t1 = _context13.sent;
return _context13.abrupt("return", (0, _context13.t0)(_context13.t1));
case 15:
case "end":
return _context13.stop();
}
}
}, _callee13, this);
}));
return function paginatedList(_x5, _x6) {
return _paginatedList.apply(this, arguments);
};
}()
/**
* Lists all permissions.
*
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers={}] Headers to use when making
* this request.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object[], Error>}
*/
}, {
key: "listPermissions",
value: function () {
var _listPermissions = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee14() {
var options,
path,
paginationOptions,
_args14 = arguments;
return _regenerator.default.wrap(function _callee14$(_context14) {
while (1) {
switch (_context14.prev = _context14.next) {
case 0:
options = _args14.length > 0 && _args14[0] !== undefined ? _args14[0] : {};
path = (0, _endpoint.default)("permissions"); // Ensure the default sort parameter is something that exists in permissions
// entries, as `last_modified` doesn't; here, we pick "id".
paginationOptions = (0, _objectSpread2.default)({
sort: "id"
}, options);
return _context14.abrupt("return", this.paginatedList(path, paginationOptions, {
headers: this._getHeaders(options),
retry: this._getRetry(options)
}));
case 4:
case "end":
return _context14.stop();
}
}
}, _callee14, this);
}));
return function listPermissions() {
return _listPermissions.apply(this, arguments);
};
}()
/**
* Retrieves the list of buckets.
*
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers={}] Headers to use when making
* this request.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object[], Error>}
*/
}, {
key: "listBuckets",
value: function () {
var _listBuckets = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee15() {
var options,
path,
_args15 = arguments;
return _regenerator.default.wrap(function _callee15$(_context15) {
while (1) {
switch (_context15.prev = _context15.next) {
case 0:
options = _args15.length > 0 && _args15[0] !== undefined ? _args15[0] : {};
path = (0, _endpoint.default)("bucket");
return _context15.abrupt("return", this.paginatedList(path, options, {
headers: this._getHeaders(options),
retry: this._getRetry(options)
}));
case 3:
case "end":
return _context15.stop();
}
}
}, _callee15, this);
}));
return function listBuckets() {
return _listBuckets.apply(this, arguments);
};
}()
/**
* Creates a new bucket on the server.
*
* @param {String|null} id The bucket name (optional).
* @param {Object} [options={}] The options object.
* @param {Boolean} [options.data] The bucket data option.
* @param {Boolean} [options.safe] The safe option.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "createBucket",
value: function () {
var _createBucket = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee16(id) {
var options,
_options$data,
data,
permissions,
path,
_args16 = arguments;
return _regenerator.default.wrap(function _callee16$(_context16) {
while (1) {
switch (_context16.prev = _context16.next) {
case 0:
options = _args16.length > 1 && _args16[1] !== undefined ? _args16[1] : {};
_options$data = options.data, data = _options$data === void 0 ? {} : _options$data, permissions = options.permissions;
if (id != null) {
data.id = id;
}
path = data.id ? (0, _endpoint.default)("bucket", data.id) : (0, _endpoint.default)("bucket");
return _context16.abrupt("return", this.execute(requests.createRequest(path, {
data: data,
permissions: permissions
}, {
headers: this._getHeaders(options),
safe: this._getSafe(options)
}), {
retry: this._getRetry(options)
}));
case 5:
case "end":
return _context16.stop();
}
}
}, _callee16, this);
}));
return function createBucket(_x10) {
return _createBucket.apply(this, arguments);
};
}()
/**
* Deletes a bucket from the server.
*
* @ignore
* @param {Object|String} bucket The bucket to delete.
* @param {Object} [options={}] The options object.
* @param {Boolean} [options.safe] The safe option.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Number} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "deleteBucket",
value: function () {
var _deleteBucket = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee17(bucket) {
var options,
bucketObj,
path,
_bucketObj$options,
last_modified,
_args17 = arguments;
return _regenerator.default.wrap(function _callee17$(_context17) {
while (1) {
switch (_context17.prev = _context17.next) {
case 0:
options = _args17.length > 1 && _args17[1] !== undefined ? _args17[1] : {};
bucketObj = (0, _utils.toDataBody)(bucket);
if (bucketObj.id) {
_context17.next = 4;
break;
}
throw new Error("A bucket id is required.");
case 4:
path = (0, _endpoint.default)("bucket", bucketObj.id);
_bucketObj$options = (0, _objectSpread2.default)({}, bucketObj, options), last_modified = _bucketObj$options.last_modified;
return _context17.abrupt("return", this.execute(requests.deleteRequest(path, {
last_modified: last_modified,
headers: this._getHeaders(options),
safe: this._getSafe(options)
}), {
retry: this._getRetry(options)
}));
case 7:
case "end":
return _context17.stop();
}
}
}, _callee17, this);
}));
return function deleteBucket(_x11) {
return _deleteBucket.apply(this, arguments);
};
}()
/**
* Deletes all buckets on the server.
*
* @ignore
* @param {Object} [options={}] The options object.
* @param {Boolean} [options.safe] The safe option.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "deleteBuckets",
value: function () {
var _deleteBuckets = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee18() {
var options,
path,
_args18 = arguments;
return _regenerator.default.wrap(function _callee18$(_context18) {
while (1) {
switch (_context18.prev = _context18.next) {
case 0:
options = _args18.length > 0 && _args18[0] !== undefined ? _args18[0] : {};
path = (0, _endpoint.default)("bucket");
return _context18.abrupt("return", this.execute(requests.deleteRequest(path, {
last_modified: options.last_modified,
headers: this._getHeaders(options),
safe: this._getSafe(options)
}), {
retry: this._getRetry(options)
}));
case 3:
case "end":
return _context18.stop();
}
}
}, _callee18, this);
}));
return function deleteBuckets() {
return _deleteBuckets.apply(this, arguments);
};
}()
}, {
key: "remote",
get: function get() {
return this._remote;
}
/**
* @ignore
*/
,
set: function set(url) {
var version;
try {
version = url.match(/\/(v\d+)\/?$/)[1];
} catch (err) {
throw new Error("The remote URL must contain the version: " + url);
}
if (version !== SUPPORTED_PROTOCOL_VERSION) {
throw new Error("Unsupported protocol version: ".concat(version));
}
this._remote = url;
this._version = version;
}
/**
* The current server protocol version, eg. `v1`.
* @type {String}
*/
}, {
key: "version",
get: function get() {
return this._version;
}
/**
* Backoff remaining time, in milliseconds. Defaults to zero if no backoff is
* ongoing.
*
* @type {Number}
*/
}, {
key: "backoff",
get: function get() {
var currentTime = new Date().getTime();
if (this._backoffReleaseTime && currentTime < this._backoffReleaseTime) {
return this._backoffReleaseTime - currentTime;
}
return 0;
}
}]);
return KintoClientBase;
}(), ((0, _applyDecoratedDescriptor2.default)(_class.prototype, "fetchServerSettings", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "fetchServerSettings"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "fetchServerCapabilities", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "fetchServerCapabilities"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "fetchUser", [_dec3], Object.getOwnPropertyDescriptor(_class.prototype, "fetchUser"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "fetchHTTPApiVersion", [_dec4], Object.getOwnPropertyDescriptor(_class.prototype, "fetchHTTPApiVersion"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "batch", [_dec5], Object.getOwnPropertyDescriptor(_class.prototype, "batch"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "listPermissions", [_dec6], Object.getOwnPropertyDescriptor(_class.prototype, "listPermissions"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "deleteBuckets", [_dec7], Object.getOwnPropertyDescriptor(_class.prototype, "deleteBuckets"), _class.prototype)), _class));
exports.default = KintoClientBase;
},{"./batch":308,"./bucket":309,"./endpoint":311,"./http":313,"./requests":315,"./utils":316,"@babel/runtime/helpers/applyDecoratedDescriptor":277,"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/interopRequireWildcard":289,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/regenerator":305}],308:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.aggregate = aggregate;
/**
* Exports batch responses as a result object.
*
* @private
* @param {Array} responses The batch subrequest responses.
* @param {Array} requests The initial issued requests.
* @return {Object}
*/
function aggregate() {
var responses = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var requests = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
if (responses.length !== requests.length) {
throw new Error("Responses length should match requests one.");
}
var results = {
errors: [],
published: [],
conflicts: [],
skipped: []
};
return responses.reduce(function (acc, response, index) {
var status = response.status;
var request = requests[index];
if (status >= 200 && status < 400) {
acc.published.push(response.body);
} else if (status === 404) {
// Extract the id manually from request path while waiting for Kinto/kinto#818
var regex = /(buckets|groups|collections|records)\/([^/]+)$/;
var extracts = request.path.match(regex);
var id = extracts.length === 3 ? extracts[2] : undefined;
acc.skipped.push({
id: id,
path: request.path,
error: response.body
});
} else if (status === 412) {
acc.conflicts.push({
// XXX: specifying the type is probably superfluous
type: "outgoing",
local: request.body,
remote: response.body.details && response.body.details.existing || null
});
} else {
acc.errors.push({
path: request.path,
sent: request,
error: response.body
});
}
return acc;
}, results);
}
},{}],309:[function(require,module,exports){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _applyDecoratedDescriptor2 = _interopRequireDefault(require("@babel/runtime/helpers/applyDecoratedDescriptor"));
var _utils = require("./utils");
var _collection = _interopRequireDefault(require("./collection"));
var requests = _interopRequireWildcard(require("./requests"));
var _endpoint = _interopRequireDefault(require("./endpoint"));
var _dec, _class;
/**
* Abstract representation of a selected bucket.
*
*/
var Bucket = (_dec = (0, _utils.capable)(["history"]), (_class =
/*#__PURE__*/
function () {
/**
* Constructor.
*
* @param {KintoClient} client The client instance.
* @param {String} name The bucket name.
* @param {Object} [options={}] The headers object option.
* @param {Object} [options.headers] The headers object option.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.retry] The retry option.
*/
function Bucket(client, name) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
(0, _classCallCheck2.default)(this, Bucket);
/**
* @ignore
*/
this.client = client;
/**
* The bucket name.
* @type {String}
*/
this.name = name;
/**
* @ignore
*/
this._isBatch = !!options.batch;
/**
* @ignore
*/
this._headers = options.headers || {};
this._retry = options.retry || 0;
this._safe = !!options.safe;
}
/**
* Get the value of "headers" for a given request, merging the
* per-request headers with our own "default" headers.
*
* @private
*/
(0, _createClass2.default)(Bucket, [{
key: "_getHeaders",
value: function _getHeaders(options) {
return (0, _objectSpread2.default)({}, this._headers, options.headers);
}
/**
* Get the value of "safe" for a given request, using the
* per-request option if present or falling back to our default
* otherwise.
*
* @private
* @param {Object} options The options for a request.
* @returns {Boolean}
*/
}, {
key: "_getSafe",
value: function _getSafe(options) {
return (0, _objectSpread2.default)({
safe: this._safe
}, options).safe;
}
/**
* As _getSafe, but for "retry".
*
* @private
*/
}, {
key: "_getRetry",
value: function _getRetry(options) {
return (0, _objectSpread2.default)({
retry: this._retry
}, options).retry;
}
/**
* Selects a collection.
*
* @param {String} name The collection name.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Boolean} [options.safe] The safe option.
* @return {Collection}
*/
}, {
key: "collection",
value: function collection(name) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return new _collection.default(this.client, this, name, {
batch: this._isBatch,
headers: this._getHeaders(options),
retry: this._getRetry(options),
safe: this._getSafe(options)
});
}
/**
* Retrieves bucket data.
*
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "getData",
value: function () {
var _getData = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee() {
var options,
request,
_ref,
data,
_args = arguments;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
request = {
headers: this._getHeaders(options),
path: (0, _endpoint.default)("bucket", this.name)
};
_context.next = 4;
return this.client.execute(request, {
retry: this._getRetry(options)
});
case 4:
_ref = _context.sent;
data = _ref.data;
return _context.abrupt("return", data);
case 7:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
return function getData() {
return _getData.apply(this, arguments);
};
}()
/**
* Set bucket data.
* @param {Object} data The bucket data object.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers={}] The headers object option.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Boolean} [options.patch] The patch option.
* @param {Number} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "setData",
value: function () {
var _setData = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2(data) {
var options,
bucket,
bucketId,
path,
patch,
permissions,
_data$options,
last_modified,
request,
_args2 = arguments;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
options = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : {};
if ((0, _utils.isObject)(data)) {
_context2.next = 3;
break;
}
throw new Error("A bucket object is required.");
case 3:
bucket = (0, _objectSpread2.default)({}, data, {
id: this.name
}); // For default bucket, we need to drop the id from the data object.
// Bug in Kinto < 3.1.1
bucketId = bucket.id;
if (bucket.id === "default") {
delete bucket.id;
}
path = (0, _endpoint.default)("bucket", bucketId);
patch = options.patch, permissions = options.permissions;
_data$options = (0, _objectSpread2.default)({}, data, options), last_modified = _data$options.last_modified;
request = requests.updateRequest(path, {
data: bucket,
permissions: permissions
}, {
last_modified: last_modified,
patch: patch,
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context2.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 11:
case "end":
return _context2.stop();
}
}
}, _callee2, this);
}));
return function setData(_x) {
return _setData.apply(this, arguments);
};
}()
/**
* Retrieves the list of history entries in the current bucket.
*
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Array<Object>, Error>}
*/
}, {
key: "listHistory",
value: function () {
var _listHistory = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee3() {
var options,
path,
_args3 = arguments;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
options = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : {};
path = (0, _endpoint.default)("history", this.name);
return _context3.abrupt("return", this.client.paginatedList(path, options, {
headers: this._getHeaders(options),
retry: this._getRetry(options)
}));
case 3:
case "end":
return _context3.stop();
}
}
}, _callee3, this);
}));
return function listHistory() {
return _listHistory.apply(this, arguments);
};
}()
/**
* Retrieves the list of collections in the current bucket.
*
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Array<Object>, Error>}
*/
}, {
key: "listCollections",
value: function () {
var _listCollections = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee4() {
var options,
path,
_args4 = arguments;
return _regenerator.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
options = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {};
path = (0, _endpoint.default)("collection", this.name);
return _context4.abrupt("return", this.client.paginatedList(path, options, {
headers: this._getHeaders(options),
retry: this._getRetry(options)
}));
case 3:
case "end":
return _context4.stop();
}
}
}, _callee4, this);
}));
return function listCollections() {
return _listCollections.apply(this, arguments);
};
}()
/**
* Creates a new collection in current bucket.
*
* @param {String|undefined} id The collection id.
* @param {Object} [options={}] The options object.
* @param {Boolean} [options.safe] The safe option.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Object} [options.permissions] The permissions object.
* @param {Object} [options.data] The data object.
* @return {Promise<Object, Error>}
*/
}, {
key: "createCollection",
value: function () {
var _createCollection = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee5(id) {
var options,
permissions,
_options$data,
data,
path,
request,
_args5 = arguments;
return _regenerator.default.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
options = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {};
permissions = options.permissions, _options$data = options.data, data = _options$data === void 0 ? {} : _options$data;
data.id = id;
path = (0, _endpoint.default)("collection", this.name, id);
request = requests.createRequest(path, {
data: data,
permissions: permissions
}, {
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context5.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 6:
case "end":
return _context5.stop();
}
}
}, _callee5, this);
}));
return function createCollection(_x2) {
return _createCollection.apply(this, arguments);
};
}()
/**
* Deletes a collection from the current bucket.
*
* @param {Object|String} collection The collection to delete.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "deleteCollection",
value: function () {
var _deleteCollection = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee6(collection) {
var options,
collectionObj,
id,
_collectionObj$option,
last_modified,
path,
request,
_args6 = arguments;
return _regenerator.default.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
collectionObj = (0, _utils.toDataBody)(collection);
if (collectionObj.id) {
_context6.next = 4;
break;
}
throw new Error("A collection id is required.");
case 4:
id = collectionObj.id;
_collectionObj$option = (0, _objectSpread2.default)({}, collectionObj, options), last_modified = _collectionObj$option.last_modified;
path = (0, _endpoint.default)("collection", this.name, id);
request = requests.deleteRequest(path, {
last_modified: last_modified,
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context6.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 9:
case "end":
return _context6.stop();
}
}
}, _callee6, this);
}));
return function deleteCollection(_x3) {
return _deleteCollection.apply(this, arguments);
};
}()
/**
* Retrieves the list of groups in the current bucket.
*
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Array<Object>, Error>}
*/
}, {
key: "listGroups",
value: function () {
var _listGroups = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee7() {
var options,
path,
_args7 = arguments;
return _regenerator.default.wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
options = _args7.length > 0 && _args7[0] !== undefined ? _args7[0] : {};
path = (0, _endpoint.default)("group", this.name);
return _context7.abrupt("return", this.client.paginatedList(path, options, {
headers: this._getHeaders(options),
retry: this._getRetry(options)
}));
case 3:
case "end":
return _context7.stop();
}
}
}, _callee7, this);
}));
return function listGroups() {
return _listGroups.apply(this, arguments);
};
}()
/**
* Creates a new group in current bucket.
*
* @param {String} id The group id.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "getGroup",
value: function () {
var _getGroup = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee8(id) {
var options,
request,
_args8 = arguments;
return _regenerator.default.wrap(function _callee8$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
options = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {};
request = {
headers: this._getHeaders(options),
path: (0, _endpoint.default)("group", this.name, id)
};
return _context8.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 3:
case "end":
return _context8.stop();
}
}
}, _callee8, this);
}));
return function getGroup(_x4) {
return _getGroup.apply(this, arguments);
};
}()
/**
* Creates a new group in current bucket.
*
* @param {String|undefined} id The group id.
* @param {Array<String>} [members=[]] The list of principals.
* @param {Object} [options={}] The options object.
* @param {Object} [options.data] The data object.
* @param {Object} [options.permissions] The permissions object.
* @param {Boolean} [options.safe] The safe option.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "createGroup",
value: function () {
var _createGroup = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee9(id) {
var members,
options,
data,
path,
permissions,
request,
_args9 = arguments;
return _regenerator.default.wrap(function _callee9$(_context9) {
while (1) {
switch (_context9.prev = _context9.next) {
case 0:
members = _args9.length > 1 && _args9[1] !== undefined ? _args9[1] : [];
options = _args9.length > 2 && _args9[2] !== undefined ? _args9[2] : {};
data = (0, _objectSpread2.default)({}, options.data, {
id: id,
members: members
});
path = (0, _endpoint.default)("group", this.name, id);
permissions = options.permissions;
request = requests.createRequest(path, {
data: data,
permissions: permissions
}, {
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context9.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 7:
case "end":
return _context9.stop();
}
}
}, _callee9, this);
}));
return function createGroup(_x5) {
return _createGroup.apply(this, arguments);
};
}()
/**
* Updates an existing group in current bucket.
*
* @param {Object} group The group object.
* @param {Object} [options={}] The options object.
* @param {Object} [options.data] The data object.
* @param {Object} [options.permissions] The permissions object.
* @param {Boolean} [options.safe] The safe option.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Number} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "updateGroup",
value: function () {
var _updateGroup = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee10(group) {
var options,
data,
path,
patch,
permissions,
_data$options2,
last_modified,
request,
_args10 = arguments;
return _regenerator.default.wrap(function _callee10$(_context10) {
while (1) {
switch (_context10.prev = _context10.next) {
case 0:
options = _args10.length > 1 && _args10[1] !== undefined ? _args10[1] : {};
if ((0, _utils.isObject)(group)) {
_context10.next = 3;
break;
}
throw new Error("A group object is required.");
case 3:
if (group.id) {
_context10.next = 5;
break;
}
throw new Error("A group id is required.");
case 5:
data = (0, _objectSpread2.default)({}, options.data, group);
path = (0, _endpoint.default)("group", this.name, group.id);
patch = options.patch, permissions = options.permissions;
_data$options2 = (0, _objectSpread2.default)({}, data, options), last_modified = _data$options2.last_modified;
request = requests.updateRequest(path, {
data: data,
permissions: permissions
}, {
last_modified: last_modified,
patch: patch,
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context10.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 11:
case "end":
return _context10.stop();
}
}
}, _callee10, this);
}));
return function updateGroup(_x6) {
return _updateGroup.apply(this, arguments);
};
}()
/**
* Deletes a group from the current bucket.
*
* @param {Object|String} group The group to delete.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "deleteGroup",
value: function () {
var _deleteGroup = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee11(group) {
var options,
groupObj,
id,
_groupObj$options,
last_modified,
path,
request,
_args11 = arguments;
return _regenerator.default.wrap(function _callee11$(_context11) {
while (1) {
switch (_context11.prev = _context11.next) {
case 0:
options = _args11.length > 1 && _args11[1] !== undefined ? _args11[1] : {};
groupObj = (0, _utils.toDataBody)(group);
id = groupObj.id;
_groupObj$options = (0, _objectSpread2.default)({}, groupObj, options), last_modified = _groupObj$options.last_modified;
path = (0, _endpoint.default)("group", this.name, id);
request = requests.deleteRequest(path, {
last_modified: last_modified,
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context11.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 7:
case "end":
return _context11.stop();
}
}
}, _callee11, this);
}));
return function deleteGroup(_x7) {
return _deleteGroup.apply(this, arguments);
};
}()
/**
* Retrieves the list of permissions for this bucket.
*
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "getPermissions",
value: function () {
var _getPermissions = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee12() {
var options,
request,
_ref2,
permissions,
_args12 = arguments;
return _regenerator.default.wrap(function _callee12$(_context12) {
while (1) {
switch (_context12.prev = _context12.next) {
case 0:
options = _args12.length > 0 && _args12[0] !== undefined ? _args12[0] : {};
request = {
headers: this._getHeaders(options),
path: (0, _endpoint.default)("bucket", this.name)
};
_context12.next = 4;
return this.client.execute(request, {
retry: this._getRetry(options)
});
case 4:
_ref2 = _context12.sent;
permissions = _ref2.permissions;
return _context12.abrupt("return", permissions);
case 7:
case "end":
return _context12.stop();
}
}
}, _callee12, this);
}));
return function getPermissions() {
return _getPermissions.apply(this, arguments);
};
}()
/**
* Replaces all existing bucket permissions with the ones provided.
*
* @param {Object} permissions The permissions object.
* @param {Object} [options={}] The options object
* @param {Boolean} [options.safe] The safe option.
* @param {Object} [options.headers={}] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Object} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "setPermissions",
value: function () {
var _setPermissions = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee13(permissions) {
var options,
path,
last_modified,
data,
request,
_args13 = arguments;
return _regenerator.default.wrap(function _callee13$(_context13) {
while (1) {
switch (_context13.prev = _context13.next) {
case 0:
options = _args13.length > 1 && _args13[1] !== undefined ? _args13[1] : {};
if ((0, _utils.isObject)(permissions)) {
_context13.next = 3;
break;
}
throw new Error("A permissions object is required.");
case 3:
path = (0, _endpoint.default)("bucket", this.name);
last_modified = options.last_modified;
data = {
last_modified: last_modified
};
request = requests.updateRequest(path, {
data: data,
permissions: permissions
}, {
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context13.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 8:
case "end":
return _context13.stop();
}
}
}, _callee13, this);
}));
return function setPermissions(_x8) {
return _setPermissions.apply(this, arguments);
};
}()
/**
* Append principals to the bucket permissions.
*
* @param {Object} permissions The permissions object.
* @param {Object} [options={}] The options object
* @param {Boolean} [options.safe] The safe option.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Object} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "addPermissions",
value: function () {
var _addPermissions = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee14(permissions) {
var options,
path,
last_modified,
request,
_args14 = arguments;
return _regenerator.default.wrap(function _callee14$(_context14) {
while (1) {
switch (_context14.prev = _context14.next) {
case 0:
options = _args14.length > 1 && _args14[1] !== undefined ? _args14[1] : {};
if ((0, _utils.isObject)(permissions)) {
_context14.next = 3;
break;
}
throw new Error("A permissions object is required.");
case 3:
path = (0, _endpoint.default)("bucket", this.name);
last_modified = options.last_modified;
request = requests.jsonPatchPermissionsRequest(path, permissions, "add", {
last_modified: last_modified,
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context14.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 7:
case "end":
return _context14.stop();
}
}
}, _callee14, this);
}));
return function addPermissions(_x9) {
return _addPermissions.apply(this, arguments);
};
}()
/**
* Remove principals from the bucket permissions.
*
* @param {Object} permissions The permissions object.
* @param {Object} [options={}] The options object
* @param {Boolean} [options.safe] The safe option.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Object} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "removePermissions",
value: function () {
var _removePermissions = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee15(permissions) {
var options,
path,
last_modified,
request,
_args15 = arguments;
return _regenerator.default.wrap(function _callee15$(_context15) {
while (1) {
switch (_context15.prev = _context15.next) {
case 0:
options = _args15.length > 1 && _args15[1] !== undefined ? _args15[1] : {};
if ((0, _utils.isObject)(permissions)) {
_context15.next = 3;
break;
}
throw new Error("A permissions object is required.");
case 3:
path = (0, _endpoint.default)("bucket", this.name);
last_modified = options.last_modified;
request = requests.jsonPatchPermissionsRequest(path, permissions, "remove", {
last_modified: last_modified,
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context15.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 7:
case "end":
return _context15.stop();
}
}
}, _callee15, this);
}));
return function removePermissions(_x10) {
return _removePermissions.apply(this, arguments);
};
}()
/**
* Performs batch operations at the current bucket level.
*
* @param {Function} fn The batch operation function.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.retry=0] The retry option.
* @param {Boolean} [options.aggregate] Produces a grouped result object.
* @return {Promise<Object, Error>}
*/
}, {
key: "batch",
value: function () {
var _batch = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee16(fn) {
var options,
_args16 = arguments;
return _regenerator.default.wrap(function _callee16$(_context16) {
while (1) {
switch (_context16.prev = _context16.next) {
case 0:
options = _args16.length > 1 && _args16[1] !== undefined ? _args16[1] : {};
return _context16.abrupt("return", this.client.batch(fn, {
bucket: this.name,
headers: this._getHeaders(options),
retry: this._getRetry(options),
safe: this._getSafe(options),
aggregate: !!options.aggregate
}));
case 2:
case "end":
return _context16.stop();
}
}
}, _callee16, this);
}));
return function batch(_x11) {
return _batch.apply(this, arguments);
};
}()
}]);
return Bucket;
}(), ((0, _applyDecoratedDescriptor2.default)(_class.prototype, "listHistory", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "listHistory"), _class.prototype)), _class));
exports.default = Bucket;
},{"./collection":310,"./endpoint":311,"./requests":315,"./utils":316,"@babel/runtime/helpers/applyDecoratedDescriptor":277,"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/interopRequireWildcard":289,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/regenerator":305}],310:[function(require,module,exports){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _applyDecoratedDescriptor2 = _interopRequireDefault(require("@babel/runtime/helpers/applyDecoratedDescriptor"));
var _uuid = require("uuid");
var _utils = require("./utils");
var requests = _interopRequireWildcard(require("./requests"));
var _endpoint = _interopRequireDefault(require("./endpoint"));
var _dec, _dec2, _dec3, _class;
/**
* Abstract representation of a selected collection.
*
*/
var Collection = (_dec = (0, _utils.capable)(["attachments"]), _dec2 = (0, _utils.capable)(["attachments"]), _dec3 = (0, _utils.capable)(["history"]), (_class =
/*#__PURE__*/
function () {
/**
* Constructor.
*
* @param {KintoClient} client The client instance.
* @param {Bucket} bucket The bucket instance.
* @param {String} name The collection name.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.retry] The retry option.
* @param {Boolean} [options.batch] (Private) Whether this
* Collection is operating as part of a batch.
*/
function Collection(client, bucket, name) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
(0, _classCallCheck2.default)(this, Collection);
/**
* @ignore
*/
this.client = client;
/**
* @ignore
*/
this.bucket = bucket;
/**
* The collection name.
* @type {String}
*/
this.name = name;
/**
* @ignore
*/
this._isBatch = !!options.batch;
/**
* @ignore
*/
this._retry = options.retry || 0;
this._safe = !!options.safe; // FIXME: This is kind of ugly; shouldn't the bucket be responsible
// for doing the merge?
this._headers = (0, _objectSpread2.default)({}, this.bucket._headers, options.headers);
}
/**
* Get the value of "headers" for a given request, merging the
* per-request headers with our own "default" headers.
*
* @private
*/
(0, _createClass2.default)(Collection, [{
key: "_getHeaders",
value: function _getHeaders(options) {
return (0, _objectSpread2.default)({}, this._headers, options.headers);
}
/**
* Get the value of "safe" for a given request, using the
* per-request option if present or falling back to our default
* otherwise.
*
* @private
* @param {Object} options The options for a request.
* @returns {Boolean}
*/
}, {
key: "_getSafe",
value: function _getSafe(options) {
return (0, _objectSpread2.default)({
safe: this._safe
}, options).safe;
}
/**
* As _getSafe, but for "retry".
*
* @private
*/
}, {
key: "_getRetry",
value: function _getRetry(options) {
return (0, _objectSpread2.default)({
retry: this._retry
}, options).retry;
}
/**
* Retrieves the total number of records in this collection.
*
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Number, Error>}
*/
}, {
key: "getTotalRecords",
value: function () {
var _getTotalRecords = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee() {
var options,
path,
request,
_ref,
headers,
_args = arguments;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
path = (0, _endpoint.default)("record", this.bucket.name, this.name);
request = {
headers: this._getHeaders(options),
path: path,
method: "HEAD"
};
_context.next = 5;
return this.client.execute(request, {
raw: true,
retry: this._getRetry(options)
});
case 5:
_ref = _context.sent;
headers = _ref.headers;
return _context.abrupt("return", parseInt(headers.get("Total-Records"), 10));
case 8:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
return function getTotalRecords() {
return _getTotalRecords.apply(this, arguments);
};
}()
/**
* Retrieves collection data.
*
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Object} [options.query] Query parameters to pass in
* the request. This might be useful for features that aren't
* yet supported by this library.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "getData",
value: function () {
var _getData = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2() {
var options,
path,
querystring,
request,
_ref2,
data,
_args2 = arguments;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
options = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {};
path = (0, _endpoint.default)("collection", this.bucket.name, this.name);
if (options.query) {
querystring = (0, _utils.qsify)(options.query);
path = path + "?" + querystring;
}
request = {
headers: this._getHeaders(options),
path: path
};
_context2.next = 6;
return this.client.execute(request, {
retry: this._getRetry(options)
});
case 6:
_ref2 = _context2.sent;
data = _ref2.data;
return _context2.abrupt("return", data);
case 9:
case "end":
return _context2.stop();
}
}
}, _callee2, this);
}));
return function getData() {
return _getData.apply(this, arguments);
};
}()
/**
* Set collection data.
* @param {Object} data The collection data object.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Boolean} [options.safe] The safe option.
* @param {Boolean} [options.patch] The patch option.
* @param {Number} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "setData",
value: function () {
var _setData = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee3(data) {
var options,
patch,
permissions,
_data$options,
last_modified,
path,
request,
_args3 = arguments;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
options = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {};
if ((0, _utils.isObject)(data)) {
_context3.next = 3;
break;
}
throw new Error("A collection object is required.");
case 3:
patch = options.patch, permissions = options.permissions;
_data$options = (0, _objectSpread2.default)({}, data, options), last_modified = _data$options.last_modified;
path = (0, _endpoint.default)("collection", this.bucket.name, this.name);
request = requests.updateRequest(path, {
data: data,
permissions: permissions
}, {
last_modified: last_modified,
patch: patch,
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context3.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 8:
case "end":
return _context3.stop();
}
}
}, _callee3, this);
}));
return function setData(_x) {
return _setData.apply(this, arguments);
};
}()
/**
* Retrieves the list of permissions for this collection.
*
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "getPermissions",
value: function () {
var _getPermissions = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee4() {
var options,
path,
request,
_ref3,
permissions,
_args4 = arguments;
return _regenerator.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
options = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {};
path = (0, _endpoint.default)("collection", this.bucket.name, this.name);
request = {
headers: this._getHeaders(options),
path: path
};
_context4.next = 5;
return this.client.execute(request, {
retry: this._getRetry(options)
});
case 5:
_ref3 = _context4.sent;
permissions = _ref3.permissions;
return _context4.abrupt("return", permissions);
case 8:
case "end":
return _context4.stop();
}
}
}, _callee4, this);
}));
return function getPermissions() {
return _getPermissions.apply(this, arguments);
};
}()
/**
* Replaces all existing collection permissions with the ones provided.
*
* @param {Object} permissions The permissions object.
* @param {Object} [options={}] The options object
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "setPermissions",
value: function () {
var _setPermissions = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee5(permissions) {
var options,
path,
data,
request,
_args5 = arguments;
return _regenerator.default.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
options = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {};
if ((0, _utils.isObject)(permissions)) {
_context5.next = 3;
break;
}
throw new Error("A permissions object is required.");
case 3:
path = (0, _endpoint.default)("collection", this.bucket.name, this.name);
data = {
last_modified: options.last_modified
};
request = requests.updateRequest(path, {
data: data,
permissions: permissions
}, {
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context5.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 7:
case "end":
return _context5.stop();
}
}
}, _callee5, this);
}));
return function setPermissions(_x2) {
return _setPermissions.apply(this, arguments);
};
}()
/**
* Append principals to the collection permissions.
*
* @param {Object} permissions The permissions object.
* @param {Object} [options={}] The options object
* @param {Boolean} [options.safe] The safe option.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Object} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "addPermissions",
value: function () {
var _addPermissions = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee6(permissions) {
var options,
path,
last_modified,
request,
_args6 = arguments;
return _regenerator.default.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
if ((0, _utils.isObject)(permissions)) {
_context6.next = 3;
break;
}
throw new Error("A permissions object is required.");
case 3:
path = (0, _endpoint.default)("collection", this.bucket.name, this.name);
last_modified = options.last_modified;
request = requests.jsonPatchPermissionsRequest(path, permissions, "add", {
last_modified: last_modified,
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context6.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 7:
case "end":
return _context6.stop();
}
}
}, _callee6, this);
}));
return function addPermissions(_x3) {
return _addPermissions.apply(this, arguments);
};
}()
/**
* Remove principals from the collection permissions.
*
* @param {Object} permissions The permissions object.
* @param {Object} [options={}] The options object
* @param {Boolean} [options.safe] The safe option.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Object} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "removePermissions",
value: function () {
var _removePermissions = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee7(permissions) {
var options,
path,
last_modified,
request,
_args7 = arguments;
return _regenerator.default.wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
options = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {};
if ((0, _utils.isObject)(permissions)) {
_context7.next = 3;
break;
}
throw new Error("A permissions object is required.");
case 3:
path = (0, _endpoint.default)("collection", this.bucket.name, this.name);
last_modified = options.last_modified;
request = requests.jsonPatchPermissionsRequest(path, permissions, "remove", {
last_modified: last_modified,
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context7.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 7:
case "end":
return _context7.stop();
}
}
}, _callee7, this);
}));
return function removePermissions(_x4) {
return _removePermissions.apply(this, arguments);
};
}()
/**
* Creates a record in current collection.
*
* @param {Object} record The record to create.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Boolean} [options.safe] The safe option.
* @param {Object} [options.permissions] The permissions option.
* @return {Promise<Object, Error>}
*/
}, {
key: "createRecord",
value: function () {
var _createRecord = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee8(record) {
var options,
permissions,
path,
request,
_args8 = arguments;
return _regenerator.default.wrap(function _callee8$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
options = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {};
permissions = options.permissions;
path = (0, _endpoint.default)("record", this.bucket.name, this.name, record.id);
request = requests.createRequest(path, {
data: record,
permissions: permissions
}, {
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context8.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 5:
case "end":
return _context8.stop();
}
}
}, _callee8, this);
}));
return function createRecord(_x5) {
return _createRecord.apply(this, arguments);
};
}()
/**
* Adds an attachment to a record, creating the record when it doesn't exist.
*
* @param {String} dataURL The data url.
* @param {Object} [record={}] The record data.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.last_modified] The last_modified option.
* @param {Object} [options.permissions] The permissions option.
* @param {String} [options.filename] Force the attachment filename.
* @param {String} [options.gzipped] Force the attachment to be gzipped or not.
* @return {Promise<Object, Error>}
*/
}, {
key: "addAttachment",
value: function () {
var _addAttachment = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee9(dataURI) {
var record,
options,
permissions,
id,
path,
_record$options,
last_modified,
addAttachmentRequest,
_args9 = arguments;
return _regenerator.default.wrap(function _callee9$(_context9) {
while (1) {
switch (_context9.prev = _context9.next) {
case 0:
record = _args9.length > 1 && _args9[1] !== undefined ? _args9[1] : {};
options = _args9.length > 2 && _args9[2] !== undefined ? _args9[2] : {};
permissions = options.permissions;
id = record.id || _uuid.v4.v4();
path = (0, _endpoint.default)("attachment", this.bucket.name, this.name, id);
_record$options = (0, _objectSpread2.default)({}, record, options), last_modified = _record$options.last_modified;
addAttachmentRequest = requests.addAttachmentRequest(path, dataURI, {
data: record,
permissions: permissions
}, {
last_modified: last_modified,
filename: options.filename,
gzipped: options.gzipped,
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
_context9.next = 9;
return this.client.execute(addAttachmentRequest, {
stringify: false,
retry: this._getRetry(options)
});
case 9:
return _context9.abrupt("return", this.getRecord(id));
case 10:
case "end":
return _context9.stop();
}
}
}, _callee9, this);
}));
return function addAttachment(_x6) {
return _addAttachment.apply(this, arguments);
};
}()
/**
* Removes an attachment from a given record.
*
* @param {Object} recordId The record id.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.last_modified] The last_modified option.
*/
}, {
key: "removeAttachment",
value: function () {
var _removeAttachment = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee10(recordId) {
var options,
last_modified,
path,
request,
_args10 = arguments;
return _regenerator.default.wrap(function _callee10$(_context10) {
while (1) {
switch (_context10.prev = _context10.next) {
case 0:
options = _args10.length > 1 && _args10[1] !== undefined ? _args10[1] : {};
last_modified = options.last_modified;
path = (0, _endpoint.default)("attachment", this.bucket.name, this.name, recordId);
request = requests.deleteRequest(path, {
last_modified: last_modified,
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context10.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 5:
case "end":
return _context10.stop();
}
}
}, _callee10, this);
}));
return function removeAttachment(_x7) {
return _removeAttachment.apply(this, arguments);
};
}()
/**
* Updates a record in current collection.
*
* @param {Object} record The record to update.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.last_modified] The last_modified option.
* @param {Object} [options.permissions] The permissions option.
* @return {Promise<Object, Error>}
*/
}, {
key: "updateRecord",
value: function () {
var _updateRecord = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee11(record) {
var options,
permissions,
_record$options2,
last_modified,
path,
request,
_args11 = arguments;
return _regenerator.default.wrap(function _callee11$(_context11) {
while (1) {
switch (_context11.prev = _context11.next) {
case 0:
options = _args11.length > 1 && _args11[1] !== undefined ? _args11[1] : {};
if ((0, _utils.isObject)(record)) {
_context11.next = 3;
break;
}
throw new Error("A record object is required.");
case 3:
if (record.id) {
_context11.next = 5;
break;
}
throw new Error("A record id is required.");
case 5:
permissions = options.permissions;
_record$options2 = (0, _objectSpread2.default)({}, record, options), last_modified = _record$options2.last_modified;
path = (0, _endpoint.default)("record", this.bucket.name, this.name, record.id);
request = requests.updateRequest(path, {
data: record,
permissions: permissions
}, {
headers: this._getHeaders(options),
safe: this._getSafe(options),
last_modified: last_modified,
patch: !!options.patch
});
return _context11.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 10:
case "end":
return _context11.stop();
}
}
}, _callee11, this);
}));
return function updateRecord(_x8) {
return _updateRecord.apply(this, arguments);
};
}()
/**
* Deletes a record from the current collection.
*
* @param {Object|String} record The record to delete.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.last_modified] The last_modified option.
* @return {Promise<Object, Error>}
*/
}, {
key: "deleteRecord",
value: function () {
var _deleteRecord = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee12(record) {
var options,
recordObj,
id,
_recordObj$options,
last_modified,
path,
request,
_args12 = arguments;
return _regenerator.default.wrap(function _callee12$(_context12) {
while (1) {
switch (_context12.prev = _context12.next) {
case 0:
options = _args12.length > 1 && _args12[1] !== undefined ? _args12[1] : {};
recordObj = (0, _utils.toDataBody)(record);
if (recordObj.id) {
_context12.next = 4;
break;
}
throw new Error("A record id is required.");
case 4:
id = recordObj.id;
_recordObj$options = (0, _objectSpread2.default)({}, recordObj, options), last_modified = _recordObj$options.last_modified;
path = (0, _endpoint.default)("record", this.bucket.name, this.name, id);
request = requests.deleteRequest(path, {
last_modified: last_modified,
headers: this._getHeaders(options),
safe: this._getSafe(options)
});
return _context12.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 9:
case "end":
return _context12.stop();
}
}
}, _callee12, this);
}));
return function deleteRecord(_x9) {
return _deleteRecord.apply(this, arguments);
};
}()
/**
* Retrieves a record from the current collection.
*
* @param {String} id The record id to retrieve.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @return {Promise<Object, Error>}
*/
}, {
key: "getRecord",
value: function () {
var _getRecord = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee13(id) {
var options,
path,
request,
_args13 = arguments;
return _regenerator.default.wrap(function _callee13$(_context13) {
while (1) {
switch (_context13.prev = _context13.next) {
case 0:
options = _args13.length > 1 && _args13[1] !== undefined ? _args13[1] : {};
path = (0, _endpoint.default)("record", this.bucket.name, this.name, id);
request = {
headers: this._getHeaders(options),
path: path
};
return _context13.abrupt("return", this.client.execute(request, {
retry: this._getRetry(options)
}));
case 4:
case "end":
return _context13.stop();
}
}
}, _callee13, this);
}));
return function getRecord(_x10) {
return _getRecord.apply(this, arguments);
};
}()
/**
* Lists records from the current collection.
*
* Sorting is done by passing a `sort` string option:
*
* - The field to order the results by, prefixed with `-` for descending.
* Default: `-last_modified`.
*
* @see http://kinto.readthedocs.io/en/stable/api/1.x/sorting.html
*
* Filtering is done by passing a `filters` option object:
*
* - `{fieldname: "value"}`
* - `{min_fieldname: 4000}`
* - `{in_fieldname: "1,2,3"}`
* - `{not_fieldname: 0}`
* - `{exclude_fieldname: "0,1"}`
*
* @see http://kinto.readthedocs.io/en/stable/api/1.x/filtering.html
*
* Paginating is done by passing a `limit` option, then calling the `next()`
* method from the resolved result object to fetch the next page, if any.
*
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Number} [options.retry=0] Number of retries to make
* when faced with transient errors.
* @param {Object} [options.filters=[]] The filters object.
* @param {String} [options.sort="-last_modified"] The sort field.
* @param {String} [options.at] The timestamp to get a snapshot at.
* @param {String} [options.limit=null] The limit field.
* @param {String} [options.pages=1] The number of result pages to aggregate.
* @param {Number} [options.since=null] Only retrieve records modified since the provided timestamp.
* @return {Promise<Object, Error>}
*/
}, {
key: "listRecords",
value: function () {
var _listRecords = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee14() {
var options,
path,
_args14 = arguments;
return _regenerator.default.wrap(function _callee14$(_context14) {
while (1) {
switch (_context14.prev = _context14.next) {
case 0:
options = _args14.length > 0 && _args14[0] !== undefined ? _args14[0] : {};
path = (0, _endpoint.default)("record", this.bucket.name, this.name);
if (!options.hasOwnProperty("at")) {
_context14.next = 6;
break;
}
return _context14.abrupt("return", this.getSnapshot(options.at));
case 6:
return _context14.abrupt("return", this.client.paginatedList(path, options, {
headers: this._getHeaders(options),
retry: this._getRetry(options)
}));
case 7:
case "end":
return _context14.stop();
}
}
}, _callee14, this);
}));
return function listRecords() {
return _listRecords.apply(this, arguments);
};
}()
/**
* @private
*/
}, {
key: "isHistoryComplete",
value: function () {
var _isHistoryComplete = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee15() {
var _ref4, _ref4$data, oldestHistoryEntry;
return _regenerator.default.wrap(function _callee15$(_context15) {
while (1) {
switch (_context15.prev = _context15.next) {
case 0:
_context15.next = 2;
return this.bucket.listHistory({
limit: 1,
filters: {
action: "create",
resource_name: "collection",
collection_id: this.name
}
});
case 2:
_ref4 = _context15.sent;
_ref4$data = (0, _slicedToArray2.default)(_ref4.data, 1);
oldestHistoryEntry = _ref4$data[0];
return _context15.abrupt("return", !!oldestHistoryEntry);
case 6:
case "end":
return _context15.stop();
}
}
}, _callee15, this);
}));
return function isHistoryComplete() {
return _isHistoryComplete.apply(this, arguments);
};
}()
/**
* @private
*/
}, {
key: "listChangesBackTo",
value: function () {
var _listChangesBackTo = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee16(at) {
var _ref5, changes;
return _regenerator.default.wrap(function _callee16$(_context16) {
while (1) {
switch (_context16.prev = _context16.next) {
case 0:
_context16.next = 2;
return this.isHistoryComplete();
case 2:
if (_context16.sent) {
_context16.next = 4;
break;
}
throw new Error("Computing a snapshot is only possible when the full history for a " + "collection is available. Here, the history plugin seems to have " + "been enabled after the creation of the collection.");
case 4:
_context16.next = 6;
return this.bucket.listHistory({
pages: Infinity,
// all pages up to target timestamp are required
sort: "-target.data.last_modified",
filters: {
resource_name: "record",
collection_id: this.name,
"max_target.data.last_modified": String(at) // eq. to <=
}
});
case 6:
_ref5 = _context16.sent;
changes = _ref5.data;
return _context16.abrupt("return", changes);
case 9:
case "end":
return _context16.stop();
}
}
}, _callee16, this);
}));
return function listChangesBackTo(_x11) {
return _listChangesBackTo.apply(this, arguments);
};
}()
/**
* @private
*/
}, {
key: "getSnapshot",
value: function () {
var _getSnapshot = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee17(at) {
var changes, seenIds, snapshot, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _loop, _iterator, _step;
return _regenerator.default.wrap(function _callee17$(_context17) {
while (1) {
switch (_context17.prev = _context17.next) {
case 0:
if (!(!Number.isInteger(at) || at <= 0)) {
_context17.next = 2;
break;
}
throw new Error("Invalid argument, expected a positive integer.");
case 2:
_context17.next = 4;
return this.listChangesBackTo(at);
case 4:
changes = _context17.sent;
// Replay changes to compute the requested snapshot.
seenIds = new Set();
snapshot = [];
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context17.prev = 10;
_loop = function _loop() {
var _ref6 = _step.value;
var action = _ref6.action,
record = _ref6.target.data;
if (action == "delete") {
seenIds.add(record.id); // ensure not reprocessing deleted entries
snapshot = snapshot.filter(function (r) {
return r.id !== record.id;
});
} else if (!seenIds.has(record.id)) {
seenIds.add(record.id);
snapshot.push(record);
}
};
for (_iterator = changes[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
_loop();
}
_context17.next = 19;
break;
case 15:
_context17.prev = 15;
_context17.t0 = _context17["catch"](10);
_didIteratorError = true;
_iteratorError = _context17.t0;
case 19:
_context17.prev = 19;
_context17.prev = 20;
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
case 22:
_context17.prev = 22;
if (!_didIteratorError) {
_context17.next = 25;
break;
}
throw _iteratorError;
case 25:
return _context17.finish(22);
case 26:
return _context17.finish(19);
case 27:
return _context17.abrupt("return", {
last_modified: String(at),
data: snapshot.sort(function (a, b) {
return b.last_modified - a.last_modified;
}),
next: function next() {
throw new Error("Snapshots don't support pagination");
},
hasNextPage: false,
totalRecords: snapshot.length
});
case 28:
case "end":
return _context17.stop();
}
}
}, _callee17, this, [[10, 15, 19, 27], [20,, 22, 26]]);
}));
return function getSnapshot(_x12) {
return _getSnapshot.apply(this, arguments);
};
}()
/**
* Performs batch operations at the current collection level.
*
* @param {Function} fn The batch operation function.
* @param {Object} [options={}] The options object.
* @param {Object} [options.headers] The headers object option.
* @param {Boolean} [options.safe] The safe option.
* @param {Number} [options.retry] The retry option.
* @param {Boolean} [options.aggregate] Produces a grouped result object.
* @return {Promise<Object, Error>}
*/
}, {
key: "batch",
value: function () {
var _batch = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee18(fn) {
var options,
_args18 = arguments;
return _regenerator.default.wrap(function _callee18$(_context18) {
while (1) {
switch (_context18.prev = _context18.next) {
case 0:
options = _args18.length > 1 && _args18[1] !== undefined ? _args18[1] : {};
return _context18.abrupt("return", this.client.batch(fn, {
bucket: this.bucket.name,
collection: this.name,
headers: this._getHeaders(options),
retry: this._getRetry(options),
safe: this._getSafe(options),
aggregate: !!options.aggregate
}));
case 2:
case "end":
return _context18.stop();
}
}
}, _callee18, this);
}));
return function batch(_x13) {
return _batch.apply(this, arguments);
};
}()
}]);
return Collection;
}(), ((0, _applyDecoratedDescriptor2.default)(_class.prototype, "addAttachment", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "addAttachment"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "removeAttachment", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "removeAttachment"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "getSnapshot", [_dec3], Object.getOwnPropertyDescriptor(_class.prototype, "getSnapshot"), _class.prototype)), _class));
exports.default = Collection;
},{"./endpoint":311,"./requests":315,"./utils":316,"@babel/runtime/helpers/applyDecoratedDescriptor":277,"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/interopRequireWildcard":289,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/slicedToArray":298,"@babel/runtime/regenerator":305,"uuid":317}],311:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = endpoint;
/**
* Endpoints templates.
* @type {Object}
*/
var ENDPOINTS = {
root: function root() {
return "/";
},
batch: function batch() {
return "/batch";
},
permissions: function permissions() {
return "/permissions";
},
bucket: function bucket(_bucket) {
return "/buckets" + (_bucket ? "/".concat(_bucket) : "");
},
history: function history(bucket) {
return "".concat(ENDPOINTS.bucket(bucket), "/history");
},
collection: function collection(bucket, coll) {
return "".concat(ENDPOINTS.bucket(bucket), "/collections") + (coll ? "/".concat(coll) : "");
},
group: function group(bucket, _group) {
return "".concat(ENDPOINTS.bucket(bucket), "/groups") + (_group ? "/".concat(_group) : "");
},
record: function record(bucket, coll, id) {
return "".concat(ENDPOINTS.collection(bucket, coll), "/records") + (id ? "/".concat(id) : "");
},
attachment: function attachment(bucket, coll, id) {
return "".concat(ENDPOINTS.record(bucket, coll, id), "/attachment");
}
};
/**
* Retrieves a server enpoint by its name.
*
* @private
* @param {String} name The endpoint name.
* @param {...string} args The endpoint parameters.
* @return {String}
*/
function endpoint(name) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
return ENDPOINTS[name].apply(ENDPOINTS, args);
}
},{}],312:[function(require,module,exports){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.UnparseableResponseError = exports.ServerResponse = exports.NetworkTimeoutError = exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
function _extendableBuiltin5(cls) {
function ExtendableBuiltin() {
var instance = Reflect.construct(cls, Array.from(arguments));
Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
return instance;
}
ExtendableBuiltin.prototype = Object.create(cls.prototype, {
constructor: {
value: cls,
enumerable: false,
writable: true,
configurable: true
}
});
if (Object.setPrototypeOf) {
Object.setPrototypeOf(ExtendableBuiltin, cls);
} else {
ExtendableBuiltin.__proto__ = cls;
}
return ExtendableBuiltin;
}
function _extendableBuiltin3(cls) {
function ExtendableBuiltin() {
var instance = Reflect.construct(cls, Array.from(arguments));
Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
return instance;
}
ExtendableBuiltin.prototype = Object.create(cls.prototype, {
constructor: {
value: cls,
enumerable: false,
writable: true,
configurable: true
}
});
if (Object.setPrototypeOf) {
Object.setPrototypeOf(ExtendableBuiltin, cls);
} else {
ExtendableBuiltin.__proto__ = cls;
}
return ExtendableBuiltin;
}
function _extendableBuiltin(cls) {
function ExtendableBuiltin() {
var instance = Reflect.construct(cls, Array.from(arguments));
Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
return instance;
}
ExtendableBuiltin.prototype = Object.create(cls.prototype, {
constructor: {
value: cls,
enumerable: false,
writable: true,
configurable: true
}
});
if (Object.setPrototypeOf) {
Object.setPrototypeOf(ExtendableBuiltin, cls);
} else {
ExtendableBuiltin.__proto__ = cls;
}
return ExtendableBuiltin;
}
/**
* Kinto server error code descriptors.
* @type {Object}
*/
var ERROR_CODES = {
104: "Missing Authorization Token",
105: "Invalid Authorization Token",
106: "Request body was not valid JSON",
107: "Invalid request parameter",
108: "Missing request parameter",
109: "Invalid posted data",
110: "Invalid Token / id",
111: "Missing Token / id",
112: "Content-Length header was not provided",
113: "Request body too large",
114: "Resource was created, updated or deleted meanwhile",
115: "Method not allowed on this end point (hint: server may be readonly)",
116: "Requested version not available on this server",
117: "Client has sent too many requests",
121: "Resource access is forbidden for this user",
122: "Another resource violates constraint",
201: "Service Temporary unavailable due to high load",
202: "Service deprecated",
999: "Internal Server Error"
};
var _default = ERROR_CODES;
exports.default = _default;
var NetworkTimeoutError =
/*#__PURE__*/
function (_extendableBuiltin2) {
(0, _inherits2.default)(NetworkTimeoutError, _extendableBuiltin2);
function NetworkTimeoutError(url, options) {
var _this;
(0, _classCallCheck2.default)(this, NetworkTimeoutError);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(NetworkTimeoutError).call(this, "Timeout while trying to access ".concat(url, " with ").concat(JSON.stringify(options))));
if (Error.captureStackTrace) {
Error.captureStackTrace((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), NetworkTimeoutError);
}
_this.url = url;
_this.options = options;
return _this;
}
return NetworkTimeoutError;
}(_extendableBuiltin(Error));
exports.NetworkTimeoutError = NetworkTimeoutError;
var UnparseableResponseError =
/*#__PURE__*/
function (_extendableBuiltin4) {
(0, _inherits2.default)(UnparseableResponseError, _extendableBuiltin4);
function UnparseableResponseError(response, body, error) {
var _this2;
(0, _classCallCheck2.default)(this, UnparseableResponseError);
var status = response.status;
_this2 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(UnparseableResponseError).call(this, "Response from server unparseable (HTTP ".concat(status || 0, "; ").concat(error, "): ").concat(body)));
if (Error.captureStackTrace) {
Error.captureStackTrace((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this2)), UnparseableResponseError);
}
_this2.status = status;
_this2.response = response;
_this2.stack = error.stack;
_this2.error = error;
return _this2;
}
return UnparseableResponseError;
}(_extendableBuiltin3(Error));
/**
* "Error" subclass representing a >=400 response from the server.
*
* Whether or not this is an error depends on your application.
*
* The `json` field can be undefined if the server responded with an
* empty response body. This shouldn't generally happen. Most "bad"
* responses come with a JSON error description, or (if they're
* fronted by a CDN or nginx or something) occasionally non-JSON
* responses (which become UnparseableResponseErrors, above).
*/
exports.UnparseableResponseError = UnparseableResponseError;
var ServerResponse =
/*#__PURE__*/
function (_extendableBuiltin6) {
(0, _inherits2.default)(ServerResponse, _extendableBuiltin6);
function ServerResponse(response, json) {
var _this3;
(0, _classCallCheck2.default)(this, ServerResponse);
var status = response.status;
var statusText = response.statusText;
var errnoMsg;
if (json) {
// Try to fill in information from the JSON error.
statusText = json.error || statusText; // Take errnoMsg from either ERROR_CODES or json.message.
if (json.errno && json.errno in ERROR_CODES) {
errnoMsg = ERROR_CODES[json.errno];
} else if (json.message) {
errnoMsg = json.message;
} // If we had both ERROR_CODES and json.message, and they differ,
// combine them.
if (errnoMsg && json.message && json.message !== errnoMsg) {
errnoMsg += " (".concat(json.message, ")");
}
}
var message = "HTTP ".concat(status, " ").concat(statusText);
if (errnoMsg) {
message += ": ".concat(errnoMsg);
}
_this3 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ServerResponse).call(this, message.trim()));
if (Error.captureStackTrace) {
Error.captureStackTrace((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this3)), ServerResponse);
}
_this3.response = response;
_this3.data = json;
return _this3;
}
return ServerResponse;
}(_extendableBuiltin5(Error));
exports.ServerResponse = ServerResponse;
},{"@babel/runtime/helpers/assertThisInitialized":280,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/getPrototypeOf":286,"@babel/runtime/helpers/inherits":287,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/possibleConstructorReturn":296}],313:[function(require,module,exports){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _utils = require("./utils");
var _errors = require("./errors");
/**
* Enhanced HTTP client for the Kinto protocol.
* @private
*/
var HTTP =
/*#__PURE__*/
function () {
(0, _createClass2.default)(HTTP, null, [{
key: "DEFAULT_REQUEST_HEADERS",
/**
* Default HTTP request headers applied to each outgoing request.
*
* @type {Object}
*/
get: function get() {
return {
Accept: "application/json",
"Content-Type": "application/json"
};
}
/**
* Default options.
*
* @type {Object}
*/
}, {
key: "defaultOptions",
get: function get() {
return {
timeout: null,
requestMode: "cors"
};
}
/**
* Constructor.
*
* @param {EventEmitter} events The event handler.
* @param {Object} [options={}} The options object.
* @param {Number} [options.timeout=null] The request timeout in ms, if any (default: `null`).
* @param {String} [options.requestMode="cors"] The HTTP request mode (default: `"cors"`).
*/
}]);
function HTTP(events) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _classCallCheck2.default)(this, HTTP);
// public properties
/**
* The event emitter instance.
* @type {EventEmitter}
*/
if (!events) {
throw new Error("No events handler provided");
}
this.events = events;
/**
* The request mode.
* @see https://fetch.spec.whatwg.org/#requestmode
* @type {String}
*/
this.requestMode = options.requestMode || HTTP.defaultOptions.requestMode;
/**
* The request timeout.
* @type {Number}
*/
this.timeout = options.timeout || HTTP.defaultOptions.timeout;
}
/**
* @private
*/
(0, _createClass2.default)(HTTP, [{
key: "timedFetch",
value: function timedFetch(url, options) {
var _this = this;
var hasTimedout = false;
return new Promise(function (resolve, reject) {
// Detect if a request has timed out.
var _timeoutId;
if (_this.timeout) {
_timeoutId = setTimeout(function () {
hasTimedout = true;
reject(new _errors.NetworkTimeoutError(url, options));
}, _this.timeout);
}
function proceedWithHandler(fn) {
return function (arg) {
if (!hasTimedout) {
if (_timeoutId) {
clearTimeout(_timeoutId);
}
fn(arg);
}
};
}
fetch(url, options).then(proceedWithHandler(resolve)).catch(proceedWithHandler(reject));
});
}
/**
* @private
*/
}, {
key: "processResponse",
value: function () {
var _processResponse = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee(response) {
var status, headers, text, json;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
status = response.status, headers = response.headers;
_context.next = 3;
return response.text();
case 3:
text = _context.sent;
if (!(text.length !== 0)) {
_context.next = 12;
break;
}
_context.prev = 5;
json = JSON.parse(text);
_context.next = 12;
break;
case 9:
_context.prev = 9;
_context.t0 = _context["catch"](5);
throw new _errors.UnparseableResponseError(response, text, _context.t0);
case 12:
if (!(status >= 400)) {
_context.next = 14;
break;
}
throw new _errors.ServerResponse(response, json);
case 14:
return _context.abrupt("return", {
status: status,
json: json,
headers: headers
});
case 15:
case "end":
return _context.stop();
}
}
}, _callee, this, [[5, 9]]);
}));
return function processResponse(_x) {
return _processResponse.apply(this, arguments);
};
}()
/**
* @private
*/
}, {
key: "retry",
value: function () {
var _retry = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2(url, retryAfter, request, options) {
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return (0, _utils.delay)(retryAfter);
case 2:
return _context2.abrupt("return", this.request(url, request, (0, _objectSpread2.default)({}, options, {
retry: options.retry - 1
})));
case 3:
case "end":
return _context2.stop();
}
}
}, _callee2, this);
}));
return function retry(_x2, _x3, _x4, _x5) {
return _retry.apply(this, arguments);
};
}()
/**
* Performs an HTTP request to the Kinto server.
*
* Resolves with an objet containing the following HTTP response properties:
* - `{Number} status` The HTTP status code.
* - `{Object} json` The JSON response body.
* - `{Headers} headers` The response headers object; see the ES6 fetch() spec.
*
* @param {String} url The URL.
* @param {Object} [request={}] The request object, passed to
* fetch() as its options object.
* @param {Object} [request.headers] The request headers object (default: {})
* @param {Object} [options={}] Options for making the
* request
* @param {Number} [options.retry] Number of retries (default: 0)
* @return {Promise}
*/
}, {
key: "request",
value: function () {
var _request2 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee3(url) {
var _request,
options,
response,
status,
headers,
retryAfter,
_args3 = arguments;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_request = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {
headers: {}
};
options = _args3.length > 2 && _args3[2] !== undefined ? _args3[2] : {
retry: 0
};
// Ensure default request headers are always set
_request.headers = (0, _objectSpread2.default)({}, HTTP.DEFAULT_REQUEST_HEADERS, _request.headers); // If a multipart body is provided, remove any custom Content-Type header as
// the fetch() implementation will add the correct one for us.
if (_request.body && typeof _request.body.append === "function") {
delete _request.headers["Content-Type"];
}
_request.mode = this.requestMode;
_context3.next = 7;
return this.timedFetch(url, _request);
case 7:
response = _context3.sent;
status = response.status, headers = response.headers;
this._checkForDeprecationHeader(headers);
this._checkForBackoffHeader(status, headers); // Check if the server summons the client to retry after a while.
retryAfter = this._checkForRetryAfterHeader(status, headers); // If number of allowed of retries is not exhausted, retry the same request.
if (!(retryAfter && options.retry > 0)) {
_context3.next = 16;
break;
}
return _context3.abrupt("return", this.retry(url, retryAfter, _request, options));
case 16:
return _context3.abrupt("return", this.processResponse(response));
case 17:
case "end":
return _context3.stop();
}
}
}, _callee3, this);
}));
return function request(_x6) {
return _request2.apply(this, arguments);
};
}()
}, {
key: "_checkForDeprecationHeader",
value: function _checkForDeprecationHeader(headers) {
var alertHeader = headers.get("Alert");
if (!alertHeader) {
return;
}
var alert;
try {
alert = JSON.parse(alertHeader);
} catch (err) {
console.warn("Unable to parse Alert header message", alertHeader);
return;
}
console.warn(alert.message, alert.url);
this.events.emit("deprecated", alert);
}
}, {
key: "_checkForBackoffHeader",
value: function _checkForBackoffHeader(status, headers) {
var backoffMs;
var backoffSeconds = parseInt(headers.get("Backoff"), 10);
if (backoffSeconds > 0) {
backoffMs = new Date().getTime() + backoffSeconds * 1000;
} else {
backoffMs = 0;
}
this.events.emit("backoff", backoffMs);
}
}, {
key: "_checkForRetryAfterHeader",
value: function _checkForRetryAfterHeader(status, headers) {
var retryAfter = headers.get("Retry-After");
if (!retryAfter) {
return;
}
var delay = parseInt(retryAfter, 10) * 1000;
retryAfter = new Date().getTime() + delay;
this.events.emit("retry-after", retryAfter);
return delay;
}
}]);
return HTTP;
}();
exports.default = HTTP;
},{"./errors":312,"./utils":316,"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/regenerator":305}],314:[function(require,module,exports){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _events = require("events");
var _base = _interopRequireDefault(require("./base"));
var KintoClient =
/*#__PURE__*/
function (_KintoClientBase) {
(0, _inherits2.default)(KintoClient, _KintoClientBase);
function KintoClient(remote) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _classCallCheck2.default)(this, KintoClient);
var events = options.events || new _events.EventEmitter();
return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(KintoClient).call(this, remote, Object.assign({
events: events
}, options)));
}
return KintoClient;
}(_base.default); // This is a hack to avoid Browserify to expose the above class
// at `new KintoClient()` instead of `new KintoClient.default()`.
// See https://github.com/Kinto/kinto-http.js/issues/77
exports.default = KintoClient;
if ((typeof module === "undefined" ? "undefined" : (0, _typeof2.default)(module)) === "object") {
module.exports = KintoClient;
}
},{"./base":307,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/getPrototypeOf":286,"@babel/runtime/helpers/inherits":287,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/possibleConstructorReturn":296,"@babel/runtime/helpers/typeof":301,"events":306}],315:[function(require,module,exports){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createRequest = createRequest;
exports.updateRequest = updateRequest;
exports.jsonPatchPermissionsRequest = jsonPatchPermissionsRequest;
exports.deleteRequest = deleteRequest;
exports.addAttachmentRequest = addAttachmentRequest;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _utils = require("./utils");
var requestDefaults = {
safe: false,
// check if we should set default content type here
headers: {},
permissions: undefined,
data: undefined,
patch: false
};
/**
* @private
*/
function safeHeader(safe, last_modified) {
if (!safe) {
return {};
}
if (last_modified) {
return {
"If-Match": "\"".concat(last_modified, "\"")
};
}
return {
"If-None-Match": "*"
};
}
/**
* @private
*/
function createRequest(path, _ref) {
var data = _ref.data,
permissions = _ref.permissions;
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var _requestDefaults$opti = (0, _objectSpread2.default)({}, requestDefaults, options),
headers = _requestDefaults$opti.headers,
safe = _requestDefaults$opti.safe;
return {
method: data && data.id ? "PUT" : "POST",
path: path,
headers: (0, _objectSpread2.default)({}, headers, safeHeader(safe)),
body: {
data: data,
permissions: permissions
}
};
}
/**
* @private
*/
function updateRequest(path, _ref2) {
var data = _ref2.data,
permissions = _ref2.permissions;
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var _requestDefaults$opti2 = (0, _objectSpread2.default)({}, requestDefaults, options),
headers = _requestDefaults$opti2.headers,
safe = _requestDefaults$opti2.safe,
patch = _requestDefaults$opti2.patch;
var _data$options = (0, _objectSpread2.default)({}, data, options),
last_modified = _data$options.last_modified;
if (Object.keys((0, _utils.omit)(data, "id", "last_modified")).length === 0) {
data = undefined;
}
return {
method: patch ? "PATCH" : "PUT",
path: path,
headers: (0, _objectSpread2.default)({}, headers, safeHeader(safe, last_modified)),
body: {
data: data,
permissions: permissions
}
};
}
/**
* @private
*/
function jsonPatchPermissionsRequest(path, permissions, opType) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var _requestDefaults$opti3 = (0, _objectSpread2.default)({}, requestDefaults, options),
headers = _requestDefaults$opti3.headers,
safe = _requestDefaults$opti3.safe,
last_modified = _requestDefaults$opti3.last_modified;
var ops = [];
var _arr = Object.entries(permissions);
for (var _i = 0; _i < _arr.length; _i++) {
var _arr$_i = (0, _slicedToArray2.default)(_arr[_i], 2),
type = _arr$_i[0],
principals = _arr$_i[1];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = principals[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var principal = _step.value;
ops.push({
op: opType,
path: "/permissions/".concat(type, "/").concat(principal)
});
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
return {
method: "PATCH",
path: path,
headers: (0, _objectSpread2.default)({}, headers, safeHeader(safe, last_modified), {
"Content-Type": "application/json-patch+json"
}),
body: ops
};
}
/**
* @private
*/
function deleteRequest(path) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var _requestDefaults$opti4 = (0, _objectSpread2.default)({}, requestDefaults, options),
headers = _requestDefaults$opti4.headers,
safe = _requestDefaults$opti4.safe,
last_modified = _requestDefaults$opti4.last_modified;
if (safe && !last_modified) {
throw new Error("Safe concurrency check requires a last_modified value.");
}
return {
method: "DELETE",
path: path,
headers: (0, _objectSpread2.default)({}, headers, safeHeader(safe, last_modified))
};
}
/**
* @private
*/
function addAttachmentRequest(path, dataURI) {
var _ref3 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
data = _ref3.data,
permissions = _ref3.permissions;
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var _requestDefaults$opti5 = (0, _objectSpread2.default)({}, requestDefaults, options),
headers = _requestDefaults$opti5.headers,
safe = _requestDefaults$opti5.safe,
gzipped = _requestDefaults$opti5.gzipped;
var _data$options2 = (0, _objectSpread2.default)({}, data, options),
last_modified = _data$options2.last_modified;
var body = {
data: data,
permissions: permissions
};
var formData = (0, _utils.createFormData)(dataURI, body, options);
var customPath = gzipped != null ? customPath = path + "?gzipped=" + (gzipped ? "true" : "false") : path;
return {
method: "POST",
path: customPath,
headers: (0, _objectSpread2.default)({}, headers, safeHeader(safe, last_modified)),
body: formData
};
}
},{"./utils":316,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/slicedToArray":298}],316:[function(require,module,exports){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.partition = partition;
exports.delay = delay;
exports.pMap = pMap;
exports.omit = omit;
exports.toDataBody = toDataBody;
exports.qsify = qsify;
exports.checkVersion = checkVersion;
exports.support = support;
exports.capable = capable;
exports.nobatch = nobatch;
exports.isObject = isObject;
exports.parseDataURL = parseDataURL;
exports.extractFileInfo = extractFileInfo;
exports.createFormData = createFormData;
exports.cleanUndefinedProperties = cleanUndefinedProperties;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _objectSpread3 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _toArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
/**
* Chunks an array into n pieces.
*
* @private
* @param {Array} array
* @param {Number} n
* @return {Array}
*/
function partition(array, n) {
if (n <= 0) {
return array;
}
return array.reduce(function (acc, x, i) {
if (i === 0 || i % n === 0) {
acc.push([x]);
} else {
acc[acc.length - 1].push(x);
}
return acc;
}, []);
}
/**
* Returns a Promise always resolving after the specified amount in milliseconds.
*
* @return Promise<void>
*/
function delay(ms) {
return new Promise(function (resolve) {
return setTimeout(resolve, ms);
});
}
/**
* Maps a list to promises using the provided mapping function, executes them
* sequentially then returns a Promise resolving with ordered results obtained.
* Think of this as a sequential Promise.all.
*
* @private
* @param {Array} list The list to map.
* @param {Function} fn The mapping function.
* @return {Promise}
*/
function pMap(_x, _x2) {
return _pMap.apply(this, arguments);
}
/**
* Takes an object and returns a copy of it with the provided keys omitted.
*
* @private
* @param {Object} obj The source object.
* @param {...String} keys The keys to omit.
* @return {Object}
*/
function _pMap() {
_pMap = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2(list, fn) {
var results;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
results = [];
_context2.next = 3;
return list.reduce(
/*#__PURE__*/
function () {
var _ref = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee(promise, entry) {
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return promise;
case 2:
_context.t0 = results;
_context.next = 5;
return fn(entry);
case 5:
_context.t1 = _context.sent;
results = _context.t0.concat.call(_context.t0, _context.t1);
case 7:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
return function (_x3, _x4) {
return _ref.apply(this, arguments);
};
}(), Promise.resolve());
case 3:
return _context2.abrupt("return", results);
case 4:
case "end":
return _context2.stop();
}
}
}, _callee2, this);
}));
return _pMap.apply(this, arguments);
}
function omit(obj) {
for (var _len = arguments.length, keys = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
keys[_key - 1] = arguments[_key];
}
return Object.keys(obj).reduce(function (acc, key) {
if (!keys.includes(key)) {
acc[key] = obj[key];
}
return acc;
}, {});
}
/**
* Always returns a resource data object from the provided argument.
*
* @private
* @param {Object|String} resource
* @return {Object}
*/
function toDataBody(resource) {
if (isObject(resource)) {
return resource;
}
if (typeof resource === "string") {
return {
id: resource
};
}
throw new Error("Invalid argument.");
}
/**
* Transforms an object into an URL query string, stripping out any undefined
* values.
*
* @param {Object} obj
* @return {String}
*/
function qsify(obj) {
var encode = function encode(v) {
return encodeURIComponent(typeof v === "boolean" ? String(v) : v);
};
var stripUndefined = function stripUndefined(o) {
return JSON.parse(JSON.stringify(o));
};
var stripped = stripUndefined(obj);
return Object.keys(stripped).map(function (k) {
var ks = encode(k) + "=";
if (Array.isArray(stripped[k])) {
return ks + stripped[k].map(function (v) {
return encode(v);
}).join(",");
} else {
return ks + encode(stripped[k]);
}
}).join("&");
}
/**
* Checks if a version is within the provided range.
*
* @param {String} version The version to check.
* @param {String} minVersion The minimum supported version (inclusive).
* @param {String} maxVersion The minimum supported version (exclusive).
* @throws {Error} If the version is outside of the provided range.
*/
function checkVersion(version, minVersion, maxVersion) {
var extract = function extract(str) {
return str.split(".").map(function (x) {
return parseInt(x, 10);
});
};
var _extract = extract(version),
_extract2 = (0, _slicedToArray2.default)(_extract, 2),
verMajor = _extract2[0],
verMinor = _extract2[1];
var _extract3 = extract(minVersion),
_extract4 = (0, _slicedToArray2.default)(_extract3, 2),
minMajor = _extract4[0],
minMinor = _extract4[1];
var _extract5 = extract(maxVersion),
_extract6 = (0, _slicedToArray2.default)(_extract5, 2),
maxMajor = _extract6[0],
maxMinor = _extract6[1];
var checks = [verMajor < minMajor, verMajor === minMajor && verMinor < minMinor, verMajor > maxMajor, verMajor === maxMajor && verMinor >= maxMinor];
if (checks.some(function (x) {
return x;
})) {
throw new Error("Version ".concat(version, " doesn't satisfy ").concat(minVersion, " <= x < ").concat(maxVersion));
}
}
/**
* Generates a decorator function ensuring a version check is performed against
* the provided requirements before executing it.
*
* @param {String} min The required min version (inclusive).
* @param {String} max The required max version (inclusive).
* @return {Function}
*/
function support(min, max) {
return function (target, key, descriptor) {
var fn = descriptor.value;
return {
configurable: true,
get: function get() {
var _this = this;
var wrappedMethod = function wrappedMethod() {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
// "this" is the current instance which its method is decorated.
var client = "client" in _this ? _this.client : _this;
return client.fetchHTTPApiVersion().then(function (version) {
return checkVersion(version, min, max);
}).then(function () {
return fn.apply(_this, args);
});
};
Object.defineProperty(this, key, {
value: wrappedMethod,
configurable: true,
writable: true
});
return wrappedMethod;
}
};
};
}
/**
* Generates a decorator function ensuring that the specified capabilities are
* available on the server before executing it.
*
* @param {Array<String>} capabilities The required capabilities.
* @return {Function}
*/
function capable(capabilities) {
return function (target, key, descriptor) {
var fn = descriptor.value;
return {
configurable: true,
get: function get() {
var _this2 = this;
var wrappedMethod = function wrappedMethod() {
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
// "this" is the current instance which its method is decorated.
var client = "client" in _this2 ? _this2.client : _this2;
return client.fetchServerCapabilities().then(function (available) {
var missing = capabilities.filter(function (c) {
return !(c in available);
});
if (missing.length > 0) {
var missingStr = missing.join(", ");
throw new Error("Required capabilities ".concat(missingStr, " not present on server"));
}
}).then(function () {
return fn.apply(_this2, args);
});
};
Object.defineProperty(this, key, {
value: wrappedMethod,
configurable: true,
writable: true
});
return wrappedMethod;
}
};
};
}
/**
* Generates a decorator function ensuring an operation is not performed from
* within a batch request.
*
* @param {String} message The error message to throw.
* @return {Function}
*/
function nobatch(message) {
return function (target, key, descriptor) {
var fn = descriptor.value;
return {
configurable: true,
get: function get() {
var _this3 = this;
var wrappedMethod = function wrappedMethod() {
// "this" is the current instance which its method is decorated.
if (_this3._isBatch) {
throw new Error(message);
}
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
args[_key4] = arguments[_key4];
}
return fn.apply(_this3, args);
};
Object.defineProperty(this, key, {
value: wrappedMethod,
configurable: true,
writable: true
});
return wrappedMethod;
}
};
};
}
/**
* Returns true if the specified value is an object (i.e. not an array nor null).
* @param {Object} thing The value to inspect.
* @return {bool}
*/
function isObject(thing) {
return (0, _typeof2.default)(thing) === "object" && thing !== null && !Array.isArray(thing);
}
/**
* Parses a data url.
* @param {String} dataURL The data url.
* @return {Object}
*/
function parseDataURL(dataURL) {
var regex = /^data:(.*);base64,(.*)/;
var match = dataURL.match(regex);
if (!match) {
throw new Error("Invalid data-url: ".concat(String(dataURL).substr(0, 32), "..."));
}
var props = match[1];
var base64 = match[2];
var _props$split = props.split(";"),
_props$split2 = (0, _toArray2.default)(_props$split),
type = _props$split2[0],
rawParams = _props$split2.slice(1);
var params = rawParams.reduce(function (acc, param) {
var _param$split = param.split("="),
_param$split2 = (0, _slicedToArray2.default)(_param$split, 2),
key = _param$split2[0],
value = _param$split2[1];
return (0, _objectSpread3.default)({}, acc, (0, _defineProperty2.default)({}, key, value));
}, {});
return (0, _objectSpread3.default)({}, params, {
type: type,
base64: base64
});
}
/**
* Extracts file information from a data url.
* @param {String} dataURL The data url.
* @return {Object}
*/
function extractFileInfo(dataURL) {
var _parseDataURL = parseDataURL(dataURL),
name = _parseDataURL.name,
type = _parseDataURL.type,
base64 = _parseDataURL.base64;
var binary = atob(base64);
var array = [];
for (var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
var blob = new Blob([new Uint8Array(array)], {
type: type
});
return {
blob: blob,
name: name
};
}
/**
* Creates a FormData instance from a data url and an existing JSON response
* body.
* @param {String} dataURL The data url.
* @param {Object} body The response body.
* @param {Object} [options={}] The options object.
* @param {Object} [options.filename] Force attachment file name.
* @return {FormData}
*/
function createFormData(dataURL, body) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var _options$filename = options.filename,
filename = _options$filename === void 0 ? "untitled" : _options$filename;
var _extractFileInfo = extractFileInfo(dataURL),
blob = _extractFileInfo.blob,
name = _extractFileInfo.name;
var formData = new FormData();
formData.append("attachment", blob, name || filename);
for (var property in body) {
if (typeof body[property] !== "undefined") {
formData.append(property, JSON.stringify(body[property]));
}
}
return formData;
}
/**
* Clones an object with all its undefined keys removed.
* @private
*/
function cleanUndefinedProperties(obj) {
var result = {};
for (var key in obj) {
if (typeof obj[key] !== "undefined") {
result[key] = obj[key];
}
}
return result;
}
},{"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/defineProperty":285,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/slicedToArray":298,"@babel/runtime/helpers/toArray":299,"@babel/runtime/helpers/typeof":301,"@babel/runtime/regenerator":305}],317:[function(require,module,exports){
var v1 = require('./v1');
var v4 = require('./v4');
var uuid = v4;
uuid.v1 = v1;
uuid.v4 = v4;
module.exports = uuid;
},{"./v1":320,"./v4":321}],318:[function(require,module,exports){
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
var byteToHex = [];
for (var i = 0; i < 256; ++i) {
byteToHex[i] = (i + 0x100).toString(16).substr(1);
}
function bytesToUuid(buf, offset) {
var i = offset || 0;
var bth = byteToHex;
// join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
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++]]]).join('');
}
module.exports = bytesToUuid;
},{}],319:[function(require,module,exports){
// Unique ID creation requires a high quality random # generator. In the
// browser this is a little complicated due to unknown quality of Math.random()
// and inconsistent support for the `crypto` API. We do the best we can via
// feature-detection
// getRandomValues needs to be invoked in a context where "this" is a Crypto
// implementation. Also, find the complete implementation of crypto on IE11.
var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||
(typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));
if (getRandomValues) {
// WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
module.exports = function whatwgRNG() {
getRandomValues(rnds8);
return rnds8;
};
} else {
// Math.random()-based (RNG)
//
// If all else fails, use Math.random(). It's fast, but is of unspecified
// quality.
var rnds = new Array(16);
module.exports = function mathRNG() {
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;
};
}
},{}],320:[function(require,module,exports){
var rng = require('./lib/rng');
var bytesToUuid = require('./lib/bytesToUuid');
// **`v1()` - Generate time-based UUID**
//
// Inspired by https://github.com/LiosK/UUID.js
// and http://docs.python.org/library/uuid.html
var _nodeId;
var _clockseq;
// Previous uuid creation time
var _lastMSecs = 0;
var _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 node = options.node || _nodeId;
var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;
// node and clockseq need to be initialized to random values if they're not
// specified. We do this lazily to minimize issues related to insufficient
// system entropy. See #189
if (node == null || clockseq == null) {
var seedBytes = rng();
if (node == null) {
// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
node = _nodeId = [
seedBytes[0] | 0x01,
seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]
];
}
if (clockseq == null) {
// Per 4.2.2, randomize (14 bit) clockseq
clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
}
}
// 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 !== undefined ? 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 !== undefined ? 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 === undefined) {
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 === undefined) {
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`
for (var n = 0; n < 6; ++n) {
b[i + n] = node[n];
}
return buf ? buf : bytesToUuid(b);
}
module.exports = v1;
},{"./lib/bytesToUuid":318,"./lib/rng":319}],321:[function(require,module,exports){
var rng = require('./lib/rng');
var bytesToUuid = require('./lib/bytesToUuid');
function v4(options, buf, offset) {
var i = buf && offset || 0;
if (typeof(options) == 'string') {
buf = options === 'binary' ? new Array(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 || bytesToUuid(rnds);
}
module.exports = v4;
},{"./lib/bytesToUuid":318,"./lib/rng":319}],322:[function(require,module,exports){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _collection = _interopRequireDefault(require("./collection"));
var _base = _interopRequireDefault(require("./adapters/base"));
var DEFAULT_BUCKET_NAME = "default";
var DEFAULT_REMOTE = "http://localhost:8888/v1";
var DEFAULT_RETRY = 1;
/**
* KintoBase class.
*/
var KintoBase =
/*#__PURE__*/
function () {
(0, _createClass2.default)(KintoBase, null, [{
key: "adapters",
/**
* Provides a public access to the base adapter class. Users can create a
* custom DB adapter by extending {@link BaseAdapter}.
*
* @type {Object}
*/
get: function get() {
return {
BaseAdapter: _base.default
};
}
/**
* Synchronization strategies. Available strategies are:
*
* - `MANUAL`: Conflicts will be reported in a dedicated array.
* - `SERVER_WINS`: Conflicts are resolved using remote data.
* - `CLIENT_WINS`: Conflicts are resolved using local data.
*
* @type {Object}
*/
}, {
key: "syncStrategy",
get: function get() {
return _collection.default.strategy;
}
/**
* Constructor.
*
* Options:
* - `{String}` `remote` The server URL to use.
* - `{String}` `bucket` The collection bucket name.
* - `{EventEmitter}` `events` Events handler.
* - `{BaseAdapter}` `adapter` The base DB adapter class.
* - `{Object}` `adapterOptions` Options given to the adapter.
* - `{Object}` `headers` The HTTP headers to use.
* - `{Object}` `retry` Number of retries when the server fails to process the request (default: `1`)
* - `{String}` `requestMode` The HTTP CORS mode to use.
* - `{Number}` `timeout` The requests timeout in ms (default: `5000`).
*
* @param {Object} options The options object.
*/
}]);
function KintoBase() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
(0, _classCallCheck2.default)(this, KintoBase);
var defaults = {
bucket: DEFAULT_BUCKET_NAME,
remote: DEFAULT_REMOTE,
retry: DEFAULT_RETRY
};
this._options = (0, _objectSpread2.default)({}, defaults, options);
if (!this._options.adapter) {
throw new Error("No adapter provided");
}
var _this$_options = this._options,
ApiClass = _this$_options.ApiClass,
events = _this$_options.events,
headers = _this$_options.headers,
remote = _this$_options.remote,
requestMode = _this$_options.requestMode,
retry = _this$_options.retry,
timeout = _this$_options.timeout; // public properties
/**
* The kinto HTTP client instance.
* @type {KintoClient}
*/
this.api = new ApiClass(remote, {
events: events,
headers: headers,
requestMode: requestMode,
retry: retry,
timeout: timeout
});
/**
* The event emitter instance.
* @type {EventEmitter}
*/
this.events = this._options.events;
}
/**
* Creates a {@link Collection} instance. The second (optional) parameter
* will set collection-level options like e.g. `remoteTransformers`.
*
* @param {String} collName The collection name.
* @param {Object} [options={}] Extra options or override client's options.
* @param {Object} [options.idSchema] IdSchema instance (default: UUID)
* @param {Object} [options.remoteTransformers] Array<RemoteTransformer> (default: `[]`])
* @param {Object} [options.hooks] Array<Hook> (default: `[]`])
* @param {Object} [options.localFields] Array<Field> (default: `[]`])
* @return {Collection}
*/
(0, _createClass2.default)(KintoBase, [{
key: "collection",
value: function collection(collName) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (!collName) {
throw new Error("missing collection name");
}
var _this$_options$option = (0, _objectSpread2.default)({}, this._options, options),
bucket = _this$_options$option.bucket,
events = _this$_options$option.events,
adapter = _this$_options$option.adapter,
adapterOptions = _this$_options$option.adapterOptions;
var idSchema = options.idSchema,
remoteTransformers = options.remoteTransformers,
hooks = options.hooks,
localFields = options.localFields;
return new _collection.default(bucket, collName, this.api, {
events: events,
adapter: adapter,
adapterOptions: adapterOptions,
idSchema: idSchema,
remoteTransformers: remoteTransformers,
hooks: hooks,
localFields: localFields
});
}
}]);
return KintoBase;
}();
exports.default = KintoBase;
},{"./adapters/base":324,"./collection":325,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295}],323:[function(require,module,exports){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.open = _open2;
exports.execute = execute;
exports.default = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _base = _interopRequireDefault(require("./base.js"));
var _utils = require("../utils");
var INDEXED_FIELDS = ["id", "_status", "last_modified"];
/**
* Small helper that wraps the opening of an IndexedDB into a Promise.
*
* @param dbname {String} The database name.
* @param version {Integer} Schema version
* @param onupgradeneeded {Function} The callback to execute if schema is
* missing or different.
* @return {Promise<IDBDatabase>}
*/
function _open2(_x, _x2) {
return _open.apply(this, arguments);
}
/**
* Helper to run the specified callback in a single transaction on the
* specified store.
* The helper focuses on transaction wrapping into a promise.
*
* @param db {IDBDatabase} The database instance.
* @param name {String} The store name.
* @param callback {Function} The piece of code to execute in the transaction.
* @param options {Object} Options.
* @param options.mode {String} Transaction mode (default: read).
* @return {Promise} any value returned by the callback.
*/
function _open() {
_open = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee13(dbname, _ref) {
var version, onupgradeneeded;
return _regenerator.default.wrap(function _callee13$(_context13) {
while (1) {
switch (_context13.prev = _context13.next) {
case 0:
version = _ref.version, onupgradeneeded = _ref.onupgradeneeded;
return _context13.abrupt("return", new Promise(function (resolve, reject) {
var request = indexedDB.open(dbname, version);
request.onupgradeneeded = function (event) {
var db = event.target.result;
db.onerror = function (event) {
return reject(event.target.error);
};
return onupgradeneeded(event);
};
request.onerror = function (event) {
reject(event.target.error);
};
request.onsuccess = function (event) {
var db = event.target.result;
resolve(db);
};
}));
case 2:
case "end":
return _context13.stop();
}
}
}, _callee13, this);
}));
return _open.apply(this, arguments);
}
function execute(_x3, _x4, _x5) {
return _execute.apply(this, arguments);
}
/**
* Helper to wrap the deletion of an IndexedDB database into a promise.
*
* @param dbName {String} the database to delete
* @return {Promise}
*/
function _execute() {
_execute = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee14(db, name, callback) {
var options,
mode,
_args14 = arguments;
return _regenerator.default.wrap(function _callee14$(_context14) {
while (1) {
switch (_context14.prev = _context14.next) {
case 0:
options = _args14.length > 3 && _args14[3] !== undefined ? _args14[3] : {};
mode = options.mode;
return _context14.abrupt("return", new Promise(function (resolve, reject) {
// On Safari, calling IDBDatabase.transaction with mode == undefined raises
// a TypeError.
var transaction = mode ? db.transaction([name], mode) : db.transaction([name]);
var store = transaction.objectStore(name); // Let the callback abort this transaction.
var abort = function abort(e) {
transaction.abort();
reject(e);
}; // Execute the specified callback **synchronously**.
var result;
try {
result = callback(store, abort);
} catch (e) {
abort(e);
}
transaction.onerror = function (event) {
return reject(event.target.error);
};
transaction.oncomplete = function (event) {
return resolve(result);
};
}));
case 3:
case "end":
return _context14.stop();
}
}
}, _callee14, this);
}));
return _execute.apply(this, arguments);
}
function deleteDatabase(_x6) {
return _deleteDatabase.apply(this, arguments);
}
/**
* IDB cursor handlers.
* @type {Object}
*/
function _deleteDatabase() {
_deleteDatabase = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee15(dbName) {
return _regenerator.default.wrap(function _callee15$(_context15) {
while (1) {
switch (_context15.prev = _context15.next) {
case 0:
return _context15.abrupt("return", new Promise(function (resolve, reject) {
var request = indexedDB.deleteDatabase(dbName);
request.onsuccess = function (event) {
return resolve(event.target);
};
request.onerror = function (event) {
return reject(event.target.error);
};
}));
case 1:
case "end":
return _context15.stop();
}
}
}, _callee15, this);
}));
return _deleteDatabase.apply(this, arguments);
}
var cursorHandlers = {
all: function all(filters, done) {
var results = [];
return function (event) {
var cursor = event.target.result;
if (cursor) {
var value = cursor.value;
if ((0, _utils.filterObject)(filters, value)) {
results.push(value);
}
cursor.continue();
} else {
done(results);
}
};
},
in: function _in(values, filters, done) {
var results = [];
var i = 0;
return function (event) {
var cursor = event.target.result;
if (!cursor) {
done(results);
return;
}
var key = cursor.key,
value = cursor.value; // `key` can be an array of two values (see `keyPath` in indices definitions).
// `values` can be an array of arrays if we filter using an index whose key path
// is an array (eg. `cursorHandlers.in([["bid/cid", 42], ["bid/cid", 43]], ...)`)
while (key > values[i]) {
// The cursor has passed beyond this key. Check next.
++i;
if (i === values.length) {
done(results); // There is no next. Stop searching.
return;
}
}
var isEqual = Array.isArray(key) ? (0, _utils.arrayEqual)(key, values[i]) : key === values[i];
if (isEqual) {
if ((0, _utils.filterObject)(filters, value)) {
results.push(value);
}
cursor.continue();
} else {
cursor.continue(values[i]);
}
};
}
};
/**
* Creates an IDB request and attach it the appropriate cursor event handler to
* perform a list query.
*
* Multiple matching values are handled by passing an array.
*
* @param {String} cid The collection id (ie. `{bid}/{cid}`)
* @param {IDBStore} store The IDB store.
* @param {Object} filters Filter the records by field.
* @param {Function} done The operation completion handler.
* @return {IDBRequest}
*/
function createListRequest(cid, store, filters, done) {
var filterFields = Object.keys(filters); // If no filters, get all results in one bulk.
if (filterFields.length == 0) {
var _request = store.index("cid").getAll(IDBKeyRange.only(cid));
_request.onsuccess = function (event) {
return done(event.target.result);
};
return _request;
} // Introspect filters and check if they leverage an indexed field.
var indexField = filterFields.find(function (field) {
return INDEXED_FIELDS.includes(field);
});
if (!indexField) {
// Iterate on all records for this collection (ie. cid)
var isSubQuery = Object.keys(filters).some(function (key) {
return key.includes(".");
}); // (ie. filters: {"article.title": "hello"})
if (isSubQuery) {
var newFilter = (0, _utils.transformSubObjectFilters)(filters);
var _request3 = store.index("cid").openCursor(IDBKeyRange.only(cid));
_request3.onsuccess = cursorHandlers.all(newFilter, done);
return _request3;
}
var _request2 = store.index("cid").openCursor(IDBKeyRange.only(cid));
_request2.onsuccess = cursorHandlers.all(filters, done);
return _request2;
} // If `indexField` was used already, don't filter again.
var remainingFilters = (0, _utils.omitKeys)(filters, [indexField]); // value specified in the filter (eg. `filters: { _status: ["created", "updated"] }`)
var value = filters[indexField]; // For the "id" field, use the primary key.
var indexStore = indexField == "id" ? store : store.index(indexField); // WHERE IN equivalent clause
if (Array.isArray(value)) {
if (value.length === 0) {
return done([]);
}
var values = value.map(function (i) {
return [cid, i];
}).sort();
var range = IDBKeyRange.bound(values[0], values[values.length - 1]);
var _request4 = indexStore.openCursor(range);
_request4.onsuccess = cursorHandlers.in(values, remainingFilters, done);
return _request4;
} // If no filters on custom attribute, get all results in one bulk.
if (remainingFilters.length == 0) {
var _request5 = indexStore.getAll(IDBKeyRange.only([cid, value]));
_request5.onsuccess = function (event) {
return done(event.target.result);
};
return _request5;
} // WHERE field = value clause
var request = indexStore.openCursor(IDBKeyRange.only([cid, value]));
request.onsuccess = cursorHandlers.all(remainingFilters, done);
return request;
}
/**
* IndexedDB adapter.
*
* This adapter doesn't support any options.
*/
var IDB =
/*#__PURE__*/
function (_BaseAdapter) {
(0, _inherits2.default)(IDB, _BaseAdapter);
/**
* Constructor.
*
* @param {String} cid The key base for this collection (eg. `bid/cid`)
* @param {Object} options
* @param {String} options.dbName The IndexedDB name (default: `"KintoDB"`)
* @param {String} options.migrateOldData Whether old database data should be migrated (default: `false`)
*/
function IDB(cid) {
var _this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _classCallCheck2.default)(this, IDB);
_this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(IDB).call(this));
_this.cid = cid;
_this.dbName = options.dbName || "KintoDB";
_this._options = options;
_this._db = null;
return _this;
}
(0, _createClass2.default)(IDB, [{
key: "_handleError",
value: function _handleError(method, err) {
var error = new Error("IndexedDB ".concat(method, "() ").concat(err.message));
error.stack = err.stack;
throw error;
}
/**
* Ensures a connection to the IndexedDB database has been opened.
*
* @override
* @return {Promise}
*/
}, {
key: "open",
value: function () {
var _open3 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee() {
var dataToMigrate, records, timestamp;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!this._db) {
_context.next = 2;
break;
}
return _context.abrupt("return", this);
case 2:
if (!this._options.migrateOldData) {
_context.next = 8;
break;
}
_context.next = 5;
return migrationRequired(this.cid);
case 5:
_context.t0 = _context.sent;
_context.next = 9;
break;
case 8:
_context.t0 = null;
case 9:
dataToMigrate = _context.t0;
_context.next = 12;
return _open2(this.dbName, {
version: 2,
onupgradeneeded: function onupgradeneeded(event) {
var db = event.target.result;
if (event.oldVersion < 1) {
// Records store
var recordsStore = db.createObjectStore("records", {
keyPath: ["_cid", "id"]
}); // An index to obtain all the records in a collection.
recordsStore.createIndex("cid", "_cid"); // Here we create indices for every known field in records by collection.
// Local record status ("synced", "created", "updated", "deleted")
recordsStore.createIndex("_status", ["_cid", "_status"]); // Last modified field
recordsStore.createIndex("last_modified", ["_cid", "last_modified"]); // Timestamps store
db.createObjectStore("timestamps", {
keyPath: "cid"
});
}
if (event.oldVersion < 2) {
// Collections store
db.createObjectStore("collections", {
keyPath: "cid"
});
}
}
});
case 12:
this._db = _context.sent;
if (!dataToMigrate) {
_context.next = 23;
break;
}
records = dataToMigrate.records, timestamp = dataToMigrate.timestamp;
_context.next = 17;
return this.importBulk(records);
case 17:
_context.next = 19;
return this.saveLastModified(timestamp);
case 19:
console.log("".concat(this.cid, ": data was migrated successfully.")); // Delete the old database.
_context.next = 22;
return deleteDatabase(this.cid);
case 22:
console.warn("".concat(this.cid, ": old database was deleted."));
case 23:
return _context.abrupt("return", this);
case 24:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
return function open() {
return _open3.apply(this, arguments);
};
}()
/**
* Closes current connection to the database.
*
* @override
* @return {Promise}
*/
}, {
key: "close",
value: function close() {
if (this._db) {
this._db.close(); // indexedDB.close is synchronous
this._db = null;
}
return Promise.resolve();
}
/**
* Returns a transaction and an object store for a store name.
*
* To determine if a transaction has completed successfully, we should rather
* listen to the transaction’s complete event rather than the IDBObjectStore
* request’s success event, because the transaction may still fail after the
* success event fires.
*
* @param {String} name Store name
* @param {Function} callback to execute
* @param {Object} options Options
* @param {String} options.mode Transaction mode ("readwrite" or undefined)
* @return {Object}
*/
}, {
key: "prepare",
value: function () {
var _prepare = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2(name, callback, options) {
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return this.open();
case 2:
_context2.next = 4;
return execute(this._db, name, callback, options);
case 4:
case "end":
return _context2.stop();
}
}
}, _callee2, this);
}));
return function prepare(_x7, _x8, _x9) {
return _prepare.apply(this, arguments);
};
}()
/**
* Deletes every records in the current collection.
*
* @override
* @return {Promise}
*/
}, {
key: "clear",
value: function () {
var _clear = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee3() {
var _this2 = this;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_context3.prev = 0;
_context3.next = 3;
return this.prepare("records", function (store) {
var range = IDBKeyRange.only(_this2.cid);
var request = store.index("cid").openKeyCursor(range);
request.onsuccess = function (event) {
var cursor = event.target.result;
if (cursor) {
store.delete(cursor.primaryKey);
cursor.continue();
}
};
return request;
}, {
mode: "readwrite"
});
case 3:
_context3.next = 8;
break;
case 5:
_context3.prev = 5;
_context3.t0 = _context3["catch"](0);
this._handleError("clear", _context3.t0);
case 8:
case "end":
return _context3.stop();
}
}
}, _callee3, this, [[0, 5]]);
}));
return function clear() {
return _clear.apply(this, arguments);
};
}()
/**
* Executes the set of synchronous CRUD operations described in the provided
* callback within an IndexedDB transaction, for current db store.
*
* The callback will be provided an object exposing the following synchronous
* CRUD operation methods: get, create, update, delete.
*
* Important note: because limitations in IndexedDB implementations, no
* asynchronous code should be performed within the provided callback; the
* promise will therefore be rejected if the callback returns a Promise.
*
* Options:
* - {Array} preload: The list of record IDs to fetch and make available to
* the transaction object get() method (default: [])
*
* @example
* const db = new IDB("example");
* const result = await db.execute(transaction => {
* transaction.create({id: 1, title: "foo"});
* transaction.update({id: 2, title: "bar"});
* transaction.delete(3);
* return "foo";
* });
*
* @override
* @param {Function} callback The operation description callback.
* @param {Object} options The options object.
* @return {Promise}
*/
}, {
key: "execute",
value: function () {
var _execute2 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee4(callback) {
var _this3 = this;
var options,
result,
_args4 = arguments;
return _regenerator.default.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
options = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : {
preload: []
};
_context4.next = 3;
return this.prepare("records", function (store, abort) {
var runCallback = function runCallback() {
var preloaded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
// Expose a consistent API for every adapter instead of raw store methods.
var proxy = transactionProxy(_this3, store, preloaded); // The callback is executed synchronously within the same transaction.
try {
var returned = callback(proxy);
if (returned instanceof Promise) {
// XXX: investigate how to provide documentation details in error.
throw new Error("execute() callback should not return a Promise.");
} // Bring to scope that will be returned (once promise awaited).
result = returned;
} catch (e) {
// The callback has thrown an error explicitly. Abort transaction cleanly.
abort(e);
}
}; // No option to preload records, go straight to `callback`.
if (!options.preload.length) {
return runCallback();
} // Preload specified records using a list request.
var filters = {
id: options.preload
};
createListRequest(_this3.cid, store, filters, function (records) {
// Store obtained records by id.
var preloaded = {};
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = records[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var record = _step.value;
delete record["_cid"];
preloaded[record.id] = record;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
runCallback(preloaded);
});
}, {
mode: "readwrite"
});
case 3:
return _context4.abrupt("return", result);
case 4:
case "end":
return _context4.stop();
}
}
}, _callee4, this);
}));
return function execute(_x10) {
return _execute2.apply(this, arguments);
};
}()
/**
* Retrieve a record by its primary key from the IndexedDB database.
*
* @override
* @param {String} id The record id.
* @return {Promise}
*/
}, {
key: "get",
value: function () {
var _get = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee5(id) {
var _this4 = this;
var record;
return _regenerator.default.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
_context5.prev = 0;
_context5.next = 3;
return this.prepare("records", function (store) {
store.get([_this4.cid, id]).onsuccess = function (e) {
return record = e.target.result;
};
});
case 3:
return _context5.abrupt("return", record);
case 6:
_context5.prev = 6;
_context5.t0 = _context5["catch"](0);
this._handleError("get", _context5.t0);
case 9:
case "end":
return _context5.stop();
}
}
}, _callee5, this, [[0, 6]]);
}));
return function get(_x11) {
return _get.apply(this, arguments);
};
}()
/**
* Lists all records from the IndexedDB database.
*
* @override
* @param {Object} params The filters and order to apply to the results.
* @return {Promise}
*/
}, {
key: "list",
value: function () {
var _list = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee6() {
var _this5 = this;
var params,
filters,
results,
_args6 = arguments;
return _regenerator.default.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
params = _args6.length > 0 && _args6[0] !== undefined ? _args6[0] : {
filters: {}
};
filters = params.filters;
_context6.prev = 2;
results = [];
_context6.next = 6;
return this.prepare("records", function (store) {
createListRequest(_this5.cid, store, filters, function (_results) {
// we have received all requested records that match the filters,
// we now park them within current scope and hide the `_cid` attribute.
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = _results[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var result = _step2.value;
delete result["_cid"];
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
results = _results;
});
});
case 6:
return _context6.abrupt("return", params.order ? (0, _utils.sortObjects)(params.order, results) : results);
case 9:
_context6.prev = 9;
_context6.t0 = _context6["catch"](2);
this._handleError("list", _context6.t0);
case 12:
case "end":
return _context6.stop();
}
}
}, _callee6, this, [[2, 9]]);
}));
return function list() {
return _list.apply(this, arguments);
};
}()
/**
* Store the lastModified value into metadata store.
*
* @override
* @param {Number} lastModified
* @return {Promise}
*/
}, {
key: "saveLastModified",
value: function () {
var _saveLastModified = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee7(lastModified) {
var _this6 = this;
var value;
return _regenerator.default.wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
value = parseInt(lastModified, 10) || null;
_context7.prev = 1;
_context7.next = 4;
return this.prepare("timestamps", function (store) {
return store.put({
cid: _this6.cid,
value: value
});
}, {
mode: "readwrite"
});
case 4:
return _context7.abrupt("return", value);
case 7:
_context7.prev = 7;
_context7.t0 = _context7["catch"](1);
this._handleError("saveLastModified", _context7.t0);
case 10:
case "end":
return _context7.stop();
}
}
}, _callee7, this, [[1, 7]]);
}));
return function saveLastModified(_x12) {
return _saveLastModified.apply(this, arguments);
};
}()
/**
* Retrieve saved lastModified value.
*
* @override
* @return {Promise}
*/
}, {
key: "getLastModified",
value: function () {
var _getLastModified = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee8() {
var _this7 = this;
var entry;
return _regenerator.default.wrap(function _callee8$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
_context8.prev = 0;
entry = null;
_context8.next = 4;
return this.prepare("timestamps", function (store) {
store.get(_this7.cid).onsuccess = function (e) {
return entry = e.target.result;
};
});
case 4:
return _context8.abrupt("return", entry ? entry.value : null);
case 7:
_context8.prev = 7;
_context8.t0 = _context8["catch"](0);
this._handleError("getLastModified", _context8.t0);
case 10:
case "end":
return _context8.stop();
}
}
}, _callee8, this, [[0, 7]]);
}));
return function getLastModified() {
return _getLastModified.apply(this, arguments);
};
}()
/**
* Load a dump of records exported from a server.
*
* @deprecated Use {@link importBulk} instead.
* @abstract
* @param {Array} records The records to load.
* @return {Promise}
*/
}, {
key: "loadDump",
value: function () {
var _loadDump = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee9(records) {
return _regenerator.default.wrap(function _callee9$(_context9) {
while (1) {
switch (_context9.prev = _context9.next) {
case 0:
return _context9.abrupt("return", this.importBulk(records));
case 1:
case "end":
return _context9.stop();
}
}
}, _callee9, this);
}));
return function loadDump(_x13) {
return _loadDump.apply(this, arguments);
};
}()
/**
* Load records in bulk that were exported from a server.
*
* @abstract
* @param {Array} records The records to load.
* @return {Promise}
*/
}, {
key: "importBulk",
value: function () {
var _importBulk = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee10(records) {
var previousLastModified, lastModified;
return _regenerator.default.wrap(function _callee10$(_context10) {
while (1) {
switch (_context10.prev = _context10.next) {
case 0:
_context10.prev = 0;
_context10.next = 3;
return this.execute(function (transaction) {
// Since the put operations are asynchronous, we chain
// them together. The last one will be waited for the
// `transaction.oncomplete` callback. (see #execute())
var i = 0;
putNext();
function putNext() {
if (i == records.length) {
return;
} // On error, `transaction.onerror` is called.
transaction.update(records[i]).onsuccess = putNext;
++i;
}
});
case 3:
_context10.next = 5;
return this.getLastModified();
case 5:
previousLastModified = _context10.sent;
lastModified = Math.max.apply(Math, (0, _toConsumableArray2.default)(records.map(function (record) {
return record.last_modified;
})));
if (!(lastModified > previousLastModified)) {
_context10.next = 10;
break;
}
_context10.next = 10;
return this.saveLastModified(lastModified);
case 10:
return _context10.abrupt("return", records);
case 13:
_context10.prev = 13;
_context10.t0 = _context10["catch"](0);
this._handleError("importBulk", _context10.t0);
case 16:
case "end":
return _context10.stop();
}
}
}, _callee10, this, [[0, 13]]);
}));
return function importBulk(_x14) {
return _importBulk.apply(this, arguments);
};
}()
}, {
key: "saveMetadata",
value: function () {
var _saveMetadata = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee11(metadata) {
var _this8 = this;
return _regenerator.default.wrap(function _callee11$(_context11) {
while (1) {
switch (_context11.prev = _context11.next) {
case 0:
_context11.prev = 0;
_context11.next = 3;
return this.prepare("collections", function (store) {
return store.put({
cid: _this8.cid,
metadata: metadata
});
}, {
mode: "readwrite"
});
case 3:
return _context11.abrupt("return", metadata);
case 6:
_context11.prev = 6;
_context11.t0 = _context11["catch"](0);
this._handleError("saveMetadata", _context11.t0);
case 9:
case "end":
return _context11.stop();
}
}
}, _callee11, this, [[0, 6]]);
}));
return function saveMetadata(_x15) {
return _saveMetadata.apply(this, arguments);
};
}()
}, {
key: "getMetadata",
value: function () {
var _getMetadata = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee12() {
var _this9 = this;
var entry;
return _regenerator.default.wrap(function _callee12$(_context12) {
while (1) {
switch (_context12.prev = _context12.next) {
case 0:
_context12.prev = 0;
entry = null;
_context12.next = 4;
return this.prepare("collections", function (store) {
store.get(_this9.cid).onsuccess = function (e) {
return entry = e.target.result;
};
});
case 4:
return _context12.abrupt("return", entry ? entry.metadata : null);
case 7:
_context12.prev = 7;
_context12.t0 = _context12["catch"](0);
this._handleError("getMetadata", _context12.t0);
case 10:
case "end":
return _context12.stop();
}
}
}, _callee12, this, [[0, 7]]);
}));
return function getMetadata() {
return _getMetadata.apply(this, arguments);
};
}()
}]);
return IDB;
}(_base.default);
/**
* IDB transaction proxy.
*
* @param {IDB} adapter The call IDB adapter
* @param {IDBStore} store The IndexedDB database store.
* @param {Array} preloaded The list of records to make available to
* get() (default: []).
* @return {Object}
*/
exports.default = IDB;
function transactionProxy(adapter, store) {
var preloaded = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var _cid = adapter.cid;
return {
create: function create(record) {
store.add((0, _objectSpread2.default)({}, record, {
_cid: _cid
}));
},
update: function update(record) {
return store.put((0, _objectSpread2.default)({}, record, {
_cid: _cid
}));
},
delete: function _delete(id) {
store.delete([_cid, id]);
},
get: function get(id) {
return preloaded[id];
}
};
}
/**
* Up to version 10.X of kinto.js, each collection had its own collection.
* The database name was `${bid}/${cid}` (eg. `"blocklists/certificates"`)
* and contained only one store with the same name.
*/
function migrationRequired(_x16) {
return _migrationRequired.apply(this, arguments);
}
function _migrationRequired() {
_migrationRequired = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee16(dbName) {
var exists, db, records, timestamp;
return _regenerator.default.wrap(function _callee16$(_context16) {
while (1) {
switch (_context16.prev = _context16.next) {
case 0:
exists = true;
_context16.next = 3;
return _open2(dbName, {
version: 1,
onupgradeneeded: function onupgradeneeded(event) {
exists = false;
}
});
case 3:
db = _context16.sent;
// Check that the DB we're looking at is really a legacy one,
// and not some remainder of the open() operation above.
exists &= db.objectStoreNames.contains("__meta__") && db.objectStoreNames.contains(dbName);
if (exists) {
_context16.next = 10;
break;
}
db.close(); // Testing the existence creates it, so delete it :)
_context16.next = 9;
return deleteDatabase(dbName);
case 9:
return _context16.abrupt("return", null);
case 10:
console.warn("".concat(dbName, ": old IndexedDB database found."));
_context16.prev = 11;
_context16.next = 14;
return execute(db, dbName, function (store) {
store.openCursor().onsuccess = cursorHandlers.all({}, function (res) {
return records = res;
});
});
case 14:
console.log("".concat(dbName, ": found ").concat(records.length, " records.")); // Check if there's a entry for this.
timestamp = null;
_context16.next = 18;
return execute(db, "__meta__", function (store) {
store.get("".concat(dbName, "-lastModified")).onsuccess = function (e) {
timestamp = e.target.result ? e.target.result.value : null;
};
});
case 18:
if (timestamp) {
_context16.next = 21;
break;
}
_context16.next = 21;
return execute(db, "__meta__", function (store) {
store.get("lastModified").onsuccess = function (e) {
timestamp = e.target.result ? e.target.result.value : null;
};
});
case 21:
console.log("".concat(dbName, ": ").concat(timestamp ? "found" : "no", " timestamp.")); // Those will be inserted in the new database/schema.
return _context16.abrupt("return", {
records: records,
timestamp: timestamp
});
case 25:
_context16.prev = 25;
_context16.t0 = _context16["catch"](11);
console.error("Error occured during migration", _context16.t0);
return _context16.abrupt("return", null);
case 29:
_context16.prev = 29;
db.close();
return _context16.finish(29);
case 32:
case "end":
return _context16.stop();
}
}
}, _callee16, this, [[11, 25, 29, 32]]);
}));
return _migrationRequired.apply(this, arguments);
}
},{"../utils":327,"./base.js":324,"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/getPrototypeOf":286,"@babel/runtime/helpers/inherits":287,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/possibleConstructorReturn":296,"@babel/runtime/helpers/toConsumableArray":300,"@babel/runtime/regenerator":305}],324:[function(require,module,exports){
"use strict";
/**
* Base db adapter.
*
* @abstract
*/
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var BaseAdapter =
/*#__PURE__*/
function () {
function BaseAdapter() {
(0, _classCallCheck2.default)(this, BaseAdapter);
}
(0, _createClass2.default)(BaseAdapter, [{
key: "clear",
/**
* Deletes every records present in the database.
*
* @abstract
* @return {Promise}
*/
value: function clear() {
throw new Error("Not Implemented.");
}
/**
* Executes a batch of operations within a single transaction.
*
* @abstract
* @param {Function} callback The operation callback.
* @param {Object} options The options object.
* @return {Promise}
*/
}, {
key: "execute",
value: function execute(callback) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
preload: []
};
throw new Error("Not Implemented.");
}
/**
* Retrieve a record by its primary key from the database.
*
* @abstract
* @param {String} id The record id.
* @return {Promise}
*/
}, {
key: "get",
value: function get(id) {
throw new Error("Not Implemented.");
}
/**
* Lists all records from the database.
*
* @abstract
* @param {Object} params The filters and order to apply to the results.
* @return {Promise}
*/
}, {
key: "list",
value: function list() {
var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
filters: {},
order: ""
};
throw new Error("Not Implemented.");
}
/**
* Store the lastModified value.
*
* @abstract
* @param {Number} lastModified
* @return {Promise}
*/
}, {
key: "saveLastModified",
value: function saveLastModified(lastModified) {
throw new Error("Not Implemented.");
}
/**
* Retrieve saved lastModified value.
*
* @abstract
* @return {Promise}
*/
}, {
key: "getLastModified",
value: function getLastModified() {
throw new Error("Not Implemented.");
}
/**
* Load records in bulk that were exported from a server.
*
* @abstract
* @param {Array} records The records to load.
* @return {Promise}
*/
}, {
key: "importBulk",
value: function importBulk(records) {
throw new Error("Not Implemented.");
}
/**
* Load a dump of records exported from a server.
*
* @deprecated Use {@link importBulk} instead.
* @abstract
* @param {Array} records The records to load.
* @return {Promise}
*/
}, {
key: "loadDump",
value: function loadDump(records) {
throw new Error("Not Implemented.");
}
}, {
key: "saveMetadata",
value: function saveMetadata(metadata) {
throw new Error("Not Implemented.");
}
}, {
key: "getMetadata",
value: function getMetadata() {
throw new Error("Not Implemented.");
}
}]);
return BaseAdapter;
}();
exports.default = BaseAdapter;
},{"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/interopRequireDefault":288}],325:[function(require,module,exports){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.recordsEqual = recordsEqual;
exports.createKeyValueStoreIdSchema = createKeyValueStoreIdSchema;
exports.CollectionTransaction = exports.default = exports.ServerWasFlushedError = exports.SyncResultObject = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapNativeSuper"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _base = _interopRequireDefault(require("./adapters/base"));
var _IDB = _interopRequireDefault(require("./adapters/IDB"));
var _utils = require("./utils");
var _uuid = require("uuid");
var RECORD_FIELDS_TO_CLEAN = ["_status"];
var AVAILABLE_HOOKS = ["incoming-changes"];
var IMPORT_CHUNK_SIZE = 200;
/**
* Compare two records omitting local fields and synchronization
* attributes (like _status and last_modified)
* @param {Object} a A record to compare.
* @param {Object} b A record to compare.
* @param {Array} localFields Additional fields to ignore during the comparison
* @return {boolean}
*/
function recordsEqual(a, b) {
var localFields = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var fieldsToClean = RECORD_FIELDS_TO_CLEAN.concat(["last_modified"]).concat(localFields);
var cleanLocal = function cleanLocal(r) {
return (0, _utils.omitKeys)(r, fieldsToClean);
};
return (0, _utils.deepEqual)(cleanLocal(a), cleanLocal(b));
}
/**
* Synchronization result object.
*/
var SyncResultObject =
/*#__PURE__*/
function () {
/**
* Public constructor.
*/
function SyncResultObject() {
var _this = this;
(0, _classCallCheck2.default)(this, SyncResultObject);
/**
* Current synchronization result status; becomes `false` when conflicts or
* errors are registered.
* @type {Boolean}
*/
this.lastModified = null;
this._lists = {};
["errors", "created", "updated", "deleted", "published", "conflicts", "skipped", "resolved", "void"].forEach(function (l) {
return _this._lists[l] = [];
});
this._cached = {};
}
/**
* Adds entries for a given result type.
*
* @param {String} type The result type.
* @param {Array} entries The result entries.
* @return {SyncResultObject}
*/
(0, _createClass2.default)(SyncResultObject, [{
key: "add",
value: function add(type, entries) {
if (!Array.isArray(this._lists[type])) {
console.warn("Unknown type \"".concat(type, "\""));
return;
}
if (!Array.isArray(entries)) {
entries = [entries];
}
this._lists[type] = this._lists[type].concat(entries);
delete this._cached[type];
return this;
}
}, {
key: "_deduplicate",
value: function _deduplicate(list) {
if (!(list in this._cached)) {
// Deduplicate entries by id. If the values don't have `id` attribute, just
// keep all.
var recordsWithoutId = new Set();
var recordsById = new Map();
this._lists[list].forEach(function (record) {
if (!record.id) {
recordsWithoutId.add(record);
} else {
recordsById.set(record.id, record);
}
});
this._cached[list] = Array.from(recordsById.values()).concat(Array.from(recordsWithoutId));
}
return this._cached[list];
}
/**
* Reinitializes result entries for a given result type.
*
* @param {String} type The result type.
* @return {SyncResultObject}
*/
}, {
key: "reset",
value: function reset(type) {
this._lists[type] = [];
delete this._cached[type];
return this;
}
}, {
key: "toObject",
value: function toObject() {
// Only used in tests.
return {
ok: this.ok,
lastModified: this.lastModified,
errors: this.errors,
created: this.created,
updated: this.updated,
deleted: this.deleted,
skipped: this.skipped,
published: this.published,
conflicts: this.conflicts,
resolved: this.resolved
};
}
}, {
key: "ok",
get: function get() {
return this.errors.length + this.conflicts.length === 0;
}
}, {
key: "errors",
get: function get() {
return this._lists["errors"];
}
}, {
key: "conflicts",
get: function get() {
return this._lists["conflicts"];
}
}, {
key: "skipped",
get: function get() {
return this._deduplicate("skipped");
}
}, {
key: "resolved",
get: function get() {
return this._deduplicate("resolved");
}
}, {
key: "created",
get: function get() {
return this._deduplicate("created");
}
}, {
key: "updated",
get: function get() {
return this._deduplicate("updated");
}
}, {
key: "deleted",
get: function get() {
return this._deduplicate("deleted");
}
}, {
key: "published",
get: function get() {
return this._deduplicate("published");
}
}]);
return SyncResultObject;
}();
exports.SyncResultObject = SyncResultObject;
var ServerWasFlushedError =
/*#__PURE__*/
function (_Error) {
(0, _inherits2.default)(ServerWasFlushedError, _Error);
function ServerWasFlushedError(clientTimestamp, serverTimestamp, message) {
var _this2;
(0, _classCallCheck2.default)(this, ServerWasFlushedError);
_this2 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ServerWasFlushedError).call(this, message));
if (Error.captureStackTrace) {
Error.captureStackTrace((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this2)), ServerWasFlushedError);
}
_this2.clientTimestamp = clientTimestamp;
_this2.serverTimestamp = serverTimestamp;
return _this2;
}
return ServerWasFlushedError;
}((0, _wrapNativeSuper2.default)(Error));
exports.ServerWasFlushedError = ServerWasFlushedError;
function createUUIDSchema() {
return {
generate: function generate() {
return (0, _uuid.v4)();
},
validate: function validate(id) {
return typeof id == "string" && _utils.RE_RECORD_ID.test(id);
}
};
}
/**
* IDSchema for when using kinto.js as a key-value store.
* Using this IDSchema requires you to set a property as the id.
* This will be the property used to retrieve this record.
*
* @example
* const exampleCollection = db.collection("example", { idSchema: createKeyValueStoreIdSchema() })
* await exampleCollection.create({ title: "How to tie a tie", favoriteColor: "blue", id: "user123" }, { useRecordId: true })
* await exampleCollection.getAny("user123")
*/
function createKeyValueStoreIdSchema() {
return {
generate: function generate() {
throw new Error("createKeyValueStoreIdSchema() does not generate an id");
},
validate: function validate() {
return true;
}
};
}
function markStatus(record, status) {
return (0, _objectSpread2.default)({}, record, {
_status: status
});
}
function markDeleted(record) {
return markStatus(record, "deleted");
}
function markSynced(record) {
return markStatus(record, "synced");
}
/**
* Import a remote change into the local database.
*
* @param {IDBTransactionProxy} transaction The transaction handler.
* @param {Object} remote The remote change object to import.
* @param {Array<String>} localFields The list of fields that remain local.
* @param {String} strategy The {@link Collection.strategy}.
* @return {Object}
*/
function importChange(transaction, remote, localFields, strategy) {
var local = transaction.get(remote.id);
if (!local) {
// Not found locally but remote change is marked as deleted; skip to
// avoid recreation.
if (remote.deleted) {
return {
type: "skipped",
data: remote
};
}
var _synced = markSynced(remote);
transaction.create(_synced);
return {
type: "created",
data: _synced
};
} // Apply remote changes on local record.
var synced = (0, _objectSpread2.default)({}, local, markSynced(remote)); // With pull only, we don't need to compare records since we override them.
if (strategy === Collection.strategy.PULL_ONLY) {
if (remote.deleted) {
transaction.delete(remote.id);
return {
type: "deleted",
data: local
};
}
transaction.update(synced);
return {
type: "updated",
data: {
old: local,
new: synced
}
};
} // With other sync strategies, we detect conflicts,
// by comparing local and remote, ignoring local fields.
var isIdentical = recordsEqual(local, remote, localFields); // Detect or ignore conflicts if record has also been modified locally.
if (local._status !== "synced") {
// Locally deleted, unsynced: scheduled for remote deletion.
if (local._status === "deleted") {
return {
type: "skipped",
data: local
};
}
if (isIdentical) {
// If records are identical, import anyway, so we bump the
// local last_modified value from the server and set record
// status to "synced".
transaction.update(synced);
return {
type: "updated",
data: {
old: local,
new: synced
}
};
}
if (local.last_modified !== undefined && local.last_modified === remote.last_modified) {
// If our local version has the same last_modified as the remote
// one, this represents an object that corresponds to a resolved
// conflict. Our local version represents the final output, so
// we keep that one. (No transaction operation to do.)
// But if our last_modified is undefined,
// that means we've created the same object locally as one on
// the server, which *must* be a conflict.
return {
type: "void"
};
}
return {
type: "conflicts",
data: {
type: "incoming",
local: local,
remote: remote
}
};
} // Local record was synced.
if (remote.deleted) {
transaction.delete(remote.id);
return {
type: "deleted",
data: local
};
} // Import locally.
transaction.update(synced); // if identical, simply exclude it from all SyncResultObject lists
var type = isIdentical ? "void" : "updated";
return {
type: type,
data: {
old: local,
new: synced
}
};
}
/**
* Abstracts a collection of records stored in the local database, providing
* CRUD operations and synchronization helpers.
*/
var Collection =
/*#__PURE__*/
function () {
/**
* Constructor.
*
* Options:
* - `{BaseAdapter} adapter` The DB adapter (default: `IDB`)
*
* @param {String} bucket The bucket identifier.
* @param {String} name The collection name.
* @param {Api} api The Api instance.
* @param {Object} options The options object.
*/
function Collection(bucket, name, api) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
(0, _classCallCheck2.default)(this, Collection);
this._bucket = bucket;
this._name = name;
this._lastModified = null;
var DBAdapter = options.adapter || _IDB.default;
if (!DBAdapter) {
throw new Error("No adapter provided");
}
var db = new DBAdapter("".concat(bucket, "/").concat(name), options.adapterOptions);
if (!(db instanceof _base.default)) {
throw new Error("Unsupported adapter.");
} // public properties
/**
* The db adapter instance
* @type {BaseAdapter}
*/
this.db = db;
/**
* The Api instance.
* @type {KintoClient}
*/
this.api = api;
/**
* The event emitter instance.
* @type {EventEmitter}
*/
this.events = options.events;
/**
* The IdSchema instance.
* @type {Object}
*/
this.idSchema = this._validateIdSchema(options.idSchema);
/**
* The list of remote transformers.
* @type {Array}
*/
this.remoteTransformers = this._validateRemoteTransformers(options.remoteTransformers);
/**
* The list of hooks.
* @type {Object}
*/
this.hooks = this._validateHooks(options.hooks);
/**
* The list of fields names that will remain local.
* @type {Array}
*/
this.localFields = options.localFields || [];
}
/**
* The collection name.
* @type {String}
*/
(0, _createClass2.default)(Collection, [{
key: "_validateIdSchema",
/**
* Validates an idSchema.
*
* @param {Object|undefined} idSchema
* @return {Object}
*/
value: function _validateIdSchema(idSchema) {
if (typeof idSchema === "undefined") {
return createUUIDSchema();
}
if ((0, _typeof2.default)(idSchema) !== "object") {
throw new Error("idSchema must be an object.");
} else if (typeof idSchema.generate !== "function") {
throw new Error("idSchema must provide a generate function.");
} else if (typeof idSchema.validate !== "function") {
throw new Error("idSchema must provide a validate function.");
}
return idSchema;
}
/**
* Validates a list of remote transformers.
*
* @param {Array|undefined} remoteTransformers
* @return {Array}
*/
}, {
key: "_validateRemoteTransformers",
value: function _validateRemoteTransformers(remoteTransformers) {
if (typeof remoteTransformers === "undefined") {
return [];
}
if (!Array.isArray(remoteTransformers)) {
throw new Error("remoteTransformers should be an array.");
}
return remoteTransformers.map(function (transformer) {
if ((0, _typeof2.default)(transformer) !== "object") {
throw new Error("A transformer must be an object.");
} else if (typeof transformer.encode !== "function") {
throw new Error("A transformer must provide an encode function.");
} else if (typeof transformer.decode !== "function") {
throw new Error("A transformer must provide a decode function.");
}
return transformer;
});
}
/**
* Validate the passed hook is correct.
*
* @param {Array|undefined} hook.
* @return {Array}
**/
}, {
key: "_validateHook",
value: function _validateHook(hook) {
if (!Array.isArray(hook)) {
throw new Error("A hook definition should be an array of functions.");
}
return hook.map(function (fn) {
if (typeof fn !== "function") {
throw new Error("A hook definition should be an array of functions.");
}
return fn;
});
}
/**
* Validates a list of hooks.
*
* @param {Object|undefined} hooks
* @return {Object}
*/
}, {
key: "_validateHooks",
value: function _validateHooks(hooks) {
if (typeof hooks === "undefined") {
return {};
}
if (Array.isArray(hooks)) {
throw new Error("hooks should be an object, not an array.");
}
if ((0, _typeof2.default)(hooks) !== "object") {
throw new Error("hooks should be an object.");
}
var validatedHooks = {};
for (var hook in hooks) {
if (!AVAILABLE_HOOKS.includes(hook)) {
throw new Error("The hook should be one of " + AVAILABLE_HOOKS.join(", "));
}
validatedHooks[hook] = this._validateHook(hooks[hook]);
}
return validatedHooks;
}
/**
* Deletes every records in the current collection and marks the collection as
* never synced.
*
* @return {Promise}
*/
}, {
key: "clear",
value: function () {
var _clear = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee() {
return _regenerator.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return this.db.clear();
case 2:
_context.next = 4;
return this.db.saveMetadata(null);
case 4:
_context.next = 6;
return this.db.saveLastModified(null);
case 6:
return _context.abrupt("return", {
data: [],
permissions: {}
});
case 7:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
return function clear() {
return _clear.apply(this, arguments);
};
}()
/**
* Encodes a record.
*
* @param {String} type Either "remote" or "local".
* @param {Object} record The record object to encode.
* @return {Promise}
*/
}, {
key: "_encodeRecord",
value: function _encodeRecord(type, record) {
if (!this["".concat(type, "Transformers")].length) {
return Promise.resolve(record);
}
return (0, _utils.waterfall)(this["".concat(type, "Transformers")].map(function (transformer) {
return function (record) {
return transformer.encode(record);
};
}), record);
}
/**
* Decodes a record.
*
* @param {String} type Either "remote" or "local".
* @param {Object} record The record object to decode.
* @return {Promise}
*/
}, {
key: "_decodeRecord",
value: function _decodeRecord(type, record) {
if (!this["".concat(type, "Transformers")].length) {
return Promise.resolve(record);
}
return (0, _utils.waterfall)(this["".concat(type, "Transformers")].reverse().map(function (transformer) {
return function (record) {
return transformer.decode(record);
};
}), record);
}
/**
* Adds a record to the local database, asserting that none
* already exist with this ID.
*
* Note: If either the `useRecordId` or `synced` options are true, then the
* record object must contain the id field to be validated. If none of these
* options are true, an id is generated using the current IdSchema; in this
* case, the record passed must not have an id.
*
* Options:
* - {Boolean} synced Sets record status to "synced" (default: `false`).
* - {Boolean} useRecordId Forces the `id` field from the record to be used,
* instead of one that is generated automatically
* (default: `false`).
*
* @param {Object} record
* @param {Object} options
* @return {Promise}
*/
}, {
key: "create",
value: function create(record) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
useRecordId: false,
synced: false
};
// Validate the record and its ID (if any), even though this
// validation is also done in the CollectionTransaction method,
// because we need to pass the ID to preloadIds.
var reject = function reject(msg) {
return Promise.reject(new Error(msg));
};
if ((0, _typeof2.default)(record) !== "object") {
return reject("Record is not an object.");
}
if ((options.synced || options.useRecordId) && !Object.prototype.hasOwnProperty.call(record, "id")) {
return reject("Missing required Id; synced and useRecordId options require one");
}
if (!options.synced && !options.useRecordId && Object.prototype.hasOwnProperty.call(record, "id")) {
return reject("Extraneous Id; can't create a record having one set.");
}
var newRecord = (0, _objectSpread2.default)({}, record, {
id: options.synced || options.useRecordId ? record.id : this.idSchema.generate(record),
_status: options.synced ? "synced" : "created"
});
if (!this.idSchema.validate(newRecord.id)) {
return reject("Invalid Id: ".concat(newRecord.id));
}
return this.execute(function (txn) {
return txn.create(newRecord);
}, {
preloadIds: [newRecord.id]
}).catch(function (err) {
if (options.useRecordId) {
throw new Error("Couldn't create record. It may have been virtually deleted.");
}
throw err;
});
}
/**
* Like {@link CollectionTransaction#update}, but wrapped in its own transaction.
*
* Options:
* - {Boolean} synced: Sets record status to "synced" (default: false)
* - {Boolean} patch: Extends the existing record instead of overwriting it
* (default: false)
*
* @param {Object} record
* @param {Object} options
* @return {Promise}
*/
}, {
key: "update",
value: function update(record) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
synced: false,
patch: false
};
// Validate the record and its ID, even though this validation is
// also done in the CollectionTransaction method, because we need
// to pass the ID to preloadIds.
if ((0, _typeof2.default)(record) !== "object") {
return Promise.reject(new Error("Record is not an object."));
}
if (!Object.prototype.hasOwnProperty.call(record, "id")) {
return Promise.reject(new Error("Cannot update a record missing id."));
}
if (!this.idSchema.validate(record.id)) {
return Promise.reject(new Error("Invalid Id: ".concat(record.id)));
}
return this.execute(function (txn) {
return txn.update(record, options);
}, {
preloadIds: [record.id]
});
}
/**
* Like {@link CollectionTransaction#upsert}, but wrapped in its own transaction.
*
* @param {Object} record
* @return {Promise}
*/
}, {
key: "upsert",
value: function upsert(record) {
// Validate the record and its ID, even though this validation is
// also done in the CollectionTransaction method, because we need
// to pass the ID to preloadIds.
if ((0, _typeof2.default)(record) !== "object") {
return Promise.reject(new Error("Record is not an object."));
}
if (!Object.prototype.hasOwnProperty.call(record, "id")) {
return Promise.reject(new Error("Cannot update a record missing id."));
}
if (!this.idSchema.validate(record.id)) {
return Promise.reject(new Error("Invalid Id: ".concat(record.id)));
}
return this.execute(function (txn) {
return txn.upsert(record);
}, {
preloadIds: [record.id]
});
}
/**
* Like {@link CollectionTransaction#get}, but wrapped in its own transaction.
*
* Options:
* - {Boolean} includeDeleted: Include virtually deleted records.
*
* @param {String} id
* @param {Object} options
* @return {Promise}
*/
}, {
key: "get",
value: function get(id) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
includeDeleted: false
};
return this.execute(function (txn) {
return txn.get(id, options);
}, {
preloadIds: [id]
});
}
/**
* Like {@link CollectionTransaction#getAny}, but wrapped in its own transaction.
*
* @param {String} id
* @return {Promise}
*/
}, {
key: "getAny",
value: function getAny(id) {
return this.execute(function (txn) {
return txn.getAny(id);
}, {
preloadIds: [id]
});
}
/**
* Same as {@link Collection#delete}, but wrapped in its own transaction.
*
* Options:
* - {Boolean} virtual: When set to `true`, doesn't actually delete the record,
* update its `_status` attribute to `deleted` instead (default: true)
*
* @param {String} id The record's Id.
* @param {Object} options The options object.
* @return {Promise}
*/
}, {
key: "delete",
value: function _delete(id) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
virtual: true
};
return this.execute(function (transaction) {
return transaction.delete(id, options);
}, {
preloadIds: [id]
});
}
/**
* Same as {@link Collection#deleteAll}, but wrapped in its own transaction, execulding the parameter.
*
* @return {Promise}
*/
}, {
key: "deleteAll",
value: function () {
var _deleteAll = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee2() {
var _ref, data, recordIds;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return this.list({}, {
includeDeleted: false
});
case 2:
_ref = _context2.sent;
data = _ref.data;
recordIds = data.map(function (record) {
return record.id;
});
return _context2.abrupt("return", this.execute(function (transaction) {
return transaction.deleteAll(recordIds);
}, {
preloadIds: recordIds
}));
case 6:
case "end":
return _context2.stop();
}
}
}, _callee2, this);
}));
return function deleteAll() {
return _deleteAll.apply(this, arguments);
};
}()
/**
* The same as {@link CollectionTransaction#deleteAny}, but wrapped
* in its own transaction.
*
* @param {String} id The record's Id.
* @return {Promise}
*/
}, {
key: "deleteAny",
value: function deleteAny(id) {
return this.execute(function (txn) {
return txn.deleteAny(id);
}, {
preloadIds: [id]
});
}
/**
* Lists records from the local database.
*
* Params:
* - {Object} filters Filter the results (default: `{}`).
* - {String} order The order to apply (default: `-last_modified`).
*
* Options:
* - {Boolean} includeDeleted: Include virtually deleted records.
*
* @param {Object} params The filters and order to apply to the results.
* @param {Object} options The options object.
* @return {Promise}
*/
}, {
key: "list",
value: function () {
var _list = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee3() {
var params,
options,
results,
data,
_args3 = arguments;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
params = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : {};
options = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {
includeDeleted: false
};
params = (0, _objectSpread2.default)({
order: "-last_modified",
filters: {}
}, params);
_context3.next = 5;
return this.db.list(params);
case 5:
results = _context3.sent;
data = results;
if (!options.includeDeleted) {
data = results.filter(function (record) {
return record._status !== "deleted";
});
}
return _context3.abrupt("return", {
data: data,
permissions: {}
});
case 9:
case "end":
return _context3.stop();
}
}
}, _callee3, this);
}));
return function list() {
return _list.apply(this, arguments);
};
}()
/**
* Imports remote changes into the local database.
* This method is in charge of detecting the conflicts, and resolve them
* according to the specified strategy.
* @param {SyncResultObject} syncResultObject The sync result object.
* @param {Array} decodedChanges The list of changes to import in the local database.
* @param {String} strategy The {@link Collection.strategy} (default: MANUAL)
* @return {Promise}
*/
}, {
key: "importChanges",
value: function () {
var _importChanges = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee4(syncResultObject, decodedChanges) {
var _this3 = this;
var strategy,
_loop,
i,
data,
_args5 = arguments;
return _regenerator.default.wrap(function _callee4$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
strategy = _args5.length > 2 && _args5[2] !== undefined ? _args5[2] : Collection.strategy.MANUAL;
_context5.prev = 1;
_loop =
/*#__PURE__*/
_regenerator.default.mark(function _loop(i) {
var slice, _ref2, imports, resolved;
return _regenerator.default.wrap(function _loop$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
slice = decodedChanges.slice(i, i + IMPORT_CHUNK_SIZE);
_context4.next = 3;
return _this3.db.execute(function (transaction) {
var imports = slice.map(function (remote) {
// Store remote change into local database.
return importChange(transaction, remote, _this3.localFields, strategy);
});
var conflicts = imports.filter(function (i) {
return i.type === "conflicts";
}).map(function (i) {
return i.data;
});
var resolved = _this3._handleConflicts(transaction, conflicts, strategy);
return {
imports: imports,
resolved: resolved
};
}, {
preload: slice.map(function (record) {
return record.id;
})
});
case 3:
_ref2 = _context4.sent;
imports = _ref2.imports;
resolved = _ref2.resolved;
// Lists of created/updated/deleted records
imports.forEach(function (_ref3) {
var type = _ref3.type,
data = _ref3.data;
return syncResultObject.add(type, data);
}); // Automatically resolved conflicts (if not manual)
if (resolved.length > 0) {
syncResultObject.reset("conflicts").add("resolved", resolved);
}
case 8:
case "end":
return _context4.stop();
}
}
}, _loop, this);
});
i = 0;
case 4:
if (!(i < decodedChanges.length)) {
_context5.next = 9;
break;
}
return _context5.delegateYield(_loop(i), "t0", 6);
case 6:
i += IMPORT_CHUNK_SIZE;
_context5.next = 4;
break;
case 9:
_context5.next = 15;
break;
case 11:
_context5.prev = 11;
_context5.t1 = _context5["catch"](1);
data = {
type: "incoming",
message: _context5.t1.message,
stack: _context5.t1.stack
}; // XXX one error of the whole transaction instead of per atomic op
syncResultObject.add("errors", data);
case 15:
return _context5.abrupt("return", syncResultObject);
case 16:
case "end":
return _context5.stop();
}
}
}, _callee4, this, [[1, 11]]);
}));
return function importChanges(_x, _x2) {
return _importChanges.apply(this, arguments);
};
}()
/**
* Imports the responses of pushed changes into the local database.
* Basically it stores the timestamp assigned by the server into the local
* database.
* @param {SyncResultObject} syncResultObject The sync result object.
* @param {Array} toApplyLocally The list of changes to import in the local database.
* @param {Array} conflicts The list of conflicts that have to be resolved.
* @param {String} strategy The {@link Collection.strategy}.
* @return {Promise}
*/
}, {
key: "_applyPushedResults",
value: function () {
var _applyPushedResults2 = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee5(syncResultObject, toApplyLocally, conflicts) {
var _this4 = this;
var strategy,
toDeleteLocally,
toUpdateLocally,
_ref4,
published,
resolved,
_args6 = arguments;
return _regenerator.default.wrap(function _callee5$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
strategy = _args6.length > 3 && _args6[3] !== undefined ? _args6[3] : Collection.strategy.MANUAL;
toDeleteLocally = toApplyLocally.filter(function (r) {
return r.deleted;
});
toUpdateLocally = toApplyLocally.filter(function (r) {
return !r.deleted;
});
_context6.next = 5;
return this.db.execute(function (transaction) {
var updated = toUpdateLocally.map(function (record) {
var synced = markSynced(record);
transaction.update(synced);
return synced;
});
var deleted = toDeleteLocally.map(function (record) {
transaction.delete(record.id); // Amend result data with the deleted attribute set
return {
id: record.id,
deleted: true
};
});
var published = updated.concat(deleted); // Handle conflicts, if any
var resolved = _this4._handleConflicts(transaction, conflicts, strategy);
return {
published: published,
resolved: resolved
};
});
case 5:
_ref4 = _context6.sent;
published = _ref4.published;
resolved = _ref4.resolved;
syncResultObject.add("published", published);
if (resolved.length > 0) {
syncResultObject.reset("conflicts").reset("resolved").add("resolved", resolved);
}
return _context6.abrupt("return", syncResultObject);
case 11:
case "end":
return _context6.stop();
}
}
}, _callee5, this);
}));
return function _applyPushedResults(_x3, _x4, _x5) {
return _applyPushedResults2.apply(this, arguments);
};
}()
/**
* Handles synchronization conflicts according to specified strategy.
*
* @param {SyncResultObject} result The sync result object.
* @param {String} strategy The {@link Collection.strategy}.
* @return {Promise<Array<Object>>} The resolved conflicts, as an
* array of {accepted, rejected} objects
*/
}, {
key: "_handleConflicts",
value: function _handleConflicts(transaction, conflicts, strategy) {
var _this5 = this;
if (strategy === Collection.strategy.MANUAL) {
return [];
}
return conflicts.map(function (conflict) {
var resolution = strategy === Collection.strategy.CLIENT_WINS ? conflict.local : conflict.remote;
var rejected = strategy === Collection.strategy.CLIENT_WINS ? conflict.remote : conflict.local;
var accepted, status, id;
if (resolution === null) {
// We "resolved" with the server-side deletion. Delete locally.
// This only happens during SERVER_WINS because the local
// version of a record can never be null.
// We can get "null" from the remote side if we got a conflict
// and there is no remote version available; see kinto-http.js
// batch.js:aggregate.
transaction.delete(conflict.local.id);
accepted = null; // The record was deleted, but that status is "synced" with
// the server, so we don't need to push the change.
status = "synced";
id = conflict.local.id;
} else {
var updated = _this5._resolveRaw(conflict, resolution);
transaction.update(updated);
accepted = updated;
status = updated._status;
id = updated.id;
}
return {
rejected: rejected,
accepted: accepted,
id: id,
_status: status
};
});
}
/**
* Execute a bunch of operations in a transaction.
*
* This transaction should be atomic -- either all of its operations
* will succeed, or none will.
*
* The argument to this function is itself a function which will be
* called with a {@link CollectionTransaction}. Collection methods
* are available on this transaction, but instead of returning
* promises, they are synchronous. execute() returns a Promise whose
* value will be the return value of the provided function.
*
* Most operations will require access to the record itself, which
* must be preloaded by passing its ID in the preloadIds option.
*
* Options:
* - {Array} preloadIds: list of IDs to fetch at the beginning of
* the transaction
*
* @return {Promise} Resolves with the result of the given function
* when the transaction commits.
*/
}, {
key: "execute",
value: function execute(doOperations) {
var _this6 = this;
var _ref5 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref5$preloadIds = _ref5.preloadIds,
preloadIds = _ref5$preloadIds === void 0 ? [] : _ref5$preloadIds;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = preloadIds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var id = _step.value;
if (!this.idSchema.validate(id)) {
return Promise.reject(Error("Invalid Id: ".concat(id)));
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return this.db.execute(function (transaction) {
var txn = new CollectionTransaction(_this6, transaction);
var result = doOperations(txn);
txn.emitEvents();
return result;
}, {
preload: preloadIds
});
}
/**
* Resets the local records as if they were never synced; existing records are
* marked as newly created, deleted records are dropped.
*
* A next call to {@link Collection.sync} will thus republish the whole
* content of the local collection to the server.
*
* @return {Promise} Resolves with the number of processed records.
*/
}, {
key: "resetSyncStatus",
value: function () {
var _resetSyncStatus = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee6() {
var unsynced;
return _regenerator.default.wrap(function _callee6$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
_context7.next = 2;
return this.list({
filters: {
_status: ["deleted", "synced"]
},
order: ""
}, {
includeDeleted: true
});
case 2:
unsynced = _context7.sent;
_context7.next = 5;
return this.db.execute(function (transaction) {
unsynced.data.forEach(function (record) {
if (record._status === "deleted") {
// Garbage collect deleted records.
transaction.delete(record.id);
} else {
// Records that were synced become «created».
transaction.update((0, _objectSpread2.default)({}, record, {
last_modified: undefined,
_status: "created"
}));
}
});
});
case 5:
this._lastModified = null;
_context7.next = 8;
return this.db.saveLastModified(null);
case 8:
return _context7.abrupt("return", unsynced.data.length);
case 9:
case "end":
return _context7.stop();
}
}
}, _callee6, this);
}));
return function resetSyncStatus() {
return _resetSyncStatus.apply(this, arguments);
};
}()
/**
* Returns an object containing two lists:
*
* - `toDelete`: unsynced deleted records we can safely delete;
* - `toSync`: local updates to send to the server.
*
* @return {Promise}
*/
}, {
key: "gatherLocalChanges",
value: function () {
var _gatherLocalChanges = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee7() {
var unsynced, deleted;
return _regenerator.default.wrap(function _callee7$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
_context8.next = 2;
return this.list({
filters: {
_status: ["created", "updated"]
},
order: ""
});
case 2:
unsynced = _context8.sent;
_context8.next = 5;
return this.list({
filters: {
_status: "deleted"
},
order: ""
}, {
includeDeleted: true
});
case 5:
deleted = _context8.sent;
_context8.next = 8;
return Promise.all(unsynced.data.concat(deleted.data).map(this._encodeRecord.bind(this, "remote")));
case 8:
return _context8.abrupt("return", _context8.sent);
case 9:
case "end":
return _context8.stop();
}
}
}, _callee7, this);
}));
return function gatherLocalChanges() {
return _gatherLocalChanges.apply(this, arguments);
};
}()
/**
* Fetch remote changes, import them to the local database, and handle
* conflicts according to `options.strategy`. Then, updates the passed
* {@link SyncResultObject} with import results.
*
* Options:
* - {String} strategy: The selected sync strategy.
* - {String} expectedTimestamp: A timestamp to use as a "cache busting" query parameter.
* - {Array<String>} exclude: A list of record ids to exclude from pull.
* - {Object} headers: The HTTP headers to use in the request.
* - {int} retry: The number of retries to do if the HTTP request fails.
* - {int} lastModified: The timestamp to use in `?_since` query.
*
* @param {KintoClient.Collection} client Kinto client Collection instance.
* @param {SyncResultObject} syncResultObject The sync result object.
* @param {Object} options The options object.
* @return {Promise}
*/
}, {
key: "pullChanges",
value: function () {
var _pullChanges = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee8(client, syncResultObject) {
var _this7 = this;
var options,
since,
filters,
exclude_id,
_ref6,
data,
last_modified,
unquoted,
localSynced,
serverChanged,
emptyCollection,
e,
decodedChanges,
payload,
afterHooks,
_args9 = arguments;
return _regenerator.default.wrap(function _callee8$(_context9) {
while (1) {
switch (_context9.prev = _context9.next) {
case 0:
options = _args9.length > 2 && _args9[2] !== undefined ? _args9[2] : {};
if (syncResultObject.ok) {
_context9.next = 3;
break;
}
return _context9.abrupt("return", syncResultObject);
case 3:
if (!this.lastModified) {
_context9.next = 7;
break;
}
_context9.t0 = this.lastModified;
_context9.next = 10;
break;
case 7:
_context9.next = 9;
return this.db.getLastModified();
case 9:
_context9.t0 = _context9.sent;
case 10:
since = _context9.t0;
options = (0, _objectSpread2.default)({
strategy: Collection.strategy.MANUAL,
lastModified: since,
headers: {}
}, options); // Optionally ignore some records when pulling for changes.
// (avoid redownloading our own changes on last step of #sync())
if (options.exclude) {
// Limit the list of excluded records to the first 50 records in order
// to remain under de-facto URL size limit (~2000 chars).
// http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers/417184#417184
exclude_id = options.exclude.slice(0, 50).map(function (r) {
return r.id;
}).join(",");
filters = {
exclude_id: exclude_id
};
}
if (options.expectedTimestamp) {
filters = (0, _objectSpread2.default)({}, filters, {
_expected: options.expectedTimestamp
});
} // First fetch remote changes from the server
_context9.next = 16;
return client.listRecords({
// Since should be ETag (see https://github.com/Kinto/kinto.js/issues/356)
since: options.lastModified ? "".concat(options.lastModified) : undefined,
headers: options.headers,
retry: options.retry,
// Fetch every page by default (FIXME: option to limit pages, see #277)
pages: Infinity,
filters: filters
});
case 16:
_ref6 = _context9.sent;
data = _ref6.data;
last_modified = _ref6.last_modified;
// last_modified is the ETag header value (string).
// For retro-compatibility with first kinto.js versions
// parse it to integer.
unquoted = last_modified ? parseInt(last_modified, 10) : undefined; // Check if server was flushed.
// This is relevant for the Kinto demo server
// (and thus for many new comers).
localSynced = options.lastModified;
serverChanged = unquoted > options.lastModified;
emptyCollection = data.length === 0;
if (!(!options.exclude && localSynced && serverChanged && emptyCollection)) {
_context9.next = 26;
break;
}
e = new ServerWasFlushedError(localSynced, unquoted, "Server has been flushed. Client Side Timestamp: " + localSynced + " Server Side Timestamp: " + unquoted);
throw e;
case 26:
// Atomic updates are not sensible here because unquoted is not
// computed as a function of syncResultObject.lastModified.
// eslint-disable-next-line require-atomic-updates
syncResultObject.lastModified = unquoted; // Decode incoming changes.
_context9.next = 29;
return Promise.all(data.map(function (change) {
return _this7._decodeRecord("remote", change);
}));
case 29:
decodedChanges = _context9.sent;
// Hook receives decoded records.
payload = {
lastModified: unquoted,
changes: decodedChanges
};
_context9.next = 33;
return this.applyHook("incoming-changes", payload);
case 33:
afterHooks = _context9.sent;
if (!(afterHooks.changes.length > 0)) {
_context9.next = 37;
break;
}
_context9.next = 37;
return this.importChanges(syncResultObject, afterHooks.changes, options.strategy);
case 37:
return _context9.abrupt("return", syncResultObject);
case 38:
case "end":
return _context9.stop();
}
}
}, _callee8, this);
}));
return function pullChanges(_x6, _x7) {
return _pullChanges.apply(this, arguments);
};
}()
}, {
key: "applyHook",
value: function applyHook(hookName, payload) {
var _this8 = this;
if (typeof this.hooks[hookName] == "undefined") {
return Promise.resolve(payload);
}
return (0, _utils.waterfall)(this.hooks[hookName].map(function (hook) {
return function (record) {
var result = hook(payload, _this8);
var resultThenable = result && typeof result.then === "function";
var resultChanges = result && Object.prototype.hasOwnProperty.call(result, "changes");
if (!(resultThenable || resultChanges)) {
throw new Error("Invalid return value for hook: ".concat(JSON.stringify(result), " has no 'then()' or 'changes' properties"));
}
return result;
};
}), payload);
}
/**
* Publish local changes to the remote server and updates the passed
* {@link SyncResultObject} with publication results.
*
* Options:
* - {String} strategy: The selected sync strategy.
* - {Object} headers: The HTTP headers to use in the request.
* - {int} retry: The number of retries to do if the HTTP request fails.
*
* @param {KintoClient.Collection} client Kinto client Collection instance.
* @param {SyncResultObject} syncResultObject The sync result object.
* @param {Object} changes The change object.
* @param {Array} changes.toDelete The list of records to delete.
* @param {Array} changes.toSync The list of records to create/update.
* @param {Object} options The options object.
* @return {Promise}
*/
}, {
key: "pushChanges",
value: function () {
var _pushChanges = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee9(client, changes, syncResultObject) {
var _this9 = this;
var options,
safe,
toDelete,
toSync,
synced,
conflicts,
_iteratorNormalCompletion2,
_didIteratorError2,
_iteratorError2,
_iterator2,
_step2,
_step2$value,
type,
local,
remote,
safeLocal,
realLocal,
realRemote,
conflict,
missingRemotely,
published,
toApplyLocally,
decoded,
_args10 = arguments;
return _regenerator.default.wrap(function _callee9$(_context10) {
while (1) {
switch (_context10.prev = _context10.next) {
case 0:
options = _args10.length > 3 && _args10[3] !== undefined ? _args10[3] : {};
if (syncResultObject.ok) {
_context10.next = 3;
break;
}
return _context10.abrupt("return", syncResultObject);
case 3:
safe = !options.strategy || options.strategy !== Collection.CLIENT_WINS;
toDelete = changes.filter(function (r) {
return r._status == "deleted";
});
toSync = changes.filter(function (r) {
return r._status != "deleted";
}); // Perform a batch request with every changes.
_context10.next = 8;
return client.batch(function (batch) {
toDelete.forEach(function (r) {
// never published locally deleted records should not be pusblished
if (r.last_modified) {
batch.deleteRecord(r);
}
});
toSync.forEach(function (r) {
// Clean local fields (like _status) before sending to server.
var published = _this9.cleanLocalFields(r);
if (r._status === "created") {
batch.createRecord(published);
} else {
batch.updateRecord(published);
}
});
}, {
headers: options.headers,
retry: options.retry,
safe: safe,
aggregate: true
});
case 8:
synced = _context10.sent;
// Store outgoing errors into sync result object
syncResultObject.add("errors", synced.errors.map(function (e) {
return (0, _objectSpread2.default)({}, e, {
type: "outgoing"
});
})); // Store outgoing conflicts into sync result object
conflicts = [];
_iteratorNormalCompletion2 = true;
_didIteratorError2 = false;
_iteratorError2 = undefined;
_context10.prev = 14;
_iterator2 = synced.conflicts[Symbol.iterator]();
case 16:
if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) {
_context10.next = 33;
break;
}
_step2$value = _step2.value, type = _step2$value.type, local = _step2$value.local, remote = _step2$value.remote;
// Note: we ensure that local data are actually available, as they may
// be missing in the case of a published deletion.
safeLocal = local && local.data || {
id: remote.id
};
_context10.next = 21;
return this._decodeRecord("remote", safeLocal);
case 21:
realLocal = _context10.sent;
_context10.t0 = remote;
if (!_context10.t0) {
_context10.next = 27;
break;
}
_context10.next = 26;
return this._decodeRecord("remote", remote);
case 26:
_context10.t0 = _context10.sent;
case 27:
realRemote = _context10.t0;
conflict = {
type: type,
local: realLocal,
remote: realRemote
};
conflicts.push(conflict);
case 30:
_iteratorNormalCompletion2 = true;
_context10.next = 16;
break;
case 33:
_context10.next = 39;
break;
case 35:
_context10.prev = 35;
_context10.t1 = _context10["catch"](14);
_didIteratorError2 = true;
_iteratorError2 = _context10.t1;
case 39:
_context10.prev = 39;
_context10.prev = 40;
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
}
case 42:
_context10.prev = 42;
if (!_didIteratorError2) {
_context10.next = 45;
break;
}
throw _iteratorError2;
case 45:
return _context10.finish(42);
case 46:
return _context10.finish(39);
case 47:
syncResultObject.add("conflicts", conflicts); // Records that must be deleted are either deletions that were pushed
// to server (published) or deleted records that were never pushed (skipped).
missingRemotely = synced.skipped.map(function (r) {
return (0, _objectSpread2.default)({}, r, {
deleted: true
});
}); // For created and updated records, the last_modified coming from server
// will be stored locally.
// Reflect publication results locally using the response from
// the batch request.
published = synced.published.map(function (c) {
return c.data;
});
toApplyLocally = published.concat(missingRemotely); // Apply the decode transformers, if any
_context10.next = 53;
return Promise.all(toApplyLocally.map(function (record) {
return _this9._decodeRecord("remote", record);
}));
case 53:
decoded = _context10.sent;
if (!(decoded.length > 0 || conflicts.length > 0)) {
_context10.next = 57;
break;
}
_context10.next = 57;
return this._applyPushedResults(syncResultObject, decoded, conflicts, options.strategy);
case 57:
return _context10.abrupt("return", syncResultObject);
case 58:
case "end":
return _context10.stop();
}
}
}, _callee9, this, [[14, 35, 39, 47], [40,, 42, 46]]);
}));
return function pushChanges(_x8, _x9, _x10) {
return _pushChanges.apply(this, arguments);
};
}()
/**
* Return a copy of the specified record without the local fields.
*
* @param {Object} record A record with potential local fields.
* @return {Object}
*/
}, {
key: "cleanLocalFields",
value: function cleanLocalFields(record) {
var localKeys = RECORD_FIELDS_TO_CLEAN.concat(this.localFields);
return (0, _utils.omitKeys)(record, localKeys);
}
/**
* Resolves a conflict, updating local record according to proposed
* resolution — keeping remote record `last_modified` value as a reference for
* further batch sending.
*
* @param {Object} conflict The conflict object.
* @param {Object} resolution The proposed record.
* @return {Promise}
*/
}, {
key: "resolve",
value: function resolve(conflict, resolution) {
var _this10 = this;
return this.db.execute(function (transaction) {
var updated = _this10._resolveRaw(conflict, resolution);
transaction.update(updated);
return {
data: updated,
permissions: {}
};
});
}
/**
* @private
*/
}, {
key: "_resolveRaw",
value: function _resolveRaw(conflict, resolution) {
var resolved = (0, _objectSpread2.default)({}, resolution, {
// Ensure local record has the latest authoritative timestamp
last_modified: conflict.remote && conflict.remote.last_modified
}); // If the resolution object is strictly equal to the
// remote record, then we can mark it as synced locally.
// Otherwise, mark it as updated (so that the resolution is pushed).
var synced = (0, _utils.deepEqual)(resolved, conflict.remote);
return markStatus(resolved, synced ? "synced" : "updated");
}
/**
* Synchronize remote and local data. The promise will resolve with a
* {@link SyncResultObject}, though will reject:
*
* - if the server is currently backed off;
* - if the server has been detected flushed.
*
* Options:
* - {Object} headers: HTTP headers to attach to outgoing requests.
* - {String} expectedTimestamp: A timestamp to use as a "cache busting" query parameter.
* - {Number} retry: Number of retries when server fails to process the request (default: 1).
* - {Collection.strategy} strategy: See {@link Collection.strategy}.
* - {Boolean} ignoreBackoff: Force synchronization even if server is currently
* backed off.
* - {String} bucket: The remove bucket id to use (default: null)
* - {String} collection: The remove collection id to use (default: null)
* - {String} remote The remote Kinto server endpoint to use (default: null).
*
* @param {Object} options Options.
* @return {Promise}
* @throws {Error} If an invalid remote option is passed.
*/
}, {
key: "sync",
value: function () {
var _sync = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee10() {
var _this11 = this;
var options,
previousRemote,
seconds,
client,
result,
lastModified,
toSync,
resolvedUnsynced,
resolvedEncoded,
pullOpts,
_args11 = arguments;
return _regenerator.default.wrap(function _callee10$(_context11) {
while (1) {
switch (_context11.prev = _context11.next) {
case 0:
options = _args11.length > 0 && _args11[0] !== undefined ? _args11[0] : {
strategy: Collection.strategy.MANUAL,
headers: {},
retry: 1,
ignoreBackoff: false,
bucket: null,
collection: null,
remote: null,
expectedTimestamp: null
};
options = (0, _objectSpread2.default)({}, options, {
bucket: options.bucket || this.bucket,
collection: options.collection || this.name
});
previousRemote = this.api.remote;
if (options.remote) {
// Note: setting the remote ensures it's valid, throws when invalid.
this.api.remote = options.remote;
}
if (!(!options.ignoreBackoff && this.api.backoff > 0)) {
_context11.next = 7;
break;
}
seconds = Math.ceil(this.api.backoff / 1000);
return _context11.abrupt("return", Promise.reject(new Error("Server is asking clients to back off; retry in ".concat(seconds, "s or use the ignoreBackoff option."))));
case 7:
client = this.api.bucket(options.bucket).collection(options.collection);
result = new SyncResultObject();
_context11.prev = 9;
_context11.next = 12;
return this.pullMetadata(client, options);
case 12:
_context11.next = 14;
return this.pullChanges(client, result, options);
case 14:
lastModified = result.lastModified;
if (!(options.strategy != Collection.strategy.PULL_ONLY)) {
_context11.next = 32;
break;
}
_context11.next = 18;
return this.gatherLocalChanges();
case 18:
toSync = _context11.sent;
_context11.next = 21;
return this.pushChanges(client, toSync, result, options);
case 21:
// Publish local resolution of push conflicts to server (on CLIENT_WINS)
resolvedUnsynced = result.resolved.filter(function (r) {
return r._status !== "synced";
});
if (!(resolvedUnsynced.length > 0)) {
_context11.next = 28;
break;
}
_context11.next = 25;
return Promise.all(resolvedUnsynced.map(function (resolution) {
var record = resolution.accepted;
if (record === null) {
record = {
id: resolution.id,
_status: resolution._status
};
}
return _this11._encodeRecord("remote", record);
}));
case 25:
resolvedEncoded = _context11.sent;
_context11.next = 28;
return this.pushChanges(client, resolvedEncoded, result, options);
case 28:
if (!(result.published.length > 0)) {
_context11.next = 32;
break;
}
// Avoid redownloading our own changes during the last pull.
pullOpts = (0, _objectSpread2.default)({}, options, {
lastModified: lastModified,
exclude: result.published
});
_context11.next = 32;
return this.pullChanges(client, result, pullOpts);
case 32:
if (!result.ok) {
_context11.next = 36;
break;
}
_context11.next = 35;
return this.db.saveLastModified(result.lastModified);
case 35:
this._lastModified = _context11.sent;
case 36:
_context11.next = 42;
break;
case 38:
_context11.prev = 38;
_context11.t0 = _context11["catch"](9);
this.events.emit("sync:error", (0, _objectSpread2.default)({}, options, {
error: _context11.t0
}));
throw _context11.t0;
case 42:
_context11.prev = 42;
// Ensure API default remote is reverted if a custom one's been used
this.api.remote = previousRemote;
return _context11.finish(42);
case 45:
this.events.emit("sync:success", (0, _objectSpread2.default)({}, options, {
result: result
}));
return _context11.abrupt("return", result);
case 47:
case "end":
return _context11.stop();
}
}
}, _callee10, this, [[9, 38, 42, 45]]);
}));
return function sync() {
return _sync.apply(this, arguments);
};
}()
/**
* Load a list of records already synced with the remote server.
*
* The local records which are unsynced or whose timestamp is either missing
* or superior to those being loaded will be ignored.
*
* @deprecated Use {@link importBulk} instead.
* @param {Array} records The previously exported list of records to load.
* @return {Promise} with the effectively imported records.
*/
}, {
key: "loadDump",
value: function () {
var _loadDump = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee11(records) {
return _regenerator.default.wrap(function _callee11$(_context12) {
while (1) {
switch (_context12.prev = _context12.next) {
case 0:
return _context12.abrupt("return", this.importBulk(records));
case 1:
case "end":
return _context12.stop();
}
}
}, _callee11, this);
}));
return function loadDump(_x11) {
return _loadDump.apply(this, arguments);
};
}()
/**
* Load a list of records already synced with the remote server.
*
* The local records which are unsynced or whose timestamp is either missing
* or superior to those being loaded will be ignored.
*
* @param {Array} records The previously exported list of records to load.
* @return {Promise} with the effectively imported records.
*/
}, {
key: "importBulk",
value: function () {
var _importBulk = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee12(records) {
var _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, record, _ref7, data, existingById, newRecords;
return _regenerator.default.wrap(function _callee12$(_context13) {
while (1) {
switch (_context13.prev = _context13.next) {
case 0:
if (Array.isArray(records)) {
_context13.next = 2;
break;
}
throw new Error("Records is not an array.");
case 2:
_iteratorNormalCompletion3 = true;
_didIteratorError3 = false;
_iteratorError3 = undefined;
_context13.prev = 5;
_iterator3 = records[Symbol.iterator]();
case 7:
if (_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done) {
_context13.next = 16;
break;
}
record = _step3.value;
if (!(!Object.prototype.hasOwnProperty.call(record, "id") || !this.idSchema.validate(record.id))) {
_context13.next = 11;
break;
}
throw new Error("Record has invalid ID: " + JSON.stringify(record));
case 11:
if (record.last_modified) {
_context13.next = 13;
break;
}
throw new Error("Record has no last_modified value: " + JSON.stringify(record));
case 13:
_iteratorNormalCompletion3 = true;
_context13.next = 7;
break;
case 16:
_context13.next = 22;
break;
case 18:
_context13.prev = 18;
_context13.t0 = _context13["catch"](5);
_didIteratorError3 = true;
_iteratorError3 = _context13.t0;
case 22:
_context13.prev = 22;
_context13.prev = 23;
if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
_iterator3.return();
}
case 25:
_context13.prev = 25;
if (!_didIteratorError3) {
_context13.next = 28;
break;
}
throw _iteratorError3;
case 28:
return _context13.finish(25);
case 29:
return _context13.finish(22);
case 30:
_context13.next = 32;
return this.list({}, {
includeDeleted: true
});
case 32:
_ref7 = _context13.sent;
data = _ref7.data;
existingById = data.reduce(function (acc, record) {
acc[record.id] = record;
return acc;
}, {});
newRecords = records.filter(function (record) {
var localRecord = existingById[record.id];
var shouldKeep = // No local record with this id.
localRecord === undefined || // Or local record is synced
localRecord._status === "synced" && // And was synced from server
localRecord.last_modified !== undefined && // And is older than imported one.
record.last_modified > localRecord.last_modified;
return shouldKeep;
});
_context13.next = 38;
return this.db.importBulk(newRecords.map(markSynced));
case 38:
return _context13.abrupt("return", _context13.sent);
case 39:
case "end":
return _context13.stop();
}
}
}, _callee12, this, [[5, 18, 22, 30], [23,, 25, 29]]);
}));
return function importBulk(_x12) {
return _importBulk.apply(this, arguments);
};
}()
}, {
key: "pullMetadata",
value: function () {
var _pullMetadata = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee13(client) {
var options,
expectedTimestamp,
headers,
query,
metadata,
_args14 = arguments;
return _regenerator.default.wrap(function _callee13$(_context14) {
while (1) {
switch (_context14.prev = _context14.next) {
case 0:
options = _args14.length > 1 && _args14[1] !== undefined ? _args14[1] : {};
expectedTimestamp = options.expectedTimestamp, headers = options.headers;
query = expectedTimestamp ? {
query: {
_expected: expectedTimestamp
}
} : undefined;
_context14.next = 5;
return client.getData((0, _objectSpread2.default)({}, query, {
headers: headers
}));
case 5:
metadata = _context14.sent;
return _context14.abrupt("return", this.db.saveMetadata(metadata));
case 7:
case "end":
return _context14.stop();
}
}
}, _callee13, this);
}));
return function pullMetadata(_x13) {
return _pullMetadata.apply(this, arguments);
};
}()
}, {
key: "metadata",
value: function () {
var _metadata = (0, _asyncToGenerator2.default)(
/*#__PURE__*/
_regenerator.default.mark(function _callee14() {
return _regenerator.default.wrap(function _callee14$(_context15) {
while (1) {
switch (_context15.prev = _context15.next) {
case 0:
return _context15.abrupt("return", this.db.getMetadata());
case 1:
case "end":
return _context15.stop();
}
}
}, _callee14, this);
}));
return function metadata() {
return _metadata.apply(this, arguments);
};
}()
}, {
key: "name",
get: function get() {
return this._name;
}
/**
* The bucket name.
* @type {String}
*/
}, {
key: "bucket",
get: function get() {
return this._bucket;
}
/**
* The last modified timestamp.
* @type {Number}
*/
}, {
key: "lastModified",
get: function get() {
return this._lastModified;
}
/**
* Synchronization strategies. Available strategies are:
*
* - `MANUAL`: Conflicts will be reported in a dedicated array.
* - `SERVER_WINS`: Conflicts are resolved using remote data.
* - `CLIENT_WINS`: Conflicts are resolved using local data.
*
* @type {Object}
*/
}], [{
key: "strategy",
get: function get() {
return {
CLIENT_WINS: "client_wins",
SERVER_WINS: "server_wins",
PULL_ONLY: "pull_only",
MANUAL: "manual"
};
}
}]);
return Collection;
}();
/**
* A Collection-oriented wrapper for an adapter's transaction.
*
* This defines the high-level functions available on a collection.
* The collection itself offers functions of the same name. These will
* perform just one operation in its own transaction.
*/
exports.default = Collection;
var CollectionTransaction =
/*#__PURE__*/
function () {
function CollectionTransaction(collection, adapterTransaction) {
(0, _classCallCheck2.default)(this, CollectionTransaction);
this.collection = collection;
this.adapterTransaction = adapterTransaction;
this._events = [];
}
(0, _createClass2.default)(CollectionTransaction, [{
key: "_queueEvent",
value: function _queueEvent(action, payload) {
this._events.push({
action: action,
payload: payload
});
}
/**
* Emit queued events, to be called once every transaction operations have
* been executed successfully.
*/
}, {
key: "emitEvents",
value: function emitEvents() {
var _iteratorNormalCompletion4 = true;
var _didIteratorError4 = false;
var _iteratorError4 = undefined;
try {
for (var _iterator4 = this._events[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
var _step4$value = _step4.value,
action = _step4$value.action,
payload = _step4$value.payload;
this.collection.events.emit(action, payload);
}
} catch (err) {
_didIteratorError4 = true;
_iteratorError4 = err;
} finally {
try {
if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
_iterator4.return();
}
} finally {
if (_didIteratorError4) {
throw _iteratorError4;
}
}
}
if (this._events.length > 0) {
var targets = this._events.map(function (_ref8) {
var action = _ref8.action,
payload = _ref8.payload;
return (0, _objectSpread2.default)({
action: action
}, payload);
});
this.collection.events.emit("change", {
targets: targets
});
}
this._events = [];
}
/**
* Retrieve a record by its id from the local database, or
* undefined if none exists.
*
* This will also return virtually deleted records.
*
* @param {String} id
* @return {Object}
*/
}, {
key: "getAny",
value: function getAny(id) {
var record = this.adapterTransaction.get(id);
return {
data: record,
permissions: {}
};
}
/**
* Retrieve a record by its id from the local database.
*
* Options:
* - {Boolean} includeDeleted: Include virtually deleted records.
*
* @param {String} id
* @param {Object} options
* @return {Object}
*/
}, {
key: "get",
value: function get(id) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
includeDeleted: false
};
var res = this.getAny(id);
if (!res.data || !options.includeDeleted && res.data._status === "deleted") {
throw new Error("Record with id=".concat(id, " not found."));
}
return res;
}
/**
* Deletes a record from the local database.
*
* Options:
* - {Boolean} virtual: When set to `true`, doesn't actually delete the record,
* update its `_status` attribute to `deleted` instead (default: true)
*
* @param {String} id The record's Id.
* @param {Object} options The options object.
* @return {Object}
*/
}, {
key: "delete",
value: function _delete(id) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
virtual: true
};
// Ensure the record actually exists.
var existing = this.adapterTransaction.get(id);
var alreadyDeleted = existing && existing._status == "deleted";
if (!existing || alreadyDeleted && options.virtual) {
throw new Error("Record with id=".concat(id, " not found."));
} // Virtual updates status.
if (options.virtual) {
this.adapterTransaction.update(markDeleted(existing));
} else {
// Delete for real.
this.adapterTransaction.delete(id);
}
this._queueEvent("delete", {
data: existing
});
return {
data: existing,
permissions: {}
};
}
/**
* Soft delete all records from the local database.
*
* @param {Array} ids Array of non-deleted Record Ids.
* @return {Object}
*/
}, {
key: "deleteAll",
value: function deleteAll(ids) {
var _this12 = this;
var existingRecords = [];
ids.forEach(function (id) {
existingRecords.push(_this12.adapterTransaction.get(id));
_this12.delete(id);
});
this._queueEvent("deleteAll", {
data: existingRecords
});
return {
data: existingRecords,
permissions: {}
};
}
/**
* Deletes a record from the local database, if any exists.
* Otherwise, do nothing.
*
* @param {String} id The record's Id.
* @return {Object}
*/
}, {
key: "deleteAny",
value: function deleteAny(id) {
var existing = this.adapterTransaction.get(id);
if (existing) {
this.adapterTransaction.update(markDeleted(existing));
this._queueEvent("delete", {
data: existing
});
}
return {
data: (0, _objectSpread2.default)({
id: id
}, existing),
deleted: !!existing,
permissions: {}
};
}
/**
* Adds a record to the local database, asserting that none
* already exist with this ID.
*
* @param {Object} record, which must contain an ID
* @return {Object}
*/
}, {
key: "create",
value: function create(record) {
if ((0, _typeof2.default)(record) !== "object") {
throw new Error("Record is not an object.");
}
if (!Object.prototype.hasOwnProperty.call(record, "id")) {
throw new Error("Cannot create a record missing id");
}
if (!this.collection.idSchema.validate(record.id)) {
throw new Error("Invalid Id: ".concat(record.id));
}
this.adapterTransaction.create(record);
this._queueEvent("create", {
data: record
});
return {
data: record,
permissions: {}
};
}
/**
* Updates a record from the local database.
*
* Options:
* - {Boolean} synced: Sets record status to "synced" (default: false)
* - {Boolean} patch: Extends the existing record instead of overwriting it
* (default: false)
*
* @param {Object} record
* @param {Object} options
* @return {Object}
*/
}, {
key: "update",
value: function update(record) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
synced: false,
patch: false
};
if ((0, _typeof2.default)(record) !== "object") {
throw new Error("Record is not an object.");
}
if (!Object.prototype.hasOwnProperty.call(record, "id")) {
throw new Error("Cannot update a record missing id.");
}
if (!this.collection.idSchema.validate(record.id)) {
throw new Error("Invalid Id: ".concat(record.id));
}
var oldRecord = this.adapterTransaction.get(record.id);
if (!oldRecord) {
throw new Error("Record with id=".concat(record.id, " not found."));
}
var newRecord = options.patch ? (0, _objectSpread2.default)({}, oldRecord, record) : record;
var updated = this._updateRaw(oldRecord, newRecord, options);
this.adapterTransaction.update(updated);
this._queueEvent("update", {
data: updated,
oldRecord: oldRecord
});
return {
data: updated,
oldRecord: oldRecord,
permissions: {}
};
}
/**
* Lower-level primitive for updating a record while respecting
* _status and last_modified.
*
* @param {Object} oldRecord: the record retrieved from the DB
* @param {Object} newRecord: the record to replace it with
* @return {Object}
*/
}, {
key: "_updateRaw",
value: function _updateRaw(oldRecord, newRecord) {
var _ref9 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
_ref9$synced = _ref9.synced,
synced = _ref9$synced === void 0 ? false : _ref9$synced;
var updated = (0, _objectSpread2.default)({}, newRecord); // Make sure to never loose the existing timestamp.
if (oldRecord && oldRecord.last_modified && !updated.last_modified) {
updated.last_modified = oldRecord.last_modified;
} // If only local fields have changed, then keep record as synced.
// If status is created, keep record as created.
// If status is deleted, mark as updated.
var isIdentical = oldRecord && recordsEqual(oldRecord, updated, this.collection.localFields);
var keepSynced = isIdentical && oldRecord._status == "synced";
var neverSynced = !oldRecord || oldRecord && oldRecord._status == "created";
var newStatus = keepSynced || synced ? "synced" : neverSynced ? "created" : "updated";
return markStatus(updated, newStatus);
}
/**
* Upsert a record into the local database.
*
* This record must have an ID.
*
* If a record with this ID already exists, it will be replaced.
* Otherwise, this record will be inserted.
*
* @param {Object} record
* @return {Object}
*/
}, {
key: "upsert",
value: function upsert(record) {
if ((0, _typeof2.default)(record) !== "object") {
throw new Error("Record is not an object.");
}
if (!Object.prototype.hasOwnProperty.call(record, "id")) {
throw new Error("Cannot update a record missing id.");
}
if (!this.collection.idSchema.validate(record.id)) {
throw new Error("Invalid Id: ".concat(record.id));
}
var oldRecord = this.adapterTransaction.get(record.id);
var updated = this._updateRaw(oldRecord, record);
this.adapterTransaction.update(updated); // Don't return deleted records -- pretend they are gone
if (oldRecord && oldRecord._status == "deleted") {
oldRecord = undefined;
}
if (oldRecord) {
this._queueEvent("update", {
data: updated,
oldRecord: oldRecord
});
} else {
this._queueEvent("create", {
data: updated
});
}
return {
data: updated,
oldRecord: oldRecord,
permissions: {}
};
}
}]);
return CollectionTransaction;
}();
exports.CollectionTransaction = CollectionTransaction;
},{"./adapters/IDB":323,"./adapters/base":324,"./utils":327,"@babel/runtime/helpers/assertThisInitialized":280,"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/getPrototypeOf":286,"@babel/runtime/helpers/inherits":287,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/possibleConstructorReturn":296,"@babel/runtime/helpers/typeof":301,"@babel/runtime/helpers/wrapNativeSuper":302,"@babel/runtime/regenerator":305,"uuid":317}],326:[function(require,module,exports){
(function (global){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _events = require("events");
var _kintoHttp = _interopRequireDefault(require("kinto-http"));
var _base = _interopRequireDefault(require("./adapters/base"));
var _IDB = _interopRequireDefault(require("./adapters/IDB"));
var _KintoBase2 = _interopRequireDefault(require("./KintoBase"));
// babel-polyfill can only be imported once
if (!global._babelPolyfill) {
require("@babel/polyfill");
}
var Kinto =
/*#__PURE__*/
function (_KintoBase) {
(0, _inherits2.default)(Kinto, _KintoBase);
(0, _createClass2.default)(Kinto, null, [{
key: "adapters",
/**
* Provides a public access to the base adapter classes. Users can create
* a custom DB adapter by extending BaseAdapter.
*
* @type {Object}
*/
get: function get() {
return {
BaseAdapter: _base.default,
IDB: _IDB.default
};
}
}]);
function Kinto() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
(0, _classCallCheck2.default)(this, Kinto);
var defaults = {
adapter: Kinto.adapters.IDB,
events: new _events.EventEmitter(),
ApiClass: _kintoHttp.default
};
return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Kinto).call(this, (0, _objectSpread2.default)({}, defaults, options)));
}
return Kinto;
}(_KintoBase2.default); // This fixes compatibility with CommonJS required by browserify.
// See http://stackoverflow.com/questions/33505992/babel-6-changes-how-it-exports-default/33683495#33683495
exports.default = Kinto;
if ((typeof module === "undefined" ? "undefined" : (0, _typeof2.default)(module)) === "object") {
module.exports = Kinto;
}
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./KintoBase":322,"./adapters/IDB":323,"./adapters/base":324,"@babel/polyfill":1,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/getPrototypeOf":286,"@babel/runtime/helpers/inherits":287,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/possibleConstructorReturn":296,"@babel/runtime/helpers/typeof":301,"events":306,"kinto-http":314}],327:[function(require,module,exports){
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.sortObjects = sortObjects;
exports.filterObject = filterObject;
exports.filterObjects = filterObjects;
exports.waterfall = waterfall;
exports.deepEqual = deepEqual;
exports.omitKeys = omitKeys;
exports.arrayEqual = arrayEqual;
exports.transformSubObjectFilters = transformSubObjectFilters;
exports.RE_RECORD_ID = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var RE_RECORD_ID = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
/**
* Checks if a value is undefined.
* @param {Any} value
* @return {Boolean}
*/
exports.RE_RECORD_ID = RE_RECORD_ID;
function _isUndefined(value) {
return typeof value === "undefined";
}
/**
* Sorts records in a list according to a given ordering.
*
* @param {String} order The ordering, eg. `-last_modified`.
* @param {Array} list The collection to order.
* @return {Array}
*/
function sortObjects(order, list) {
var hasDash = order[0] === "-";
var field = hasDash ? order.slice(1) : order;
var direction = hasDash ? -1 : 1;
return list.slice().sort(function (a, b) {
if (a[field] && _isUndefined(b[field])) {
return direction;
}
if (b[field] && _isUndefined(a[field])) {
return -direction;
}
if (_isUndefined(a[field]) && _isUndefined(b[field])) {
return 0;
}
return a[field] > b[field] ? direction : -direction;
});
}
/**
* Test if a single object matches all given filters.
*
* @param {Object} filters The filters object.
* @param {Object} entry The object to filter.
* @return {Boolean}
*/
function filterObject(filters, entry) {
return Object.keys(filters).every(function (filter) {
var value = filters[filter];
if (Array.isArray(value)) {
return value.some(function (candidate) {
return candidate === entry[filter];
});
} else if ((0, _typeof2.default)(value) === "object") {
return filterObject(value, entry[filter]);
} else if (!Object.prototype.hasOwnProperty.call(entry, filter)) {
console.error("The property ".concat(filter, " does not exist"));
return false;
}
return entry[filter] === value;
});
}
/**
* Filters records in a list matching all given filters.
*
* @param {Object} filters The filters object.
* @param {Array} list The collection to filter.
* @return {Array}
*/
function filterObjects(filters, list) {
return list.filter(function (entry) {
return filterObject(filters, entry);
});
}
/**
* Resolves a list of functions sequentially, which can be sync or async; in
* case of async, functions must return a promise.
*
* @param {Array} fns The list of functions.
* @param {Any} init The initial value.
* @return {Promise}
*/
function waterfall(fns, init) {
if (!fns.length) {
return Promise.resolve(init);
}
return fns.reduce(function (promise, nextFn) {
return promise.then(nextFn);
}, Promise.resolve(init));
}
/**
* Simple deep object comparison function. This only supports comparison of
* serializable JavaScript objects.
*
* @param {Object} a The source object.
* @param {Object} b The compared object.
* @return {Boolean}
*/
function deepEqual(a, b) {
if (a === b) {
return true;
}
if ((0, _typeof2.default)(a) !== (0, _typeof2.default)(b)) {
return false;
}
if (!(a && (0, _typeof2.default)(a) == "object") || !(b && (0, _typeof2.default)(b) == "object")) {
return false;
}
if (Object.keys(a).length !== Object.keys(b).length) {
return false;
}
for (var k in a) {
if (!deepEqual(a[k], b[k])) {
return false;
}
}
return true;
}
/**
* Return an object without the specified keys.
*
* @param {Object} obj The original object.
* @param {Array} keys The list of keys to exclude.
* @return {Object} A copy without the specified keys.
*/
function omitKeys(obj) {
var keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var result = (0, _objectSpread2.default)({}, obj);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var key = _step.value;
delete result[key];
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return result;
}
function arrayEqual(a, b) {
if (a.length !== b.length) {
return false;
}
for (var i = a.length; i--;) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
function makeNestedObjectFromArr(arr, val, nestedFiltersObj) {
var last = arr.length - 1;
return arr.reduce(function (acc, cv, i) {
if (i === last) {
return acc[cv] = val;
} else if (Object.prototype.hasOwnProperty.call(acc, cv)) {
return acc[cv];
} else {
return acc[cv] = {};
}
}, nestedFiltersObj);
}
function transformSubObjectFilters(filtersObj) {
var transformedFilters = {};
for (var key in filtersObj) {
var keysArr = key.split(".");
var val = filtersObj[key];
makeNestedObjectFromArr(keysArr, val, transformedFilters);
}
return transformedFilters;
}
},{"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/typeof":301}]},{},[326])(326)
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvZXM2L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9hcnJheS9pbmNsdWRlcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvZm4vb2JqZWN0L2VudHJpZXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ZuL29iamVjdC9nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9vYmplY3QvdmFsdWVzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9wcm9taXNlL2ZpbmFsbHkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ZuL3N0cmluZy9wYWQtZW5kLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9zdHJpbmcvcGFkLXN0YXJ0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9zeW1ib2wvYXN5bmMtaXRlcmF0b3IuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2EtZnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2EtbnVtYmVyLXZhbHVlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hZGQtdG8tdW5zY29wYWJsZXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLWluc3RhbmNlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWNvcHktd2l0aGluLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1maWxsLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1pbmNsdWRlcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktbWV0aG9kcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktcmVkdWNlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYmluZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY2xhc3NvZi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29mLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLXN0cm9uZy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29sbGVjdGlvbi13ZWFrLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb3JlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jcmVhdGUtcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2N0eC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGF0ZS10by1pc28tc3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kYXRlLXRvLXByaW1pdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVmaW5lZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RvbS1jcmVhdGUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2VudW0tYnVnLWtleXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2VudW0ta2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy1pcy1yZWdleHAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19maXgtcmUtd2tzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mbGFncy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZm9yLW9mLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hhcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGlkZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faHRtbC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faWU4LWRvbS1kZWZpbmUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2luaGVyaXQtaWYtcmVxdWlyZWQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ludm9rZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXktaXRlci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLWludGVnZXIuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtcmVnZXhwLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWNhbGwuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItY3JlYXRlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRlZmluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1kZXRlY3QuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlcmF0b3JzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19saWJyYXJ5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWV4cG0xLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWZyb3VuZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1sb2cxcC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1zaWduLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19taWNyb3Rhc2suanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX25ldy1wcm9taXNlLWNhcGFiaWxpdHkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1hc3NpZ24uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1jcmVhdGUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcGQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BuLWV4dC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcG4uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ3BvLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy1pbnRlcm5hbC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWtleXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1waWUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1zYXAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC10by1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb3duLWtleXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BhcnNlLWZsb2F0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wYXJzZS1pbnQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BlcmZvcm0uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Byb21pc2UtcmVzb2x2ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvcGVydHktZGVzYy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUtYWxsLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2FtZS12YWx1ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXByb3RvLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtc3BlY2llcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC1rZXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3BlY2llcy1jb25zdHJ1Y3Rvci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaWN0LW1ldGhvZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWF0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctY29udGV4dC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWh0bWwuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1wYWQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1yZXBlYXQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy10cmltLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctd3MuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Rhc2suanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWFic29sdXRlLWluZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLXByaW1pdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQtYXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLWJ1ZmZlci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3VpZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdXNlci1hZ2VudC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdmFsaWRhdGUtY29sbGVjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLWRlZmluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLWV4dC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuY29weS13aXRoaW4uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmV2ZXJ5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maWxsLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maWx0ZXIuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZpbmQtaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZpbmQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZvci1lYWNoLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5mcm9tLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pbmRleC1vZi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuaXMtYXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lml0ZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5qb2luLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5sYXN0LWluZGV4LW9mLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5tYXAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lm9mLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5yZWR1Y2UtcmlnaHQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnJlZHVjZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuc2xpY2UuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNvbWUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNvcnQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNwZWNpZXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmRhdGUubm93LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLnRvLWlzby1zdHJpbmcuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmRhdGUudG8tanNvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS50by1wcmltaXRpdmUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmRhdGUudG8tc3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5iaW5kLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5oYXMtaW5zdGFuY2UuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmZ1bmN0aW9uLm5hbWUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hcC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5hY29zaC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5hc2luaC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5hdGFuaC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5jYnJ0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmNsejMyLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmNvc2guanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguZXhwbTEuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguZnJvdW5kLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmh5cG90LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmltdWwuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgubG9nMTAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgubG9nMXAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgubG9nMi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5zaWduLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLnNpbmguanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgudGFuaC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC50cnVuYy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmNvbnN0cnVjdG9yLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuZXBzaWxvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmlzLWZpbml0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmlzLWludGVnZXIuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1uYW4uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1zYWZlLWludGVnZXIuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5tYXgtc2FmZS1pbnRlZ2VyLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIubWluLXNhZmUtaW50ZWdlci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLnBhcnNlLWZsb2F0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIucGFyc2UtaW50LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIudG8tZml4ZWQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci50by1wcmVjaXNpb24uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5jcmVhdGUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5kZWZpbmUtcHJvcGVydGllcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmRlZmluZS1wcm9wZXJ0eS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmZyZWV6ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktbmFtZXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtcHJvdG90eXBlLW9mLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuaXMtZXh0ZW5zaWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmlzLWZyb3plbi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmlzLXNlYWxlZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmlzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3Qua2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnByZXZlbnQtZXh0ZW5zaW9ucy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnNlYWwuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5zZXQtcHJvdG90eXBlLW9mLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QudG8tc3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5wYXJzZS1mbG9hdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucGFyc2UtaW50LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5wcm9taXNlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmFwcGx5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmNvbnN0cnVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5kZWZpbmUtcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVsZXRlLXByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmVudW1lcmF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3IuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LXByb3RvdHlwZS1vZi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5nZXQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuaGFzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmlzLWV4dGVuc2libGUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3Qub3duLWtleXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QucHJldmVudC1leHRlbnNpb25zLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldC1wcm90b3R5cGUtb2YuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3Quc2V0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuY29uc3RydWN0b3IuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5mbGFncy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLm1hdGNoLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAucmVwbGFjZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLnNlYXJjaC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLnNwbGl0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAudG8tc3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zZXQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5hbmNob3IuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5iaWcuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5ibGluay5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmJvbGQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5jb2RlLXBvaW50LWF0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuZW5kcy13aXRoLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuZml4ZWQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5mb250Y29sb3IuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5mb250c2l6ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZyb20tY29kZS1wb2ludC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmluY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaXRhbGljcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcubGluay5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnJhdy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnJlcGVhdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnNtYWxsLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc3RhcnRzLXdpdGguanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdHJpa2UuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdWIuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdXAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy50cmltLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zeW1ib2wuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmFycmF5LWJ1ZmZlci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuZGF0YS12aWV3LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5mbG9hdDMyLWFycmF5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5mbG9hdDY0LWFycmF5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5pbnQxNi1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuaW50MzItYXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmludDgtYXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQxNi1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQudWludDMyLWFycmF5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQudWludDgtY2xhbXBlZC1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYud2Vhay1tYXAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LndlYWstc2V0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5hcnJheS5pbmNsdWRlcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LmVudHJpZXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QudmFsdWVzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5wcm9taXNlLmZpbmFsbHkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN0cmluZy5wYWQtZW5kLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcucGFkLXN0YXJ0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zeW1ib2wuYXN5bmMtaXRlcmF0b3IuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvd2ViLmRvbS5pdGVyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuaW1tZWRpYXRlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL3dlYi50aW1lcnMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL3dlYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL3JlZ2VuZXJhdG9yLXJ1bnRpbWUvcnVudGltZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2FycmF5V2l0aEhvbGVzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvYXJyYXlXaXRob3V0SG9sZXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2suanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jb25zdHJ1Y3QuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jcmVhdGVDbGFzcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2RlZmluZVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZ2V0UHJvdG90eXBlT2YuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbmhlcml0cy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlRGVmYXVsdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlV2lsZGNhcmQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pc05hdGl2ZUZ1bmN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvaXRlcmFibGVUb0FycmF5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvaXRlcmFibGVUb0FycmF5TGltaXQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9ub25JdGVyYWJsZVJlc3QuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9ub25JdGVyYWJsZVNwcmVhZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL29iamVjdFNwcmVhZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zZXRQcm90b3R5cGVPZi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL3NsaWNlZFRvQXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy90b0FycmF5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvdG9Db25zdW1hYmxlQXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy90eXBlb2YuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy93cmFwTmF0aXZlU3VwZXIuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvbm9kZV9tb2R1bGVzL3JlZ2VuZXJhdG9yLXJ1bnRpbWUvcnVudGltZS1tb2R1bGUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvbm9kZV9tb2R1bGVzL3JlZ2VuZXJhdG9yLXJ1bnRpbWUvcnVudGltZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9yZWdlbmVyYXRvci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzIiwibm9kZV9tb2R1bGVzL2tpbnRvLWh0dHAvbGliL2Jhc2UuanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvYmF0Y2guanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvYnVja2V0LmpzIiwibm9kZV9tb2R1bGVzL2tpbnRvLWh0dHAvbGliL2NvbGxlY3Rpb24uanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvZW5kcG9pbnQuanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvZXJyb3JzLmpzIiwibm9kZV9tb2R1bGVzL2tpbnRvLWh0dHAvbGliL2h0dHAuanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvcmVxdWVzdHMuanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvdXRpbHMuanMiLCJub2RlX21vZHVsZXMvdXVpZC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy91dWlkL2xpYi9ieXRlc1RvVXVpZC5qcyIsIm5vZGVfbW9kdWxlcy91dWlkL2xpYi9ybmctYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy91dWlkL3YxLmpzIiwibm9kZV9tb2R1bGVzL3V1aWQvdjQuanMiLCJzcmMvS2ludG9CYXNlLmpzIiwic3JjL2FkYXB0ZXJzL0lEQi5qcyIsInNyYy9hZGFwdGVycy9iYXNlLmpzIiwic3JjL2NvbGxlY3Rpb24uanMiLCJzcmMvaW5kZXguanMiLCJzcmMvdXRpbHMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSUE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBOztBQ0RBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2dEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqdEJBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzZ0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsMENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNpQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDandDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDamdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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LEtBQUssSUFBVixFQUFnQjtBQUNkLGFBQVEsR0FBRyxDQUFDLEVBQUQsQ0FBSCxHQUFVLEdBQWxCO0FBQ0QsS0FGRCxNQUVPLElBQUksTUFBTSxDQUFDLFNBQVAsQ0FBaUIsY0FBakIsQ0FBZ0MsSUFBaEMsQ0FBcUMsR0FBckMsRUFBMEMsRUFBMUMsQ0FBSixFQUFtRDtBQUN4RCxhQUFPLEdBQUcsQ0FBQyxFQUFELENBQVY7QUFDRCxLQUZNLE1BRUE7QUFDTCxhQUFRLEdBQUcsQ0FBQyxFQUFELENBQUgsR0FBVSxFQUFsQjtBQUNEO0FBQ0YsR0FSTSxFQVFKLGdCQVJJLENBQVA7QUFTRDs7QUFFTSxTQUFTLHlCQUFULENBQW1DLFVBQW5DLEVBQStDO0FBQ3BELE1BQU0sa0JBQWtCLEdBQUcsRUFBM0I7O0FBQ0EsT0FBSyxJQUFNLEdBQVgsSUFBa0IsVUFBbEIsRUFBOEI7QUFDNUIsUUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLEtBQUosQ0FBVSxHQUFWLENBQWhCO0FBQ0EsUUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLEdBQUQsQ0FBdEI7QUFDQSxJQUFBLHVCQUF1QixDQUFDLE9BQUQsRUFBVSxHQUFWLEVBQWUsa0JBQWYsQ0FBdkI7QUFDRDs7QUFDRCxTQUFPLGtCQUFQO0FBQ0QiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCJcInVzZSBzdHJpY3RcIjtcblxucmVxdWlyZShcImNvcmUtanMvZXM2XCIpO1xuXG5yZXF1aXJlKFwiY29yZS1qcy9mbi9hcnJheS9pbmNsdWRlc1wiKTtcblxucmVxdWlyZShcImNvcmUtanMvZm4vc3RyaW5nL3BhZC1zdGFydFwiKTtcblxucmVxdWlyZShcImNvcmUtanMvZm4vc3RyaW5nL3BhZC1lbmRcIik7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL2ZuL3N5bWJvbC9hc3luYy1pdGVyYXRvclwiKTtcblxucmVxdWlyZShcImNvcmUtanMvZm4vb2JqZWN0L2dldC1vd24tcHJvcGVydHktZGVzY3JpcHRvcnNcIik7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL2ZuL29iamVjdC92YWx1ZXNcIik7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL2ZuL29iamVjdC9lbnRyaWVzXCIpO1xuXG5yZXF1aXJlKFwiY29yZS1qcy9mbi9wcm9taXNlL2ZpbmFsbHlcIik7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL3dlYlwiKTtcblxucmVxdWlyZShcInJlZ2VuZXJhdG9yLXJ1bnRpbWUvcnVudGltZVwiKTtcblxuaWYgKGdsb2JhbC5fYmFiZWxQb2x5ZmlsbCAmJiB0eXBlb2YgY29uc29sZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBjb25zb2xlLndhcm4pIHtcbiAgY29uc29sZS53YXJuKFwiQGJhYmVsL3BvbHlmaWxsIGlzIGxvYWRlZCBtb3JlIHRoYW4gb25jZSBvbiB0aGlzIHBhZ2UuIFRoaXMgaXMgcHJvYmFibHkgbm90IGRlc2lyYWJsZS9pbnRlbmRlZCBcIiArIFwiYW5kIG1heSBoYXZlIGNvbnNlcXVlbmNlcyBpZiBkaWZmZXJlbnQgdmVyc2lvbnMgb2YgdGhlIHBvbHlmaWxscyBhcmUgYXBwbGllZCBzZXF1ZW50aWFsbHkuIFwiICsgXCJJZiB5b3UgZG8gbmVlZCB0byBsb2FkIHRoZSBwb2x5ZmlsbCBtb3JlIHRoYW4gb25jZSwgdXNlIEBiYWJlbC9wb2x5ZmlsbC9ub0NvbmZsaWN0IFwiICsgXCJpbnN0ZWFkIHRvIGJ5cGFzcyB0aGUgd2FybmluZy5cIik7XG59XG5cbmdsb2JhbC5fYmFiZWxQb2x5ZmlsbCA9IHRydWU7IiwicmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3ltYm9sJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuY3JlYXRlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnR5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnRpZXMnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3InKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtcHJvdG90eXBlLW9mJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3Qua2V5cycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktbmFtZXMnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC5mcmVlemUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC5zZWFsJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QucHJldmVudC1leHRlbnNpb25zJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuaXMtZnJvemVuJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuaXMtc2VhbGVkJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuaXMtZXh0ZW5zaWJsZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmFzc2lnbicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmlzJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3Quc2V0LXByb3RvdHlwZS1vZicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuZnVuY3Rpb24uYmluZCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuZnVuY3Rpb24ubmFtZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuZnVuY3Rpb24uaGFzLWluc3RhbmNlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5wYXJzZS1pbnQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnBhcnNlLWZsb2F0Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5udW1iZXIuY29uc3RydWN0b3InKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm51bWJlci50by1maXhlZCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubnVtYmVyLnRvLXByZWNpc2lvbicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubnVtYmVyLmVwc2lsb24nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm51bWJlci5pcy1maW5pdGUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm51bWJlci5pcy1pbnRlZ2VyJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5udW1iZXIuaXMtbmFuJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5udW1iZXIuaXMtc2FmZS1pbnRlZ2VyJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5udW1iZXIubWF4LXNhZmUtaW50ZWdlcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubnVtYmVyLm1pbi1zYWZlLWludGVnZXInKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm51bWJlci5wYXJzZS1mbG9hdCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubnVtYmVyLnBhcnNlLWludCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5hY29zaCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5hc2luaCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5hdGFuaCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5jYnJ0Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmNsejMyJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmNvc2gnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGguZXhwbTEnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGguZnJvdW5kJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmh5cG90Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmltdWwnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGgubG9nMTAnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGgubG9nMXAnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGgubG9nMicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5zaWduJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLnNpbmgnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGgudGFuaCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC50cnVuYycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLmZyb20tY29kZS1wb2ludCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLnJhdycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLnRyaW0nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5pdGVyYXRvcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLmNvZGUtcG9pbnQtYXQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5lbmRzLXdpdGgnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5pbmNsdWRlcycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLnJlcGVhdCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLnN0YXJ0cy13aXRoJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuYW5jaG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuYmlnJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuYmxpbmsnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5ib2xkJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuZml4ZWQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5mb250Y29sb3InKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5mb250c2l6ZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLml0YWxpY3MnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5saW5rJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuc21hbGwnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5zdHJpa2UnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5zdWInKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5zdXAnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmRhdGUubm93Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5kYXRlLnRvLWpzb24nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmRhdGUudG8taXNvLXN0cmluZycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuZGF0ZS50by1zdHJpbmcnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmRhdGUudG8tcHJpbWl0aXZlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5pcy1hcnJheScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuZnJvbScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkub2YnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LmpvaW4nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LnNsaWNlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5zb3J0Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5mb3ItZWFjaCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkubWFwJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5maWx0ZXInKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LnNvbWUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LmV2ZXJ5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5yZWR1Y2UnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LnJlZHVjZS1yaWdodCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuaW5kZXgtb2YnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5Lmxhc3QtaW5kZXgtb2YnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LmNvcHktd2l0aGluJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5maWxsJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5maW5kJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5maW5kLWluZGV4Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5zcGVjaWVzJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5pdGVyYXRvcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVnZXhwLmNvbnN0cnVjdG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWdleHAudG8tc3RyaW5nJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWdleHAuZmxhZ3MnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZ2V4cC5tYXRjaCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVnZXhwLnJlcGxhY2UnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZ2V4cC5zZWFyY2gnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZ2V4cC5zcGxpdCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucHJvbWlzZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWFwJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zZXQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LndlYWstbWFwJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi53ZWFrLXNldCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYudHlwZWQuYXJyYXktYnVmZmVyJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC5kYXRhLXZpZXcnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnR5cGVkLmludDgtYXJyYXknKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQ4LWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1jbGFtcGVkLWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC5pbnQxNi1hcnJheScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYudHlwZWQudWludDE2LWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC5pbnQzMi1hcnJheScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYudHlwZWQudWludDMyLWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC5mbG9hdDMyLWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC5mbG9hdDY0LWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmFwcGx5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmNvbnN0cnVjdCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVmbGVjdC5kZWZpbmUtcHJvcGVydHknKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVsZXRlLXByb3BlcnR5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmVudW1lcmF0ZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVmbGVjdC5nZXQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LW93bi1wcm9wZXJ0eS1kZXNjcmlwdG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC1wcm90b3R5cGUtb2YnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3QuaGFzJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmlzLWV4dGVuc2libGUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3Qub3duLWtleXMnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3QucHJldmVudC1leHRlbnNpb25zJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVmbGVjdC5zZXQtcHJvdG90eXBlLW9mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uL21vZHVsZXMvX2NvcmUnKTtcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM3LmFycmF5LmluY2x1ZGVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5BcnJheS5pbmNsdWRlcztcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM3Lm9iamVjdC5lbnRyaWVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5PYmplY3QuZW50cmllcztcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM3Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5PYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycztcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM3Lm9iamVjdC52YWx1ZXMnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fY29yZScpLk9iamVjdC52YWx1ZXM7XG4iLCIndXNlIHN0cmljdCc7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5wcm9taXNlJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNy5wcm9taXNlLmZpbmFsbHknKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fY29yZScpLlByb21pc2VbJ2ZpbmFsbHknXTtcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM3LnN0cmluZy5wYWQtZW5kJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5TdHJpbmcucGFkRW5kO1xuIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1zdGFydCcpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL19jb3JlJykuU3RyaW5nLnBhZFN0YXJ0O1xuIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczcuc3ltYm9sLmFzeW5jLWl0ZXJhdG9yJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX3drcy1leHQnKS5mKCdhc3luY0l0ZXJhdG9yJyk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgZnVuY3Rpb24hJyk7XG4gIHJldHVybiBpdDtcbn07XG4iLCJ2YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgbXNnKSB7XG4gIGlmICh0eXBlb2YgaXQgIT0gJ251bWJlcicgJiYgY29mKGl0KSAhPSAnTnVtYmVyJykgdGhyb3cgVHlwZUVycm9yKG1zZyk7XG4gIHJldHVybiAraXQ7XG59O1xuIiwiLy8gMjIuMS4zLjMxIEFycmF5LnByb3RvdHlwZVtAQHVuc2NvcGFibGVzXVxudmFyIFVOU0NPUEFCTEVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3Vuc2NvcGFibGVzJyk7XG52YXIgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTtcbmlmIChBcnJheVByb3RvW1VOU0NPUEFCTEVTXSA9PSB1bmRlZmluZWQpIHJlcXVpcmUoJy4vX2hpZGUnKShBcnJheVByb3RvLCBVTlNDT1BBQkxFUywge30pO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIEFycmF5UHJvdG9bVU5TQ09QQUJMRVNdW2tleV0gPSB0cnVlO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBDb25zdHJ1Y3RvciwgbmFtZSwgZm9yYmlkZGVuRmllbGQpIHtcbiAgaWYgKCEoaXQgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikgfHwgKGZvcmJpZGRlbkZpZWxkICE9PSB1bmRlZmluZWQgJiYgZm9yYmlkZGVuRmllbGQgaW4gaXQpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKG5hbWUgKyAnOiBpbmNvcnJlY3QgaW52b2NhdGlvbiEnKTtcbiAgfSByZXR1cm4gaXQ7XG59O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoIWlzT2JqZWN0KGl0KSkgdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYW4gb2JqZWN0IScpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiLy8gMjIuMS4zLjMgQXJyYXkucHJvdG90eXBlLmNvcHlXaXRoaW4odGFyZ2V0LCBzdGFydCwgZW5kID0gdGhpcy5sZW5ndGgpXG4ndXNlIHN0cmljdCc7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gW10uY29weVdpdGhpbiB8fCBmdW5jdGlvbiBjb3B5V2l0aGluKHRhcmdldCAvKiA9IDAgKi8sIHN0YXJ0IC8qID0gMCwgZW5kID0gQGxlbmd0aCAqLykge1xuICB2YXIgTyA9IHRvT2JqZWN0KHRoaXMpO1xuICB2YXIgbGVuID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICB2YXIgdG8gPSB0b0Fic29sdXRlSW5kZXgodGFyZ2V0LCBsZW4pO1xuICB2YXIgZnJvbSA9IHRvQWJzb2x1dGVJbmRleChzdGFydCwgbGVuKTtcbiAgdmFyIGVuZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkO1xuICB2YXIgY291bnQgPSBNYXRoLm1pbigoZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW4pKSAtIGZyb20sIGxlbiAtIHRvKTtcbiAgdmFyIGluYyA9IDE7XG4gIGlmIChmcm9tIDwgdG8gJiYgdG8gPCBmcm9tICsgY291bnQpIHtcbiAgICBpbmMgPSAtMTtcbiAgICBmcm9tICs9IGNvdW50IC0gMTtcbiAgICB0byArPSBjb3VudCAtIDE7XG4gIH1cbiAgd2hpbGUgKGNvdW50LS0gPiAwKSB7XG4gICAgaWYgKGZyb20gaW4gTykgT1t0b10gPSBPW2Zyb21dO1xuICAgIGVsc2UgZGVsZXRlIE9bdG9dO1xuICAgIHRvICs9IGluYztcbiAgICBmcm9tICs9IGluYztcbiAgfSByZXR1cm4gTztcbn07XG4iLCIvLyAyMi4xLjMuNiBBcnJheS5wcm90b3R5cGUuZmlsbCh2YWx1ZSwgc3RhcnQgPSAwLCBlbmQgPSB0aGlzLmxlbmd0aClcbid1c2Ugc3RyaWN0JztcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZmlsbCh2YWx1ZSAvKiAsIHN0YXJ0ID0gMCwgZW5kID0gQGxlbmd0aCAqLykge1xuICB2YXIgTyA9IHRvT2JqZWN0KHRoaXMpO1xuICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBpbmRleCA9IHRvQWJzb2x1dGVJbmRleChhTGVuID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgbGVuZ3RoKTtcbiAgdmFyIGVuZCA9IGFMZW4gPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkO1xuICB2YXIgZW5kUG9zID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW5ndGgpO1xuICB3aGlsZSAoZW5kUG9zID4gaW5kZXgpIE9baW5kZXgrK10gPSB2YWx1ZTtcbiAgcmV0dXJuIE87XG59O1xuIiwiLy8gZmFsc2UgLT4gQXJyYXkjaW5kZXhPZlxuLy8gdHJ1ZSAgLT4gQXJyYXkjaW5jbHVkZXNcbnZhciB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoSVNfSU5DTFVERVMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgkdGhpcywgZWwsIGZyb21JbmRleCkge1xuICAgIHZhciBPID0gdG9JT2JqZWN0KCR0aGlzKTtcbiAgICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICAgIHZhciBpbmRleCA9IHRvQWJzb2x1dGVJbmRleChmcm9tSW5kZXgsIGxlbmd0aCk7XG4gICAgdmFyIHZhbHVlO1xuICAgIC8vIEFycmF5I2luY2x1ZGVzIHVzZXMgU2FtZVZhbHVlWmVybyBlcXVhbGl0eSBhbGdvcml0aG1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgaWYgKElTX0lOQ0xVREVTICYmIGVsICE9IGVsKSB3aGlsZSAobGVuZ3RoID4gaW5kZXgpIHtcbiAgICAgIHZhbHVlID0gT1tpbmRleCsrXTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICAgIGlmICh2YWx1ZSAhPSB2YWx1ZSkgcmV0dXJuIHRydWU7XG4gICAgLy8gQXJyYXkjaW5kZXhPZiBpZ25vcmVzIGhvbGVzLCBBcnJheSNpbmNsdWRlcyAtIG5vdFxuICAgIH0gZWxzZSBmb3IgKDtsZW5ndGggPiBpbmRleDsgaW5kZXgrKykgaWYgKElTX0lOQ0xVREVTIHx8IGluZGV4IGluIE8pIHtcbiAgICAgIGlmIChPW2luZGV4XSA9PT0gZWwpIHJldHVybiBJU19JTkNMVURFUyB8fCBpbmRleCB8fCAwO1xuICAgIH0gcmV0dXJuICFJU19JTkNMVURFUyAmJiAtMTtcbiAgfTtcbn07XG4iLCIvLyAwIC0+IEFycmF5I2ZvckVhY2hcbi8vIDEgLT4gQXJyYXkjbWFwXG4vLyAyIC0+IEFycmF5I2ZpbHRlclxuLy8gMyAtPiBBcnJheSNzb21lXG4vLyA0IC0+IEFycmF5I2V2ZXJ5XG4vLyA1IC0+IEFycmF5I2ZpbmRcbi8vIDYgLT4gQXJyYXkjZmluZEluZGV4XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgYXNjID0gcmVxdWlyZSgnLi9fYXJyYXktc3BlY2llcy1jcmVhdGUnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFRZUEUsICRjcmVhdGUpIHtcbiAgdmFyIElTX01BUCA9IFRZUEUgPT0gMTtcbiAgdmFyIElTX0ZJTFRFUiA9IFRZUEUgPT0gMjtcbiAgdmFyIElTX1NPTUUgPSBUWVBFID09IDM7XG4gIHZhciBJU19FVkVSWSA9IFRZUEUgPT0gNDtcbiAgdmFyIElTX0ZJTkRfSU5ERVggPSBUWVBFID09IDY7XG4gIHZhciBOT19IT0xFUyA9IFRZUEUgPT0gNSB8fCBJU19GSU5EX0lOREVYO1xuICB2YXIgY3JlYXRlID0gJGNyZWF0ZSB8fCBhc2M7XG4gIHJldHVybiBmdW5jdGlvbiAoJHRoaXMsIGNhbGxiYWNrZm4sIHRoYXQpIHtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KCR0aGlzKTtcbiAgICB2YXIgc2VsZiA9IElPYmplY3QoTyk7XG4gICAgdmFyIGYgPSBjdHgoY2FsbGJhY2tmbiwgdGhhdCwgMyk7XG4gICAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKHNlbGYubGVuZ3RoKTtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciByZXN1bHQgPSBJU19NQVAgPyBjcmVhdGUoJHRoaXMsIGxlbmd0aCkgOiBJU19GSUxURVIgPyBjcmVhdGUoJHRoaXMsIDApIDogdW5kZWZpbmVkO1xuICAgIHZhciB2YWwsIHJlcztcbiAgICBmb3IgKDtsZW5ndGggPiBpbmRleDsgaW5kZXgrKykgaWYgKE5PX0hPTEVTIHx8IGluZGV4IGluIHNlbGYpIHtcbiAgICAgIHZhbCA9IHNlbGZbaW5kZXhdO1xuICAgICAgcmVzID0gZih2YWwsIGluZGV4LCBPKTtcbiAgICAgIGlmIChUWVBFKSB7XG4gICAgICAgIGlmIChJU19NQVApIHJlc3VsdFtpbmRleF0gPSByZXM7ICAgLy8gbWFwXG4gICAgICAgIGVsc2UgaWYgKHJlcykgc3dpdGNoIChUWVBFKSB7XG4gICAgICAgICAgY2FzZSAzOiByZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgLy8gc29tZVxuICAgICAgICAgIGNhc2UgNTogcmV0dXJuIHZhbDsgICAgICAgICAgICAgIC8vIGZpbmRcbiAgICAgICAgICBjYXNlIDY6IHJldHVybiBpbmRleDsgICAgICAgICAgICAvLyBmaW5kSW5kZXhcbiAgICAgICAgICBjYXNlIDI6IHJlc3VsdC5wdXNoKHZhbCk7ICAgICAgICAvLyBmaWx0ZXJcbiAgICAgICAgfSBlbHNlIGlmIChJU19FVkVSWSkgcmV0dXJuIGZhbHNlOyAvLyBldmVyeVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gSVNfRklORF9JTkRFWCA/IC0xIDogSVNfU09NRSB8fCBJU19FVkVSWSA/IElTX0VWRVJZIDogcmVzdWx0O1xuICB9O1xufTtcbiIsInZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciBJT2JqZWN0ID0gcmVxdWlyZSgnLi9faW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRoYXQsIGNhbGxiYWNrZm4sIGFMZW4sIG1lbW8sIGlzUmlnaHQpIHtcbiAgYUZ1bmN0aW9uKGNhbGxiYWNrZm4pO1xuICB2YXIgTyA9IHRvT2JqZWN0KHRoYXQpO1xuICB2YXIgc2VsZiA9IElPYmplY3QoTyk7XG4gIHZhciBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gIHZhciBpbmRleCA9IGlzUmlnaHQgPyBsZW5ndGggLSAxIDogMDtcbiAgdmFyIGkgPSBpc1JpZ2h0ID8gLTEgOiAxO1xuICBpZiAoYUxlbiA8IDIpIGZvciAoOzspIHtcbiAgICBpZiAoaW5kZXggaW4gc2VsZikge1xuICAgICAgbWVtbyA9IHNlbGZbaW5kZXhdO1xuICAgICAgaW5kZXggKz0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBpbmRleCArPSBpO1xuICAgIGlmIChpc1JpZ2h0ID8gaW5kZXggPCAwIDogbGVuZ3RoIDw9IGluZGV4KSB7XG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ1JlZHVjZSBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWUnKTtcbiAgICB9XG4gIH1cbiAgZm9yICg7aXNSaWdodCA/IGluZGV4ID49IDAgOiBsZW5ndGggPiBpbmRleDsgaW5kZXggKz0gaSkgaWYgKGluZGV4IGluIHNlbGYpIHtcbiAgICBtZW1vID0gY2FsbGJhY2tmbihtZW1vLCBzZWxmW2luZGV4XSwgaW5kZXgsIE8pO1xuICB9XG4gIHJldHVybiBtZW1vO1xufTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGlzQXJyYXkgPSByZXF1aXJlKCcuL19pcy1hcnJheScpO1xudmFyIFNQRUNJRVMgPSByZXF1aXJlKCcuL193a3MnKSgnc3BlY2llcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcmlnaW5hbCkge1xuICB2YXIgQztcbiAgaWYgKGlzQXJyYXkob3JpZ2luYWwpKSB7XG4gICAgQyA9IG9yaWdpbmFsLmNvbnN0cnVjdG9yO1xuICAgIC8vIGNyb3NzLXJlYWxtIGZhbGxiYWNrXG4gICAgaWYgKHR5cGVvZiBDID09ICdmdW5jdGlvbicgJiYgKEMgPT09IEFycmF5IHx8IGlzQXJyYXkoQy5wcm90b3R5cGUpKSkgQyA9IHVuZGVmaW5lZDtcbiAgICBpZiAoaXNPYmplY3QoQykpIHtcbiAgICAgIEMgPSBDW1NQRUNJRVNdO1xuICAgICAgaWYgKEMgPT09IG51bGwpIEMgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9IHJldHVybiBDID09PSB1bmRlZmluZWQgPyBBcnJheSA6IEM7XG59O1xuIiwiLy8gOS40LjIuMyBBcnJheVNwZWNpZXNDcmVhdGUob3JpZ2luYWxBcnJheSwgbGVuZ3RoKVxudmFyIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4vX2FycmF5LXNwZWNpZXMtY29uc3RydWN0b3InKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3JpZ2luYWwsIGxlbmd0aCkge1xuICByZXR1cm4gbmV3IChzcGVjaWVzQ29uc3RydWN0b3Iob3JpZ2luYWwpKShsZW5ndGgpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBpbnZva2UgPSByZXF1aXJlKCcuL19pbnZva2UnKTtcbnZhciBhcnJheVNsaWNlID0gW10uc2xpY2U7XG52YXIgZmFjdG9yaWVzID0ge307XG5cbnZhciBjb25zdHJ1Y3QgPSBmdW5jdGlvbiAoRiwgbGVuLCBhcmdzKSB7XG4gIGlmICghKGxlbiBpbiBmYWN0b3JpZXMpKSB7XG4gICAgZm9yICh2YXIgbiA9IFtdLCBpID0gMDsgaSA8IGxlbjsgaSsrKSBuW2ldID0gJ2FbJyArIGkgKyAnXSc7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW5ldy1mdW5jXG4gICAgZmFjdG9yaWVzW2xlbl0gPSBGdW5jdGlvbignRixhJywgJ3JldHVybiBuZXcgRignICsgbi5qb2luKCcsJykgKyAnKScpO1xuICB9IHJldHVybiBmYWN0b3JpZXNbbGVuXShGLCBhcmdzKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gRnVuY3Rpb24uYmluZCB8fCBmdW5jdGlvbiBiaW5kKHRoYXQgLyogLCAuLi5hcmdzICovKSB7XG4gIHZhciBmbiA9IGFGdW5jdGlvbih0aGlzKTtcbiAgdmFyIHBhcnRBcmdzID0gYXJyYXlTbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gIHZhciBib3VuZCA9IGZ1bmN0aW9uICgvKiBhcmdzLi4uICovKSB7XG4gICAgdmFyIGFyZ3MgPSBwYXJ0QXJncy5jb25jYXQoYXJyYXlTbGljZS5jYWxsKGFyZ3VtZW50cykpO1xuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgYm91bmQgPyBjb25zdHJ1Y3QoZm4sIGFyZ3MubGVuZ3RoLCBhcmdzKSA6IGludm9rZShmbiwgYXJncywgdGhhdCk7XG4gIH07XG4gIGlmIChpc09iamVjdChmbi5wcm90b3R5cGUpKSBib3VuZC5wcm90b3R5cGUgPSBmbi5wcm90b3R5cGU7XG4gIHJldHVybiBib3VuZDtcbn07XG4iLCIvLyBnZXR0aW5nIHRhZyBmcm9tIDE5LjEuMy42IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcoKVxudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xudmFyIFRBRyA9IHJlcXVpcmUoJy4vX3drcycpKCd0b1N0cmluZ1RhZycpO1xuLy8gRVMzIHdyb25nIGhlcmVcbnZhciBBUkcgPSBjb2YoZnVuY3Rpb24gKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpID09ICdBcmd1bWVudHMnO1xuXG4vLyBmYWxsYmFjayBmb3IgSUUxMSBTY3JpcHQgQWNjZXNzIERlbmllZCBlcnJvclxudmFyIHRyeUdldCA9IGZ1bmN0aW9uIChpdCwga2V5KSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGl0W2tleV07XG4gIH0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgdmFyIE8sIFQsIEI7XG4gIHJldHVybiBpdCA9PT0gdW5kZWZpbmVkID8gJ1VuZGVmaW5lZCcgOiBpdCA9PT0gbnVsbCA/ICdOdWxsJ1xuICAgIC8vIEBAdG9TdHJpbmdUYWcgY2FzZVxuICAgIDogdHlwZW9mIChUID0gdHJ5R2V0KE8gPSBPYmplY3QoaXQpLCBUQUcpKSA9PSAnc3RyaW5nJyA/IFRcbiAgICAvLyBidWlsdGluVGFnIGNhc2VcbiAgICA6IEFSRyA/IGNvZihPKVxuICAgIC8vIEVTMyBhcmd1bWVudHMgZmFsbGJhY2tcbiAgICA6IChCID0gY29mKE8pKSA9PSAnT2JqZWN0JyAmJiB0eXBlb2YgTy5jYWxsZWUgPT0gJ2Z1bmN0aW9uJyA/ICdBcmd1bWVudHMnIDogQjtcbn07XG4iLCJ2YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoaXQpLnNsaWNlKDgsIC0xKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGNyZWF0ZSA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKTtcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG52YXIgJGl0ZXJEZWZpbmUgPSByZXF1aXJlKCcuL19pdGVyLWRlZmluZScpO1xudmFyIHN0ZXAgPSByZXF1aXJlKCcuL19pdGVyLXN0ZXAnKTtcbnZhciBzZXRTcGVjaWVzID0gcmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgZmFzdEtleSA9IHJlcXVpcmUoJy4vX21ldGEnKS5mYXN0S2V5O1xudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnLi9fdmFsaWRhdGUtY29sbGVjdGlvbicpO1xudmFyIFNJWkUgPSBERVNDUklQVE9SUyA/ICdfcycgOiAnc2l6ZSc7XG5cbnZhciBnZXRFbnRyeSA9IGZ1bmN0aW9uICh0aGF0LCBrZXkpIHtcbiAgLy8gZmFzdCBjYXNlXG4gIHZhciBpbmRleCA9IGZhc3RLZXkoa2V5KTtcbiAgdmFyIGVudHJ5O1xuICBpZiAoaW5kZXggIT09ICdGJykgcmV0dXJuIHRoYXQuX2lbaW5kZXhdO1xuICAvLyBmcm96ZW4gb2JqZWN0IGNhc2VcbiAgZm9yIChlbnRyeSA9IHRoYXQuX2Y7IGVudHJ5OyBlbnRyeSA9IGVudHJ5Lm4pIHtcbiAgICBpZiAoZW50cnkuayA9PSBrZXkpIHJldHVybiBlbnRyeTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGdldENvbnN0cnVjdG9yOiBmdW5jdGlvbiAod3JhcHBlciwgTkFNRSwgSVNfTUFQLCBBRERFUikge1xuICAgIHZhciBDID0gd3JhcHBlcihmdW5jdGlvbiAodGhhdCwgaXRlcmFibGUpIHtcbiAgICAgIGFuSW5zdGFuY2UodGhhdCwgQywgTkFNRSwgJ19pJyk7XG4gICAgICB0aGF0Ll90ID0gTkFNRTsgICAgICAgICAvLyBjb2xsZWN0aW9uIHR5cGVcbiAgICAgIHRoYXQuX2kgPSBjcmVhdGUobnVsbCk7IC8vIGluZGV4XG4gICAgICB0aGF0Ll9mID0gdW5kZWZpbmVkOyAgICAvLyBmaXJzdCBlbnRyeVxuICAgICAgdGhhdC5fbCA9IHVuZGVmaW5lZDsgICAgLy8gbGFzdCBlbnRyeVxuICAgICAgdGhhdFtTSVpFXSA9IDA7ICAgICAgICAgLy8gc2l6ZVxuICAgICAgaWYgKGl0ZXJhYmxlICE9IHVuZGVmaW5lZCkgZm9yT2YoaXRlcmFibGUsIElTX01BUCwgdGhhdFtBRERFUl0sIHRoYXQpO1xuICAgIH0pO1xuICAgIHJlZGVmaW5lQWxsKEMucHJvdG90eXBlLCB7XG4gICAgICAvLyAyMy4xLjMuMSBNYXAucHJvdG90eXBlLmNsZWFyKClcbiAgICAgIC8vIDIzLjIuMy4yIFNldC5wcm90b3R5cGUuY2xlYXIoKVxuICAgICAgY2xlYXI6IGZ1bmN0aW9uIGNsZWFyKCkge1xuICAgICAgICBmb3IgKHZhciB0aGF0ID0gdmFsaWRhdGUodGhpcywgTkFNRSksIGRhdGEgPSB0aGF0Ll9pLCBlbnRyeSA9IHRoYXQuX2Y7IGVudHJ5OyBlbnRyeSA9IGVudHJ5Lm4pIHtcbiAgICAgICAgICBlbnRyeS5yID0gdHJ1ZTtcbiAgICAgICAgICBpZiAoZW50cnkucCkgZW50cnkucCA9IGVudHJ5LnAubiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBkZWxldGUgZGF0YVtlbnRyeS5pXTtcbiAgICAgICAgfVxuICAgICAgICB0aGF0Ll9mID0gdGhhdC5fbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhhdFtTSVpFXSA9IDA7XG4gICAgICB9LFxuICAgICAgLy8gMjMuMS4zLjMgTWFwLnByb3RvdHlwZS5kZWxldGUoa2V5KVxuICAgICAgLy8gMjMuMi4zLjQgU2V0LnByb3RvdHlwZS5kZWxldGUodmFsdWUpXG4gICAgICAnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkge1xuICAgICAgICB2YXIgdGhhdCA9IHZhbGlkYXRlKHRoaXMsIE5BTUUpO1xuICAgICAgICB2YXIgZW50cnkgPSBnZXRFbnRyeSh0aGF0LCBrZXkpO1xuICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICB2YXIgbmV4dCA9IGVudHJ5Lm47XG4gICAgICAgICAgdmFyIHByZXYgPSBlbnRyeS5wO1xuICAgICAgICAgIGRlbGV0ZSB0aGF0Ll9pW2VudHJ5LmldO1xuICAgICAgICAgIGVudHJ5LnIgPSB0cnVlO1xuICAgICAgICAgIGlmIChwcmV2KSBwcmV2Lm4gPSBuZXh0O1xuICAgICAgICAgIGlmIChuZXh0KSBuZXh0LnAgPSBwcmV2O1xuICAgICAgICAgIGlmICh0aGF0Ll9mID09IGVudHJ5KSB0aGF0Ll9mID0gbmV4dDtcbiAgICAgICAgICBpZiAodGhhdC5fbCA9PSBlbnRyeSkgdGhhdC5fbCA9IHByZXY7XG4gICAgICAgICAgdGhhdFtTSVpFXS0tO1xuICAgICAgICB9IHJldHVybiAhIWVudHJ5O1xuICAgICAgfSxcbiAgICAgIC8vIDIzLjIuMy42IFNldC5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxuICAgICAgLy8gMjMuMS4zLjUgTWFwLnByb3RvdHlwZS5mb3JFYWNoKGNhbGxiYWNrZm4sIHRoaXNBcmcgPSB1bmRlZmluZWQpXG4gICAgICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrZm4gLyogLCB0aGF0ID0gdW5kZWZpbmVkICovKSB7XG4gICAgICAgIHZhbGlkYXRlKHRoaXMsIE5BTUUpO1xuICAgICAgICB2YXIgZiA9IGN0eChjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgMyk7XG4gICAgICAgIHZhciBlbnRyeTtcbiAgICAgICAgd2hpbGUgKGVudHJ5ID0gZW50cnkgPyBlbnRyeS5uIDogdGhpcy5fZikge1xuICAgICAgICAgIGYoZW50cnkudiwgZW50cnkuaywgdGhpcyk7XG4gICAgICAgICAgLy8gcmV2ZXJ0IHRvIHRoZSBsYXN0IGV4aXN0aW5nIGVudHJ5XG4gICAgICAgICAgd2hpbGUgKGVudHJ5ICYmIGVudHJ5LnIpIGVudHJ5ID0gZW50cnkucDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8vIDIzLjEuMy43IE1hcC5wcm90b3R5cGUuaGFzKGtleSlcbiAgICAgIC8vIDIzLjIuMy43IFNldC5wcm90b3R5cGUuaGFzKHZhbHVlKVxuICAgICAgaGFzOiBmdW5jdGlvbiBoYXMoa2V5KSB7XG4gICAgICAgIHJldHVybiAhIWdldEVudHJ5KHZhbGlkYXRlKHRoaXMsIE5BTUUpLCBrZXkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChERVNDUklQVE9SUykgZFAoQy5wcm90b3R5cGUsICdzaXplJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB2YWxpZGF0ZSh0aGlzLCBOQU1FKVtTSVpFXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gQztcbiAgfSxcbiAgZGVmOiBmdW5jdGlvbiAodGhhdCwga2V5LCB2YWx1ZSkge1xuICAgIHZhciBlbnRyeSA9IGdldEVudHJ5KHRoYXQsIGtleSk7XG4gICAgdmFyIHByZXYsIGluZGV4O1xuICAgIC8vIGNoYW5nZSBleGlzdGluZyBlbnRyeVxuICAgIGlmIChlbnRyeSkge1xuICAgICAgZW50cnkudiA9IHZhbHVlO1xuICAgIC8vIGNyZWF0ZSBuZXcgZW50cnlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhhdC5fbCA9IGVudHJ5ID0ge1xuICAgICAgICBpOiBpbmRleCA9IGZhc3RLZXkoa2V5LCB0cnVlKSwgLy8gPC0gaW5kZXhcbiAgICAgICAgazoga2V5LCAgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIGtleVxuICAgICAgICB2OiB2YWx1ZSwgICAgICAgICAgICAgICAgICAgICAgLy8gPC0gdmFsdWVcbiAgICAgICAgcDogcHJldiA9IHRoYXQuX2wsICAgICAgICAgICAgIC8vIDwtIHByZXZpb3VzIGVudHJ5XG4gICAgICAgIG46IHVuZGVmaW5lZCwgICAgICAgICAgICAgICAgICAvLyA8LSBuZXh0IGVudHJ5XG4gICAgICAgIHI6IGZhbHNlICAgICAgICAgICAgICAgICAgICAgICAvLyA8LSByZW1vdmVkXG4gICAgICB9O1xuICAgICAgaWYgKCF0aGF0Ll9mKSB0aGF0Ll9mID0gZW50cnk7XG4gICAgICBpZiAocHJldikgcHJldi5uID0gZW50cnk7XG4gICAgICB0aGF0W1NJWkVdKys7XG4gICAgICAvLyBhZGQgdG8gaW5kZXhcbiAgICAgIGlmIChpbmRleCAhPT0gJ0YnKSB0aGF0Ll9pW2luZGV4XSA9IGVudHJ5O1xuICAgIH0gcmV0dXJuIHRoYXQ7XG4gIH0sXG4gIGdldEVudHJ5OiBnZXRFbnRyeSxcbiAgc2V0U3Ryb25nOiBmdW5jdGlvbiAoQywgTkFNRSwgSVNfTUFQKSB7XG4gICAgLy8gYWRkIC5rZXlzLCAudmFsdWVzLCAuZW50cmllcywgW0BAaXRlcmF0b3JdXG4gICAgLy8gMjMuMS4zLjQsIDIzLjEuMy44LCAyMy4xLjMuMTEsIDIzLjEuMy4xMiwgMjMuMi4zLjUsIDIzLjIuMy44LCAyMy4yLjMuMTAsIDIzLjIuMy4xMVxuICAgICRpdGVyRGVmaW5lKEMsIE5BTUUsIGZ1bmN0aW9uIChpdGVyYXRlZCwga2luZCkge1xuICAgICAgdGhpcy5fdCA9IHZhbGlkYXRlKGl0ZXJhdGVkLCBOQU1FKTsgLy8gdGFyZ2V0XG4gICAgICB0aGlzLl9rID0ga2luZDsgICAgICAgICAgICAgICAgICAgICAvLyBraW5kXG4gICAgICB0aGlzLl9sID0gdW5kZWZpbmVkOyAgICAgICAgICAgICAgICAvLyBwcmV2aW91c1xuICAgIH0sIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICAgIHZhciBraW5kID0gdGhhdC5faztcbiAgICAgIHZhciBlbnRyeSA9IHRoYXQuX2w7XG4gICAgICAvLyByZXZlcnQgdG8gdGhlIGxhc3QgZXhpc3RpbmcgZW50cnlcbiAgICAgIHdoaWxlIChlbnRyeSAmJiBlbnRyeS5yKSBlbnRyeSA9IGVudHJ5LnA7XG4gICAgICAvLyBnZXQgbmV4dCBlbnRyeVxuICAgICAgaWYgKCF0aGF0Ll90IHx8ICEodGhhdC5fbCA9IGVudHJ5ID0gZW50cnkgPyBlbnRyeS5uIDogdGhhdC5fdC5fZikpIHtcbiAgICAgICAgLy8gb3IgZmluaXNoIHRoZSBpdGVyYXRpb25cbiAgICAgICAgdGhhdC5fdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHN0ZXAoMSk7XG4gICAgICB9XG4gICAgICAvLyByZXR1cm4gc3RlcCBieSBraW5kXG4gICAgICBpZiAoa2luZCA9PSAna2V5cycpIHJldHVybiBzdGVwKDAsIGVudHJ5LmspO1xuICAgICAgaWYgKGtpbmQgPT0gJ3ZhbHVlcycpIHJldHVybiBzdGVwKDAsIGVudHJ5LnYpO1xuICAgICAgcmV0dXJuIHN0ZXAoMCwgW2VudHJ5LmssIGVudHJ5LnZdKTtcbiAgICB9LCBJU19NQVAgPyAnZW50cmllcycgOiAndmFsdWVzJywgIUlTX01BUCwgdHJ1ZSk7XG5cbiAgICAvLyBhZGQgW0BAc3BlY2llc10sIDIzLjEuMi4yLCAyMy4yLjIuMlxuICAgIHNldFNwZWNpZXMoTkFNRSk7XG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgcmVkZWZpbmVBbGwgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKTtcbnZhciBnZXRXZWFrID0gcmVxdWlyZSgnLi9fbWV0YScpLmdldFdlYWs7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG52YXIgY3JlYXRlQXJyYXlNZXRob2QgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJyk7XG52YXIgJGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnLi9fdmFsaWRhdGUtY29sbGVjdGlvbicpO1xudmFyIGFycmF5RmluZCA9IGNyZWF0ZUFycmF5TWV0aG9kKDUpO1xudmFyIGFycmF5RmluZEluZGV4ID0gY3JlYXRlQXJyYXlNZXRob2QoNik7XG52YXIgaWQgPSAwO1xuXG4vLyBmYWxsYmFjayBmb3IgdW5jYXVnaHQgZnJvemVuIGtleXNcbnZhciB1bmNhdWdodEZyb3plblN0b3JlID0gZnVuY3Rpb24gKHRoYXQpIHtcbiAgcmV0dXJuIHRoYXQuX2wgfHwgKHRoYXQuX2wgPSBuZXcgVW5jYXVnaHRGcm96ZW5TdG9yZSgpKTtcbn07XG52YXIgVW5jYXVnaHRGcm96ZW5TdG9yZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5hID0gW107XG59O1xudmFyIGZpbmRVbmNhdWdodEZyb3plbiA9IGZ1bmN0aW9uIChzdG9yZSwga2V5KSB7XG4gIHJldHVybiBhcnJheUZpbmQoc3RvcmUuYSwgZnVuY3Rpb24gKGl0KSB7XG4gICAgcmV0dXJuIGl0WzBdID09PSBrZXk7XG4gIH0pO1xufTtcblVuY2F1Z2h0RnJvemVuU3RvcmUucHJvdG90eXBlID0ge1xuICBnZXQ6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICB2YXIgZW50cnkgPSBmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgICBpZiAoZW50cnkpIHJldHVybiBlbnRyeVsxXTtcbiAgfSxcbiAgaGFzOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuICEhZmluZFVuY2F1Z2h0RnJvemVuKHRoaXMsIGtleSk7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICB2YXIgZW50cnkgPSBmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgICBpZiAoZW50cnkpIGVudHJ5WzFdID0gdmFsdWU7XG4gICAgZWxzZSB0aGlzLmEucHVzaChba2V5LCB2YWx1ZV0pO1xuICB9LFxuICAnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBpbmRleCA9IGFycmF5RmluZEluZGV4KHRoaXMuYSwgZnVuY3Rpb24gKGl0KSB7XG4gICAgICByZXR1cm4gaXRbMF0gPT09IGtleTtcbiAgICB9KTtcbiAgICBpZiAofmluZGV4KSB0aGlzLmEuc3BsaWNlKGluZGV4LCAxKTtcbiAgICByZXR1cm4gISF+aW5kZXg7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRDb25zdHJ1Y3RvcjogZnVuY3Rpb24gKHdyYXBwZXIsIE5BTUUsIElTX01BUCwgQURERVIpIHtcbiAgICB2YXIgQyA9IHdyYXBwZXIoZnVuY3Rpb24gKHRoYXQsIGl0ZXJhYmxlKSB7XG4gICAgICBhbkluc3RhbmNlKHRoYXQsIEMsIE5BTUUsICdfaScpO1xuICAgICAgdGhhdC5fdCA9IE5BTUU7ICAgICAgLy8gY29sbGVjdGlvbiB0eXBlXG4gICAgICB0aGF0Ll9pID0gaWQrKzsgICAgICAvLyBjb2xsZWN0aW9uIGlkXG4gICAgICB0aGF0Ll9sID0gdW5kZWZpbmVkOyAvLyBsZWFrIHN0b3JlIGZvciB1bmNhdWdodCBmcm96ZW4gb2JqZWN0c1xuICAgICAgaWYgKGl0ZXJhYmxlICE9IHVuZGVmaW5lZCkgZm9yT2YoaXRlcmFibGUsIElTX01BUCwgdGhhdFtBRERFUl0sIHRoYXQpO1xuICAgIH0pO1xuICAgIHJlZGVmaW5lQWxsKEMucHJvdG90eXBlLCB7XG4gICAgICAvLyAyMy4zLjMuMiBXZWFrTWFwLnByb3RvdHlwZS5kZWxldGUoa2V5KVxuICAgICAgLy8gMjMuNC4zLjMgV2Vha1NldC5wcm90b3R5cGUuZGVsZXRlKHZhbHVlKVxuICAgICAgJ2RlbGV0ZSc6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKCFpc09iamVjdChrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xuICAgICAgICBpZiAoZGF0YSA9PT0gdHJ1ZSkgcmV0dXJuIHVuY2F1Z2h0RnJvemVuU3RvcmUodmFsaWRhdGUodGhpcywgTkFNRSkpWydkZWxldGUnXShrZXkpO1xuICAgICAgICByZXR1cm4gZGF0YSAmJiAkaGFzKGRhdGEsIHRoaXMuX2kpICYmIGRlbGV0ZSBkYXRhW3RoaXMuX2ldO1xuICAgICAgfSxcbiAgICAgIC8vIDIzLjMuMy40IFdlYWtNYXAucHJvdG90eXBlLmhhcyhrZXkpXG4gICAgICAvLyAyMy40LjMuNCBXZWFrU2V0LnByb3RvdHlwZS5oYXModmFsdWUpXG4gICAgICBoYXM6IGZ1bmN0aW9uIGhhcyhrZXkpIHtcbiAgICAgICAgaWYgKCFpc09iamVjdChrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xuICAgICAgICBpZiAoZGF0YSA9PT0gdHJ1ZSkgcmV0dXJuIHVuY2F1Z2h0RnJvemVuU3RvcmUodmFsaWRhdGUodGhpcywgTkFNRSkpLmhhcyhrZXkpO1xuICAgICAgICByZXR1cm4gZGF0YSAmJiAkaGFzKGRhdGEsIHRoaXMuX2kpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBDO1xuICB9LFxuICBkZWY6IGZ1bmN0aW9uICh0aGF0LCBrZXksIHZhbHVlKSB7XG4gICAgdmFyIGRhdGEgPSBnZXRXZWFrKGFuT2JqZWN0KGtleSksIHRydWUpO1xuICAgIGlmIChkYXRhID09PSB0cnVlKSB1bmNhdWdodEZyb3plblN0b3JlKHRoYXQpLnNldChrZXksIHZhbHVlKTtcbiAgICBlbHNlIGRhdGFbdGhhdC5faV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhhdDtcbiAgfSxcbiAgdWZzdG9yZTogdW5jYXVnaHRGcm96ZW5TdG9yZVxufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIHJlZGVmaW5lQWxsID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJyk7XG52YXIgbWV0YSA9IHJlcXVpcmUoJy4vX21ldGEnKTtcbnZhciBmb3JPZiA9IHJlcXVpcmUoJy4vX2Zvci1vZicpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyICRpdGVyRGV0ZWN0ID0gcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgaW5oZXJpdElmUmVxdWlyZWQgPSByZXF1aXJlKCcuL19pbmhlcml0LWlmLXJlcXVpcmVkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE5BTUUsIHdyYXBwZXIsIG1ldGhvZHMsIGNvbW1vbiwgSVNfTUFQLCBJU19XRUFLKSB7XG4gIHZhciBCYXNlID0gZ2xvYmFsW05BTUVdO1xuICB2YXIgQyA9IEJhc2U7XG4gIHZhciBBRERFUiA9IElTX01BUCA/ICdzZXQnIDogJ2FkZCc7XG4gIHZhciBwcm90byA9IEMgJiYgQy5wcm90b3R5cGU7XG4gIHZhciBPID0ge307XG4gIHZhciBmaXhNZXRob2QgPSBmdW5jdGlvbiAoS0VZKSB7XG4gICAgdmFyIGZuID0gcHJvdG9bS0VZXTtcbiAgICByZWRlZmluZShwcm90bywgS0VZLFxuICAgICAgS0VZID09ICdkZWxldGUnID8gZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdoYXMnID8gZnVuY3Rpb24gaGFzKGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdnZXQnID8gZnVuY3Rpb24gZ2V0KGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gdW5kZWZpbmVkIDogZm4uY2FsbCh0aGlzLCBhID09PSAwID8gMCA6IGEpO1xuICAgICAgfSA6IEtFWSA9PSAnYWRkJyA/IGZ1bmN0aW9uIGFkZChhKSB7IGZuLmNhbGwodGhpcywgYSA9PT0gMCA/IDAgOiBhKTsgcmV0dXJuIHRoaXM7IH1cbiAgICAgICAgOiBmdW5jdGlvbiBzZXQoYSwgYikgeyBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSwgYik7IHJldHVybiB0aGlzOyB9XG4gICAgKTtcbiAgfTtcbiAgaWYgKHR5cGVvZiBDICE9ICdmdW5jdGlvbicgfHwgIShJU19XRUFLIHx8IHByb3RvLmZvckVhY2ggJiYgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICBuZXcgQygpLmVudHJpZXMoKS5uZXh0KCk7XG4gIH0pKSkge1xuICAgIC8vIGNyZWF0ZSBjb2xsZWN0aW9uIGNvbnN0cnVjdG9yXG4gICAgQyA9IGNvbW1vbi5nZXRDb25zdHJ1Y3Rvcih3cmFwcGVyLCBOQU1FLCBJU19NQVAsIEFEREVSKTtcbiAgICByZWRlZmluZUFsbChDLnByb3RvdHlwZSwgbWV0aG9kcyk7XG4gICAgbWV0YS5ORUVEID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBuZXcgQygpO1xuICAgIC8vIGVhcmx5IGltcGxlbWVudGF0aW9ucyBub3Qgc3VwcG9ydHMgY2hhaW5pbmdcbiAgICB2YXIgSEFTTlRfQ0hBSU5JTkcgPSBpbnN0YW5jZVtBRERFUl0oSVNfV0VBSyA/IHt9IDogLTAsIDEpICE9IGluc3RhbmNlO1xuICAgIC8vIFY4IH4gIENocm9taXVtIDQwLSB3ZWFrLWNvbGxlY3Rpb25zIHRocm93cyBvbiBwcmltaXRpdmVzLCBidXQgc2hvdWxkIHJldHVybiBmYWxzZVxuICAgIHZhciBUSFJPV1NfT05fUFJJTUlUSVZFUyA9IGZhaWxzKGZ1bmN0aW9uICgpIHsgaW5zdGFuY2UuaGFzKDEpOyB9KTtcbiAgICAvLyBtb3N0IGVhcmx5IGltcGxlbWVudGF0aW9ucyBkb2Vzbid0IHN1cHBvcnRzIGl0ZXJhYmxlcywgbW9zdCBtb2Rlcm4gLSBub3QgY2xvc2UgaXQgY29ycmVjdGx5XG4gICAgdmFyIEFDQ0VQVF9JVEVSQUJMRVMgPSAkaXRlckRldGVjdChmdW5jdGlvbiAoaXRlcikgeyBuZXcgQyhpdGVyKTsgfSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgLy8gZm9yIGVhcmx5IGltcGxlbWVudGF0aW9ucyAtMCBhbmQgKzAgbm90IHRoZSBzYW1lXG4gICAgdmFyIEJVR0dZX1pFUk8gPSAhSVNfV0VBSyAmJiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBWOCB+IENocm9taXVtIDQyLSBmYWlscyBvbmx5IHdpdGggNSsgZWxlbWVudHNcbiAgICAgIHZhciAkaW5zdGFuY2UgPSBuZXcgQygpO1xuICAgICAgdmFyIGluZGV4ID0gNTtcbiAgICAgIHdoaWxlIChpbmRleC0tKSAkaW5zdGFuY2VbQURERVJdKGluZGV4LCBpbmRleCk7XG4gICAgICByZXR1cm4gISRpbnN0YW5jZS5oYXMoLTApO1xuICAgIH0pO1xuICAgIGlmICghQUNDRVBUX0lURVJBQkxFUykge1xuICAgICAgQyA9IHdyYXBwZXIoZnVuY3Rpb24gKHRhcmdldCwgaXRlcmFibGUpIHtcbiAgICAgICAgYW5JbnN0YW5jZSh0YXJnZXQsIEMsIE5BTUUpO1xuICAgICAgICB2YXIgdGhhdCA9IGluaGVyaXRJZlJlcXVpcmVkKG5ldyBCYXNlKCksIHRhcmdldCwgQyk7XG4gICAgICAgIGlmIChpdGVyYWJsZSAhPSB1bmRlZmluZWQpIGZvck9mKGl0ZXJhYmxlLCBJU19NQVAsIHRoYXRbQURERVJdLCB0aGF0KTtcbiAgICAgICAgcmV0dXJuIHRoYXQ7XG4gICAgICB9KTtcbiAgICAgIEMucHJvdG90eXBlID0gcHJvdG87XG4gICAgICBwcm90by5jb25zdHJ1Y3RvciA9IEM7XG4gICAgfVxuICAgIGlmIChUSFJPV1NfT05fUFJJTUlUSVZFUyB8fCBCVUdHWV9aRVJPKSB7XG4gICAgICBmaXhNZXRob2QoJ2RlbGV0ZScpO1xuICAgICAgZml4TWV0aG9kKCdoYXMnKTtcbiAgICAgIElTX01BUCAmJiBmaXhNZXRob2QoJ2dldCcpO1xuICAgIH1cbiAgICBpZiAoQlVHR1lfWkVSTyB8fCBIQVNOVF9DSEFJTklORykgZml4TWV0aG9kKEFEREVSKTtcbiAgICAvLyB3ZWFrIGNvbGxlY3Rpb25zIHNob3VsZCBub3QgY29udGFpbnMgLmNsZWFyIG1ldGhvZFxuICAgIGlmIChJU19XRUFLICYmIHByb3RvLmNsZWFyKSBkZWxldGUgcHJvdG8uY2xlYXI7XG4gIH1cblxuICBzZXRUb1N0cmluZ1RhZyhDLCBOQU1FKTtcblxuICBPW05BTUVdID0gQztcbiAgJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAoQyAhPSBCYXNlKSwgTyk7XG5cbiAgaWYgKCFJU19XRUFLKSBjb21tb24uc2V0U3Ryb25nKEMsIE5BTUUsIElTX01BUCk7XG5cbiAgcmV0dXJuIEM7XG59O1xuIiwidmFyIGNvcmUgPSBtb2R1bGUuZXhwb3J0cyA9IHsgdmVyc2lvbjogJzIuNS43JyB9O1xuaWYgKHR5cGVvZiBfX2UgPT0gJ251bWJlcicpIF9fZSA9IGNvcmU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIGluZGV4LCB2YWx1ZSkge1xuICBpZiAoaW5kZXggaW4gb2JqZWN0KSAkZGVmaW5lUHJvcGVydHkuZihvYmplY3QsIGluZGV4LCBjcmVhdGVEZXNjKDAsIHZhbHVlKSk7XG4gIGVsc2Ugb2JqZWN0W2luZGV4XSA9IHZhbHVlO1xufTtcbiIsIi8vIG9wdGlvbmFsIC8gc2ltcGxlIGNvbnRleHQgYmluZGluZ1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGZuLCB0aGF0LCBsZW5ndGgpIHtcbiAgYUZ1bmN0aW9uKGZuKTtcbiAgaWYgKHRoYXQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGZuO1xuICBzd2l0Y2ggKGxlbmd0aCkge1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uIChhKSB7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhKTtcbiAgICB9O1xuICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uIChhLCBiLCBjKSB7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiLCBjKTtcbiAgICB9O1xuICB9XG4gIHJldHVybiBmdW5jdGlvbiAoLyogLi4uYXJncyAqLykge1xuICAgIHJldHVybiBmbi5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuICB9O1xufTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIwLjMuNC4zNiAvIDE1LjkuNS40MyBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZygpXG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGdldFRpbWUgPSBEYXRlLnByb3RvdHlwZS5nZXRUaW1lO1xudmFyICR0b0lTT1N0cmluZyA9IERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nO1xuXG52YXIgbHogPSBmdW5jdGlvbiAobnVtKSB7XG4gIHJldHVybiBudW0gPiA5ID8gbnVtIDogJzAnICsgbnVtO1xufTtcblxuLy8gUGhhbnRvbUpTIC8gb2xkIFdlYktpdCBoYXMgYSBicm9rZW4gaW1wbGVtZW50YXRpb25zXG5tb2R1bGUuZXhwb3J0cyA9IChmYWlscyhmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAkdG9JU09TdHJpbmcuY2FsbChuZXcgRGF0ZSgtNWUxMyAtIDEpKSAhPSAnMDM4NS0wNy0yNVQwNzowNjozOS45OTlaJztcbn0pIHx8ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICR0b0lTT1N0cmluZy5jYWxsKG5ldyBEYXRlKE5hTikpO1xufSkpID8gZnVuY3Rpb24gdG9JU09TdHJpbmcoKSB7XG4gIGlmICghaXNGaW5pdGUoZ2V0VGltZS5jYWxsKHRoaXMpKSkgdGhyb3cgUmFuZ2VFcnJvcignSW52YWxpZCB0aW1lIHZhbHVlJyk7XG4gIHZhciBkID0gdGhpcztcbiAgdmFyIHkgPSBkLmdldFVUQ0Z1bGxZZWFyKCk7XG4gIHZhciBtID0gZC5nZXRVVENNaWxsaXNlY29uZHMoKTtcbiAgdmFyIHMgPSB5IDwgMCA/ICctJyA6IHkgPiA5OTk5ID8gJysnIDogJyc7XG4gIHJldHVybiBzICsgKCcwMDAwMCcgKyBNYXRoLmFicyh5KSkuc2xpY2UocyA/IC02IDogLTQpICtcbiAgICAnLScgKyBseihkLmdldFVUQ01vbnRoKCkgKyAxKSArICctJyArIGx6KGQuZ2V0VVRDRGF0ZSgpKSArXG4gICAgJ1QnICsgbHooZC5nZXRVVENIb3VycygpKSArICc6JyArIGx6KGQuZ2V0VVRDTWludXRlcygpKSArXG4gICAgJzonICsgbHooZC5nZXRVVENTZWNvbmRzKCkpICsgJy4nICsgKG0gPiA5OSA/IG0gOiAnMCcgKyBseihtKSkgKyAnWic7XG59IDogJHRvSVNPU3RyaW5nO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBOVU1CRVIgPSAnbnVtYmVyJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaGludCkge1xuICBpZiAoaGludCAhPT0gJ3N0cmluZycgJiYgaGludCAhPT0gTlVNQkVSICYmIGhpbnQgIT09ICdkZWZhdWx0JykgdGhyb3cgVHlwZUVycm9yKCdJbmNvcnJlY3QgaGludCcpO1xuICByZXR1cm4gdG9QcmltaXRpdmUoYW5PYmplY3QodGhpcyksIGhpbnQgIT0gTlVNQkVSKTtcbn07XG4iLCIvLyA3LjIuMSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGFyZ3VtZW50KVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ID09IHVuZGVmaW5lZCkgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY2FsbCBtZXRob2Qgb24gIFwiICsgaXQpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiLy8gVGhhbmsncyBJRTggZm9yIGhpcyBmdW5ueSBkZWZpbmVQcm9wZXJ0eVxubW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdhJywgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH0gfSkuYSAhPSA3O1xufSk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBkb2N1bWVudCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLmRvY3VtZW50O1xuLy8gdHlwZW9mIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgaXMgJ29iamVjdCcgaW4gb2xkIElFXG52YXIgaXMgPSBpc09iamVjdChkb2N1bWVudCkgJiYgaXNPYmplY3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXMgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGl0KSA6IHt9O1xufTtcbiIsIi8vIElFIDgtIGRvbid0IGVudW0gYnVnIGtleXNcbm1vZHVsZS5leHBvcnRzID0gKFxuICAnY29uc3RydWN0b3IsaGFzT3duUHJvcGVydHksaXNQcm90b3R5cGVPZixwcm9wZXJ0eUlzRW51bWVyYWJsZSx0b0xvY2FsZVN0cmluZyx0b1N0cmluZyx2YWx1ZU9mJ1xuKS5zcGxpdCgnLCcpO1xuIiwiLy8gYWxsIGVudW1lcmFibGUgb2JqZWN0IGtleXMsIGluY2x1ZGVzIHN5bWJvbHNcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciBnT1BTID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKTtcbnZhciBwSUUgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICB2YXIgcmVzdWx0ID0gZ2V0S2V5cyhpdCk7XG4gIHZhciBnZXRTeW1ib2xzID0gZ09QUy5mO1xuICBpZiAoZ2V0U3ltYm9scykge1xuICAgIHZhciBzeW1ib2xzID0gZ2V0U3ltYm9scyhpdCk7XG4gICAgdmFyIGlzRW51bSA9IHBJRS5mO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIga2V5O1xuICAgIHdoaWxlIChzeW1ib2xzLmxlbmd0aCA+IGkpIGlmIChpc0VudW0uY2FsbChpdCwga2V5ID0gc3ltYm9sc1tpKytdKSkgcmVzdWx0LnB1c2goa2V5KTtcbiAgfSByZXR1cm4gcmVzdWx0O1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xuXG52YXIgJGV4cG9ydCA9IGZ1bmN0aW9uICh0eXBlLCBuYW1lLCBzb3VyY2UpIHtcbiAgdmFyIElTX0ZPUkNFRCA9IHR5cGUgJiAkZXhwb3J0LkY7XG4gIHZhciBJU19HTE9CQUwgPSB0eXBlICYgJGV4cG9ydC5HO1xuICB2YXIgSVNfU1RBVElDID0gdHlwZSAmICRleHBvcnQuUztcbiAgdmFyIElTX1BST1RPID0gdHlwZSAmICRleHBvcnQuUDtcbiAgdmFyIElTX0JJTkQgPSB0eXBlICYgJGV4cG9ydC5CO1xuICB2YXIgdGFyZ2V0ID0gSVNfR0xPQkFMID8gZ2xvYmFsIDogSVNfU1RBVElDID8gZ2xvYmFsW25hbWVdIHx8IChnbG9iYWxbbmFtZV0gPSB7fSkgOiAoZ2xvYmFsW25hbWVdIHx8IHt9KVtQUk9UT1RZUEVdO1xuICB2YXIgZXhwb3J0cyA9IElTX0dMT0JBTCA/IGNvcmUgOiBjb3JlW25hbWVdIHx8IChjb3JlW25hbWVdID0ge30pO1xuICB2YXIgZXhwUHJvdG8gPSBleHBvcnRzW1BST1RPVFlQRV0gfHwgKGV4cG9ydHNbUFJPVE9UWVBFXSA9IHt9KTtcbiAgdmFyIGtleSwgb3duLCBvdXQsIGV4cDtcbiAgaWYgKElTX0dMT0JBTCkgc291cmNlID0gbmFtZTtcbiAgZm9yIChrZXkgaW4gc291cmNlKSB7XG4gICAgLy8gY29udGFpbnMgaW4gbmF0aXZlXG4gICAgb3duID0gIUlTX0ZPUkNFRCAmJiB0YXJnZXQgJiYgdGFyZ2V0W2tleV0gIT09IHVuZGVmaW5lZDtcbiAgICAvLyBleHBvcnQgbmF0aXZlIG9yIHBhc3NlZFxuICAgIG91dCA9IChvd24gPyB0YXJnZXQgOiBzb3VyY2UpW2tleV07XG4gICAgLy8gYmluZCB0aW1lcnMgdG8gZ2xvYmFsIGZvciBjYWxsIGZyb20gZXhwb3J0IGNvbnRleHRcbiAgICBleHAgPSBJU19CSU5EICYmIG93biA/IGN0eChvdXQsIGdsb2JhbCkgOiBJU19QUk9UTyAmJiB0eXBlb2Ygb3V0ID09ICdmdW5jdGlvbicgPyBjdHgoRnVuY3Rpb24uY2FsbCwgb3V0KSA6IG91dDtcbiAgICAvLyBleHRlbmQgZ2xvYmFsXG4gICAgaWYgKHRhcmdldCkgcmVkZWZpbmUodGFyZ2V0LCBrZXksIG91dCwgdHlwZSAmICRleHBvcnQuVSk7XG4gICAgLy8gZXhwb3J0XG4gICAgaWYgKGV4cG9ydHNba2V5XSAhPSBvdXQpIGhpZGUoZXhwb3J0cywga2V5LCBleHApO1xuICAgIGlmIChJU19QUk9UTyAmJiBleHBQcm90b1trZXldICE9IG91dCkgZXhwUHJvdG9ba2V5XSA9IG91dDtcbiAgfVxufTtcbmdsb2JhbC5jb3JlID0gY29yZTtcbi8vIHR5cGUgYml0bWFwXG4kZXhwb3J0LkYgPSAxOyAgIC8vIGZvcmNlZFxuJGV4cG9ydC5HID0gMjsgICAvLyBnbG9iYWxcbiRleHBvcnQuUyA9IDQ7ICAgLy8gc3RhdGljXG4kZXhwb3J0LlAgPSA4OyAgIC8vIHByb3RvXG4kZXhwb3J0LkIgPSAxNjsgIC8vIGJpbmRcbiRleHBvcnQuVyA9IDMyOyAgLy8gd3JhcFxuJGV4cG9ydC5VID0gNjQ7ICAvLyBzYWZlXG4kZXhwb3J0LlIgPSAxMjg7IC8vIHJlYWwgcHJvdG8gbWV0aG9kIGZvciBgbGlicmFyeWBcbm1vZHVsZS5leHBvcnRzID0gJGV4cG9ydDtcbiIsInZhciBNQVRDSCA9IHJlcXVpcmUoJy4vX3drcycpKCdtYXRjaCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoS0VZKSB7XG4gIHZhciByZSA9IC8uLztcbiAgdHJ5IHtcbiAgICAnLy4vJ1tLRVldKHJlKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRyeSB7XG4gICAgICByZVtNQVRDSF0gPSBmYWxzZTtcbiAgICAgIHJldHVybiAhJy8uLydbS0VZXShyZSk7XG4gICAgfSBjYXRjaCAoZikgeyAvKiBlbXB0eSAqLyB9XG4gIH0gcmV0dXJuIHRydWU7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZXhlYykge1xuICB0cnkge1xuICAgIHJldHVybiAhIWV4ZWMoKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xudmFyIHdrcyA9IHJlcXVpcmUoJy4vX3drcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChLRVksIGxlbmd0aCwgZXhlYykge1xuICB2YXIgU1lNQk9MID0gd2tzKEtFWSk7XG4gIHZhciBmbnMgPSBleGVjKGRlZmluZWQsIFNZTUJPTCwgJydbS0VZXSk7XG4gIHZhciBzdHJmbiA9IGZuc1swXTtcbiAgdmFyIHJ4Zm4gPSBmbnNbMV07XG4gIGlmIChmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgdmFyIE8gPSB7fTtcbiAgICBPW1NZTUJPTF0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA3OyB9O1xuICAgIHJldHVybiAnJ1tLRVldKE8pICE9IDc7XG4gIH0pKSB7XG4gICAgcmVkZWZpbmUoU3RyaW5nLnByb3RvdHlwZSwgS0VZLCBzdHJmbik7XG4gICAgaGlkZShSZWdFeHAucHJvdG90eXBlLCBTWU1CT0wsIGxlbmd0aCA9PSAyXG4gICAgICAvLyAyMS4yLjUuOCBSZWdFeHAucHJvdG90eXBlW0BAcmVwbGFjZV0oc3RyaW5nLCByZXBsYWNlVmFsdWUpXG4gICAgICAvLyAyMS4yLjUuMTEgUmVnRXhwLnByb3RvdHlwZVtAQHNwbGl0XShzdHJpbmcsIGxpbWl0KVxuICAgICAgPyBmdW5jdGlvbiAoc3RyaW5nLCBhcmcpIHsgcmV0dXJuIHJ4Zm4uY2FsbChzdHJpbmcsIHRoaXMsIGFyZyk7IH1cbiAgICAgIC8vIDIxLjIuNS42IFJlZ0V4cC5wcm90b3R5cGVbQEBtYXRjaF0oc3RyaW5nKVxuICAgICAgLy8gMjEuMi41LjkgUmVnRXhwLnByb3RvdHlwZVtAQHNlYXJjaF0oc3RyaW5nKVxuICAgICAgOiBmdW5jdGlvbiAoc3RyaW5nKSB7IHJldHVybiByeGZuLmNhbGwoc3RyaW5nLCB0aGlzKTsgfVxuICAgICk7XG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG4vLyAyMS4yLjUuMyBnZXQgUmVnRXhwLnByb3RvdHlwZS5mbGFnc1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRoYXQgPSBhbk9iamVjdCh0aGlzKTtcbiAgdmFyIHJlc3VsdCA9ICcnO1xuICBpZiAodGhhdC5nbG9iYWwpIHJlc3VsdCArPSAnZyc7XG4gIGlmICh0aGF0Lmlnbm9yZUNhc2UpIHJlc3VsdCArPSAnaSc7XG4gIGlmICh0aGF0Lm11bHRpbGluZSkgcmVzdWx0ICs9ICdtJztcbiAgaWYgKHRoYXQudW5pY29kZSkgcmVzdWx0ICs9ICd1JztcbiAgaWYgKHRoYXQuc3RpY2t5KSByZXN1bHQgKz0gJ3knO1xuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsInZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBjYWxsID0gcmVxdWlyZSgnLi9faXRlci1jYWxsJyk7XG52YXIgaXNBcnJheUl0ZXIgPSByZXF1aXJlKCcuL19pcy1hcnJheS1pdGVyJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIGdldEl0ZXJGbiA9IHJlcXVpcmUoJy4vY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kJyk7XG52YXIgQlJFQUsgPSB7fTtcbnZhciBSRVRVUk4gPSB7fTtcbnZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXRlcmFibGUsIGVudHJpZXMsIGZuLCB0aGF0LCBJVEVSQVRPUikge1xuICB2YXIgaXRlckZuID0gSVRFUkFUT1IgPyBmdW5jdGlvbiAoKSB7IHJldHVybiBpdGVyYWJsZTsgfSA6IGdldEl0ZXJGbihpdGVyYWJsZSk7XG4gIHZhciBmID0gY3R4KGZuLCB0aGF0LCBlbnRyaWVzID8gMiA6IDEpO1xuICB2YXIgaW5kZXggPSAwO1xuICB2YXIgbGVuZ3RoLCBzdGVwLCBpdGVyYXRvciwgcmVzdWx0O1xuICBpZiAodHlwZW9mIGl0ZXJGbiAhPSAnZnVuY3Rpb24nKSB0aHJvdyBUeXBlRXJyb3IoaXRlcmFibGUgKyAnIGlzIG5vdCBpdGVyYWJsZSEnKTtcbiAgLy8gZmFzdCBjYXNlIGZvciBhcnJheXMgd2l0aCBkZWZhdWx0IGl0ZXJhdG9yXG4gIGlmIChpc0FycmF5SXRlcihpdGVyRm4pKSBmb3IgKGxlbmd0aCA9IHRvTGVuZ3RoKGl0ZXJhYmxlLmxlbmd0aCk7IGxlbmd0aCA+IGluZGV4OyBpbmRleCsrKSB7XG4gICAgcmVzdWx0ID0gZW50cmllcyA/IGYoYW5PYmplY3Qoc3RlcCA9IGl0ZXJhYmxlW2luZGV4XSlbMF0sIHN0ZXBbMV0pIDogZihpdGVyYWJsZVtpbmRleF0pO1xuICAgIGlmIChyZXN1bHQgPT09IEJSRUFLIHx8IHJlc3VsdCA9PT0gUkVUVVJOKSByZXR1cm4gcmVzdWx0O1xuICB9IGVsc2UgZm9yIChpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKGl0ZXJhYmxlKTsgIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lOykge1xuICAgIHJlc3VsdCA9IGNhbGwoaXRlcmF0b3IsIGYsIHN0ZXAudmFsdWUsIGVudHJpZXMpO1xuICAgIGlmIChyZXN1bHQgPT09IEJSRUFLIHx8IHJlc3VsdCA9PT0gUkVUVVJOKSByZXR1cm4gcmVzdWx0O1xuICB9XG59O1xuZXhwb3J0cy5CUkVBSyA9IEJSRUFLO1xuZXhwb3J0cy5SRVRVUk4gPSBSRVRVUk47XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvODYjaXNzdWVjb21tZW50LTExNTc1OTAyOFxudmFyIGdsb2JhbCA9IG1vZHVsZS5leHBvcnRzID0gdHlwZW9mIHdpbmRvdyAhPSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuTWF0aCA9PSBNYXRoXG4gID8gd2luZG93IDogdHlwZW9mIHNlbGYgIT0gJ3VuZGVmaW5lZCcgJiYgc2VsZi5NYXRoID09IE1hdGggPyBzZWxmXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICA6IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5pZiAodHlwZW9mIF9fZyA9PSAnbnVtYmVyJykgX19nID0gZ2xvYmFsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG4iLCJ2YXIgaGFzT3duUHJvcGVydHkgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBrZXkpIHtcbiAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoaXQsIGtleSk7XG59O1xuIiwidmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgcmV0dXJuIGRQLmYob2JqZWN0LCBrZXksIGNyZWF0ZURlc2MoMSwgdmFsdWUpKTtcbn0gOiBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIG9iamVjdFtrZXldID0gdmFsdWU7XG4gIHJldHVybiBvYmplY3Q7XG59O1xuIiwidmFyIGRvY3VtZW50ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuZG9jdW1lbnQ7XG5tb2R1bGUuZXhwb3J0cyA9IGRvY3VtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiIsIm1vZHVsZS5leHBvcnRzID0gIXJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKSgnZGl2JyksICdhJywgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH0gfSkuYSAhPSA3O1xufSk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBzZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4vX3NldC1wcm90bycpLnNldDtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRoYXQsIHRhcmdldCwgQykge1xuICB2YXIgUyA9IHRhcmdldC5jb25zdHJ1Y3RvcjtcbiAgdmFyIFA7XG4gIGlmIChTICE9PSBDICYmIHR5cGVvZiBTID09ICdmdW5jdGlvbicgJiYgKFAgPSBTLnByb3RvdHlwZSkgIT09IEMucHJvdG90eXBlICYmIGlzT2JqZWN0KFApICYmIHNldFByb3RvdHlwZU9mKSB7XG4gICAgc2V0UHJvdG90eXBlT2YodGhhdCwgUCk7XG4gIH0gcmV0dXJuIHRoYXQ7XG59O1xuIiwiLy8gZmFzdCBhcHBseSwgaHR0cDovL2pzcGVyZi5sbmtpdC5jb20vZmFzdC1hcHBseS81XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChmbiwgYXJncywgdGhhdCkge1xuICB2YXIgdW4gPSB0aGF0ID09PSB1bmRlZmluZWQ7XG4gIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICBjYXNlIDA6IHJldHVybiB1biA/IGZuKClcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCk7XG4gICAgY2FzZSAxOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdKTtcbiAgICBjYXNlIDI6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgIGNhc2UgMzogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgY2FzZSA0OiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTtcbiAgfSByZXR1cm4gZm4uYXBwbHkodGhhdCwgYXJncyk7XG59O1xuIiwiLy8gZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBhbmQgbm9uLWVudW1lcmFibGUgb2xkIFY4IHN0cmluZ3NcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wcm90b3R5cGUtYnVpbHRpbnNcbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0KCd6JykucHJvcGVydHlJc0VudW1lcmFibGUoMCkgPyBPYmplY3QgOiBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGNvZihpdCkgPT0gJ1N0cmluZycgPyBpdC5zcGxpdCgnJykgOiBPYmplY3QoaXQpO1xufTtcbiIsIi8vIGNoZWNrIG9uIGRlZmF1bHQgQXJyYXkgaXRlcmF0b3JcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciBJVEVSQVRPUiA9IHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpO1xudmFyIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBpdCAhPT0gdW5kZWZpbmVkICYmIChJdGVyYXRvcnMuQXJyYXkgPT09IGl0IHx8IEFycmF5UHJvdG9bSVRFUkFUT1JdID09PSBpdCk7XG59O1xuIiwiLy8gNy4yLjIgSXNBcnJheShhcmd1bWVudClcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBpc0FycmF5KGFyZykge1xuICByZXR1cm4gY29mKGFyZykgPT0gJ0FycmF5Jztcbn07XG4iLCIvLyAyMC4xLjIuMyBOdW1iZXIuaXNJbnRlZ2VyKG51bWJlcilcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGZsb29yID0gTWF0aC5mbG9vcjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNJbnRlZ2VyKGl0KSB7XG4gIHJldHVybiAhaXNPYmplY3QoaXQpICYmIGlzRmluaXRlKGl0KSAmJiBmbG9vcihpdCkgPT09IGl0O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiB0eXBlb2YgaXQgPT09ICdvYmplY3QnID8gaXQgIT09IG51bGwgOiB0eXBlb2YgaXQgPT09ICdmdW5jdGlvbic7XG59O1xuIiwiLy8gNy4yLjggSXNSZWdFeHAoYXJndW1lbnQpXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbnZhciBNQVRDSCA9IHJlcXVpcmUoJy4vX3drcycpKCdtYXRjaCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgdmFyIGlzUmVnRXhwO1xuICByZXR1cm4gaXNPYmplY3QoaXQpICYmICgoaXNSZWdFeHAgPSBpdFtNQVRDSF0pICE9PSB1bmRlZmluZWQgPyAhIWlzUmVnRXhwIDogY29mKGl0KSA9PSAnUmVnRXhwJyk7XG59O1xuIiwiLy8gY2FsbCBzb21ldGhpbmcgb24gaXRlcmF0b3Igc3RlcCB3aXRoIHNhZmUgY2xvc2luZyBvbiBlcnJvclxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdGVyYXRvciwgZm4sIHZhbHVlLCBlbnRyaWVzKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGVudHJpZXMgPyBmbihhbk9iamVjdCh2YWx1ZSlbMF0sIHZhbHVlWzFdKSA6IGZuKHZhbHVlKTtcbiAgLy8gNy40LjYgSXRlcmF0b3JDbG9zZShpdGVyYXRvciwgY29tcGxldGlvbilcbiAgfSBjYXRjaCAoZSkge1xuICAgIHZhciByZXQgPSBpdGVyYXRvclsncmV0dXJuJ107XG4gICAgaWYgKHJldCAhPT0gdW5kZWZpbmVkKSBhbk9iamVjdChyZXQuY2FsbChpdGVyYXRvcikpO1xuICAgIHRocm93IGU7XG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xudmFyIGRlc2NyaXB0b3IgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XG5cbi8vIDI1LjEuMi4xLjEgJUl0ZXJhdG9yUHJvdG90eXBlJVtAQGl0ZXJhdG9yXSgpXG5yZXF1aXJlKCcuL19oaWRlJykoSXRlcmF0b3JQcm90b3R5cGUsIHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpLCBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIE5BTUUsIG5leHQpIHtcbiAgQ29uc3RydWN0b3IucHJvdG90eXBlID0gY3JlYXRlKEl0ZXJhdG9yUHJvdG90eXBlLCB7IG5leHQ6IGRlc2NyaXB0b3IoMSwgbmV4dCkgfSk7XG4gIHNldFRvU3RyaW5nVGFnKENvbnN0cnVjdG9yLCBOQU1FICsgJyBJdGVyYXRvcicpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBMSUJSQVJZID0gcmVxdWlyZSgnLi9fbGlicmFyeScpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciAkaXRlckNyZWF0ZSA9IHJlcXVpcmUoJy4vX2l0ZXItY3JlYXRlJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgQlVHR1kgPSAhKFtdLmtleXMgJiYgJ25leHQnIGluIFtdLmtleXMoKSk7IC8vIFNhZmFyaSBoYXMgYnVnZ3kgaXRlcmF0b3JzIHcvbyBgbmV4dGBcbnZhciBGRl9JVEVSQVRPUiA9ICdAQGl0ZXJhdG9yJztcbnZhciBLRVlTID0gJ2tleXMnO1xudmFyIFZBTFVFUyA9ICd2YWx1ZXMnO1xuXG52YXIgcmV0dXJuVGhpcyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEJhc2UsIE5BTUUsIENvbnN0cnVjdG9yLCBuZXh0LCBERUZBVUxULCBJU19TRVQsIEZPUkNFRCkge1xuICAkaXRlckNyZWF0ZShDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCk7XG4gIHZhciBnZXRNZXRob2QgPSBmdW5jdGlvbiAoa2luZCkge1xuICAgIGlmICghQlVHR1kgJiYga2luZCBpbiBwcm90bykgcmV0dXJuIHByb3RvW2tpbmRdO1xuICAgIHN3aXRjaCAoa2luZCkge1xuICAgICAgY2FzZSBLRVlTOiByZXR1cm4gZnVuY3Rpb24ga2V5cygpIHsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgICAgIGNhc2UgVkFMVUVTOiByZXR1cm4gZnVuY3Rpb24gdmFsdWVzKCkgeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICAgIH0gcmV0dXJuIGZ1bmN0aW9uIGVudHJpZXMoKSB7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gIH07XG4gIHZhciBUQUcgPSBOQU1FICsgJyBJdGVyYXRvcic7XG4gIHZhciBERUZfVkFMVUVTID0gREVGQVVMVCA9PSBWQUxVRVM7XG4gIHZhciBWQUxVRVNfQlVHID0gZmFsc2U7XG4gIHZhciBwcm90byA9IEJhc2UucHJvdG90eXBlO1xuICB2YXIgJG5hdGl2ZSA9IHByb3RvW0lURVJBVE9SXSB8fCBwcm90b1tGRl9JVEVSQVRPUl0gfHwgREVGQVVMVCAmJiBwcm90b1tERUZBVUxUXTtcbiAgdmFyICRkZWZhdWx0ID0gJG5hdGl2ZSB8fCBnZXRNZXRob2QoREVGQVVMVCk7XG4gIHZhciAkZW50cmllcyA9IERFRkFVTFQgPyAhREVGX1ZBTFVFUyA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKCdlbnRyaWVzJykgOiB1bmRlZmluZWQ7XG4gIHZhciAkYW55TmF0aXZlID0gTkFNRSA9PSAnQXJyYXknID8gcHJvdG8uZW50cmllcyB8fCAkbmF0aXZlIDogJG5hdGl2ZTtcbiAgdmFyIG1ldGhvZHMsIGtleSwgSXRlcmF0b3JQcm90b3R5cGU7XG4gIC8vIEZpeCBuYXRpdmVcbiAgaWYgKCRhbnlOYXRpdmUpIHtcbiAgICBJdGVyYXRvclByb3RvdHlwZSA9IGdldFByb3RvdHlwZU9mKCRhbnlOYXRpdmUuY2FsbChuZXcgQmFzZSgpKSk7XG4gICAgaWYgKEl0ZXJhdG9yUHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlICYmIEl0ZXJhdG9yUHJvdG90eXBlLm5leHQpIHtcbiAgICAgIC8vIFNldCBAQHRvU3RyaW5nVGFnIHRvIG5hdGl2ZSBpdGVyYXRvcnNcbiAgICAgIHNldFRvU3RyaW5nVGFnKEl0ZXJhdG9yUHJvdG90eXBlLCBUQUcsIHRydWUpO1xuICAgICAgLy8gZml4IGZvciBzb21lIG9sZCBlbmdpbmVzXG4gICAgICBpZiAoIUxJQlJBUlkgJiYgdHlwZW9mIEl0ZXJhdG9yUHJvdG90eXBlW0lURVJBVE9SXSAhPSAnZnVuY3Rpb24nKSBoaWRlKEl0ZXJhdG9yUHJvdG90eXBlLCBJVEVSQVRPUiwgcmV0dXJuVGhpcyk7XG4gICAgfVxuICB9XG4gIC8vIGZpeCBBcnJheSN7dmFsdWVzLCBAQGl0ZXJhdG9yfS5uYW1lIGluIFY4IC8gRkZcbiAgaWYgKERFRl9WQUxVRVMgJiYgJG5hdGl2ZSAmJiAkbmF0aXZlLm5hbWUgIT09IFZBTFVFUykge1xuICAgIFZBTFVFU19CVUcgPSB0cnVlO1xuICAgICRkZWZhdWx0ID0gZnVuY3Rpb24gdmFsdWVzKCkgeyByZXR1cm4gJG5hdGl2ZS5jYWxsKHRoaXMpOyB9O1xuICB9XG4gIC8vIERlZmluZSBpdGVyYXRvclxuICBpZiAoKCFMSUJSQVJZIHx8IEZPUkNFRCkgJiYgKEJVR0dZIHx8IFZBTFVFU19CVUcgfHwgIXByb3RvW0lURVJBVE9SXSkpIHtcbiAgICBoaWRlKHByb3RvLCBJVEVSQVRPUiwgJGRlZmF1bHQpO1xuICB9XG4gIC8vIFBsdWcgZm9yIGxpYnJhcnlcbiAgSXRlcmF0b3JzW05BTUVdID0gJGRlZmF1bHQ7XG4gIEl0ZXJhdG9yc1tUQUddID0gcmV0dXJuVGhpcztcbiAgaWYgKERFRkFVTFQpIHtcbiAgICBtZXRob2RzID0ge1xuICAgICAgdmFsdWVzOiBERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoVkFMVUVTKSxcbiAgICAgIGtleXM6IElTX1NFVCA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKEtFWVMpLFxuICAgICAgZW50cmllczogJGVudHJpZXNcbiAgICB9O1xuICAgIGlmIChGT1JDRUQpIGZvciAoa2V5IGluIG1ldGhvZHMpIHtcbiAgICAgIGlmICghKGtleSBpbiBwcm90bykpIHJlZGVmaW5lKHByb3RvLCBrZXksIG1ldGhvZHNba2V5XSk7XG4gICAgfSBlbHNlICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKEJVR0dZIHx8IFZBTFVFU19CVUcpLCBOQU1FLCBtZXRob2RzKTtcbiAgfVxuICByZXR1cm4gbWV0aG9kcztcbn07XG4iLCJ2YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBTQUZFX0NMT1NJTkcgPSBmYWxzZTtcblxudHJ5IHtcbiAgdmFyIHJpdGVyID0gWzddW0lURVJBVE9SXSgpO1xuICByaXRlclsncmV0dXJuJ10gPSBmdW5jdGlvbiAoKSB7IFNBRkVfQ0xPU0lORyA9IHRydWU7IH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10aHJvdy1saXRlcmFsXG4gIEFycmF5LmZyb20ocml0ZXIsIGZ1bmN0aW9uICgpIHsgdGhyb3cgMjsgfSk7XG59IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZXhlYywgc2tpcENsb3NpbmcpIHtcbiAgaWYgKCFza2lwQ2xvc2luZyAmJiAhU0FGRV9DTE9TSU5HKSByZXR1cm4gZmFsc2U7XG4gIHZhciBzYWZlID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IFs3XTtcbiAgICB2YXIgaXRlciA9IGFycltJVEVSQVRPUl0oKTtcbiAgICBpdGVyLm5leHQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB7IGRvbmU6IHNhZmUgPSB0cnVlIH07IH07XG4gICAgYXJyW0lURVJBVE9SXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGl0ZXI7IH07XG4gICAgZXhlYyhhcnIpO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbiAgcmV0dXJuIHNhZmU7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZG9uZSwgdmFsdWUpIHtcbiAgcmV0dXJuIHsgdmFsdWU6IHZhbHVlLCBkb25lOiAhIWRvbmUgfTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHt9O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmYWxzZTtcbiIsIi8vIDIwLjIuMi4xNCBNYXRoLmV4cG0xKHgpXG52YXIgJGV4cG0xID0gTWF0aC5leHBtMTtcbm1vZHVsZS5leHBvcnRzID0gKCEkZXhwbTFcbiAgLy8gT2xkIEZGIGJ1Z1xuICB8fCAkZXhwbTEoMTApID4gMjIwMjUuNDY1Nzk0ODA2NzE5IHx8ICRleHBtMSgxMCkgPCAyMjAyNS40NjU3OTQ4MDY3MTY1MTY4XG4gIC8vIFRvciBCcm93c2VyIGJ1Z1xuICB8fCAkZXhwbTEoLTJlLTE3KSAhPSAtMmUtMTdcbikgPyBmdW5jdGlvbiBleHBtMSh4KSB7XG4gIHJldHVybiAoeCA9ICt4KSA9PSAwID8geCA6IHggPiAtMWUtNiAmJiB4IDwgMWUtNiA/IHggKyB4ICogeCAvIDIgOiBNYXRoLmV4cCh4KSAtIDE7XG59IDogJGV4cG0xO1xuIiwiLy8gMjAuMi4yLjE2IE1hdGguZnJvdW5kKHgpXG52YXIgc2lnbiA9IHJlcXVpcmUoJy4vX21hdGgtc2lnbicpO1xudmFyIHBvdyA9IE1hdGgucG93O1xudmFyIEVQU0lMT04gPSBwb3coMiwgLTUyKTtcbnZhciBFUFNJTE9OMzIgPSBwb3coMiwgLTIzKTtcbnZhciBNQVgzMiA9IHBvdygyLCAxMjcpICogKDIgLSBFUFNJTE9OMzIpO1xudmFyIE1JTjMyID0gcG93KDIsIC0xMjYpO1xuXG52YXIgcm91bmRUaWVzVG9FdmVuID0gZnVuY3Rpb24gKG4pIHtcbiAgcmV0dXJuIG4gKyAxIC8gRVBTSUxPTiAtIDEgLyBFUFNJTE9OO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBNYXRoLmZyb3VuZCB8fCBmdW5jdGlvbiBmcm91bmQoeCkge1xuICB2YXIgJGFicyA9IE1hdGguYWJzKHgpO1xuICB2YXIgJHNpZ24gPSBzaWduKHgpO1xuICB2YXIgYSwgcmVzdWx0O1xuICBpZiAoJGFicyA8IE1JTjMyKSByZXR1cm4gJHNpZ24gKiByb3VuZFRpZXNUb0V2ZW4oJGFicyAvIE1JTjMyIC8gRVBTSUxPTjMyKSAqIE1JTjMyICogRVBTSUxPTjMyO1xuICBhID0gKDEgKyBFUFNJTE9OMzIgLyBFUFNJTE9OKSAqICRhYnM7XG4gIHJlc3VsdCA9IGEgLSAoYSAtICRhYnMpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gIGlmIChyZXN1bHQgPiBNQVgzMiB8fCByZXN1bHQgIT0gcmVzdWx0KSByZXR1cm4gJHNpZ24gKiBJbmZpbml0eTtcbiAgcmV0dXJuICRzaWduICogcmVzdWx0O1xufTtcbiIsIi8vIDIwLjIuMi4yMCBNYXRoLmxvZzFwKHgpXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGgubG9nMXAgfHwgZnVuY3Rpb24gbG9nMXAoeCkge1xuICByZXR1cm4gKHggPSAreCkgPiAtMWUtOCAmJiB4IDwgMWUtOCA/IHggLSB4ICogeCAvIDIgOiBNYXRoLmxvZygxICsgeCk7XG59O1xuIiwiLy8gMjAuMi4yLjI4IE1hdGguc2lnbih4KVxubW9kdWxlLmV4cG9ydHMgPSBNYXRoLnNpZ24gfHwgZnVuY3Rpb24gc2lnbih4KSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgcmV0dXJuICh4ID0gK3gpID09IDAgfHwgeCAhPSB4ID8geCA6IHggPCAwID8gLTEgOiAxO1xufTtcbiIsInZhciBNRVRBID0gcmVxdWlyZSgnLi9fdWlkJykoJ21ldGEnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHNldERlc2MgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGlkID0gMDtcbnZhciBpc0V4dGVuc2libGUgPSBPYmplY3QuaXNFeHRlbnNpYmxlIHx8IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRydWU7XG59O1xudmFyIEZSRUVaRSA9ICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIGlzRXh0ZW5zaWJsZShPYmplY3QucHJldmVudEV4dGVuc2lvbnMoe30pKTtcbn0pO1xudmFyIHNldE1ldGEgPSBmdW5jdGlvbiAoaXQpIHtcbiAgc2V0RGVzYyhpdCwgTUVUQSwgeyB2YWx1ZToge1xuICAgIGk6ICdPJyArICsraWQsIC8vIG9iamVjdCBJRFxuICAgIHc6IHt9ICAgICAgICAgIC8vIHdlYWsgY29sbGVjdGlvbnMgSURzXG4gIH0gfSk7XG59O1xudmFyIGZhc3RLZXkgPSBmdW5jdGlvbiAoaXQsIGNyZWF0ZSkge1xuICAvLyByZXR1cm4gcHJpbWl0aXZlIHdpdGggcHJlZml4XG4gIGlmICghaXNPYmplY3QoaXQpKSByZXR1cm4gdHlwZW9mIGl0ID09ICdzeW1ib2wnID8gaXQgOiAodHlwZW9mIGl0ID09ICdzdHJpbmcnID8gJ1MnIDogJ1AnKSArIGl0O1xuICBpZiAoIWhhcyhpdCwgTUVUQSkpIHtcbiAgICAvLyBjYW4ndCBzZXQgbWV0YWRhdGEgdG8gdW5jYXVnaHQgZnJvemVuIG9iamVjdFxuICAgIGlmICghaXNFeHRlbnNpYmxlKGl0KSkgcmV0dXJuICdGJztcbiAgICAvLyBub3QgbmVjZXNzYXJ5IHRvIGFkZCBtZXRhZGF0YVxuICAgIGlmICghY3JlYXRlKSByZXR1cm4gJ0UnO1xuICAgIC8vIGFkZCBtaXNzaW5nIG1ldGFkYXRhXG4gICAgc2V0TWV0YShpdCk7XG4gIC8vIHJldHVybiBvYmplY3QgSURcbiAgfSByZXR1cm4gaXRbTUVUQV0uaTtcbn07XG52YXIgZ2V0V2VhayA9IGZ1bmN0aW9uIChpdCwgY3JlYXRlKSB7XG4gIGlmICghaGFzKGl0LCBNRVRBKSkge1xuICAgIC8vIGNhbid0IHNldCBtZXRhZGF0YSB0byB1bmNhdWdodCBmcm96ZW4gb2JqZWN0XG4gICAgaWYgKCFpc0V4dGVuc2libGUoaXQpKSByZXR1cm4gdHJ1ZTtcbiAgICAvLyBub3QgbmVjZXNzYXJ5IHRvIGFkZCBtZXRhZGF0YVxuICAgIGlmICghY3JlYXRlKSByZXR1cm4gZmFsc2U7XG4gICAgLy8gYWRkIG1pc3NpbmcgbWV0YWRhdGFcbiAgICBzZXRNZXRhKGl0KTtcbiAgLy8gcmV0dXJuIGhhc2ggd2VhayBjb2xsZWN0aW9ucyBJRHNcbiAgfSByZXR1cm4gaXRbTUVUQV0udztcbn07XG4vLyBhZGQgbWV0YWRhdGEgb24gZnJlZXplLWZhbWlseSBtZXRob2RzIGNhbGxpbmdcbnZhciBvbkZyZWV6ZSA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoRlJFRVpFICYmIG1ldGEuTkVFRCAmJiBpc0V4dGVuc2libGUoaXQpICYmICFoYXMoaXQsIE1FVEEpKSBzZXRNZXRhKGl0KTtcbiAgcmV0dXJuIGl0O1xufTtcbnZhciBtZXRhID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gIEtFWTogTUVUQSxcbiAgTkVFRDogZmFsc2UsXG4gIGZhc3RLZXk6IGZhc3RLZXksXG4gIGdldFdlYWs6IGdldFdlYWssXG4gIG9uRnJlZXplOiBvbkZyZWV6ZVxufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBtYWNyb3Rhc2sgPSByZXF1aXJlKCcuL190YXNrJykuc2V0O1xudmFyIE9ic2VydmVyID0gZ2xvYmFsLk11dGF0aW9uT2JzZXJ2ZXIgfHwgZ2xvYmFsLldlYktpdE11dGF0aW9uT2JzZXJ2ZXI7XG52YXIgcHJvY2VzcyA9IGdsb2JhbC5wcm9jZXNzO1xudmFyIFByb21pc2UgPSBnbG9iYWwuUHJvbWlzZTtcbnZhciBpc05vZGUgPSByZXF1aXJlKCcuL19jb2YnKShwcm9jZXNzKSA9PSAncHJvY2Vzcyc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaGVhZCwgbGFzdCwgbm90aWZ5O1xuXG4gIHZhciBmbHVzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcGFyZW50LCBmbjtcbiAgICBpZiAoaXNOb2RlICYmIChwYXJlbnQgPSBwcm9jZXNzLmRvbWFpbikpIHBhcmVudC5leGl0KCk7XG4gICAgd2hpbGUgKGhlYWQpIHtcbiAgICAgIGZuID0gaGVhZC5mbjtcbiAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICB0cnkge1xuICAgICAgICBmbigpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoaGVhZCkgbm90aWZ5KCk7XG4gICAgICAgIGVsc2UgbGFzdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9IGxhc3QgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHBhcmVudCkgcGFyZW50LmVudGVyKCk7XG4gIH07XG5cbiAgLy8gTm9kZS5qc1xuICBpZiAoaXNOb2RlKSB7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgfTtcbiAgLy8gYnJvd3NlcnMgd2l0aCBNdXRhdGlvbk9ic2VydmVyLCBleGNlcHQgaU9TIFNhZmFyaSAtIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8zMzlcbiAgfSBlbHNlIGlmIChPYnNlcnZlciAmJiAhKGdsb2JhbC5uYXZpZ2F0b3IgJiYgZ2xvYmFsLm5hdmlnYXRvci5zdGFuZGFsb25lKSkge1xuICAgIHZhciB0b2dnbGUgPSB0cnVlO1xuICAgIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpO1xuICAgIG5ldyBPYnNlcnZlcihmbHVzaCkub2JzZXJ2ZShub2RlLCB7IGNoYXJhY3RlckRhdGE6IHRydWUgfSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgbm9kZS5kYXRhID0gdG9nZ2xlID0gIXRvZ2dsZTtcbiAgICB9O1xuICAvLyBlbnZpcm9ubWVudHMgd2l0aCBtYXliZSBub24tY29tcGxldGVseSBjb3JyZWN0LCBidXQgZXhpc3RlbnQgUHJvbWlzZVxuICB9IGVsc2UgaWYgKFByb21pc2UgJiYgUHJvbWlzZS5yZXNvbHZlKSB7XG4gICAgLy8gUHJvbWlzZS5yZXNvbHZlIHdpdGhvdXQgYW4gYXJndW1lbnQgdGhyb3dzIGFuIGVycm9yIGluIExHIFdlYk9TIDJcbiAgICB2YXIgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHByb21pc2UudGhlbihmbHVzaCk7XG4gICAgfTtcbiAgLy8gZm9yIG90aGVyIGVudmlyb25tZW50cyAtIG1hY3JvdGFzayBiYXNlZCBvbjpcbiAgLy8gLSBzZXRJbW1lZGlhdGVcbiAgLy8gLSBNZXNzYWdlQ2hhbm5lbFxuICAvLyAtIHdpbmRvdy5wb3N0TWVzc2FnXG4gIC8vIC0gb25yZWFkeXN0YXRlY2hhbmdlXG4gIC8vIC0gc2V0VGltZW91dFxuICB9IGVsc2Uge1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHN0cmFuZ2UgSUUgKyB3ZWJwYWNrIGRldiBzZXJ2ZXIgYnVnIC0gdXNlIC5jYWxsKGdsb2JhbClcbiAgICAgIG1hY3JvdGFzay5jYWxsKGdsb2JhbCwgZmx1c2gpO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gKGZuKSB7XG4gICAgdmFyIHRhc2sgPSB7IGZuOiBmbiwgbmV4dDogdW5kZWZpbmVkIH07XG4gICAgaWYgKGxhc3QpIGxhc3QubmV4dCA9IHRhc2s7XG4gICAgaWYgKCFoZWFkKSB7XG4gICAgICBoZWFkID0gdGFzaztcbiAgICAgIG5vdGlmeSgpO1xuICAgIH0gbGFzdCA9IHRhc2s7XG4gIH07XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMjUuNC4xLjUgTmV3UHJvbWlzZUNhcGFiaWxpdHkoQylcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5cbmZ1bmN0aW9uIFByb21pc2VDYXBhYmlsaXR5KEMpIHtcbiAgdmFyIHJlc29sdmUsIHJlamVjdDtcbiAgdGhpcy5wcm9taXNlID0gbmV3IEMoZnVuY3Rpb24gKCQkcmVzb2x2ZSwgJCRyZWplY3QpIHtcbiAgICBpZiAocmVzb2x2ZSAhPT0gdW5kZWZpbmVkIHx8IHJlamVjdCAhPT0gdW5kZWZpbmVkKSB0aHJvdyBUeXBlRXJyb3IoJ0JhZCBQcm9taXNlIGNvbnN0cnVjdG9yJyk7XG4gICAgcmVzb2x2ZSA9ICQkcmVzb2x2ZTtcbiAgICByZWplY3QgPSAkJHJlamVjdDtcbiAgfSk7XG4gIHRoaXMucmVzb2x2ZSA9IGFGdW5jdGlvbihyZXNvbHZlKTtcbiAgdGhpcy5yZWplY3QgPSBhRnVuY3Rpb24ocmVqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMuZiA9IGZ1bmN0aW9uIChDKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZUNhcGFiaWxpdHkoQyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMTkuMS4yLjEgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHNvdXJjZSwgLi4uKVxudmFyIGdldEtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xudmFyIGdPUFMgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wcycpO1xudmFyIHBJRSA9IHJlcXVpcmUoJy4vX29iamVjdC1waWUnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIElPYmplY3QgPSByZXF1aXJlKCcuL19pb2JqZWN0Jyk7XG52YXIgJGFzc2lnbiA9IE9iamVjdC5hc3NpZ247XG5cbi8vIHNob3VsZCB3b3JrIHdpdGggc3ltYm9scyBhbmQgc2hvdWxkIGhhdmUgZGV0ZXJtaW5pc3RpYyBwcm9wZXJ0eSBvcmRlciAoVjggYnVnKVxubW9kdWxlLmV4cG9ydHMgPSAhJGFzc2lnbiB8fCByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgdmFyIEEgPSB7fTtcbiAgdmFyIEIgPSB7fTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gIHZhciBTID0gU3ltYm9sKCk7XG4gIHZhciBLID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0JztcbiAgQVtTXSA9IDc7XG4gIEsuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24gKGspIHsgQltrXSA9IGs7IH0pO1xuICByZXR1cm4gJGFzc2lnbih7fSwgQSlbU10gIT0gNyB8fCBPYmplY3Qua2V5cygkYXNzaWduKHt9LCBCKSkuam9pbignJykgIT0gSztcbn0pID8gZnVuY3Rpb24gYXNzaWduKHRhcmdldCwgc291cmNlKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgdmFyIFQgPSB0b09iamVjdCh0YXJnZXQpO1xuICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBpbmRleCA9IDE7XG4gIHZhciBnZXRTeW1ib2xzID0gZ09QUy5mO1xuICB2YXIgaXNFbnVtID0gcElFLmY7XG4gIHdoaWxlIChhTGVuID4gaW5kZXgpIHtcbiAgICB2YXIgUyA9IElPYmplY3QoYXJndW1lbnRzW2luZGV4KytdKTtcbiAgICB2YXIga2V5cyA9IGdldFN5bWJvbHMgPyBnZXRLZXlzKFMpLmNvbmNhdChnZXRTeW1ib2xzKFMpKSA6IGdldEtleXMoUyk7XG4gICAgdmFyIGxlbmd0aCA9IGtleXMubGVuZ3RoO1xuICAgIHZhciBqID0gMDtcbiAgICB2YXIga2V5O1xuICAgIHdoaWxlIChsZW5ndGggPiBqKSBpZiAoaXNFbnVtLmNhbGwoUywga2V5ID0ga2V5c1tqKytdKSkgVFtrZXldID0gU1trZXldO1xuICB9IHJldHVybiBUO1xufSA6ICRhc3NpZ247XG4iLCIvLyAxOS4xLjIuMiAvIDE1LjIuMy41IE9iamVjdC5jcmVhdGUoTyBbLCBQcm9wZXJ0aWVzXSlcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGRQcyA9IHJlcXVpcmUoJy4vX29iamVjdC1kcHMnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKTtcbnZhciBJRV9QUk9UTyA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcbnZhciBFbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcblxuLy8gQ3JlYXRlIG9iamVjdCB3aXRoIGZha2UgYG51bGxgIHByb3RvdHlwZTogdXNlIGlmcmFtZSBPYmplY3Qgd2l0aCBjbGVhcmVkIHByb3RvdHlwZVxudmFyIGNyZWF0ZURpY3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIFRocmFzaCwgd2FzdGUgYW5kIHNvZG9teTogSUUgR0MgYnVnXG4gIHZhciBpZnJhbWUgPSByZXF1aXJlKCcuL19kb20tY3JlYXRlJykoJ2lmcmFtZScpO1xuICB2YXIgaSA9IGVudW1CdWdLZXlzLmxlbmd0aDtcbiAgdmFyIGx0ID0gJzwnO1xuICB2YXIgZ3QgPSAnPic7XG4gIHZhciBpZnJhbWVEb2N1bWVudDtcbiAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIHJlcXVpcmUoJy4vX2h0bWwnKS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6JzsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zY3JpcHQtdXJsXG4gIC8vIGNyZWF0ZURpY3QgPSBpZnJhbWUuY29udGVudFdpbmRvdy5PYmplY3Q7XG4gIC8vIGh0bWwucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgaWZyYW1lRG9jdW1lbnQgPSBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudDtcbiAgaWZyYW1lRG9jdW1lbnQub3BlbigpO1xuICBpZnJhbWVEb2N1bWVudC53cml0ZShsdCArICdzY3JpcHQnICsgZ3QgKyAnZG9jdW1lbnQuRj1PYmplY3QnICsgbHQgKyAnL3NjcmlwdCcgKyBndCk7XG4gIGlmcmFtZURvY3VtZW50LmNsb3NlKCk7XG4gIGNyZWF0ZURpY3QgPSBpZnJhbWVEb2N1bWVudC5GO1xuICB3aGlsZSAoaS0tKSBkZWxldGUgY3JlYXRlRGljdFtQUk9UT1RZUEVdW2VudW1CdWdLZXlzW2ldXTtcbiAgcmV0dXJuIGNyZWF0ZURpY3QoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmNyZWF0ZSB8fCBmdW5jdGlvbiBjcmVhdGUoTywgUHJvcGVydGllcykge1xuICB2YXIgcmVzdWx0O1xuICBpZiAoTyAhPT0gbnVsbCkge1xuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBhbk9iamVjdChPKTtcbiAgICByZXN1bHQgPSBuZXcgRW1wdHkoKTtcbiAgICBFbXB0eVtQUk9UT1RZUEVdID0gbnVsbDtcbiAgICAvLyBhZGQgXCJfX3Byb3RvX19cIiBmb3IgT2JqZWN0LmdldFByb3RvdHlwZU9mIHBvbHlmaWxsXG4gICAgcmVzdWx0W0lFX1BST1RPXSA9IE87XG4gIH0gZWxzZSByZXN1bHQgPSBjcmVhdGVEaWN0KCk7XG4gIHJldHVybiBQcm9wZXJ0aWVzID09PSB1bmRlZmluZWQgPyByZXN1bHQgOiBkUHMocmVzdWx0LCBQcm9wZXJ0aWVzKTtcbn07XG4iLCJ2YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBJRThfRE9NX0RFRklORSA9IHJlcXVpcmUoJy4vX2llOC1kb20tZGVmaW5lJyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBkUCA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcblxuZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSA6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpIHtcbiAgYW5PYmplY3QoTyk7XG4gIFAgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcbiAgYW5PYmplY3QoQXR0cmlidXRlcyk7XG4gIGlmIChJRThfRE9NX0RFRklORSkgdHJ5IHtcbiAgICByZXR1cm4gZFAoTywgUCwgQXR0cmlidXRlcyk7XG4gIH0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxuICBpZiAoJ2dldCcgaW4gQXR0cmlidXRlcyB8fCAnc2V0JyBpbiBBdHRyaWJ1dGVzKSB0aHJvdyBUeXBlRXJyb3IoJ0FjY2Vzc29ycyBub3Qgc3VwcG9ydGVkIScpO1xuICBpZiAoJ3ZhbHVlJyBpbiBBdHRyaWJ1dGVzKSBPW1BdID0gQXR0cmlidXRlcy52YWx1ZTtcbiAgcmV0dXJuIE87XG59O1xuIiwidmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gT2JqZWN0LmRlZmluZVByb3BlcnRpZXMgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpIHtcbiAgYW5PYmplY3QoTyk7XG4gIHZhciBrZXlzID0gZ2V0S2V5cyhQcm9wZXJ0aWVzKTtcbiAgdmFyIGxlbmd0aCA9IGtleXMubGVuZ3RoO1xuICB2YXIgaSA9IDA7XG4gIHZhciBQO1xuICB3aGlsZSAobGVuZ3RoID4gaSkgZFAuZihPLCBQID0ga2V5c1tpKytdLCBQcm9wZXJ0aWVzW1BdKTtcbiAgcmV0dXJuIE87XG59O1xuIiwidmFyIHBJRSA9IHJlcXVpcmUoJy4vX29iamVjdC1waWUnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIElFOF9ET01fREVGSU5FID0gcmVxdWlyZSgnLi9faWU4LWRvbS1kZWZpbmUnKTtcbnZhciBnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcblxuZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IGdPUEQgOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUCkge1xuICBPID0gdG9JT2JqZWN0KE8pO1xuICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XG4gIGlmIChJRThfRE9NX0RFRklORSkgdHJ5IHtcbiAgICByZXR1cm4gZ09QRChPLCBQKTtcbiAgfSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG4gIGlmIChoYXMoTywgUCkpIHJldHVybiBjcmVhdGVEZXNjKCFwSUUuZi5jYWxsKE8sIFApLCBPW1BdKTtcbn07XG4iLCIvLyBmYWxsYmFjayBmb3IgSUUxMSBidWdneSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB3aXRoIGlmcmFtZSBhbmQgd2luZG93XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIGdPUE4gPSByZXF1aXJlKCcuL19vYmplY3QtZ29wbicpLmY7XG52YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxudmFyIHdpbmRvd05hbWVzID0gdHlwZW9mIHdpbmRvdyA9PSAnb2JqZWN0JyAmJiB3aW5kb3cgJiYgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXNcbiAgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh3aW5kb3cpIDogW107XG5cbnZhciBnZXRXaW5kb3dOYW1lcyA9IGZ1bmN0aW9uIChpdCkge1xuICB0cnkge1xuICAgIHJldHVybiBnT1BOKGl0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB3aW5kb3dOYW1lcy5zbGljZSgpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5mID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhpdCkge1xuICByZXR1cm4gd2luZG93TmFtZXMgJiYgdG9TdHJpbmcuY2FsbChpdCkgPT0gJ1tvYmplY3QgV2luZG93XScgPyBnZXRXaW5kb3dOYW1lcyhpdCkgOiBnT1BOKHRvSU9iamVjdChpdCkpO1xufTtcbiIsIi8vIDE5LjEuMi43IC8gMTUuMi4zLjQgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoTylcbnZhciAka2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzLWludGVybmFsJyk7XG52YXIgaGlkZGVuS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKS5jb25jYXQoJ2xlbmd0aCcsICdwcm90b3R5cGUnKTtcblxuZXhwb3J0cy5mID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgfHwgZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhPKSB7XG4gIHJldHVybiAka2V5cyhPLCBoaWRkZW5LZXlzKTtcbn07XG4iLCJleHBvcnRzLmYgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzO1xuIiwiLy8gMTkuMS4yLjkgLyAxNS4yLjMuMiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoTylcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIElFX1BST1RPID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xudmFyIE9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YgfHwgZnVuY3Rpb24gKE8pIHtcbiAgTyA9IHRvT2JqZWN0KE8pO1xuICBpZiAoaGFzKE8sIElFX1BST1RPKSkgcmV0dXJuIE9bSUVfUFJPVE9dO1xuICBpZiAodHlwZW9mIE8uY29uc3RydWN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBPIGluc3RhbmNlb2YgTy5jb25zdHJ1Y3Rvcikge1xuICAgIHJldHVybiBPLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcbiAgfSByZXR1cm4gTyBpbnN0YW5jZW9mIE9iamVjdCA/IE9iamVjdFByb3RvIDogbnVsbDtcbn07XG4iLCJ2YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIGFycmF5SW5kZXhPZiA9IHJlcXVpcmUoJy4vX2FycmF5LWluY2x1ZGVzJykoZmFsc2UpO1xudmFyIElFX1BST1RPID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWVzKSB7XG4gIHZhciBPID0gdG9JT2JqZWN0KG9iamVjdCk7XG4gIHZhciBpID0gMDtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIga2V5O1xuICBmb3IgKGtleSBpbiBPKSBpZiAoa2V5ICE9IElFX1BST1RPKSBoYXMoTywga2V5KSAmJiByZXN1bHQucHVzaChrZXkpO1xuICAvLyBEb24ndCBlbnVtIGJ1ZyAmIGhpZGRlbiBrZXlzXG4gIHdoaWxlIChuYW1lcy5sZW5ndGggPiBpKSBpZiAoaGFzKE8sIGtleSA9IG5hbWVzW2krK10pKSB7XG4gICAgfmFycmF5SW5kZXhPZihyZXN1bHQsIGtleSkgfHwgcmVzdWx0LnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsIi8vIDE5LjEuMi4xNCAvIDE1LjIuMy4xNCBPYmplY3Qua2V5cyhPKVxudmFyICRrZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMtaW50ZXJuYWwnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiBrZXlzKE8pIHtcbiAgcmV0dXJuICRrZXlzKE8sIGVudW1CdWdLZXlzKTtcbn07XG4iLCJleHBvcnRzLmYgPSB7fS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcbiIsIi8vIG1vc3QgT2JqZWN0IG1ldGhvZHMgYnkgRVM2IHNob3VsZCBhY2NlcHQgcHJpbWl0aXZlc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEtFWSwgZXhlYykge1xuICB2YXIgZm4gPSAoY29yZS5PYmplY3QgfHwge30pW0tFWV0gfHwgT2JqZWN0W0tFWV07XG4gIHZhciBleHAgPSB7fTtcbiAgZXhwW0tFWV0gPSBleGVjKGZuKTtcbiAgJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbiAoKSB7IGZuKDEpOyB9KSwgJ09iamVjdCcsIGV4cCk7XG59O1xuIiwidmFyIGdldEtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBpc0VudW0gPSByZXF1aXJlKCcuL19vYmplY3QtcGllJykuZjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGlzRW50cmllcykge1xuICByZXR1cm4gZnVuY3Rpb24gKGl0KSB7XG4gICAgdmFyIE8gPSB0b0lPYmplY3QoaXQpO1xuICAgIHZhciBrZXlzID0gZ2V0S2V5cyhPKTtcbiAgICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICB2YXIga2V5O1xuICAgIHdoaWxlIChsZW5ndGggPiBpKSBpZiAoaXNFbnVtLmNhbGwoTywga2V5ID0ga2V5c1tpKytdKSkge1xuICAgICAgcmVzdWx0LnB1c2goaXNFbnRyaWVzID8gW2tleSwgT1trZXldXSA6IE9ba2V5XSk7XG4gICAgfSByZXR1cm4gcmVzdWx0O1xuICB9O1xufTtcbiIsIi8vIGFsbCBvYmplY3Qga2V5cywgaW5jbHVkZXMgbm9uLWVudW1lcmFibGUgYW5kIHN5bWJvbHNcbnZhciBnT1BOID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKTtcbnZhciBnT1BTID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIFJlZmxlY3QgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5SZWZsZWN0O1xubW9kdWxlLmV4cG9ydHMgPSBSZWZsZWN0ICYmIFJlZmxlY3Qub3duS2V5cyB8fCBmdW5jdGlvbiBvd25LZXlzKGl0KSB7XG4gIHZhciBrZXlzID0gZ09QTi5mKGFuT2JqZWN0KGl0KSk7XG4gIHZhciBnZXRTeW1ib2xzID0gZ09QUy5mO1xuICByZXR1cm4gZ2V0U3ltYm9scyA/IGtleXMuY29uY2F0KGdldFN5bWJvbHMoaXQpKSA6IGtleXM7XG59O1xuIiwidmFyICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykucGFyc2VGbG9hdDtcbnZhciAkdHJpbSA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbTtcblxubW9kdWxlLmV4cG9ydHMgPSAxIC8gJHBhcnNlRmxvYXQocmVxdWlyZSgnLi9fc3RyaW5nLXdzJykgKyAnLTAnKSAhPT0gLUluZmluaXR5ID8gZnVuY3Rpb24gcGFyc2VGbG9hdChzdHIpIHtcbiAgdmFyIHN0cmluZyA9ICR0cmltKFN0cmluZyhzdHIpLCAzKTtcbiAgdmFyIHJlc3VsdCA9ICRwYXJzZUZsb2F0KHN0cmluZyk7XG4gIHJldHVybiByZXN1bHQgPT09IDAgJiYgc3RyaW5nLmNoYXJBdCgwKSA9PSAnLScgPyAtMCA6IHJlc3VsdDtcbn0gOiAkcGFyc2VGbG9hdDtcbiIsInZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5wYXJzZUludDtcbnZhciAkdHJpbSA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbTtcbnZhciB3cyA9IHJlcXVpcmUoJy4vX3N0cmluZy13cycpO1xudmFyIGhleCA9IC9eWy0rXT8wW3hYXS87XG5cbm1vZHVsZS5leHBvcnRzID0gJHBhcnNlSW50KHdzICsgJzA4JykgIT09IDggfHwgJHBhcnNlSW50KHdzICsgJzB4MTYnKSAhPT0gMjIgPyBmdW5jdGlvbiBwYXJzZUludChzdHIsIHJhZGl4KSB7XG4gIHZhciBzdHJpbmcgPSAkdHJpbShTdHJpbmcoc3RyKSwgMyk7XG4gIHJldHVybiAkcGFyc2VJbnQoc3RyaW5nLCAocmFkaXggPj4+IDApIHx8IChoZXgudGVzdChzdHJpbmcpID8gMTYgOiAxMCkpO1xufSA6ICRwYXJzZUludDtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4geyBlOiBmYWxzZSwgdjogZXhlYygpIH07XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4geyBlOiB0cnVlLCB2OiBlIH07XG4gIH1cbn07XG4iLCJ2YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIG5ld1Byb21pc2VDYXBhYmlsaXR5ID0gcmVxdWlyZSgnLi9fbmV3LXByb21pc2UtY2FwYWJpbGl0eScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChDLCB4KSB7XG4gIGFuT2JqZWN0KEMpO1xuICBpZiAoaXNPYmplY3QoeCkgJiYgeC5jb25zdHJ1Y3RvciA9PT0gQykgcmV0dXJuIHg7XG4gIHZhciBwcm9taXNlQ2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5LmYoQyk7XG4gIHZhciByZXNvbHZlID0gcHJvbWlzZUNhcGFiaWxpdHkucmVzb2x2ZTtcbiAgcmVzb2x2ZSh4KTtcbiAgcmV0dXJuIHByb21pc2VDYXBhYmlsaXR5LnByb21pc2U7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoYml0bWFwLCB2YWx1ZSkge1xuICByZXR1cm4ge1xuICAgIGVudW1lcmFibGU6ICEoYml0bWFwICYgMSksXG4gICAgY29uZmlndXJhYmxlOiAhKGJpdG1hcCAmIDIpLFxuICAgIHdyaXRhYmxlOiAhKGJpdG1hcCAmIDQpLFxuICAgIHZhbHVlOiB2YWx1ZVxuICB9O1xufTtcbiIsInZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YXJnZXQsIHNyYywgc2FmZSkge1xuICBmb3IgKHZhciBrZXkgaW4gc3JjKSByZWRlZmluZSh0YXJnZXQsIGtleSwgc3JjW2tleV0sIHNhZmUpO1xuICByZXR1cm4gdGFyZ2V0O1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIFNSQyA9IHJlcXVpcmUoJy4vX3VpZCcpKCdzcmMnKTtcbnZhciBUT19TVFJJTkcgPSAndG9TdHJpbmcnO1xudmFyICR0b1N0cmluZyA9IEZ1bmN0aW9uW1RPX1NUUklOR107XG52YXIgVFBMID0gKCcnICsgJHRvU3RyaW5nKS5zcGxpdChUT19TVFJJTkcpO1xuXG5yZXF1aXJlKCcuL19jb3JlJykuaW5zcGVjdFNvdXJjZSA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gJHRvU3RyaW5nLmNhbGwoaXQpO1xufTtcblxuKG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE8sIGtleSwgdmFsLCBzYWZlKSB7XG4gIHZhciBpc0Z1bmN0aW9uID0gdHlwZW9mIHZhbCA9PSAnZnVuY3Rpb24nO1xuICBpZiAoaXNGdW5jdGlvbikgaGFzKHZhbCwgJ25hbWUnKSB8fCBoaWRlKHZhbCwgJ25hbWUnLCBrZXkpO1xuICBpZiAoT1trZXldID09PSB2YWwpIHJldHVybjtcbiAgaWYgKGlzRnVuY3Rpb24pIGhhcyh2YWwsIFNSQykgfHwgaGlkZSh2YWwsIFNSQywgT1trZXldID8gJycgKyBPW2tleV0gOiBUUEwuam9pbihTdHJpbmcoa2V5KSkpO1xuICBpZiAoTyA9PT0gZ2xvYmFsKSB7XG4gICAgT1trZXldID0gdmFsO1xuICB9IGVsc2UgaWYgKCFzYWZlKSB7XG4gICAgZGVsZXRlIE9ba2V5XTtcbiAgICBoaWRlKE8sIGtleSwgdmFsKTtcbiAgfSBlbHNlIGlmIChPW2tleV0pIHtcbiAgICBPW2tleV0gPSB2YWw7XG4gIH0gZWxzZSB7XG4gICAgaGlkZShPLCBrZXksIHZhbCk7XG4gIH1cbi8vIGFkZCBmYWtlIEZ1bmN0aW9uI3RvU3RyaW5nIGZvciBjb3JyZWN0IHdvcmsgd3JhcHBlZCBtZXRob2RzIC8gY29uc3RydWN0b3JzIHdpdGggbWV0aG9kcyBsaWtlIExvRGFzaCBpc05hdGl2ZVxufSkoRnVuY3Rpb24ucHJvdG90eXBlLCBUT19TVFJJTkcsIGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICByZXR1cm4gdHlwZW9mIHRoaXMgPT0gJ2Z1bmN0aW9uJyAmJiB0aGlzW1NSQ10gfHwgJHRvU3RyaW5nLmNhbGwodGhpcyk7XG59KTtcbiIsIi8vIDcuMi45IFNhbWVWYWx1ZSh4LCB5KVxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuaXMgfHwgZnVuY3Rpb24gaXMoeCwgeSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gIHJldHVybiB4ID09PSB5ID8geCAhPT0gMCB8fCAxIC8geCA9PT0gMSAvIHkgOiB4ICE9IHggJiYgeSAhPSB5O1xufTtcbiIsIi8vIFdvcmtzIHdpdGggX19wcm90b19fIG9ubHkuIE9sZCB2OCBjYW4ndCB3b3JrIHdpdGggbnVsbCBwcm90byBvYmplY3RzLlxuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgY2hlY2sgPSBmdW5jdGlvbiAoTywgcHJvdG8pIHtcbiAgYW5PYmplY3QoTyk7XG4gIGlmICghaXNPYmplY3QocHJvdG8pICYmIHByb3RvICE9PSBudWxsKSB0aHJvdyBUeXBlRXJyb3IocHJvdG8gKyBcIjogY2FuJ3Qgc2V0IGFzIHByb3RvdHlwZSFcIik7XG59O1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNldDogT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8ICgnX19wcm90b19fJyBpbiB7fSA/IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgICBmdW5jdGlvbiAodGVzdCwgYnVnZ3ksIHNldCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2V0ID0gcmVxdWlyZSgnLi9fY3R4JykoRnVuY3Rpb24uY2FsbCwgcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mKE9iamVjdC5wcm90b3R5cGUsICdfX3Byb3RvX18nKS5zZXQsIDIpO1xuICAgICAgICBzZXQodGVzdCwgW10pO1xuICAgICAgICBidWdneSA9ICEodGVzdCBpbnN0YW5jZW9mIEFycmF5KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHsgYnVnZ3kgPSB0cnVlOyB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24gc2V0UHJvdG90eXBlT2YoTywgcHJvdG8pIHtcbiAgICAgICAgY2hlY2soTywgcHJvdG8pO1xuICAgICAgICBpZiAoYnVnZ3kpIE8uX19wcm90b19fID0gcHJvdG87XG4gICAgICAgIGVsc2Ugc2V0KE8sIHByb3RvKTtcbiAgICAgICAgcmV0dXJuIE87XG4gICAgICB9O1xuICAgIH0oe30sIGZhbHNlKSA6IHVuZGVmaW5lZCksXG4gIGNoZWNrOiBjaGVja1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciBTUEVDSUVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoS0VZKSB7XG4gIHZhciBDID0gZ2xvYmFsW0tFWV07XG4gIGlmIChERVNDUklQVE9SUyAmJiBDICYmICFDW1NQRUNJRVNdKSBkUC5mKEMsIFNQRUNJRVMsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9XG4gIH0pO1xufTtcbiIsInZhciBkZWYgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIFRBRyA9IHJlcXVpcmUoJy4vX3drcycpKCd0b1N0cmluZ1RhZycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgdGFnLCBzdGF0KSB7XG4gIGlmIChpdCAmJiAhaGFzKGl0ID0gc3RhdCA/IGl0IDogaXQucHJvdG90eXBlLCBUQUcpKSBkZWYoaXQsIFRBRywgeyBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiB0YWcgfSk7XG59O1xuIiwidmFyIHNoYXJlZCA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpKCdrZXlzJyk7XG52YXIgdWlkID0gcmVxdWlyZSgnLi9fdWlkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuIHNoYXJlZFtrZXldIHx8IChzaGFyZWRba2V5XSA9IHVpZChrZXkpKTtcbn07XG4iLCJ2YXIgY29yZSA9IHJlcXVpcmUoJy4vX2NvcmUnKTtcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBTSEFSRUQgPSAnX19jb3JlLWpzX3NoYXJlZF9fJztcbnZhciBzdG9yZSA9IGdsb2JhbFtTSEFSRURdIHx8IChnbG9iYWxbU0hBUkVEXSA9IHt9KTtcblxuKG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgcmV0dXJuIHN0b3JlW2tleV0gfHwgKHN0b3JlW2tleV0gPSB2YWx1ZSAhPT0gdW5kZWZpbmVkID8gdmFsdWUgOiB7fSk7XG59KSgndmVyc2lvbnMnLCBbXSkucHVzaCh7XG4gIHZlcnNpb246IGNvcmUudmVyc2lvbixcbiAgbW9kZTogcmVxdWlyZSgnLi9fbGlicmFyeScpID8gJ3B1cmUnIDogJ2dsb2JhbCcsXG4gIGNvcHlyaWdodDogJ8KpIDIwMTggRGVuaXMgUHVzaGthcmV2ICh6bG9pcm9jay5ydSknXG59KTtcbiIsIi8vIDcuMy4yMCBTcGVjaWVzQ29uc3RydWN0b3IoTywgZGVmYXVsdENvbnN0cnVjdG9yKVxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyIFNQRUNJRVMgPSByZXF1aXJlKCcuL193a3MnKSgnc3BlY2llcycpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoTywgRCkge1xuICB2YXIgQyA9IGFuT2JqZWN0KE8pLmNvbnN0cnVjdG9yO1xuICB2YXIgUztcbiAgcmV0dXJuIEMgPT09IHVuZGVmaW5lZCB8fCAoUyA9IGFuT2JqZWN0KEMpW1NQRUNJRVNdKSA9PSB1bmRlZmluZWQgPyBEIDogYUZ1bmN0aW9uKFMpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG1ldGhvZCwgYXJnKSB7XG4gIHJldHVybiAhIW1ldGhvZCAmJiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZWxlc3MtY2FsbFxuICAgIGFyZyA/IG1ldGhvZC5jYWxsKG51bGwsIGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfSwgMSkgOiBtZXRob2QuY2FsbChudWxsKTtcbiAgfSk7XG59O1xuIiwidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuLy8gdHJ1ZSAgLT4gU3RyaW5nI2F0XG4vLyBmYWxzZSAtPiBTdHJpbmcjY29kZVBvaW50QXRcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFRPX1NUUklORykge1xuICByZXR1cm4gZnVuY3Rpb24gKHRoYXQsIHBvcykge1xuICAgIHZhciBzID0gU3RyaW5nKGRlZmluZWQodGhhdCkpO1xuICAgIHZhciBpID0gdG9JbnRlZ2VyKHBvcyk7XG4gICAgdmFyIGwgPSBzLmxlbmd0aDtcbiAgICB2YXIgYSwgYjtcbiAgICBpZiAoaSA8IDAgfHwgaSA+PSBsKSByZXR1cm4gVE9fU1RSSU5HID8gJycgOiB1bmRlZmluZWQ7XG4gICAgYSA9IHMuY2hhckNvZGVBdChpKTtcbiAgICByZXR1cm4gYSA8IDB4ZDgwMCB8fCBhID4gMHhkYmZmIHx8IGkgKyAxID09PSBsIHx8IChiID0gcy5jaGFyQ29kZUF0KGkgKyAxKSkgPCAweGRjMDAgfHwgYiA+IDB4ZGZmZlxuICAgICAgPyBUT19TVFJJTkcgPyBzLmNoYXJBdChpKSA6IGFcbiAgICAgIDogVE9fU1RSSU5HID8gcy5zbGljZShpLCBpICsgMikgOiAoYSAtIDB4ZDgwMCA8PCAxMCkgKyAoYiAtIDB4ZGMwMCkgKyAweDEwMDAwO1xuICB9O1xufTtcbiIsIi8vIGhlbHBlciBmb3IgU3RyaW5nI3tzdGFydHNXaXRoLCBlbmRzV2l0aCwgaW5jbHVkZXN9XG52YXIgaXNSZWdFeHAgPSByZXF1aXJlKCcuL19pcy1yZWdleHAnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0aGF0LCBzZWFyY2hTdHJpbmcsIE5BTUUpIHtcbiAgaWYgKGlzUmVnRXhwKHNlYXJjaFN0cmluZykpIHRocm93IFR5cGVFcnJvcignU3RyaW5nIycgKyBOQU1FICsgXCIgZG9lc24ndCBhY2NlcHQgcmVnZXghXCIpO1xuICByZXR1cm4gU3RyaW5nKGRlZmluZWQodGhhdCkpO1xufTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG52YXIgcXVvdCA9IC9cIi9nO1xuLy8gQi4yLjMuMi4xIENyZWF0ZUhUTUwoc3RyaW5nLCB0YWcsIGF0dHJpYnV0ZSwgdmFsdWUpXG52YXIgY3JlYXRlSFRNTCA9IGZ1bmN0aW9uIChzdHJpbmcsIHRhZywgYXR0cmlidXRlLCB2YWx1ZSkge1xuICB2YXIgUyA9IFN0cmluZyhkZWZpbmVkKHN0cmluZykpO1xuICB2YXIgcDEgPSAnPCcgKyB0YWc7XG4gIGlmIChhdHRyaWJ1dGUgIT09ICcnKSBwMSArPSAnICcgKyBhdHRyaWJ1dGUgKyAnPVwiJyArIFN0cmluZyh2YWx1ZSkucmVwbGFjZShxdW90LCAnJnF1b3Q7JykgKyAnXCInO1xuICByZXR1cm4gcDEgKyAnPicgKyBTICsgJzwvJyArIHRhZyArICc+Jztcbn07XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChOQU1FLCBleGVjKSB7XG4gIHZhciBPID0ge307XG4gIE9bTkFNRV0gPSBleGVjKGNyZWF0ZUhUTUwpO1xuICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdGVzdCA9ICcnW05BTUVdKCdcIicpO1xuICAgIHJldHVybiB0ZXN0ICE9PSB0ZXN0LnRvTG93ZXJDYXNlKCkgfHwgdGVzdC5zcGxpdCgnXCInKS5sZW5ndGggPiAzO1xuICB9KSwgJ1N0cmluZycsIE8pO1xufTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLXN0cmluZy1wYWQtc3RhcnQtZW5kXG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciByZXBlYXQgPSByZXF1aXJlKCcuL19zdHJpbmctcmVwZWF0Jyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhhdCwgbWF4TGVuZ3RoLCBmaWxsU3RyaW5nLCBsZWZ0KSB7XG4gIHZhciBTID0gU3RyaW5nKGRlZmluZWQodGhhdCkpO1xuICB2YXIgc3RyaW5nTGVuZ3RoID0gUy5sZW5ndGg7XG4gIHZhciBmaWxsU3RyID0gZmlsbFN0cmluZyA9PT0gdW5kZWZpbmVkID8gJyAnIDogU3RyaW5nKGZpbGxTdHJpbmcpO1xuICB2YXIgaW50TWF4TGVuZ3RoID0gdG9MZW5ndGgobWF4TGVuZ3RoKTtcbiAgaWYgKGludE1heExlbmd0aCA8PSBzdHJpbmdMZW5ndGggfHwgZmlsbFN0ciA9PSAnJykgcmV0dXJuIFM7XG4gIHZhciBmaWxsTGVuID0gaW50TWF4TGVuZ3RoIC0gc3RyaW5nTGVuZ3RoO1xuICB2YXIgc3RyaW5nRmlsbGVyID0gcmVwZWF0LmNhbGwoZmlsbFN0ciwgTWF0aC5jZWlsKGZpbGxMZW4gLyBmaWxsU3RyLmxlbmd0aCkpO1xuICBpZiAoc3RyaW5nRmlsbGVyLmxlbmd0aCA+IGZpbGxMZW4pIHN0cmluZ0ZpbGxlciA9IHN0cmluZ0ZpbGxlci5zbGljZSgwLCBmaWxsTGVuKTtcbiAgcmV0dXJuIGxlZnQgPyBzdHJpbmdGaWxsZXIgKyBTIDogUyArIHN0cmluZ0ZpbGxlcjtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcmVwZWF0KGNvdW50KSB7XG4gIHZhciBzdHIgPSBTdHJpbmcoZGVmaW5lZCh0aGlzKSk7XG4gIHZhciByZXMgPSAnJztcbiAgdmFyIG4gPSB0b0ludGVnZXIoY291bnQpO1xuICBpZiAobiA8IDAgfHwgbiA9PSBJbmZpbml0eSkgdGhyb3cgUmFuZ2VFcnJvcihcIkNvdW50IGNhbid0IGJlIG5lZ2F0aXZlXCIpO1xuICBmb3IgKDtuID4gMDsgKG4gPj4+PSAxKSAmJiAoc3RyICs9IHN0cikpIGlmIChuICYgMSkgcmVzICs9IHN0cjtcbiAgcmV0dXJuIHJlcztcbn07XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIHNwYWNlcyA9IHJlcXVpcmUoJy4vX3N0cmluZy13cycpO1xudmFyIHNwYWNlID0gJ1snICsgc3BhY2VzICsgJ10nO1xudmFyIG5vbiA9ICdcXHUyMDBiXFx1MDA4NSc7XG52YXIgbHRyaW0gPSBSZWdFeHAoJ14nICsgc3BhY2UgKyBzcGFjZSArICcqJyk7XG52YXIgcnRyaW0gPSBSZWdFeHAoc3BhY2UgKyBzcGFjZSArICcqJCcpO1xuXG52YXIgZXhwb3J0ZXIgPSBmdW5jdGlvbiAoS0VZLCBleGVjLCBBTElBUykge1xuICB2YXIgZXhwID0ge307XG4gIHZhciBGT1JDRSA9IGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gISFzcGFjZXNbS0VZXSgpIHx8IG5vbltLRVldKCkgIT0gbm9uO1xuICB9KTtcbiAgdmFyIGZuID0gZXhwW0tFWV0gPSBGT1JDRSA/IGV4ZWModHJpbSkgOiBzcGFjZXNbS0VZXTtcbiAgaWYgKEFMSUFTKSBleHBbQUxJQVNdID0gZm47XG4gICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogRk9SQ0UsICdTdHJpbmcnLCBleHApO1xufTtcblxuLy8gMSAtPiBTdHJpbmcjdHJpbUxlZnRcbi8vIDIgLT4gU3RyaW5nI3RyaW1SaWdodFxuLy8gMyAtPiBTdHJpbmcjdHJpbVxudmFyIHRyaW0gPSBleHBvcnRlci50cmltID0gZnVuY3Rpb24gKHN0cmluZywgVFlQRSkge1xuICBzdHJpbmcgPSBTdHJpbmcoZGVmaW5lZChzdHJpbmcpKTtcbiAgaWYgKFRZUEUgJiAxKSBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZShsdHJpbSwgJycpO1xuICBpZiAoVFlQRSAmIDIpIHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKHJ0cmltLCAnJyk7XG4gIHJldHVybiBzdHJpbmc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydGVyO1xuIiwibW9kdWxlLmV4cG9ydHMgPSAnXFx4MDlcXHgwQVxceDBCXFx4MENcXHgwRFxceDIwXFx4QTBcXHUxNjgwXFx1MTgwRVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDMnICtcbiAgJ1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMEFcXHUyMDJGXFx1MjA1RlxcdTMwMDBcXHUyMDI4XFx1MjAyOVxcdUZFRkYnO1xuIiwidmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGludm9rZSA9IHJlcXVpcmUoJy4vX2ludm9rZScpO1xudmFyIGh0bWwgPSByZXF1aXJlKCcuL19odG1sJyk7XG52YXIgY2VsID0gcmVxdWlyZSgnLi9fZG9tLWNyZWF0ZScpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIHByb2Nlc3MgPSBnbG9iYWwucHJvY2VzcztcbnZhciBzZXRUYXNrID0gZ2xvYmFsLnNldEltbWVkaWF0ZTtcbnZhciBjbGVhclRhc2sgPSBnbG9iYWwuY2xlYXJJbW1lZGlhdGU7XG52YXIgTWVzc2FnZUNoYW5uZWwgPSBnbG9iYWwuTWVzc2FnZUNoYW5uZWw7XG52YXIgRGlzcGF0Y2ggPSBnbG9iYWwuRGlzcGF0Y2g7XG52YXIgY291bnRlciA9IDA7XG52YXIgcXVldWUgPSB7fTtcbnZhciBPTlJFQURZU1RBVEVDSEFOR0UgPSAnb25yZWFkeXN0YXRlY2hhbmdlJztcbnZhciBkZWZlciwgY2hhbm5lbCwgcG9ydDtcbnZhciBydW4gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpZCA9ICt0aGlzO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcHJvdG90eXBlLWJ1aWx0aW5zXG4gIGlmIChxdWV1ZS5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcbiAgICB2YXIgZm4gPSBxdWV1ZVtpZF07XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgICBmbigpO1xuICB9XG59O1xudmFyIGxpc3RlbmVyID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gIHJ1bi5jYWxsKGV2ZW50LmRhdGEpO1xufTtcbi8vIE5vZGUuanMgMC45KyAmIElFMTArIGhhcyBzZXRJbW1lZGlhdGUsIG90aGVyd2lzZTpcbmlmICghc2V0VGFzayB8fCAhY2xlYXJUYXNrKSB7XG4gIHNldFRhc2sgPSBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoZm4pIHtcbiAgICB2YXIgYXJncyA9IFtdO1xuICAgIHZhciBpID0gMTtcbiAgICB3aGlsZSAoYXJndW1lbnRzLmxlbmd0aCA+IGkpIGFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XG4gICAgcXVldWVbKytjb3VudGVyXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICAgICAgaW52b2tlKHR5cGVvZiBmbiA9PSAnZnVuY3Rpb24nID8gZm4gOiBGdW5jdGlvbihmbiksIGFyZ3MpO1xuICAgIH07XG4gICAgZGVmZXIoY291bnRlcik7XG4gICAgcmV0dXJuIGNvdW50ZXI7XG4gIH07XG4gIGNsZWFyVGFzayA9IGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKGlkKSB7XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgfTtcbiAgLy8gTm9kZS5qcyAwLjgtXG4gIGlmIChyZXF1aXJlKCcuL19jb2YnKShwcm9jZXNzKSA9PSAncHJvY2VzcycpIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhjdHgocnVuLCBpZCwgMSkpO1xuICAgIH07XG4gIC8vIFNwaGVyZSAoSlMgZ2FtZSBlbmdpbmUpIERpc3BhdGNoIEFQSVxuICB9IGVsc2UgaWYgKERpc3BhdGNoICYmIERpc3BhdGNoLm5vdykge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBEaXNwYXRjaC5ub3coY3R4KHJ1biwgaWQsIDEpKTtcbiAgICB9O1xuICAvLyBCcm93c2VycyB3aXRoIE1lc3NhZ2VDaGFubmVsLCBpbmNsdWRlcyBXZWJXb3JrZXJzXG4gIH0gZWxzZSBpZiAoTWVzc2FnZUNoYW5uZWwpIHtcbiAgICBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgcG9ydCA9IGNoYW5uZWwucG9ydDI7XG4gICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBsaXN0ZW5lcjtcbiAgICBkZWZlciA9IGN0eChwb3J0LnBvc3RNZXNzYWdlLCBwb3J0LCAxKTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBwb3N0TWVzc2FnZSwgc2tpcCBXZWJXb3JrZXJzXG4gIC8vIElFOCBoYXMgcG9zdE1lc3NhZ2UsIGJ1dCBpdCdzIHN5bmMgJiB0eXBlb2YgaXRzIHBvc3RNZXNzYWdlIGlzICdvYmplY3QnXG4gIH0gZWxzZSBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIgJiYgdHlwZW9mIHBvc3RNZXNzYWdlID09ICdmdW5jdGlvbicgJiYgIWdsb2JhbC5pbXBvcnRTY3JpcHRzKSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShpZCArICcnLCAnKicpO1xuICAgIH07XG4gICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBsaXN0ZW5lciwgZmFsc2UpO1xuICAvLyBJRTgtXG4gIH0gZWxzZSBpZiAoT05SRUFEWVNUQVRFQ0hBTkdFIGluIGNlbCgnc2NyaXB0JykpIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgaHRtbC5hcHBlbmRDaGlsZChjZWwoJ3NjcmlwdCcpKVtPTlJFQURZU1RBVEVDSEFOR0VdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBodG1sLnJlbW92ZUNoaWxkKHRoaXMpO1xuICAgICAgICBydW4uY2FsbChpZCk7XG4gICAgICB9O1xuICAgIH07XG4gIC8vIFJlc3Qgb2xkIGJyb3dzZXJzXG4gIH0gZWxzZSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIHNldFRpbWVvdXQoY3R4KHJ1biwgaWQsIDEpLCAwKTtcbiAgICB9O1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2V0OiBzZXRUYXNrLFxuICBjbGVhcjogY2xlYXJUYXNrXG59O1xuIiwidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBtYXggPSBNYXRoLm1heDtcbnZhciBtaW4gPSBNYXRoLm1pbjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGluZGV4LCBsZW5ndGgpIHtcbiAgaW5kZXggPSB0b0ludGVnZXIoaW5kZXgpO1xuICByZXR1cm4gaW5kZXggPCAwID8gbWF4KGluZGV4ICsgbGVuZ3RoLCAwKSA6IG1pbihpbmRleCwgbGVuZ3RoKTtcbn07XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy10b2luZGV4XG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoaXQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIDA7XG4gIHZhciBudW1iZXIgPSB0b0ludGVnZXIoaXQpO1xuICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgobnVtYmVyKTtcbiAgaWYgKG51bWJlciAhPT0gbGVuZ3RoKSB0aHJvdyBSYW5nZUVycm9yKCdXcm9uZyBsZW5ndGghJyk7XG4gIHJldHVybiBsZW5ndGg7XG59O1xuIiwiLy8gNy4xLjQgVG9JbnRlZ2VyXG52YXIgY2VpbCA9IE1hdGguY2VpbDtcbnZhciBmbG9vciA9IE1hdGguZmxvb3I7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXNOYU4oaXQgPSAraXQpID8gMCA6IChpdCA+IDAgPyBmbG9vciA6IGNlaWwpKGl0KTtcbn07XG4iLCIvLyB0byBpbmRleGVkIG9iamVjdCwgdG9PYmplY3Qgd2l0aCBmYWxsYmFjayBmb3Igbm9uLWFycmF5LWxpa2UgRVMzIHN0cmluZ3NcbnZhciBJT2JqZWN0ID0gcmVxdWlyZSgnLi9faW9iamVjdCcpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gSU9iamVjdChkZWZpbmVkKGl0KSk7XG59O1xuIiwiLy8gNy4xLjE1IFRvTGVuZ3RoXG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIG1pbiA9IE1hdGgubWluO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGl0ID4gMCA/IG1pbih0b0ludGVnZXIoaXQpLCAweDFmZmZmZmZmZmZmZmZmKSA6IDA7IC8vIHBvdygyLCA1MykgLSAxID09IDkwMDcxOTkyNTQ3NDA5OTFcbn07XG4iLCIvLyA3LjEuMTMgVG9PYmplY3QoYXJndW1lbnQpXG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBPYmplY3QoZGVmaW5lZChpdCkpO1xufTtcbiIsIi8vIDcuMS4xIFRvUHJpbWl0aXZlKGlucHV0IFssIFByZWZlcnJlZFR5cGVdKVxudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG4vLyBpbnN0ZWFkIG9mIHRoZSBFUzYgc3BlYyB2ZXJzaW9uLCB3ZSBkaWRuJ3QgaW1wbGVtZW50IEBAdG9QcmltaXRpdmUgY2FzZVxuLy8gYW5kIHRoZSBzZWNvbmQgYXJndW1lbnQgLSBmbGFnIC0gcHJlZmVycmVkIHR5cGUgaXMgYSBzdHJpbmdcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBTKSB7XG4gIGlmICghaXNPYmplY3QoaXQpKSByZXR1cm4gaXQ7XG4gIHZhciBmbiwgdmFsO1xuICBpZiAoUyAmJiB0eXBlb2YgKGZuID0gaXQudG9TdHJpbmcpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSkgcmV0dXJuIHZhbDtcbiAgaWYgKHR5cGVvZiAoZm4gPSBpdC52YWx1ZU9mKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpIHJldHVybiB2YWw7XG4gIGlmICghUyAmJiB0eXBlb2YgKGZuID0gaXQudG9TdHJpbmcpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSkgcmV0dXJuIHZhbDtcbiAgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY29udmVydCBvYmplY3QgdG8gcHJpbWl0aXZlIHZhbHVlXCIpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbmlmIChyZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpKSB7XG4gIHZhciBMSUJSQVJZID0gcmVxdWlyZSgnLi9fbGlicmFyeScpO1xuICB2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG4gIHZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG4gIHZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4gIHZhciAkdHlwZWQgPSByZXF1aXJlKCcuL190eXBlZCcpO1xuICB2YXIgJGJ1ZmZlciA9IHJlcXVpcmUoJy4vX3R5cGVkLWJ1ZmZlcicpO1xuICB2YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG4gIHZhciBhbkluc3RhbmNlID0gcmVxdWlyZSgnLi9fYW4taW5zdGFuY2UnKTtcbiAgdmFyIHByb3BlcnR5RGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbiAgdmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG4gIHZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xuICB2YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xuICB2YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbiAgdmFyIHRvSW5kZXggPSByZXF1aXJlKCcuL190by1pbmRleCcpO1xuICB2YXIgdG9BYnNvbHV0ZUluZGV4ID0gcmVxdWlyZSgnLi9fdG8tYWJzb2x1dGUtaW5kZXgnKTtcbiAgdmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG4gIHZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbiAgdmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuL19jbGFzc29mJyk7XG4gIHZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuICB2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbiAgdmFyIGlzQXJyYXlJdGVyID0gcmVxdWlyZSgnLi9faXMtYXJyYXktaXRlcicpO1xuICB2YXIgY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xuICB2YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG4gIHZhciBnT1BOID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKS5mO1xuICB2YXIgZ2V0SXRlckZuID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcbiAgdmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xuICB2YXIgd2tzID0gcmVxdWlyZSgnLi9fd2tzJyk7XG4gIHZhciBjcmVhdGVBcnJheU1ldGhvZCA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKTtcbiAgdmFyIGNyZWF0ZUFycmF5SW5jbHVkZXMgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpO1xuICB2YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xuICB2YXIgQXJyYXlJdGVyYXRvcnMgPSByZXF1aXJlKCcuL2VzNi5hcnJheS5pdGVyYXRvcicpO1xuICB2YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG4gIHZhciAkaXRlckRldGVjdCA9IHJlcXVpcmUoJy4vX2l0ZXItZGV0ZWN0Jyk7XG4gIHZhciBzZXRTcGVjaWVzID0gcmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKTtcbiAgdmFyIGFycmF5RmlsbCA9IHJlcXVpcmUoJy4vX2FycmF5LWZpbGwnKTtcbiAgdmFyIGFycmF5Q29weVdpdGhpbiA9IHJlcXVpcmUoJy4vX2FycmF5LWNvcHktd2l0aGluJyk7XG4gIHZhciAkRFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbiAgdmFyICRHT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKTtcbiAgdmFyIGRQID0gJERQLmY7XG4gIHZhciBnT1BEID0gJEdPUEQuZjtcbiAgdmFyIFJhbmdlRXJyb3IgPSBnbG9iYWwuUmFuZ2VFcnJvcjtcbiAgdmFyIFR5cGVFcnJvciA9IGdsb2JhbC5UeXBlRXJyb3I7XG4gIHZhciBVaW50OEFycmF5ID0gZ2xvYmFsLlVpbnQ4QXJyYXk7XG4gIHZhciBBUlJBWV9CVUZGRVIgPSAnQXJyYXlCdWZmZXInO1xuICB2YXIgU0hBUkVEX0JVRkZFUiA9ICdTaGFyZWQnICsgQVJSQVlfQlVGRkVSO1xuICB2YXIgQllURVNfUEVSX0VMRU1FTlQgPSAnQllURVNfUEVSX0VMRU1FTlQnO1xuICB2YXIgUFJPVE9UWVBFID0gJ3Byb3RvdHlwZSc7XG4gIHZhciBBcnJheVByb3RvID0gQXJyYXlbUFJPVE9UWVBFXTtcbiAgdmFyICRBcnJheUJ1ZmZlciA9ICRidWZmZXIuQXJyYXlCdWZmZXI7XG4gIHZhciAkRGF0YVZpZXcgPSAkYnVmZmVyLkRhdGFWaWV3O1xuICB2YXIgYXJyYXlGb3JFYWNoID0gY3JlYXRlQXJyYXlNZXRob2QoMCk7XG4gIHZhciBhcnJheUZpbHRlciA9IGNyZWF0ZUFycmF5TWV0aG9kKDIpO1xuICB2YXIgYXJyYXlTb21lID0gY3JlYXRlQXJyYXlNZXRob2QoMyk7XG4gIHZhciBhcnJheUV2ZXJ5ID0gY3JlYXRlQXJyYXlNZXRob2QoNCk7XG4gIHZhciBhcnJheUZpbmQgPSBjcmVhdGVBcnJheU1ldGhvZCg1KTtcbiAgdmFyIGFycmF5RmluZEluZGV4ID0gY3JlYXRlQXJyYXlNZXRob2QoNik7XG4gIHZhciBhcnJheUluY2x1ZGVzID0gY3JlYXRlQXJyYXlJbmNsdWRlcyh0cnVlKTtcbiAgdmFyIGFycmF5SW5kZXhPZiA9IGNyZWF0ZUFycmF5SW5jbHVkZXMoZmFsc2UpO1xuICB2YXIgYXJyYXlWYWx1ZXMgPSBBcnJheUl0ZXJhdG9ycy52YWx1ZXM7XG4gIHZhciBhcnJheUtleXMgPSBBcnJheUl0ZXJhdG9ycy5rZXlzO1xuICB2YXIgYXJyYXlFbnRyaWVzID0gQXJyYXlJdGVyYXRvcnMuZW50cmllcztcbiAgdmFyIGFycmF5TGFzdEluZGV4T2YgPSBBcnJheVByb3RvLmxhc3RJbmRleE9mO1xuICB2YXIgYXJyYXlSZWR1Y2UgPSBBcnJheVByb3RvLnJlZHVjZTtcbiAgdmFyIGFycmF5UmVkdWNlUmlnaHQgPSBBcnJheVByb3RvLnJlZHVjZVJpZ2h0O1xuICB2YXIgYXJyYXlKb2luID0gQXJyYXlQcm90by5qb2luO1xuICB2YXIgYXJyYXlTb3J0ID0gQXJyYXlQcm90by5zb3J0O1xuICB2YXIgYXJyYXlTbGljZSA9IEFycmF5UHJvdG8uc2xpY2U7XG4gIHZhciBhcnJheVRvU3RyaW5nID0gQXJyYXlQcm90by50b1N0cmluZztcbiAgdmFyIGFycmF5VG9Mb2NhbGVTdHJpbmcgPSBBcnJheVByb3RvLnRvTG9jYWxlU3RyaW5nO1xuICB2YXIgSVRFUkFUT1IgPSB3a3MoJ2l0ZXJhdG9yJyk7XG4gIHZhciBUQUcgPSB3a3MoJ3RvU3RyaW5nVGFnJyk7XG4gIHZhciBUWVBFRF9DT05TVFJVQ1RPUiA9IHVpZCgndHlwZWRfY29uc3RydWN0b3InKTtcbiAgdmFyIERFRl9DT05TVFJVQ1RPUiA9IHVpZCgnZGVmX2NvbnN0cnVjdG9yJyk7XG4gIHZhciBBTExfQ09OU1RSVUNUT1JTID0gJHR5cGVkLkNPTlNUUjtcbiAgdmFyIFRZUEVEX0FSUkFZID0gJHR5cGVkLlRZUEVEO1xuICB2YXIgVklFVyA9ICR0eXBlZC5WSUVXO1xuICB2YXIgV1JPTkdfTEVOR1RIID0gJ1dyb25nIGxlbmd0aCEnO1xuXG4gIHZhciAkbWFwID0gY3JlYXRlQXJyYXlNZXRob2QoMSwgZnVuY3Rpb24gKE8sIGxlbmd0aCkge1xuICAgIHJldHVybiBhbGxvY2F0ZShzcGVjaWVzQ29uc3RydWN0b3IoTywgT1tERUZfQ09OU1RSVUNUT1JdKSwgbGVuZ3RoKTtcbiAgfSk7XG5cbiAgdmFyIExJVFRMRV9FTkRJQU4gPSBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KG5ldyBVaW50MTZBcnJheShbMV0pLmJ1ZmZlcilbMF0gPT09IDE7XG4gIH0pO1xuXG4gIHZhciBGT1JDRURfU0VUID0gISFVaW50OEFycmF5ICYmICEhVWludDhBcnJheVtQUk9UT1RZUEVdLnNldCAmJiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgbmV3IFVpbnQ4QXJyYXkoMSkuc2V0KHt9KTtcbiAgfSk7XG5cbiAgdmFyIHRvT2Zmc2V0ID0gZnVuY3Rpb24gKGl0LCBCWVRFUykge1xuICAgIHZhciBvZmZzZXQgPSB0b0ludGVnZXIoaXQpO1xuICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCAlIEJZVEVTKSB0aHJvdyBSYW5nZUVycm9yKCdXcm9uZyBvZmZzZXQhJyk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfTtcblxuICB2YXIgdmFsaWRhdGUgPSBmdW5jdGlvbiAoaXQpIHtcbiAgICBpZiAoaXNPYmplY3QoaXQpICYmIFRZUEVEX0FSUkFZIGluIGl0KSByZXR1cm4gaXQ7XG4gICAgdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYSB0eXBlZCBhcnJheSEnKTtcbiAgfTtcblxuICB2YXIgYWxsb2NhdGUgPSBmdW5jdGlvbiAoQywgbGVuZ3RoKSB7XG4gICAgaWYgKCEoaXNPYmplY3QoQykgJiYgVFlQRURfQ09OU1RSVUNUT1IgaW4gQykpIHtcbiAgICAgIHRocm93IFR5cGVFcnJvcignSXQgaXMgbm90IGEgdHlwZWQgYXJyYXkgY29uc3RydWN0b3IhJyk7XG4gICAgfSByZXR1cm4gbmV3IEMobGVuZ3RoKTtcbiAgfTtcblxuICB2YXIgc3BlY2llc0Zyb21MaXN0ID0gZnVuY3Rpb24gKE8sIGxpc3QpIHtcbiAgICByZXR1cm4gZnJvbUxpc3Qoc3BlY2llc0NvbnN0cnVjdG9yKE8sIE9bREVGX0NPTlNUUlVDVE9SXSksIGxpc3QpO1xuICB9O1xuXG4gIHZhciBmcm9tTGlzdCA9IGZ1bmN0aW9uIChDLCBsaXN0KSB7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgbGVuZ3RoID0gbGlzdC5sZW5ndGg7XG4gICAgdmFyIHJlc3VsdCA9IGFsbG9jYXRlKEMsIGxlbmd0aCk7XG4gICAgd2hpbGUgKGxlbmd0aCA+IGluZGV4KSByZXN1bHRbaW5kZXhdID0gbGlzdFtpbmRleCsrXTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIHZhciBhZGRHZXR0ZXIgPSBmdW5jdGlvbiAoaXQsIGtleSwgaW50ZXJuYWwpIHtcbiAgICBkUChpdCwga2V5LCB7IGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5fZFtpbnRlcm5hbF07IH0gfSk7XG4gIH07XG5cbiAgdmFyICRmcm9tID0gZnVuY3Rpb24gZnJvbShzb3VyY2UgLyogLCBtYXBmbiwgdGhpc0FyZyAqLykge1xuICAgIHZhciBPID0gdG9PYmplY3Qoc291cmNlKTtcbiAgICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIG1hcGZuID0gYUxlbiA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQ7XG4gICAgdmFyIG1hcHBpbmcgPSBtYXBmbiAhPT0gdW5kZWZpbmVkO1xuICAgIHZhciBpdGVyRm4gPSBnZXRJdGVyRm4oTyk7XG4gICAgdmFyIGksIGxlbmd0aCwgdmFsdWVzLCByZXN1bHQsIHN0ZXAsIGl0ZXJhdG9yO1xuICAgIGlmIChpdGVyRm4gIT0gdW5kZWZpbmVkICYmICFpc0FycmF5SXRlcihpdGVyRm4pKSB7XG4gICAgICBmb3IgKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoTyksIHZhbHVlcyA9IFtdLCBpID0gMDsgIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lOyBpKyspIHtcbiAgICAgICAgdmFsdWVzLnB1c2goc3RlcC52YWx1ZSk7XG4gICAgICB9IE8gPSB2YWx1ZXM7XG4gICAgfVxuICAgIGlmIChtYXBwaW5nICYmIGFMZW4gPiAyKSBtYXBmbiA9IGN0eChtYXBmbiwgYXJndW1lbnRzWzJdLCAyKTtcbiAgICBmb3IgKGkgPSAwLCBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aCksIHJlc3VsdCA9IGFsbG9jYXRlKHRoaXMsIGxlbmd0aCk7IGxlbmd0aCA+IGk7IGkrKykge1xuICAgICAgcmVzdWx0W2ldID0gbWFwcGluZyA/IG1hcGZuKE9baV0sIGkpIDogT1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICB2YXIgJG9mID0gZnVuY3Rpb24gb2YoLyogLi4uaXRlbXMgKi8pIHtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciByZXN1bHQgPSBhbGxvY2F0ZSh0aGlzLCBsZW5ndGgpO1xuICAgIHdoaWxlIChsZW5ndGggPiBpbmRleCkgcmVzdWx0W2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleCsrXTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIGlPUyBTYWZhcmkgNi54IGZhaWxzIGhlcmVcbiAgdmFyIFRPX0xPQ0FMRV9CVUcgPSAhIVVpbnQ4QXJyYXkgJiYgZmFpbHMoZnVuY3Rpb24gKCkgeyBhcnJheVRvTG9jYWxlU3RyaW5nLmNhbGwobmV3IFVpbnQ4QXJyYXkoMSkpOyB9KTtcblxuICB2YXIgJHRvTG9jYWxlU3RyaW5nID0gZnVuY3Rpb24gdG9Mb2NhbGVTdHJpbmcoKSB7XG4gICAgcmV0dXJuIGFycmF5VG9Mb2NhbGVTdHJpbmcuYXBwbHkoVE9fTE9DQUxFX0JVRyA/IGFycmF5U2xpY2UuY2FsbCh2YWxpZGF0ZSh0aGlzKSkgOiB2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgfTtcblxuICB2YXIgcHJvdG8gPSB7XG4gICAgY29weVdpdGhpbjogZnVuY3Rpb24gY29weVdpdGhpbih0YXJnZXQsIHN0YXJ0IC8qICwgZW5kICovKSB7XG4gICAgICByZXR1cm4gYXJyYXlDb3B5V2l0aGluLmNhbGwodmFsaWRhdGUodGhpcyksIHRhcmdldCwgc3RhcnQsIGFyZ3VtZW50cy5sZW5ndGggPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGV2ZXJ5OiBmdW5jdGlvbiBldmVyeShjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgcmV0dXJuIGFycmF5RXZlcnkodmFsaWRhdGUodGhpcyksIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGZpbGw6IGZ1bmN0aW9uIGZpbGwodmFsdWUgLyogLCBzdGFydCwgZW5kICovKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheUZpbGwuYXBwbHkodmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcihjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgcmV0dXJuIHNwZWNpZXNGcm9tTGlzdCh0aGlzLCBhcnJheUZpbHRlcih2YWxpZGF0ZSh0aGlzKSwgY2FsbGJhY2tmbixcbiAgICAgICAgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpKTtcbiAgICB9LFxuICAgIGZpbmQ6IGZ1bmN0aW9uIGZpbmQocHJlZGljYXRlIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgcmV0dXJuIGFycmF5RmluZCh2YWxpZGF0ZSh0aGlzKSwgcHJlZGljYXRlLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBmaW5kSW5kZXg6IGZ1bmN0aW9uIGZpbmRJbmRleChwcmVkaWNhdGUgLyogLCB0aGlzQXJnICovKSB7XG4gICAgICByZXR1cm4gYXJyYXlGaW5kSW5kZXgodmFsaWRhdGUodGhpcyksIHByZWRpY2F0ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICAgIH0sXG4gICAgZm9yRWFjaDogZnVuY3Rpb24gZm9yRWFjaChjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgYXJyYXlGb3JFYWNoKHZhbGlkYXRlKHRoaXMpLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBpbmRleE9mOiBmdW5jdGlvbiBpbmRleE9mKHNlYXJjaEVsZW1lbnQgLyogLCBmcm9tSW5kZXggKi8pIHtcbiAgICAgIHJldHVybiBhcnJheUluZGV4T2YodmFsaWRhdGUodGhpcyksIHNlYXJjaEVsZW1lbnQsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGluY2x1ZGVzOiBmdW5jdGlvbiBpbmNsdWRlcyhzZWFyY2hFbGVtZW50IC8qICwgZnJvbUluZGV4ICovKSB7XG4gICAgICByZXR1cm4gYXJyYXlJbmNsdWRlcyh2YWxpZGF0ZSh0aGlzKSwgc2VhcmNoRWxlbWVudCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICAgIH0sXG4gICAgam9pbjogZnVuY3Rpb24gam9pbihzZXBhcmF0b3IpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgcmV0dXJuIGFycmF5Sm9pbi5hcHBseSh2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIGxhc3RJbmRleE9mOiBmdW5jdGlvbiBsYXN0SW5kZXhPZihzZWFyY2hFbGVtZW50IC8qICwgZnJvbUluZGV4ICovKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheUxhc3RJbmRleE9mLmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgbWFwOiBmdW5jdGlvbiBtYXAobWFwZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgICByZXR1cm4gJG1hcCh2YWxpZGF0ZSh0aGlzKSwgbWFwZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIHJlZHVjZTogZnVuY3Rpb24gcmVkdWNlKGNhbGxiYWNrZm4gLyogLCBpbml0aWFsVmFsdWUgKi8pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgcmV0dXJuIGFycmF5UmVkdWNlLmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgcmVkdWNlUmlnaHQ6IGZ1bmN0aW9uIHJlZHVjZVJpZ2h0KGNhbGxiYWNrZm4gLyogLCBpbml0aWFsVmFsdWUgKi8pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgcmV0dXJuIGFycmF5UmVkdWNlUmlnaHQuYXBwbHkodmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICByZXZlcnNlOiBmdW5jdGlvbiByZXZlcnNlKCkge1xuICAgICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgICAgdmFyIGxlbmd0aCA9IHZhbGlkYXRlKHRoYXQpLmxlbmd0aDtcbiAgICAgIHZhciBtaWRkbGUgPSBNYXRoLmZsb29yKGxlbmd0aCAvIDIpO1xuICAgICAgdmFyIGluZGV4ID0gMDtcbiAgICAgIHZhciB2YWx1ZTtcbiAgICAgIHdoaWxlIChpbmRleCA8IG1pZGRsZSkge1xuICAgICAgICB2YWx1ZSA9IHRoYXRbaW5kZXhdO1xuICAgICAgICB0aGF0W2luZGV4KytdID0gdGhhdFstLWxlbmd0aF07XG4gICAgICAgIHRoYXRbbGVuZ3RoXSA9IHZhbHVlO1xuICAgICAgfSByZXR1cm4gdGhhdDtcbiAgICB9LFxuICAgIHNvbWU6IGZ1bmN0aW9uIHNvbWUoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIHJldHVybiBhcnJheVNvbWUodmFsaWRhdGUodGhpcyksIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIHNvcnQ6IGZ1bmN0aW9uIHNvcnQoY29tcGFyZWZuKSB7XG4gICAgICByZXR1cm4gYXJyYXlTb3J0LmNhbGwodmFsaWRhdGUodGhpcyksIGNvbXBhcmVmbik7XG4gICAgfSxcbiAgICBzdWJhcnJheTogZnVuY3Rpb24gc3ViYXJyYXkoYmVnaW4sIGVuZCkge1xuICAgICAgdmFyIE8gPSB2YWxpZGF0ZSh0aGlzKTtcbiAgICAgIHZhciBsZW5ndGggPSBPLmxlbmd0aDtcbiAgICAgIHZhciAkYmVnaW4gPSB0b0Fic29sdXRlSW5kZXgoYmVnaW4sIGxlbmd0aCk7XG4gICAgICByZXR1cm4gbmV3IChzcGVjaWVzQ29uc3RydWN0b3IoTywgT1tERUZfQ09OU1RSVUNUT1JdKSkoXG4gICAgICAgIE8uYnVmZmVyLFxuICAgICAgICBPLmJ5dGVPZmZzZXQgKyAkYmVnaW4gKiBPLkJZVEVTX1BFUl9FTEVNRU5ULFxuICAgICAgICB0b0xlbmd0aCgoZW5kID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW5ndGgpKSAtICRiZWdpbilcbiAgICAgICk7XG4gICAgfVxuICB9O1xuXG4gIHZhciAkc2xpY2UgPSBmdW5jdGlvbiBzbGljZShzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIHNwZWNpZXNGcm9tTGlzdCh0aGlzLCBhcnJheVNsaWNlLmNhbGwodmFsaWRhdGUodGhpcyksIHN0YXJ0LCBlbmQpKTtcbiAgfTtcblxuICB2YXIgJHNldCA9IGZ1bmN0aW9uIHNldChhcnJheUxpa2UgLyogLCBvZmZzZXQgKi8pIHtcbiAgICB2YWxpZGF0ZSh0aGlzKTtcbiAgICB2YXIgb2Zmc2V0ID0gdG9PZmZzZXQoYXJndW1lbnRzWzFdLCAxKTtcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgdmFyIHNyYyA9IHRvT2JqZWN0KGFycmF5TGlrZSk7XG4gICAgdmFyIGxlbiA9IHRvTGVuZ3RoKHNyYy5sZW5ndGgpO1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgaWYgKGxlbiArIG9mZnNldCA+IGxlbmd0aCkgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xuICAgIHdoaWxlIChpbmRleCA8IGxlbikgdGhpc1tvZmZzZXQgKyBpbmRleF0gPSBzcmNbaW5kZXgrK107XG4gIH07XG5cbiAgdmFyICRpdGVyYXRvcnMgPSB7XG4gICAgZW50cmllczogZnVuY3Rpb24gZW50cmllcygpIHtcbiAgICAgIHJldHVybiBhcnJheUVudHJpZXMuY2FsbCh2YWxpZGF0ZSh0aGlzKSk7XG4gICAgfSxcbiAgICBrZXlzOiBmdW5jdGlvbiBrZXlzKCkge1xuICAgICAgcmV0dXJuIGFycmF5S2V5cy5jYWxsKHZhbGlkYXRlKHRoaXMpKTtcbiAgICB9LFxuICAgIHZhbHVlczogZnVuY3Rpb24gdmFsdWVzKCkge1xuICAgICAgcmV0dXJuIGFycmF5VmFsdWVzLmNhbGwodmFsaWRhdGUodGhpcykpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgaXNUQUluZGV4ID0gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7XG4gICAgcmV0dXJuIGlzT2JqZWN0KHRhcmdldClcbiAgICAgICYmIHRhcmdldFtUWVBFRF9BUlJBWV1cbiAgICAgICYmIHR5cGVvZiBrZXkgIT0gJ3N5bWJvbCdcbiAgICAgICYmIGtleSBpbiB0YXJnZXRcbiAgICAgICYmIFN0cmluZygra2V5KSA9PSBTdHJpbmcoa2V5KTtcbiAgfTtcbiAgdmFyICRnZXREZXNjID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSB7XG4gICAgcmV0dXJuIGlzVEFJbmRleCh0YXJnZXQsIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSkpXG4gICAgICA/IHByb3BlcnR5RGVzYygyLCB0YXJnZXRba2V5XSlcbiAgICAgIDogZ09QRCh0YXJnZXQsIGtleSk7XG4gIH07XG4gIHZhciAkc2V0RGVzYyA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBkZXNjKSB7XG4gICAgaWYgKGlzVEFJbmRleCh0YXJnZXQsIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSkpXG4gICAgICAmJiBpc09iamVjdChkZXNjKVxuICAgICAgJiYgaGFzKGRlc2MsICd2YWx1ZScpXG4gICAgICAmJiAhaGFzKGRlc2MsICdnZXQnKVxuICAgICAgJiYgIWhhcyhkZXNjLCAnc2V0JylcbiAgICAgIC8vIFRPRE86IGFkZCB2YWxpZGF0aW9uIGRlc2NyaXB0b3Igdy9vIGNhbGxpbmcgYWNjZXNzb3JzXG4gICAgICAmJiAhZGVzYy5jb25maWd1cmFibGVcbiAgICAgICYmICghaGFzKGRlc2MsICd3cml0YWJsZScpIHx8IGRlc2Mud3JpdGFibGUpXG4gICAgICAmJiAoIWhhcyhkZXNjLCAnZW51bWVyYWJsZScpIHx8IGRlc2MuZW51bWVyYWJsZSlcbiAgICApIHtcbiAgICAgIHRhcmdldFtrZXldID0gZGVzYy52YWx1ZTtcbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfSByZXR1cm4gZFAodGFyZ2V0LCBrZXksIGRlc2MpO1xuICB9O1xuXG4gIGlmICghQUxMX0NPTlNUUlVDVE9SUykge1xuICAgICRHT1BELmYgPSAkZ2V0RGVzYztcbiAgICAkRFAuZiA9ICRzZXREZXNjO1xuICB9XG5cbiAgJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhQUxMX0NPTlNUUlVDVE9SUywgJ09iamVjdCcsIHtcbiAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I6ICRnZXREZXNjLFxuICAgIGRlZmluZVByb3BlcnR5OiAkc2V0RGVzY1xuICB9KTtcblxuICBpZiAoZmFpbHMoZnVuY3Rpb24gKCkgeyBhcnJheVRvU3RyaW5nLmNhbGwoe30pOyB9KSkge1xuICAgIGFycmF5VG9TdHJpbmcgPSBhcnJheVRvTG9jYWxlU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICByZXR1cm4gYXJyYXlKb2luLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgfVxuXG4gIHZhciAkVHlwZWRBcnJheVByb3RvdHlwZSQgPSByZWRlZmluZUFsbCh7fSwgcHJvdG8pO1xuICByZWRlZmluZUFsbCgkVHlwZWRBcnJheVByb3RvdHlwZSQsICRpdGVyYXRvcnMpO1xuICBoaWRlKCRUeXBlZEFycmF5UHJvdG90eXBlJCwgSVRFUkFUT1IsICRpdGVyYXRvcnMudmFsdWVzKTtcbiAgcmVkZWZpbmVBbGwoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCB7XG4gICAgc2xpY2U6ICRzbGljZSxcbiAgICBzZXQ6ICRzZXQsXG4gICAgY29uc3RydWN0b3I6IGZ1bmN0aW9uICgpIHsgLyogbm9vcCAqLyB9LFxuICAgIHRvU3RyaW5nOiBhcnJheVRvU3RyaW5nLFxuICAgIHRvTG9jYWxlU3RyaW5nOiAkdG9Mb2NhbGVTdHJpbmdcbiAgfSk7XG4gIGFkZEdldHRlcigkVHlwZWRBcnJheVByb3RvdHlwZSQsICdidWZmZXInLCAnYicpO1xuICBhZGRHZXR0ZXIoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAnYnl0ZU9mZnNldCcsICdvJyk7XG4gIGFkZEdldHRlcigkVHlwZWRBcnJheVByb3RvdHlwZSQsICdieXRlTGVuZ3RoJywgJ2wnKTtcbiAgYWRkR2V0dGVyKCRUeXBlZEFycmF5UHJvdG90eXBlJCwgJ2xlbmd0aCcsICdlJyk7XG4gIGRQKCRUeXBlZEFycmF5UHJvdG90eXBlJCwgVEFHLCB7XG4gICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzW1RZUEVEX0FSUkFZXTsgfVxuICB9KTtcblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LXN0YXRlbWVudHNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoS0VZLCBCWVRFUywgd3JhcHBlciwgQ0xBTVBFRCkge1xuICAgIENMQU1QRUQgPSAhIUNMQU1QRUQ7XG4gICAgdmFyIE5BTUUgPSBLRVkgKyAoQ0xBTVBFRCA/ICdDbGFtcGVkJyA6ICcnKSArICdBcnJheSc7XG4gICAgdmFyIEdFVFRFUiA9ICdnZXQnICsgS0VZO1xuICAgIHZhciBTRVRURVIgPSAnc2V0JyArIEtFWTtcbiAgICB2YXIgVHlwZWRBcnJheSA9IGdsb2JhbFtOQU1FXTtcbiAgICB2YXIgQmFzZSA9IFR5cGVkQXJyYXkgfHwge307XG4gICAgdmFyIFRBQyA9IFR5cGVkQXJyYXkgJiYgZ2V0UHJvdG90eXBlT2YoVHlwZWRBcnJheSk7XG4gICAgdmFyIEZPUkNFRCA9ICFUeXBlZEFycmF5IHx8ICEkdHlwZWQuQUJWO1xuICAgIHZhciBPID0ge307XG4gICAgdmFyIFR5cGVkQXJyYXlQcm90b3R5cGUgPSBUeXBlZEFycmF5ICYmIFR5cGVkQXJyYXlbUFJPVE9UWVBFXTtcbiAgICB2YXIgZ2V0dGVyID0gZnVuY3Rpb24gKHRoYXQsIGluZGV4KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoYXQuX2Q7XG4gICAgICByZXR1cm4gZGF0YS52W0dFVFRFUl0oaW5kZXggKiBCWVRFUyArIGRhdGEubywgTElUVExFX0VORElBTik7XG4gICAgfTtcbiAgICB2YXIgc2V0dGVyID0gZnVuY3Rpb24gKHRoYXQsIGluZGV4LCB2YWx1ZSkge1xuICAgICAgdmFyIGRhdGEgPSB0aGF0Ll9kO1xuICAgICAgaWYgKENMQU1QRUQpIHZhbHVlID0gKHZhbHVlID0gTWF0aC5yb3VuZCh2YWx1ZSkpIDwgMCA/IDAgOiB2YWx1ZSA+IDB4ZmYgPyAweGZmIDogdmFsdWUgJiAweGZmO1xuICAgICAgZGF0YS52W1NFVFRFUl0oaW5kZXggKiBCWVRFUyArIGRhdGEubywgdmFsdWUsIExJVFRMRV9FTkRJQU4pO1xuICAgIH07XG4gICAgdmFyIGFkZEVsZW1lbnQgPSBmdW5jdGlvbiAodGhhdCwgaW5kZXgpIHtcbiAgICAgIGRQKHRoYXQsIGluZGV4LCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBnZXR0ZXIodGhpcywgaW5kZXgpO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiBzZXR0ZXIodGhpcywgaW5kZXgsIHZhbHVlKTtcbiAgICAgICAgfSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfTtcbiAgICBpZiAoRk9SQ0VEKSB7XG4gICAgICBUeXBlZEFycmF5ID0gd3JhcHBlcihmdW5jdGlvbiAodGhhdCwgZGF0YSwgJG9mZnNldCwgJGxlbmd0aCkge1xuICAgICAgICBhbkluc3RhbmNlKHRoYXQsIFR5cGVkQXJyYXksIE5BTUUsICdfZCcpO1xuICAgICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICAgICAgdmFyIGJ1ZmZlciwgYnl0ZUxlbmd0aCwgbGVuZ3RoLCBrbGFzcztcbiAgICAgICAgaWYgKCFpc09iamVjdChkYXRhKSkge1xuICAgICAgICAgIGxlbmd0aCA9IHRvSW5kZXgoZGF0YSk7XG4gICAgICAgICAgYnl0ZUxlbmd0aCA9IGxlbmd0aCAqIEJZVEVTO1xuICAgICAgICAgIGJ1ZmZlciA9IG5ldyAkQXJyYXlCdWZmZXIoYnl0ZUxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YSBpbnN0YW5jZW9mICRBcnJheUJ1ZmZlciB8fCAoa2xhc3MgPSBjbGFzc29mKGRhdGEpKSA9PSBBUlJBWV9CVUZGRVIgfHwga2xhc3MgPT0gU0hBUkVEX0JVRkZFUikge1xuICAgICAgICAgIGJ1ZmZlciA9IGRhdGE7XG4gICAgICAgICAgb2Zmc2V0ID0gdG9PZmZzZXQoJG9mZnNldCwgQllURVMpO1xuICAgICAgICAgIHZhciAkbGVuID0gZGF0YS5ieXRlTGVuZ3RoO1xuICAgICAgICAgIGlmICgkbGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmICgkbGVuICUgQllURVMpIHRocm93IFJhbmdlRXJyb3IoV1JPTkdfTEVOR1RIKTtcbiAgICAgICAgICAgIGJ5dGVMZW5ndGggPSAkbGVuIC0gb2Zmc2V0O1xuICAgICAgICAgICAgaWYgKGJ5dGVMZW5ndGggPCAwKSB0aHJvdyBSYW5nZUVycm9yKFdST05HX0xFTkdUSCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJ5dGVMZW5ndGggPSB0b0xlbmd0aCgkbGVuZ3RoKSAqIEJZVEVTO1xuICAgICAgICAgICAgaWYgKGJ5dGVMZW5ndGggKyBvZmZzZXQgPiAkbGVuKSB0aHJvdyBSYW5nZUVycm9yKFdST05HX0xFTkdUSCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxlbmd0aCA9IGJ5dGVMZW5ndGggLyBCWVRFUztcbiAgICAgICAgfSBlbHNlIGlmIChUWVBFRF9BUlJBWSBpbiBkYXRhKSB7XG4gICAgICAgICAgcmV0dXJuIGZyb21MaXN0KFR5cGVkQXJyYXksIGRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiAkZnJvbS5jYWxsKFR5cGVkQXJyYXksIGRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGhpZGUodGhhdCwgJ19kJywge1xuICAgICAgICAgIGI6IGJ1ZmZlcixcbiAgICAgICAgICBvOiBvZmZzZXQsXG4gICAgICAgICAgbDogYnl0ZUxlbmd0aCxcbiAgICAgICAgICBlOiBsZW5ndGgsXG4gICAgICAgICAgdjogbmV3ICREYXRhVmlldyhidWZmZXIpXG4gICAgICAgIH0pO1xuICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIGFkZEVsZW1lbnQodGhhdCwgaW5kZXgrKyk7XG4gICAgICB9KTtcbiAgICAgIFR5cGVkQXJyYXlQcm90b3R5cGUgPSBUeXBlZEFycmF5W1BST1RPVFlQRV0gPSBjcmVhdGUoJFR5cGVkQXJyYXlQcm90b3R5cGUkKTtcbiAgICAgIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgJ2NvbnN0cnVjdG9yJywgVHlwZWRBcnJheSk7XG4gICAgfSBlbHNlIGlmICghZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgVHlwZWRBcnJheSgxKTtcbiAgICB9KSB8fCAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgbmV3IFR5cGVkQXJyYXkoLTEpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIH0pIHx8ICEkaXRlckRldGVjdChmdW5jdGlvbiAoaXRlcikge1xuICAgICAgbmV3IFR5cGVkQXJyYXkoKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICAgIG5ldyBUeXBlZEFycmF5KG51bGwpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgICAgbmV3IFR5cGVkQXJyYXkoMS41KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICAgIG5ldyBUeXBlZEFycmF5KGl0ZXIpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIH0sIHRydWUpKSB7XG4gICAgICBUeXBlZEFycmF5ID0gd3JhcHBlcihmdW5jdGlvbiAodGhhdCwgZGF0YSwgJG9mZnNldCwgJGxlbmd0aCkge1xuICAgICAgICBhbkluc3RhbmNlKHRoYXQsIFR5cGVkQXJyYXksIE5BTUUpO1xuICAgICAgICB2YXIga2xhc3M7XG4gICAgICAgIC8vIGB3c2AgbW9kdWxlIGJ1ZywgdGVtcG9yYXJpbHkgcmVtb3ZlIHZhbGlkYXRpb24gbGVuZ3RoIGZvciBVaW50OEFycmF5XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS93ZWJzb2NrZXRzL3dzL3B1bGwvNjQ1XG4gICAgICAgIGlmICghaXNPYmplY3QoZGF0YSkpIHJldHVybiBuZXcgQmFzZSh0b0luZGV4KGRhdGEpKTtcbiAgICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiAkQXJyYXlCdWZmZXIgfHwgKGtsYXNzID0gY2xhc3NvZihkYXRhKSkgPT0gQVJSQVlfQlVGRkVSIHx8IGtsYXNzID09IFNIQVJFRF9CVUZGRVIpIHtcbiAgICAgICAgICByZXR1cm4gJGxlbmd0aCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IG5ldyBCYXNlKGRhdGEsIHRvT2Zmc2V0KCRvZmZzZXQsIEJZVEVTKSwgJGxlbmd0aClcbiAgICAgICAgICAgIDogJG9mZnNldCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gbmV3IEJhc2UoZGF0YSwgdG9PZmZzZXQoJG9mZnNldCwgQllURVMpKVxuICAgICAgICAgICAgICA6IG5ldyBCYXNlKGRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChUWVBFRF9BUlJBWSBpbiBkYXRhKSByZXR1cm4gZnJvbUxpc3QoVHlwZWRBcnJheSwgZGF0YSk7XG4gICAgICAgIHJldHVybiAkZnJvbS5jYWxsKFR5cGVkQXJyYXksIGRhdGEpO1xuICAgICAgfSk7XG4gICAgICBhcnJheUZvckVhY2goVEFDICE9PSBGdW5jdGlvbi5wcm90b3R5cGUgPyBnT1BOKEJhc2UpLmNvbmNhdChnT1BOKFRBQykpIDogZ09QTihCYXNlKSwgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoIShrZXkgaW4gVHlwZWRBcnJheSkpIGhpZGUoVHlwZWRBcnJheSwga2V5LCBCYXNlW2tleV0pO1xuICAgICAgfSk7XG4gICAgICBUeXBlZEFycmF5W1BST1RPVFlQRV0gPSBUeXBlZEFycmF5UHJvdG90eXBlO1xuICAgICAgaWYgKCFMSUJSQVJZKSBUeXBlZEFycmF5UHJvdG90eXBlLmNvbnN0cnVjdG9yID0gVHlwZWRBcnJheTtcbiAgICB9XG4gICAgdmFyICRuYXRpdmVJdGVyYXRvciA9IFR5cGVkQXJyYXlQcm90b3R5cGVbSVRFUkFUT1JdO1xuICAgIHZhciBDT1JSRUNUX0lURVJfTkFNRSA9ICEhJG5hdGl2ZUl0ZXJhdG9yXG4gICAgICAmJiAoJG5hdGl2ZUl0ZXJhdG9yLm5hbWUgPT0gJ3ZhbHVlcycgfHwgJG5hdGl2ZUl0ZXJhdG9yLm5hbWUgPT0gdW5kZWZpbmVkKTtcbiAgICB2YXIgJGl0ZXJhdG9yID0gJGl0ZXJhdG9ycy52YWx1ZXM7XG4gICAgaGlkZShUeXBlZEFycmF5LCBUWVBFRF9DT05TVFJVQ1RPUiwgdHJ1ZSk7XG4gICAgaGlkZShUeXBlZEFycmF5UHJvdG90eXBlLCBUWVBFRF9BUlJBWSwgTkFNRSk7XG4gICAgaGlkZShUeXBlZEFycmF5UHJvdG90eXBlLCBWSUVXLCB0cnVlKTtcbiAgICBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsIERFRl9DT05TVFJVQ1RPUiwgVHlwZWRBcnJheSk7XG5cbiAgICBpZiAoQ0xBTVBFRCA/IG5ldyBUeXBlZEFycmF5KDEpW1RBR10gIT0gTkFNRSA6ICEoVEFHIGluIFR5cGVkQXJyYXlQcm90b3R5cGUpKSB7XG4gICAgICBkUChUeXBlZEFycmF5UHJvdG90eXBlLCBUQUcsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBOQU1FOyB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBPW05BTUVdID0gVHlwZWRBcnJheTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogKFR5cGVkQXJyYXkgIT0gQmFzZSksIE8pO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlMsIE5BTUUsIHtcbiAgICAgIEJZVEVTX1BFUl9FTEVNRU5UOiBCWVRFU1xuICAgIH0pO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbiAoKSB7IEJhc2Uub2YuY2FsbChUeXBlZEFycmF5LCAxKTsgfSksIE5BTUUsIHtcbiAgICAgIGZyb206ICRmcm9tLFxuICAgICAgb2Y6ICRvZlxuICAgIH0pO1xuXG4gICAgaWYgKCEoQllURVNfUEVSX0VMRU1FTlQgaW4gVHlwZWRBcnJheVByb3RvdHlwZSkpIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgQllURVNfUEVSX0VMRU1FTlQsIEJZVEVTKTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5QLCBOQU1FLCBwcm90byk7XG5cbiAgICBzZXRTcGVjaWVzKE5BTUUpO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBGT1JDRURfU0VULCBOQU1FLCB7IHNldDogJHNldCB9KTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIUNPUlJFQ1RfSVRFUl9OQU1FLCBOQU1FLCAkaXRlcmF0b3JzKTtcblxuICAgIGlmICghTElCUkFSWSAmJiBUeXBlZEFycmF5UHJvdG90eXBlLnRvU3RyaW5nICE9IGFycmF5VG9TdHJpbmcpIFR5cGVkQXJyYXlQcm90b3R5cGUudG9TdHJpbmcgPSBhcnJheVRvU3RyaW5nO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgICBuZXcgVHlwZWRBcnJheSgxKS5zbGljZSgpO1xuICAgIH0pLCBOQU1FLCB7IHNsaWNlOiAkc2xpY2UgfSk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gWzEsIDJdLnRvTG9jYWxlU3RyaW5nKCkgIT0gbmV3IFR5cGVkQXJyYXkoWzEsIDJdKS50b0xvY2FsZVN0cmluZygpO1xuICAgIH0pIHx8ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgICBUeXBlZEFycmF5UHJvdG90eXBlLnRvTG9jYWxlU3RyaW5nLmNhbGwoWzEsIDJdKTtcbiAgICB9KSksIE5BTUUsIHsgdG9Mb2NhbGVTdHJpbmc6ICR0b0xvY2FsZVN0cmluZyB9KTtcblxuICAgIEl0ZXJhdG9yc1tOQU1FXSA9IENPUlJFQ1RfSVRFUl9OQU1FID8gJG5hdGl2ZUl0ZXJhdG9yIDogJGl0ZXJhdG9yO1xuICAgIGlmICghTElCUkFSWSAmJiAhQ09SUkVDVF9JVEVSX05BTUUpIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgSVRFUkFUT1IsICRpdGVyYXRvcik7XG4gIH07XG59IGVsc2UgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgREVTQ1JJUFRPUlMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgJHR5cGVkID0gcmVxdWlyZSgnLi9fdHlwZWQnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIHJlZGVmaW5lQWxsID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIHRvSW5kZXggPSByZXF1aXJlKCcuL190by1pbmRleCcpO1xudmFyIGdPUE4gPSByZXF1aXJlKCcuL19vYmplY3QtZ29wbicpLmY7XG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGFycmF5RmlsbCA9IHJlcXVpcmUoJy4vX2FycmF5LWZpbGwnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgQVJSQVlfQlVGRkVSID0gJ0FycmF5QnVmZmVyJztcbnZhciBEQVRBX1ZJRVcgPSAnRGF0YVZpZXcnO1xudmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xudmFyIFdST05HX0xFTkdUSCA9ICdXcm9uZyBsZW5ndGghJztcbnZhciBXUk9OR19JTkRFWCA9ICdXcm9uZyBpbmRleCEnO1xudmFyICRBcnJheUJ1ZmZlciA9IGdsb2JhbFtBUlJBWV9CVUZGRVJdO1xudmFyICREYXRhVmlldyA9IGdsb2JhbFtEQVRBX1ZJRVddO1xudmFyIE1hdGggPSBnbG9iYWwuTWF0aDtcbnZhciBSYW5nZUVycm9yID0gZ2xvYmFsLlJhbmdlRXJyb3I7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2hhZG93LXJlc3RyaWN0ZWQtbmFtZXNcbnZhciBJbmZpbml0eSA9IGdsb2JhbC5JbmZpbml0eTtcbnZhciBCYXNlQnVmZmVyID0gJEFycmF5QnVmZmVyO1xudmFyIGFicyA9IE1hdGguYWJzO1xudmFyIHBvdyA9IE1hdGgucG93O1xudmFyIGZsb29yID0gTWF0aC5mbG9vcjtcbnZhciBsb2cgPSBNYXRoLmxvZztcbnZhciBMTjIgPSBNYXRoLkxOMjtcbnZhciBCVUZGRVIgPSAnYnVmZmVyJztcbnZhciBCWVRFX0xFTkdUSCA9ICdieXRlTGVuZ3RoJztcbnZhciBCWVRFX09GRlNFVCA9ICdieXRlT2Zmc2V0JztcbnZhciAkQlVGRkVSID0gREVTQ1JJUFRPUlMgPyAnX2InIDogQlVGRkVSO1xudmFyICRMRU5HVEggPSBERVNDUklQVE9SUyA/ICdfbCcgOiBCWVRFX0xFTkdUSDtcbnZhciAkT0ZGU0VUID0gREVTQ1JJUFRPUlMgPyAnX28nIDogQllURV9PRkZTRVQ7XG5cbi8vIElFRUU3NTQgY29udmVyc2lvbnMgYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9pZWVlNzU0XG5mdW5jdGlvbiBwYWNrSUVFRTc1NCh2YWx1ZSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBidWZmZXIgPSBuZXcgQXJyYXkobkJ5dGVzKTtcbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDE7XG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxO1xuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDE7XG4gIHZhciBydCA9IG1MZW4gPT09IDIzID8gcG93KDIsIC0yNCkgLSBwb3coMiwgLTc3KSA6IDA7XG4gIHZhciBpID0gMDtcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgdmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCA/IDEgOiAwO1xuICB2YXIgZSwgbSwgYztcbiAgdmFsdWUgPSBhYnModmFsdWUpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gIGlmICh2YWx1ZSAhPSB2YWx1ZSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgbSA9IHZhbHVlICE9IHZhbHVlID8gMSA6IDA7XG4gICAgZSA9IGVNYXg7XG4gIH0gZWxzZSB7XG4gICAgZSA9IGZsb29yKGxvZyh2YWx1ZSkgLyBMTjIpO1xuICAgIGlmICh2YWx1ZSAqIChjID0gcG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS07XG4gICAgICBjICo9IDI7XG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIHBvdygyLCAxIC0gZUJpYXMpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrKztcbiAgICAgIGMgLz0gMjtcbiAgICB9XG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMDtcbiAgICAgIGUgPSBlTWF4O1xuICAgIH0gZWxzZSBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIG0gPSAodmFsdWUgKiBjIC0gMSkgKiBwb3coMiwgbUxlbik7XG4gICAgICBlID0gZSArIGVCaWFzO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBwb3coMiwgZUJpYXMgLSAxKSAqIHBvdygyLCBtTGVuKTtcbiAgICAgIGUgPSAwO1xuICAgIH1cbiAgfVxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbaSsrXSA9IG0gJiAyNTUsIG0gLz0gMjU2LCBtTGVuIC09IDgpO1xuICBlID0gZSA8PCBtTGVuIHwgbTtcbiAgZUxlbiArPSBtTGVuO1xuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltpKytdID0gZSAmIDI1NSwgZSAvPSAyNTYsIGVMZW4gLT0gOCk7XG4gIGJ1ZmZlclstLWldIHw9IHMgKiAxMjg7XG4gIHJldHVybiBidWZmZXI7XG59XG5mdW5jdGlvbiB1bnBhY2tJRUVFNzU0KGJ1ZmZlciwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxO1xuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMTtcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxO1xuICB2YXIgbkJpdHMgPSBlTGVuIC0gNztcbiAgdmFyIGkgPSBuQnl0ZXMgLSAxO1xuICB2YXIgcyA9IGJ1ZmZlcltpLS1dO1xuICB2YXIgZSA9IHMgJiAxMjc7XG4gIHZhciBtO1xuICBzID4+PSA3O1xuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gZSAqIDI1NiArIGJ1ZmZlcltpXSwgaS0tLCBuQml0cyAtPSA4KTtcbiAgbSA9IGUgJiAoMSA8PCAtbkJpdHMpIC0gMTtcbiAgZSA+Pj0gLW5CaXRzO1xuICBuQml0cyArPSBtTGVuO1xuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltpXSwgaS0tLCBuQml0cyAtPSA4KTtcbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzO1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6IHMgPyAtSW5maW5pdHkgOiBJbmZpbml0eTtcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIHBvdygyLCBtTGVuKTtcbiAgICBlID0gZSAtIGVCaWFzO1xuICB9IHJldHVybiAocyA/IC0xIDogMSkgKiBtICogcG93KDIsIGUgLSBtTGVuKTtcbn1cblxuZnVuY3Rpb24gdW5wYWNrSTMyKGJ5dGVzKSB7XG4gIHJldHVybiBieXRlc1szXSA8PCAyNCB8IGJ5dGVzWzJdIDw8IDE2IHwgYnl0ZXNbMV0gPDwgOCB8IGJ5dGVzWzBdO1xufVxuZnVuY3Rpb24gcGFja0k4KGl0KSB7XG4gIHJldHVybiBbaXQgJiAweGZmXTtcbn1cbmZ1bmN0aW9uIHBhY2tJMTYoaXQpIHtcbiAgcmV0dXJuIFtpdCAmIDB4ZmYsIGl0ID4+IDggJiAweGZmXTtcbn1cbmZ1bmN0aW9uIHBhY2tJMzIoaXQpIHtcbiAgcmV0dXJuIFtpdCAmIDB4ZmYsIGl0ID4+IDggJiAweGZmLCBpdCA+PiAxNiAmIDB4ZmYsIGl0ID4+IDI0ICYgMHhmZl07XG59XG5mdW5jdGlvbiBwYWNrRjY0KGl0KSB7XG4gIHJldHVybiBwYWNrSUVFRTc1NChpdCwgNTIsIDgpO1xufVxuZnVuY3Rpb24gcGFja0YzMihpdCkge1xuICByZXR1cm4gcGFja0lFRUU3NTQoaXQsIDIzLCA0KTtcbn1cblxuZnVuY3Rpb24gYWRkR2V0dGVyKEMsIGtleSwgaW50ZXJuYWwpIHtcbiAgZFAoQ1tQUk9UT1RZUEVdLCBrZXksIHsgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzW2ludGVybmFsXTsgfSB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0KHZpZXcsIGJ5dGVzLCBpbmRleCwgaXNMaXR0bGVFbmRpYW4pIHtcbiAgdmFyIG51bUluZGV4ID0gK2luZGV4O1xuICB2YXIgaW50SW5kZXggPSB0b0luZGV4KG51bUluZGV4KTtcbiAgaWYgKGludEluZGV4ICsgYnl0ZXMgPiB2aWV3WyRMRU5HVEhdKSB0aHJvdyBSYW5nZUVycm9yKFdST05HX0lOREVYKTtcbiAgdmFyIHN0b3JlID0gdmlld1skQlVGRkVSXS5fYjtcbiAgdmFyIHN0YXJ0ID0gaW50SW5kZXggKyB2aWV3WyRPRkZTRVRdO1xuICB2YXIgcGFjayA9IHN0b3JlLnNsaWNlKHN0YXJ0LCBzdGFydCArIGJ5dGVzKTtcbiAgcmV0dXJuIGlzTGl0dGxlRW5kaWFuID8gcGFjayA6IHBhY2sucmV2ZXJzZSgpO1xufVxuZnVuY3Rpb24gc2V0KHZpZXcsIGJ5dGVzLCBpbmRleCwgY29udmVyc2lvbiwgdmFsdWUsIGlzTGl0dGxlRW5kaWFuKSB7XG4gIHZhciBudW1JbmRleCA9ICtpbmRleDtcbiAgdmFyIGludEluZGV4ID0gdG9JbmRleChudW1JbmRleCk7XG4gIGlmIChpbnRJbmRleCArIGJ5dGVzID4gdmlld1skTEVOR1RIXSkgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19JTkRFWCk7XG4gIHZhciBzdG9yZSA9IHZpZXdbJEJVRkZFUl0uX2I7XG4gIHZhciBzdGFydCA9IGludEluZGV4ICsgdmlld1skT0ZGU0VUXTtcbiAgdmFyIHBhY2sgPSBjb252ZXJzaW9uKCt2YWx1ZSk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXM7IGkrKykgc3RvcmVbc3RhcnQgKyBpXSA9IHBhY2tbaXNMaXR0bGVFbmRpYW4gPyBpIDogYnl0ZXMgLSBpIC0gMV07XG59XG5cbmlmICghJHR5cGVkLkFCVikge1xuICAkQXJyYXlCdWZmZXIgPSBmdW5jdGlvbiBBcnJheUJ1ZmZlcihsZW5ndGgpIHtcbiAgICBhbkluc3RhbmNlKHRoaXMsICRBcnJheUJ1ZmZlciwgQVJSQVlfQlVGRkVSKTtcbiAgICB2YXIgYnl0ZUxlbmd0aCA9IHRvSW5kZXgobGVuZ3RoKTtcbiAgICB0aGlzLl9iID0gYXJyYXlGaWxsLmNhbGwobmV3IEFycmF5KGJ5dGVMZW5ndGgpLCAwKTtcbiAgICB0aGlzWyRMRU5HVEhdID0gYnl0ZUxlbmd0aDtcbiAgfTtcblxuICAkRGF0YVZpZXcgPSBmdW5jdGlvbiBEYXRhVmlldyhidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpIHtcbiAgICBhbkluc3RhbmNlKHRoaXMsICREYXRhVmlldywgREFUQV9WSUVXKTtcbiAgICBhbkluc3RhbmNlKGJ1ZmZlciwgJEFycmF5QnVmZmVyLCBEQVRBX1ZJRVcpO1xuICAgIHZhciBidWZmZXJMZW5ndGggPSBidWZmZXJbJExFTkdUSF07XG4gICAgdmFyIG9mZnNldCA9IHRvSW50ZWdlcihieXRlT2Zmc2V0KTtcbiAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBidWZmZXJMZW5ndGgpIHRocm93IFJhbmdlRXJyb3IoJ1dyb25nIG9mZnNldCEnKTtcbiAgICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA9PT0gdW5kZWZpbmVkID8gYnVmZmVyTGVuZ3RoIC0gb2Zmc2V0IDogdG9MZW5ndGgoYnl0ZUxlbmd0aCk7XG4gICAgaWYgKG9mZnNldCArIGJ5dGVMZW5ndGggPiBidWZmZXJMZW5ndGgpIHRocm93IFJhbmdlRXJyb3IoV1JPTkdfTEVOR1RIKTtcbiAgICB0aGlzWyRCVUZGRVJdID0gYnVmZmVyO1xuICAgIHRoaXNbJE9GRlNFVF0gPSBvZmZzZXQ7XG4gICAgdGhpc1skTEVOR1RIXSA9IGJ5dGVMZW5ndGg7XG4gIH07XG5cbiAgaWYgKERFU0NSSVBUT1JTKSB7XG4gICAgYWRkR2V0dGVyKCRBcnJheUJ1ZmZlciwgQllURV9MRU5HVEgsICdfbCcpO1xuICAgIGFkZEdldHRlcigkRGF0YVZpZXcsIEJVRkZFUiwgJ19iJyk7XG4gICAgYWRkR2V0dGVyKCREYXRhVmlldywgQllURV9MRU5HVEgsICdfbCcpO1xuICAgIGFkZEdldHRlcigkRGF0YVZpZXcsIEJZVEVfT0ZGU0VULCAnX28nKTtcbiAgfVxuXG4gIHJlZGVmaW5lQWxsKCREYXRhVmlld1tQUk9UT1RZUEVdLCB7XG4gICAgZ2V0SW50ODogZnVuY3Rpb24gZ2V0SW50OChieXRlT2Zmc2V0KSB7XG4gICAgICByZXR1cm4gZ2V0KHRoaXMsIDEsIGJ5dGVPZmZzZXQpWzBdIDw8IDI0ID4+IDI0O1xuICAgIH0sXG4gICAgZ2V0VWludDg6IGZ1bmN0aW9uIGdldFVpbnQ4KGJ5dGVPZmZzZXQpIHtcbiAgICAgIHJldHVybiBnZXQodGhpcywgMSwgYnl0ZU9mZnNldClbMF07XG4gICAgfSxcbiAgICBnZXRJbnQxNjogZnVuY3Rpb24gZ2V0SW50MTYoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgdmFyIGJ5dGVzID0gZ2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSk7XG4gICAgICByZXR1cm4gKGJ5dGVzWzFdIDw8IDggfCBieXRlc1swXSkgPDwgMTYgPj4gMTY7XG4gICAgfSxcbiAgICBnZXRVaW50MTY6IGZ1bmN0aW9uIGdldFVpbnQxNihieXRlT2Zmc2V0IC8qICwgbGl0dGxlRW5kaWFuICovKSB7XG4gICAgICB2YXIgYnl0ZXMgPSBnZXQodGhpcywgMiwgYnl0ZU9mZnNldCwgYXJndW1lbnRzWzFdKTtcbiAgICAgIHJldHVybiBieXRlc1sxXSA8PCA4IHwgYnl0ZXNbMF07XG4gICAgfSxcbiAgICBnZXRJbnQzMjogZnVuY3Rpb24gZ2V0SW50MzIoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgcmV0dXJuIHVucGFja0kzMihnZXQodGhpcywgNCwgYnl0ZU9mZnNldCwgYXJndW1lbnRzWzFdKSk7XG4gICAgfSxcbiAgICBnZXRVaW50MzI6IGZ1bmN0aW9uIGdldFVpbnQzMihieXRlT2Zmc2V0IC8qICwgbGl0dGxlRW5kaWFuICovKSB7XG4gICAgICByZXR1cm4gdW5wYWNrSTMyKGdldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pKSA+Pj4gMDtcbiAgICB9LFxuICAgIGdldEZsb2F0MzI6IGZ1bmN0aW9uIGdldEZsb2F0MzIoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgcmV0dXJuIHVucGFja0lFRUU3NTQoZ2V0KHRoaXMsIDQsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSksIDIzLCA0KTtcbiAgICB9LFxuICAgIGdldEZsb2F0NjQ6IGZ1bmN0aW9uIGdldEZsb2F0NjQoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgcmV0dXJuIHVucGFja0lFRUU3NTQoZ2V0KHRoaXMsIDgsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSksIDUyLCA4KTtcbiAgICB9LFxuICAgIHNldEludDg6IGZ1bmN0aW9uIHNldEludDgoYnl0ZU9mZnNldCwgdmFsdWUpIHtcbiAgICAgIHNldCh0aGlzLCAxLCBieXRlT2Zmc2V0LCBwYWNrSTgsIHZhbHVlKTtcbiAgICB9LFxuICAgIHNldFVpbnQ4OiBmdW5jdGlvbiBzZXRVaW50OChieXRlT2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgc2V0KHRoaXMsIDEsIGJ5dGVPZmZzZXQsIHBhY2tJOCwgdmFsdWUpO1xuICAgIH0sXG4gICAgc2V0SW50MTY6IGZ1bmN0aW9uIHNldEludDE2KGJ5dGVPZmZzZXQsIHZhbHVlIC8qICwgbGl0dGxlRW5kaWFuICovKSB7XG4gICAgICBzZXQodGhpcywgMiwgYnl0ZU9mZnNldCwgcGFja0kxNiwgdmFsdWUsIGFyZ3VtZW50c1syXSk7XG4gICAgfSxcbiAgICBzZXRVaW50MTY6IGZ1bmN0aW9uIHNldFVpbnQxNihieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIHBhY2tJMTYsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0SW50MzI6IGZ1bmN0aW9uIHNldEludDMyKGJ5dGVPZmZzZXQsIHZhbHVlIC8qICwgbGl0dGxlRW5kaWFuICovKSB7XG4gICAgICBzZXQodGhpcywgNCwgYnl0ZU9mZnNldCwgcGFja0kzMiwgdmFsdWUsIGFyZ3VtZW50c1syXSk7XG4gICAgfSxcbiAgICBzZXRVaW50MzI6IGZ1bmN0aW9uIHNldFVpbnQzMihieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDQsIGJ5dGVPZmZzZXQsIHBhY2tJMzIsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0RmxvYXQzMjogZnVuY3Rpb24gc2V0RmxvYXQzMihieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDQsIGJ5dGVPZmZzZXQsIHBhY2tGMzIsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0RmxvYXQ2NDogZnVuY3Rpb24gc2V0RmxvYXQ2NChieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDgsIGJ5dGVPZmZzZXQsIHBhY2tGNjQsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH1cbiAgfSk7XG59IGVsc2Uge1xuICBpZiAoIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICAkQXJyYXlCdWZmZXIoMSk7XG4gIH0pIHx8ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgbmV3ICRBcnJheUJ1ZmZlcigtMSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gIH0pIHx8IGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICBuZXcgJEFycmF5QnVmZmVyKCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgbmV3ICRBcnJheUJ1ZmZlcigxLjUpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIG5ldyAkQXJyYXlCdWZmZXIoTmFOKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICByZXR1cm4gJEFycmF5QnVmZmVyLm5hbWUgIT0gQVJSQVlfQlVGRkVSO1xuICB9KSkge1xuICAgICRBcnJheUJ1ZmZlciA9IGZ1bmN0aW9uIEFycmF5QnVmZmVyKGxlbmd0aCkge1xuICAgICAgYW5JbnN0YW5jZSh0aGlzLCAkQXJyYXlCdWZmZXIpO1xuICAgICAgcmV0dXJuIG5ldyBCYXNlQnVmZmVyKHRvSW5kZXgobGVuZ3RoKSk7XG4gICAgfTtcbiAgICB2YXIgQXJyYXlCdWZmZXJQcm90byA9ICRBcnJheUJ1ZmZlcltQUk9UT1RZUEVdID0gQmFzZUJ1ZmZlcltQUk9UT1RZUEVdO1xuICAgIGZvciAodmFyIGtleXMgPSBnT1BOKEJhc2VCdWZmZXIpLCBqID0gMCwga2V5OyBrZXlzLmxlbmd0aCA+IGo7KSB7XG4gICAgICBpZiAoISgoa2V5ID0ga2V5c1tqKytdKSBpbiAkQXJyYXlCdWZmZXIpKSBoaWRlKCRBcnJheUJ1ZmZlciwga2V5LCBCYXNlQnVmZmVyW2tleV0pO1xuICAgIH1cbiAgICBpZiAoIUxJQlJBUlkpIEFycmF5QnVmZmVyUHJvdG8uY29uc3RydWN0b3IgPSAkQXJyYXlCdWZmZXI7XG4gIH1cbiAgLy8gaU9TIFNhZmFyaSA3LnggYnVnXG4gIHZhciB2aWV3ID0gbmV3ICREYXRhVmlldyhuZXcgJEFycmF5QnVmZmVyKDIpKTtcbiAgdmFyICRzZXRJbnQ4ID0gJERhdGFWaWV3W1BST1RPVFlQRV0uc2V0SW50ODtcbiAgdmlldy5zZXRJbnQ4KDAsIDIxNDc0ODM2NDgpO1xuICB2aWV3LnNldEludDgoMSwgMjE0NzQ4MzY0OSk7XG4gIGlmICh2aWV3LmdldEludDgoMCkgfHwgIXZpZXcuZ2V0SW50OCgxKSkgcmVkZWZpbmVBbGwoJERhdGFWaWV3W1BST1RPVFlQRV0sIHtcbiAgICBzZXRJbnQ4OiBmdW5jdGlvbiBzZXRJbnQ4KGJ5dGVPZmZzZXQsIHZhbHVlKSB7XG4gICAgICAkc2V0SW50OC5jYWxsKHRoaXMsIGJ5dGVPZmZzZXQsIHZhbHVlIDw8IDI0ID4+IDI0KTtcbiAgICB9LFxuICAgIHNldFVpbnQ4OiBmdW5jdGlvbiBzZXRVaW50OChieXRlT2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgJHNldEludDguY2FsbCh0aGlzLCBieXRlT2Zmc2V0LCB2YWx1ZSA8PCAyNCA+PiAyNCk7XG4gICAgfVxuICB9LCB0cnVlKTtcbn1cbnNldFRvU3RyaW5nVGFnKCRBcnJheUJ1ZmZlciwgQVJSQVlfQlVGRkVSKTtcbnNldFRvU3RyaW5nVGFnKCREYXRhVmlldywgREFUQV9WSUVXKTtcbmhpZGUoJERhdGFWaWV3W1BST1RPVFlQRV0sICR0eXBlZC5WSUVXLCB0cnVlKTtcbmV4cG9ydHNbQVJSQVlfQlVGRkVSXSA9ICRBcnJheUJ1ZmZlcjtcbmV4cG9ydHNbREFUQV9WSUVXXSA9ICREYXRhVmlldztcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xudmFyIFRZUEVEID0gdWlkKCd0eXBlZF9hcnJheScpO1xudmFyIFZJRVcgPSB1aWQoJ3ZpZXcnKTtcbnZhciBBQlYgPSAhIShnbG9iYWwuQXJyYXlCdWZmZXIgJiYgZ2xvYmFsLkRhdGFWaWV3KTtcbnZhciBDT05TVFIgPSBBQlY7XG52YXIgaSA9IDA7XG52YXIgbCA9IDk7XG52YXIgVHlwZWQ7XG5cbnZhciBUeXBlZEFycmF5Q29uc3RydWN0b3JzID0gKFxuICAnSW50OEFycmF5LFVpbnQ4QXJyYXksVWludDhDbGFtcGVkQXJyYXksSW50MTZBcnJheSxVaW50MTZBcnJheSxJbnQzMkFycmF5LFVpbnQzMkFycmF5LEZsb2F0MzJBcnJheSxGbG9hdDY0QXJyYXknXG4pLnNwbGl0KCcsJyk7XG5cbndoaWxlIChpIDwgbCkge1xuICBpZiAoVHlwZWQgPSBnbG9iYWxbVHlwZWRBcnJheUNvbnN0cnVjdG9yc1tpKytdXSkge1xuICAgIGhpZGUoVHlwZWQucHJvdG90eXBlLCBUWVBFRCwgdHJ1ZSk7XG4gICAgaGlkZShUeXBlZC5wcm90b3R5cGUsIFZJRVcsIHRydWUpO1xuICB9IGVsc2UgQ09OU1RSID0gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBBQlY6IEFCVixcbiAgQ09OU1RSOiBDT05TVFIsXG4gIFRZUEVEOiBUWVBFRCxcbiAgVklFVzogVklFV1xufTtcbiIsInZhciBpZCA9IDA7XG52YXIgcHggPSBNYXRoLnJhbmRvbSgpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIHJldHVybiAnU3ltYm9sKCcuY29uY2F0KGtleSA9PT0gdW5kZWZpbmVkID8gJycgOiBrZXksICcpXycsICgrK2lkICsgcHgpLnRvU3RyaW5nKDM2KSk7XG59O1xuIiwidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIG5hdmlnYXRvciA9IGdsb2JhbC5uYXZpZ2F0b3I7XG5cbm1vZHVsZS5leHBvcnRzID0gbmF2aWdhdG9yICYmIG5hdmlnYXRvci51c2VyQWdlbnQgfHwgJyc7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBUWVBFKSB7XG4gIGlmICghaXNPYmplY3QoaXQpIHx8IGl0Ll90ICE9PSBUWVBFKSB0aHJvdyBUeXBlRXJyb3IoJ0luY29tcGF0aWJsZSByZWNlaXZlciwgJyArIFRZUEUgKyAnIHJlcXVpcmVkIScpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgTElCUkFSWSA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKTtcbnZhciB3a3NFeHQgPSByZXF1aXJlKCcuL193a3MtZXh0Jyk7XG52YXIgZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobmFtZSkge1xuICB2YXIgJFN5bWJvbCA9IGNvcmUuU3ltYm9sIHx8IChjb3JlLlN5bWJvbCA9IExJQlJBUlkgPyB7fSA6IGdsb2JhbC5TeW1ib2wgfHwge30pO1xuICBpZiAobmFtZS5jaGFyQXQoMCkgIT0gJ18nICYmICEobmFtZSBpbiAkU3ltYm9sKSkgZGVmaW5lUHJvcGVydHkoJFN5bWJvbCwgbmFtZSwgeyB2YWx1ZTogd2tzRXh0LmYobmFtZSkgfSk7XG59O1xuIiwiZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fd2tzJyk7XG4iLCJ2YXIgc3RvcmUgPSByZXF1aXJlKCcuL19zaGFyZWQnKSgnd2tzJyk7XG52YXIgdWlkID0gcmVxdWlyZSgnLi9fdWlkJyk7XG52YXIgU3ltYm9sID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuU3ltYm9sO1xudmFyIFVTRV9TWU1CT0wgPSB0eXBlb2YgU3ltYm9sID09ICdmdW5jdGlvbic7XG5cbnZhciAkZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIHN0b3JlW25hbWVdIHx8IChzdG9yZVtuYW1lXSA9XG4gICAgVVNFX1NZTUJPTCAmJiBTeW1ib2xbbmFtZV0gfHwgKFVTRV9TWU1CT0wgPyBTeW1ib2wgOiB1aWQpKCdTeW1ib2wuJyArIG5hbWUpKTtcbn07XG5cbiRleHBvcnRzLnN0b3JlID0gc3RvcmU7XG4iLCJ2YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKTtcbnZhciBJVEVSQVRPUiA9IHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpO1xudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19jb3JlJykuZ2V0SXRlcmF0b3JNZXRob2QgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ICE9IHVuZGVmaW5lZCkgcmV0dXJuIGl0W0lURVJBVE9SXVxuICAgIHx8IGl0WydAQGl0ZXJhdG9yJ11cbiAgICB8fCBJdGVyYXRvcnNbY2xhc3NvZihpdCldO1xufTtcbiIsIi8vIDIyLjEuMy4zIEFycmF5LnByb3RvdHlwZS5jb3B5V2l0aGluKHRhcmdldCwgc3RhcnQsIGVuZCA9IHRoaXMubGVuZ3RoKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAsICdBcnJheScsIHsgY29weVdpdGhpbjogcmVxdWlyZSgnLi9fYXJyYXktY29weS13aXRoaW4nKSB9KTtcblxucmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJykoJ2NvcHlXaXRoaW4nKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGV2ZXJ5ID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDQpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10uZXZlcnksIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy41IC8gMTUuNC40LjE2IEFycmF5LnByb3RvdHlwZS5ldmVyeShjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBldmVyeTogZnVuY3Rpb24gZXZlcnkoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJGV2ZXJ5KHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiLy8gMjIuMS4zLjYgQXJyYXkucHJvdG90eXBlLmZpbGwodmFsdWUsIHN0YXJ0ID0gMCwgZW5kID0gdGhpcy5sZW5ndGgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0FycmF5JywgeyBmaWxsOiByZXF1aXJlKCcuL19hcnJheS1maWxsJykgfSk7XG5cbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKCdmaWxsJyk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRmaWx0ZXIgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoMik7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5maWx0ZXIsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy43IC8gMTUuNC40LjIwIEFycmF5LnByb3RvdHlwZS5maWx0ZXIoY2FsbGJhY2tmbiBbLCB0aGlzQXJnXSlcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJGZpbHRlcih0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy45IEFycmF5LnByb3RvdHlwZS5maW5kSW5kZXgocHJlZGljYXRlLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkZmluZCA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSg2KTtcbnZhciBLRVkgPSAnZmluZEluZGV4JztcbnZhciBmb3JjZWQgPSB0cnVlO1xuLy8gU2hvdWxkbid0IHNraXAgaG9sZXNcbmlmIChLRVkgaW4gW10pIEFycmF5KDEpW0tFWV0oZnVuY3Rpb24gKCkgeyBmb3JjZWQgPSBmYWxzZTsgfSk7XG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIGZvcmNlZCwgJ0FycmF5Jywge1xuICBmaW5kSW5kZXg6IGZ1bmN0aW9uIGZpbmRJbmRleChjYWxsYmFja2ZuIC8qICwgdGhhdCA9IHVuZGVmaW5lZCAqLykge1xuICAgIHJldHVybiAkZmluZCh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xucmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJykoS0VZKTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy44IEFycmF5LnByb3RvdHlwZS5maW5kKHByZWRpY2F0ZSwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGZpbmQgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoNSk7XG52YXIgS0VZID0gJ2ZpbmQnO1xudmFyIGZvcmNlZCA9IHRydWU7XG4vLyBTaG91bGRuJ3Qgc2tpcCBob2xlc1xuaWYgKEtFWSBpbiBbXSkgQXJyYXkoMSlbS0VZXShmdW5jdGlvbiAoKSB7IGZvcmNlZCA9IGZhbHNlOyB9KTtcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogZm9yY2VkLCAnQXJyYXknLCB7XG4gIGZpbmQ6IGZ1bmN0aW9uIGZpbmQoY2FsbGJhY2tmbiAvKiAsIHRoYXQgPSB1bmRlZmluZWQgKi8pIHtcbiAgICByZXR1cm4gJGZpbmQodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICB9XG59KTtcbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKEtFWSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRmb3JFYWNoID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDApO1xudmFyIFNUUklDVCA9IHJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5mb3JFYWNoLCB0cnVlKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhU1RSSUNULCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xMCAvIDE1LjQuNC4xOCBBcnJheS5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgcmV0dXJuICRmb3JFYWNoKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIGNhbGwgPSByZXF1aXJlKCcuL19pdGVyLWNhbGwnKTtcbnZhciBpc0FycmF5SXRlciA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIGNyZWF0ZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fY3JlYXRlLXByb3BlcnR5Jyk7XG52YXIgZ2V0SXRlckZuID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKShmdW5jdGlvbiAoaXRlcikgeyBBcnJheS5mcm9tKGl0ZXIpOyB9KSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjIuMSBBcnJheS5mcm9tKGFycmF5TGlrZSwgbWFwZm4gPSB1bmRlZmluZWQsIHRoaXNBcmcgPSB1bmRlZmluZWQpXG4gIGZyb206IGZ1bmN0aW9uIGZyb20oYXJyYXlMaWtlIC8qICwgbWFwZm4gPSB1bmRlZmluZWQsIHRoaXNBcmcgPSB1bmRlZmluZWQgKi8pIHtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KGFycmF5TGlrZSk7XG4gICAgdmFyIEMgPSB0eXBlb2YgdGhpcyA9PSAnZnVuY3Rpb24nID8gdGhpcyA6IEFycmF5O1xuICAgIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgbWFwZm4gPSBhTGVuID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZDtcbiAgICB2YXIgbWFwcGluZyA9IG1hcGZuICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgaXRlckZuID0gZ2V0SXRlckZuKE8pO1xuICAgIHZhciBsZW5ndGgsIHJlc3VsdCwgc3RlcCwgaXRlcmF0b3I7XG4gICAgaWYgKG1hcHBpbmcpIG1hcGZuID0gY3R4KG1hcGZuLCBhTGVuID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZCwgMik7XG4gICAgLy8gaWYgb2JqZWN0IGlzbid0IGl0ZXJhYmxlIG9yIGl0J3MgYXJyYXkgd2l0aCBkZWZhdWx0IGl0ZXJhdG9yIC0gdXNlIHNpbXBsZSBjYXNlXG4gICAgaWYgKGl0ZXJGbiAhPSB1bmRlZmluZWQgJiYgIShDID09IEFycmF5ICYmIGlzQXJyYXlJdGVyKGl0ZXJGbikpKSB7XG4gICAgICBmb3IgKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoTyksIHJlc3VsdCA9IG5ldyBDKCk7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTsgaW5kZXgrKykge1xuICAgICAgICBjcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGluZGV4LCBtYXBwaW5nID8gY2FsbChpdGVyYXRvciwgbWFwZm4sIFtzdGVwLnZhbHVlLCBpbmRleF0sIHRydWUpIDogc3RlcC52YWx1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgICAgIGZvciAocmVzdWx0ID0gbmV3IEMobGVuZ3RoKTsgbGVuZ3RoID4gaW5kZXg7IGluZGV4KyspIHtcbiAgICAgICAgY3JlYXRlUHJvcGVydHkocmVzdWx0LCBpbmRleCwgbWFwcGluZyA/IG1hcGZuKE9baW5kZXhdLCBpbmRleCkgOiBPW2luZGV4XSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJlc3VsdC5sZW5ndGggPSBpbmRleDtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGluZGV4T2YgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpKGZhbHNlKTtcbnZhciAkbmF0aXZlID0gW10uaW5kZXhPZjtcbnZhciBORUdBVElWRV9aRVJPID0gISEkbmF0aXZlICYmIDEgLyBbMV0uaW5kZXhPZigxLCAtMCkgPCAwO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChORUdBVElWRV9aRVJPIHx8ICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoJG5hdGl2ZSkpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xMSAvIDE1LjQuNC4xNCBBcnJheS5wcm90b3R5cGUuaW5kZXhPZihzZWFyY2hFbGVtZW50IFssIGZyb21JbmRleF0pXG4gIGluZGV4T2Y6IGZ1bmN0aW9uIGluZGV4T2Yoc2VhcmNoRWxlbWVudCAvKiAsIGZyb21JbmRleCA9IDAgKi8pIHtcbiAgICByZXR1cm4gTkVHQVRJVkVfWkVST1xuICAgICAgLy8gY29udmVydCAtMCB0byArMFxuICAgICAgPyAkbmF0aXZlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgMFxuICAgICAgOiAkaW5kZXhPZih0aGlzLCBzZWFyY2hFbGVtZW50LCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIi8vIDIyLjEuMi4yIC8gMTUuNC4zLjIgQXJyYXkuaXNBcnJheShhcmcpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0FycmF5JywgeyBpc0FycmF5OiByZXF1aXJlKCcuL19pcy1hcnJheScpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFkZFRvVW5zY29wYWJsZXMgPSByZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKTtcbnZhciBzdGVwID0gcmVxdWlyZSgnLi9faXRlci1zdGVwJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xuXG4vLyAyMi4xLjMuNCBBcnJheS5wcm90b3R5cGUuZW50cmllcygpXG4vLyAyMi4xLjMuMTMgQXJyYXkucHJvdG90eXBlLmtleXMoKVxuLy8gMjIuMS4zLjI5IEFycmF5LnByb3RvdHlwZS52YWx1ZXMoKVxuLy8gMjIuMS4zLjMwIEFycmF5LnByb3RvdHlwZVtAQGl0ZXJhdG9yXSgpXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoQXJyYXksICdBcnJheScsIGZ1bmN0aW9uIChpdGVyYXRlZCwga2luZCkge1xuICB0aGlzLl90ID0gdG9JT2JqZWN0KGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4gIHRoaXMuX2sgPSBraW5kOyAgICAgICAgICAgICAgICAvLyBraW5kXG4vLyAyMi4xLjUuMi4xICVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uICgpIHtcbiAgdmFyIE8gPSB0aGlzLl90O1xuICB2YXIga2luZCA9IHRoaXMuX2s7XG4gIHZhciBpbmRleCA9IHRoaXMuX2krKztcbiAgaWYgKCFPIHx8IGluZGV4ID49IE8ubGVuZ3RoKSB7XG4gICAgdGhpcy5fdCA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gc3RlcCgxKTtcbiAgfVxuICBpZiAoa2luZCA9PSAna2V5cycpIHJldHVybiBzdGVwKDAsIGluZGV4KTtcbiAgaWYgKGtpbmQgPT0gJ3ZhbHVlcycpIHJldHVybiBzdGVwKDAsIE9baW5kZXhdKTtcbiAgcmV0dXJuIHN0ZXAoMCwgW2luZGV4LCBPW2luZGV4XV0pO1xufSwgJ3ZhbHVlcycpO1xuXG4vLyBhcmd1bWVudHNMaXN0W0BAaXRlcmF0b3JdIGlzICVBcnJheVByb3RvX3ZhbHVlcyUgKDkuNC40LjYsIDkuNC40LjcpXG5JdGVyYXRvcnMuQXJndW1lbnRzID0gSXRlcmF0b3JzLkFycmF5O1xuXG5hZGRUb1Vuc2NvcGFibGVzKCdrZXlzJyk7XG5hZGRUb1Vuc2NvcGFibGVzKCd2YWx1ZXMnKTtcbmFkZFRvVW5zY29wYWJsZXMoJ2VudHJpZXMnKTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy4xMyBBcnJheS5wcm90b3R5cGUuam9pbihzZXBhcmF0b3IpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBhcnJheUpvaW4gPSBbXS5qb2luO1xuXG4vLyBmYWxsYmFjayBmb3Igbm90IGFycmF5LWxpa2Ugc3RyaW5nc1xuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAocmVxdWlyZSgnLi9faW9iamVjdCcpICE9IE9iamVjdCB8fCAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKGFycmF5Sm9pbikpLCAnQXJyYXknLCB7XG4gIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKSB7XG4gICAgcmV0dXJuIGFycmF5Sm9pbi5jYWxsKHRvSU9iamVjdCh0aGlzKSwgc2VwYXJhdG9yID09PSB1bmRlZmluZWQgPyAnLCcgOiBzZXBhcmF0b3IpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyICRuYXRpdmUgPSBbXS5sYXN0SW5kZXhPZjtcbnZhciBORUdBVElWRV9aRVJPID0gISEkbmF0aXZlICYmIDEgLyBbMV0ubGFzdEluZGV4T2YoMSwgLTApIDwgMDtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoTkVHQVRJVkVfWkVSTyB8fCAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKCRuYXRpdmUpKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTQgLyAxNS40LjQuMTUgQXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mKHNlYXJjaEVsZW1lbnQgWywgZnJvbUluZGV4XSlcbiAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uIGxhc3RJbmRleE9mKHNlYXJjaEVsZW1lbnQgLyogLCBmcm9tSW5kZXggPSBAWyotMV0gKi8pIHtcbiAgICAvLyBjb252ZXJ0IC0wIHRvICswXG4gICAgaWYgKE5FR0FUSVZFX1pFUk8pIHJldHVybiAkbmF0aXZlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgMDtcbiAgICB2YXIgTyA9IHRvSU9iamVjdCh0aGlzKTtcbiAgICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICAgIHZhciBpbmRleCA9IGxlbmd0aCAtIDE7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSBpbmRleCA9IE1hdGgubWluKGluZGV4LCB0b0ludGVnZXIoYXJndW1lbnRzWzFdKSk7XG4gICAgaWYgKGluZGV4IDwgMCkgaW5kZXggPSBsZW5ndGggKyBpbmRleDtcbiAgICBmb3IgKDtpbmRleCA+PSAwOyBpbmRleC0tKSBpZiAoaW5kZXggaW4gTykgaWYgKE9baW5kZXhdID09PSBzZWFyY2hFbGVtZW50KSByZXR1cm4gaW5kZXggfHwgMDtcbiAgICByZXR1cm4gLTE7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkbWFwID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDEpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10ubWFwLCB0cnVlKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTUgLyAxNS40LjQuMTkgQXJyYXkucHJvdG90eXBlLm1hcChjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBtYXA6IGZ1bmN0aW9uIG1hcChjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgIHJldHVybiAkbWFwKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjcmVhdGVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2NyZWF0ZS1wcm9wZXJ0eScpO1xuXG4vLyBXZWJLaXQgQXJyYXkub2YgaXNuJ3QgZ2VuZXJpY1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gRigpIHsgLyogZW1wdHkgKi8gfVxuICByZXR1cm4gIShBcnJheS5vZi5jYWxsKEYpIGluc3RhbmNlb2YgRik7XG59KSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjIuMyBBcnJheS5vZiggLi4uaXRlbXMpXG4gIG9mOiBmdW5jdGlvbiBvZigvKiAuLi5hcmdzICovKSB7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIHJlc3VsdCA9IG5ldyAodHlwZW9mIHRoaXMgPT0gJ2Z1bmN0aW9uJyA/IHRoaXMgOiBBcnJheSkoYUxlbik7XG4gICAgd2hpbGUgKGFMZW4gPiBpbmRleCkgY3JlYXRlUHJvcGVydHkocmVzdWx0LCBpbmRleCwgYXJndW1lbnRzW2luZGV4KytdKTtcbiAgICByZXN1bHQubGVuZ3RoID0gYUxlbjtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHJlZHVjZSA9IHJlcXVpcmUoJy4vX2FycmF5LXJlZHVjZScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10ucmVkdWNlUmlnaHQsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xOSAvIDE1LjQuNC4yMiBBcnJheS5wcm90b3R5cGUucmVkdWNlUmlnaHQoY2FsbGJhY2tmbiBbLCBpbml0aWFsVmFsdWVdKVxuICByZWR1Y2VSaWdodDogZnVuY3Rpb24gcmVkdWNlUmlnaHQoY2FsbGJhY2tmbiAvKiAsIGluaXRpYWxWYWx1ZSAqLykge1xuICAgIHJldHVybiAkcmVkdWNlKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3VtZW50c1sxXSwgdHJ1ZSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcmVkdWNlID0gcmVxdWlyZSgnLi9fYXJyYXktcmVkdWNlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5yZWR1Y2UsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xOCAvIDE1LjQuNC4yMSBBcnJheS5wcm90b3R5cGUucmVkdWNlKGNhbGxiYWNrZm4gWywgaW5pdGlhbFZhbHVlXSlcbiAgcmVkdWNlOiBmdW5jdGlvbiByZWR1Y2UoY2FsbGJhY2tmbiAvKiAsIGluaXRpYWxWYWx1ZSAqLykge1xuICAgIHJldHVybiAkcmVkdWNlKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3VtZW50c1sxXSwgZmFsc2UpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaHRtbCA9IHJlcXVpcmUoJy4vX2h0bWwnKTtcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgYXJyYXlTbGljZSA9IFtdLnNsaWNlO1xuXG4vLyBmYWxsYmFjayBmb3Igbm90IGFycmF5LWxpa2UgRVMzIHN0cmluZ3MgYW5kIERPTSBvYmplY3RzXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICBpZiAoaHRtbCkgYXJyYXlTbGljZS5jYWxsKGh0bWwpO1xufSksICdBcnJheScsIHtcbiAgc2xpY2U6IGZ1bmN0aW9uIHNsaWNlKGJlZ2luLCBlbmQpIHtcbiAgICB2YXIgbGVuID0gdG9MZW5ndGgodGhpcy5sZW5ndGgpO1xuICAgIHZhciBrbGFzcyA9IGNvZih0aGlzKTtcbiAgICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IGVuZDtcbiAgICBpZiAoa2xhc3MgPT0gJ0FycmF5JykgcmV0dXJuIGFycmF5U2xpY2UuY2FsbCh0aGlzLCBiZWdpbiwgZW5kKTtcbiAgICB2YXIgc3RhcnQgPSB0b0Fic29sdXRlSW5kZXgoYmVnaW4sIGxlbik7XG4gICAgdmFyIHVwVG8gPSB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW4pO1xuICAgIHZhciBzaXplID0gdG9MZW5ndGgodXBUbyAtIHN0YXJ0KTtcbiAgICB2YXIgY2xvbmVkID0gbmV3IEFycmF5KHNpemUpO1xuICAgIHZhciBpID0gMDtcbiAgICBmb3IgKDsgaSA8IHNpemU7IGkrKykgY2xvbmVkW2ldID0ga2xhc3MgPT0gJ1N0cmluZydcbiAgICAgID8gdGhpcy5jaGFyQXQoc3RhcnQgKyBpKVxuICAgICAgOiB0aGlzW3N0YXJ0ICsgaV07XG4gICAgcmV0dXJuIGNsb25lZDtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRzb21lID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDMpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10uc29tZSwgdHJ1ZSksICdBcnJheScsIHtcbiAgLy8gMjIuMS4zLjIzIC8gMTUuNC40LjE3IEFycmF5LnByb3RvdHlwZS5zb21lKGNhbGxiYWNrZm4gWywgdGhpc0FyZ10pXG4gIHNvbWU6IGZ1bmN0aW9uIHNvbWUoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJHNvbWUodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzWzFdKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciAkc29ydCA9IFtdLnNvcnQ7XG52YXIgdGVzdCA9IFsxLCAyLCAzXTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoZmFpbHMoZnVuY3Rpb24gKCkge1xuICAvLyBJRTgtXG4gIHRlc3Quc29ydCh1bmRlZmluZWQpO1xufSkgfHwgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gVjggYnVnXG4gIHRlc3Quc29ydChudWxsKTtcbiAgLy8gT2xkIFdlYktpdFxufSkgfHwgIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKSgkc29ydCkpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4yNSBBcnJheS5wcm90b3R5cGUuc29ydChjb21wYXJlZm4pXG4gIHNvcnQ6IGZ1bmN0aW9uIHNvcnQoY29tcGFyZWZuKSB7XG4gICAgcmV0dXJuIGNvbXBhcmVmbiA9PT0gdW5kZWZpbmVkXG4gICAgICA/ICRzb3J0LmNhbGwodG9PYmplY3QodGhpcykpXG4gICAgICA6ICRzb3J0LmNhbGwodG9PYmplY3QodGhpcyksIGFGdW5jdGlvbihjb21wYXJlZm4pKTtcbiAgfVxufSk7XG4iLCJyZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKCdBcnJheScpO1xuIiwiLy8gMjAuMy4zLjEgLyAxNS45LjQuNCBEYXRlLm5vdygpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0RhdGUnLCB7IG5vdzogZnVuY3Rpb24gKCkgeyByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7IH0gfSk7XG4iLCIvLyAyMC4zLjQuMzYgLyAxNS45LjUuNDMgRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcoKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b0lTT1N0cmluZyA9IHJlcXVpcmUoJy4vX2RhdGUtdG8taXNvLXN0cmluZycpO1xuXG4vLyBQaGFudG9tSlMgLyBvbGQgV2ViS2l0IGhhcyBhIGJyb2tlbiBpbXBsZW1lbnRhdGlvbnNcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nICE9PSB0b0lTT1N0cmluZyksICdEYXRlJywge1xuICB0b0lTT1N0cmluZzogdG9JU09TdHJpbmdcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBuZXcgRGF0ZShOYU4pLnRvSlNPTigpICE9PSBudWxsXG4gICAgfHwgRGF0ZS5wcm90b3R5cGUudG9KU09OLmNhbGwoeyB0b0lTT1N0cmluZzogZnVuY3Rpb24gKCkgeyByZXR1cm4gMTsgfSB9KSAhPT0gMTtcbn0pLCAnRGF0ZScsIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG4gIHRvSlNPTjogZnVuY3Rpb24gdG9KU09OKGtleSkge1xuICAgIHZhciBPID0gdG9PYmplY3QodGhpcyk7XG4gICAgdmFyIHB2ID0gdG9QcmltaXRpdmUoTyk7XG4gICAgcmV0dXJuIHR5cGVvZiBwdiA9PSAnbnVtYmVyJyAmJiAhaXNGaW5pdGUocHYpID8gbnVsbCA6IE8udG9JU09TdHJpbmcoKTtcbiAgfVxufSk7XG4iLCJ2YXIgVE9fUFJJTUlUSVZFID0gcmVxdWlyZSgnLi9fd2tzJykoJ3RvUHJpbWl0aXZlJyk7XG52YXIgcHJvdG8gPSBEYXRlLnByb3RvdHlwZTtcblxuaWYgKCEoVE9fUFJJTUlUSVZFIGluIHByb3RvKSkgcmVxdWlyZSgnLi9faGlkZScpKHByb3RvLCBUT19QUklNSVRJVkUsIHJlcXVpcmUoJy4vX2RhdGUtdG8tcHJpbWl0aXZlJykpO1xuIiwidmFyIERhdGVQcm90byA9IERhdGUucHJvdG90eXBlO1xudmFyIElOVkFMSURfREFURSA9ICdJbnZhbGlkIERhdGUnO1xudmFyIFRPX1NUUklORyA9ICd0b1N0cmluZyc7XG52YXIgJHRvU3RyaW5nID0gRGF0ZVByb3RvW1RPX1NUUklOR107XG52YXIgZ2V0VGltZSA9IERhdGVQcm90by5nZXRUaW1lO1xuaWYgKG5ldyBEYXRlKE5hTikgKyAnJyAhPSBJTlZBTElEX0RBVEUpIHtcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShEYXRlUHJvdG8sIFRPX1NUUklORywgZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgdmFyIHZhbHVlID0gZ2V0VGltZS5jYWxsKHRoaXMpO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlID8gJHRvU3RyaW5nLmNhbGwodGhpcykgOiBJTlZBTElEX0RBVEU7XG4gIH0pO1xufVxuIiwiLy8gMTkuMi4zLjIgLyAxNS4zLjQuNSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCh0aGlzQXJnLCBhcmdzLi4uKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAsICdGdW5jdGlvbicsIHsgYmluZDogcmVxdWlyZSgnLi9fYmluZCcpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgSEFTX0lOU1RBTkNFID0gcmVxdWlyZSgnLi9fd2tzJykoJ2hhc0luc3RhbmNlJyk7XG52YXIgRnVuY3Rpb25Qcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcbi8vIDE5LjIuMy42IEZ1bmN0aW9uLnByb3RvdHlwZVtAQGhhc0luc3RhbmNlXShWKVxuaWYgKCEoSEFTX0lOU1RBTkNFIGluIEZ1bmN0aW9uUHJvdG8pKSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mKEZ1bmN0aW9uUHJvdG8sIEhBU19JTlNUQU5DRSwgeyB2YWx1ZTogZnVuY3Rpb24gKE8pIHtcbiAgaWYgKHR5cGVvZiB0aGlzICE9ICdmdW5jdGlvbicgfHwgIWlzT2JqZWN0KE8pKSByZXR1cm4gZmFsc2U7XG4gIGlmICghaXNPYmplY3QodGhpcy5wcm90b3R5cGUpKSByZXR1cm4gTyBpbnN0YW5jZW9mIHRoaXM7XG4gIC8vIGZvciBlbnZpcm9ubWVudCB3L28gbmF0aXZlIGBAQGhhc0luc3RhbmNlYCBsb2dpYyBlbm91Z2ggYGluc3RhbmNlb2ZgLCBidXQgYWRkIHRoaXM6XG4gIHdoaWxlIChPID0gZ2V0UHJvdG90eXBlT2YoTykpIGlmICh0aGlzLnByb3RvdHlwZSA9PT0gTykgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn0gfSk7XG4iLCJ2YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIEZQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcbnZhciBuYW1lUkUgPSAvXlxccypmdW5jdGlvbiAoW14gKF0qKS87XG52YXIgTkFNRSA9ICduYW1lJztcblxuLy8gMTkuMi40LjIgbmFtZVxuTkFNRSBpbiBGUHJvdG8gfHwgcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiBkUChGUHJvdG8sIE5BTUUsIHtcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuICgnJyArIHRoaXMpLm1hdGNoKG5hbWVSRSlbMV07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgc3Ryb25nID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbi1zdHJvbmcnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBNQVAgPSAnTWFwJztcblxuLy8gMjMuMSBNYXAgT2JqZWN0c1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uJykoTUFQLCBmdW5jdGlvbiAoZ2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBNYXAoKSB7IHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpOyB9O1xufSwge1xuICAvLyAyMy4xLjMuNiBNYXAucHJvdG90eXBlLmdldChrZXkpXG4gIGdldDogZnVuY3Rpb24gZ2V0KGtleSkge1xuICAgIHZhciBlbnRyeSA9IHN0cm9uZy5nZXRFbnRyeSh2YWxpZGF0ZSh0aGlzLCBNQVApLCBrZXkpO1xuICAgIHJldHVybiBlbnRyeSAmJiBlbnRyeS52O1xuICB9LFxuICAvLyAyMy4xLjMuOSBNYXAucHJvdG90eXBlLnNldChrZXksIHZhbHVlKVxuICBzZXQ6IGZ1bmN0aW9uIHNldChrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIHN0cm9uZy5kZWYodmFsaWRhdGUodGhpcywgTUFQKSwga2V5ID09PSAwID8gMCA6IGtleSwgdmFsdWUpO1xuICB9XG59LCBzdHJvbmcsIHRydWUpO1xuIiwiLy8gMjAuMi4yLjMgTWF0aC5hY29zaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBsb2cxcCA9IHJlcXVpcmUoJy4vX21hdGgtbG9nMXAnKTtcbnZhciBzcXJ0ID0gTWF0aC5zcXJ0O1xudmFyICRhY29zaCA9IE1hdGguYWNvc2g7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogISgkYWNvc2hcbiAgLy8gVjggYnVnOiBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzUwOVxuICAmJiBNYXRoLmZsb29yKCRhY29zaChOdW1iZXIuTUFYX1ZBTFVFKSkgPT0gNzEwXG4gIC8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hY29zaChJbmZpbml0eSkgLT4gTmFOXG4gICYmICRhY29zaChJbmZpbml0eSkgPT0gSW5maW5pdHlcbiksICdNYXRoJywge1xuICBhY29zaDogZnVuY3Rpb24gYWNvc2goeCkge1xuICAgIHJldHVybiAoeCA9ICt4KSA8IDEgPyBOYU4gOiB4ID4gOTQ5MDYyNjUuNjI0MjUxNTZcbiAgICAgID8gTWF0aC5sb2coeCkgKyBNYXRoLkxOMlxuICAgICAgOiBsb2cxcCh4IC0gMSArIHNxcnQoeCAtIDEpICogc3FydCh4ICsgMSkpO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi41IE1hdGguYXNpbmgoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGFzaW5oID0gTWF0aC5hc2luaDtcblxuZnVuY3Rpb24gYXNpbmgoeCkge1xuICByZXR1cm4gIWlzRmluaXRlKHggPSAreCkgfHwgeCA9PSAwID8geCA6IHggPCAwID8gLWFzaW5oKC14KSA6IE1hdGgubG9nKHggKyBNYXRoLnNxcnQoeCAqIHggKyAxKSk7XG59XG5cbi8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hc2luaCgwKSAtPiAtMFxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKCRhc2luaCAmJiAxIC8gJGFzaW5oKDApID4gMCksICdNYXRoJywgeyBhc2luaDogYXNpbmggfSk7XG4iLCIvLyAyMC4yLjIuNyBNYXRoLmF0YW5oKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRhdGFuaCA9IE1hdGguYXRhbmg7XG5cbi8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hdGFuaCgtMCkgLT4gMFxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKCRhdGFuaCAmJiAxIC8gJGF0YW5oKC0wKSA8IDApLCAnTWF0aCcsIHtcbiAgYXRhbmg6IGZ1bmN0aW9uIGF0YW5oKHgpIHtcbiAgICByZXR1cm4gKHggPSAreCkgPT0gMCA/IHggOiBNYXRoLmxvZygoMSArIHgpIC8gKDEgLSB4KSkgLyAyO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi45IE1hdGguY2JydCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBzaWduID0gcmVxdWlyZSgnLi9fbWF0aC1zaWduJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgY2JydDogZnVuY3Rpb24gY2JydCh4KSB7XG4gICAgcmV0dXJuIHNpZ24oeCA9ICt4KSAqIE1hdGgucG93KE1hdGguYWJzKHgpLCAxIC8gMyk7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjExIE1hdGguY2x6MzIoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgY2x6MzI6IGZ1bmN0aW9uIGNsejMyKHgpIHtcbiAgICByZXR1cm4gKHggPj4+PSAwKSA/IDMxIC0gTWF0aC5mbG9vcihNYXRoLmxvZyh4ICsgMC41KSAqIE1hdGguTE9HMkUpIDogMzI7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjEyIE1hdGguY29zaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBleHAgPSBNYXRoLmV4cDtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBjb3NoOiBmdW5jdGlvbiBjb3NoKHgpIHtcbiAgICByZXR1cm4gKGV4cCh4ID0gK3gpICsgZXhwKC14KSkgLyAyO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4xNCBNYXRoLmV4cG0xKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRleHBtMSA9IHJlcXVpcmUoJy4vX21hdGgtZXhwbTEnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoJGV4cG0xICE9IE1hdGguZXhwbTEpLCAnTWF0aCcsIHsgZXhwbTE6ICRleHBtMSB9KTtcbiIsIi8vIDIwLjIuMi4xNiBNYXRoLmZyb3VuZCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywgeyBmcm91bmQ6IHJlcXVpcmUoJy4vX21hdGgtZnJvdW5kJykgfSk7XG4iLCIvLyAyMC4yLjIuMTcgTWF0aC5oeXBvdChbdmFsdWUxWywgdmFsdWUyWywg4oCmIF1dXSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYWJzID0gTWF0aC5hYnM7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgaHlwb3Q6IGZ1bmN0aW9uIGh5cG90KHZhbHVlMSwgdmFsdWUyKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICB2YXIgc3VtID0gMDtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBsYXJnID0gMDtcbiAgICB2YXIgYXJnLCBkaXY7XG4gICAgd2hpbGUgKGkgPCBhTGVuKSB7XG4gICAgICBhcmcgPSBhYnMoYXJndW1lbnRzW2krK10pO1xuICAgICAgaWYgKGxhcmcgPCBhcmcpIHtcbiAgICAgICAgZGl2ID0gbGFyZyAvIGFyZztcbiAgICAgICAgc3VtID0gc3VtICogZGl2ICogZGl2ICsgMTtcbiAgICAgICAgbGFyZyA9IGFyZztcbiAgICAgIH0gZWxzZSBpZiAoYXJnID4gMCkge1xuICAgICAgICBkaXYgPSBhcmcgLyBsYXJnO1xuICAgICAgICBzdW0gKz0gZGl2ICogZGl2O1xuICAgICAgfSBlbHNlIHN1bSArPSBhcmc7XG4gICAgfVxuICAgIHJldHVybiBsYXJnID09PSBJbmZpbml0eSA/IEluZmluaXR5IDogbGFyZyAqIE1hdGguc3FydChzdW0pO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4xOCBNYXRoLmltdWwoeCwgeSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGltdWwgPSBNYXRoLmltdWw7XG5cbi8vIHNvbWUgV2ViS2l0IHZlcnNpb25zIGZhaWxzIHdpdGggYmlnIG51bWJlcnMsIHNvbWUgaGFzIHdyb25nIGFyaXR5XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gJGltdWwoMHhmZmZmZmZmZiwgNSkgIT0gLTUgfHwgJGltdWwubGVuZ3RoICE9IDI7XG59KSwgJ01hdGgnLCB7XG4gIGltdWw6IGZ1bmN0aW9uIGltdWwoeCwgeSkge1xuICAgIHZhciBVSU5UMTYgPSAweGZmZmY7XG4gICAgdmFyIHhuID0gK3g7XG4gICAgdmFyIHluID0gK3k7XG4gICAgdmFyIHhsID0gVUlOVDE2ICYgeG47XG4gICAgdmFyIHlsID0gVUlOVDE2ICYgeW47XG4gICAgcmV0dXJuIDAgfCB4bCAqIHlsICsgKChVSU5UMTYgJiB4biA+Pj4gMTYpICogeWwgKyB4bCAqIChVSU5UMTYgJiB5biA+Pj4gMTYpIDw8IDE2ID4+PiAwKTtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuMjEgTWF0aC5sb2cxMCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBsb2cxMDogZnVuY3Rpb24gbG9nMTAoeCkge1xuICAgIHJldHVybiBNYXRoLmxvZyh4KSAqIE1hdGguTE9HMTBFO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4yMCBNYXRoLmxvZzFwKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7IGxvZzFwOiByZXF1aXJlKCcuL19tYXRoLWxvZzFwJykgfSk7XG4iLCIvLyAyMC4yLjIuMjIgTWF0aC5sb2cyKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGxvZzI6IGZ1bmN0aW9uIGxvZzIoeCkge1xuICAgIHJldHVybiBNYXRoLmxvZyh4KSAvIE1hdGguTE4yO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4yOCBNYXRoLnNpZ24oeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHsgc2lnbjogcmVxdWlyZSgnLi9fbWF0aC1zaWduJykgfSk7XG4iLCIvLyAyMC4yLjIuMzAgTWF0aC5zaW5oKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGV4cG0xID0gcmVxdWlyZSgnLi9fbWF0aC1leHBtMScpO1xudmFyIGV4cCA9IE1hdGguZXhwO1xuXG4vLyBWOCBuZWFyIENocm9taXVtIDM4IGhhcyBhIHByb2JsZW0gd2l0aCB2ZXJ5IHNtYWxsIG51bWJlcnNcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhTWF0aC5zaW5oKC0yZS0xNykgIT0gLTJlLTE3O1xufSksICdNYXRoJywge1xuICBzaW5oOiBmdW5jdGlvbiBzaW5oKHgpIHtcbiAgICByZXR1cm4gTWF0aC5hYnMoeCA9ICt4KSA8IDFcbiAgICAgID8gKGV4cG0xKHgpIC0gZXhwbTEoLXgpKSAvIDJcbiAgICAgIDogKGV4cCh4IC0gMSkgLSBleHAoLXggLSAxKSkgKiAoTWF0aC5FIC8gMik7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjMzIE1hdGgudGFuaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBleHBtMSA9IHJlcXVpcmUoJy4vX21hdGgtZXhwbTEnKTtcbnZhciBleHAgPSBNYXRoLmV4cDtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICB0YW5oOiBmdW5jdGlvbiB0YW5oKHgpIHtcbiAgICB2YXIgYSA9IGV4cG0xKHggPSAreCk7XG4gICAgdmFyIGIgPSBleHBtMSgteCk7XG4gICAgcmV0dXJuIGEgPT0gSW5maW5pdHkgPyAxIDogYiA9PSBJbmZpbml0eSA/IC0xIDogKGEgLSBiKSAvIChleHAoeCkgKyBleHAoLXgpKTtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuMzQgTWF0aC50cnVuYyh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICB0cnVuYzogZnVuY3Rpb24gdHJ1bmMoaXQpIHtcbiAgICByZXR1cm4gKGl0ID4gMCA/IE1hdGguZmxvb3IgOiBNYXRoLmNlaWwpKGl0KTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG52YXIgaW5oZXJpdElmUmVxdWlyZWQgPSByZXF1aXJlKCcuL19pbmhlcml0LWlmLXJlcXVpcmVkJyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgZ09QTiA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZjtcbnZhciBnT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mO1xudmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciAkdHJpbSA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbTtcbnZhciBOVU1CRVIgPSAnTnVtYmVyJztcbnZhciAkTnVtYmVyID0gZ2xvYmFsW05VTUJFUl07XG52YXIgQmFzZSA9ICROdW1iZXI7XG52YXIgcHJvdG8gPSAkTnVtYmVyLnByb3RvdHlwZTtcbi8vIE9wZXJhIH4xMiBoYXMgYnJva2VuIE9iamVjdCN0b1N0cmluZ1xudmFyIEJST0tFTl9DT0YgPSBjb2YocmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpKHByb3RvKSkgPT0gTlVNQkVSO1xudmFyIFRSSU0gPSAndHJpbScgaW4gU3RyaW5nLnByb3RvdHlwZTtcblxuLy8gNy4xLjMgVG9OdW1iZXIoYXJndW1lbnQpXG52YXIgdG9OdW1iZXIgPSBmdW5jdGlvbiAoYXJndW1lbnQpIHtcbiAgdmFyIGl0ID0gdG9QcmltaXRpdmUoYXJndW1lbnQsIGZhbHNlKTtcbiAgaWYgKHR5cGVvZiBpdCA9PSAnc3RyaW5nJyAmJiBpdC5sZW5ndGggPiAyKSB7XG4gICAgaXQgPSBUUklNID8gaXQudHJpbSgpIDogJHRyaW0oaXQsIDMpO1xuICAgIHZhciBmaXJzdCA9IGl0LmNoYXJDb2RlQXQoMCk7XG4gICAgdmFyIHRoaXJkLCByYWRpeCwgbWF4Q29kZTtcbiAgICBpZiAoZmlyc3QgPT09IDQzIHx8IGZpcnN0ID09PSA0NSkge1xuICAgICAgdGhpcmQgPSBpdC5jaGFyQ29kZUF0KDIpO1xuICAgICAgaWYgKHRoaXJkID09PSA4OCB8fCB0aGlyZCA9PT0gMTIwKSByZXR1cm4gTmFOOyAvLyBOdW1iZXIoJysweDEnKSBzaG91bGQgYmUgTmFOLCBvbGQgVjggZml4XG4gICAgfSBlbHNlIGlmIChmaXJzdCA9PT0gNDgpIHtcbiAgICAgIHN3aXRjaCAoaXQuY2hhckNvZGVBdCgxKSkge1xuICAgICAgICBjYXNlIDY2OiBjYXNlIDk4OiByYWRpeCA9IDI7IG1heENvZGUgPSA0OTsgYnJlYWs7IC8vIGZhc3QgZXF1YWwgL14wYlswMV0rJC9pXG4gICAgICAgIGNhc2UgNzk6IGNhc2UgMTExOiByYWRpeCA9IDg7IG1heENvZGUgPSA1NTsgYnJlYWs7IC8vIGZhc3QgZXF1YWwgL14wb1swLTddKyQvaVxuICAgICAgICBkZWZhdWx0OiByZXR1cm4gK2l0O1xuICAgICAgfVxuICAgICAgZm9yICh2YXIgZGlnaXRzID0gaXQuc2xpY2UoMiksIGkgPSAwLCBsID0gZGlnaXRzLmxlbmd0aCwgY29kZTsgaSA8IGw7IGkrKykge1xuICAgICAgICBjb2RlID0gZGlnaXRzLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIC8vIHBhcnNlSW50IHBhcnNlcyBhIHN0cmluZyB0byBhIGZpcnN0IHVuYXZhaWxhYmxlIHN5bWJvbFxuICAgICAgICAvLyBidXQgVG9OdW1iZXIgc2hvdWxkIHJldHVybiBOYU4gaWYgYSBzdHJpbmcgY29udGFpbnMgdW5hdmFpbGFibGUgc3ltYm9sc1xuICAgICAgICBpZiAoY29kZSA8IDQ4IHx8IGNvZGUgPiBtYXhDb2RlKSByZXR1cm4gTmFOO1xuICAgICAgfSByZXR1cm4gcGFyc2VJbnQoZGlnaXRzLCByYWRpeCk7XG4gICAgfVxuICB9IHJldHVybiAraXQ7XG59O1xuXG5pZiAoISROdW1iZXIoJyAwbzEnKSB8fCAhJE51bWJlcignMGIxJykgfHwgJE51bWJlcignKzB4MScpKSB7XG4gICROdW1iZXIgPSBmdW5jdGlvbiBOdW1iZXIodmFsdWUpIHtcbiAgICB2YXIgaXQgPSBhcmd1bWVudHMubGVuZ3RoIDwgMSA/IDAgOiB2YWx1ZTtcbiAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgcmV0dXJuIHRoYXQgaW5zdGFuY2VvZiAkTnVtYmVyXG4gICAgICAvLyBjaGVjayBvbiAxLi5jb25zdHJ1Y3Rvcihmb28pIGNhc2VcbiAgICAgICYmIChCUk9LRU5fQ09GID8gZmFpbHMoZnVuY3Rpb24gKCkgeyBwcm90by52YWx1ZU9mLmNhbGwodGhhdCk7IH0pIDogY29mKHRoYXQpICE9IE5VTUJFUilcbiAgICAgICAgPyBpbmhlcml0SWZSZXF1aXJlZChuZXcgQmFzZSh0b051bWJlcihpdCkpLCB0aGF0LCAkTnVtYmVyKSA6IHRvTnVtYmVyKGl0KTtcbiAgfTtcbiAgZm9yICh2YXIga2V5cyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBnT1BOKEJhc2UpIDogKFxuICAgIC8vIEVTMzpcbiAgICAnTUFYX1ZBTFVFLE1JTl9WQUxVRSxOYU4sTkVHQVRJVkVfSU5GSU5JVFksUE9TSVRJVkVfSU5GSU5JVFksJyArXG4gICAgLy8gRVM2IChpbiBjYXNlLCBpZiBtb2R1bGVzIHdpdGggRVM2IE51bWJlciBzdGF0aWNzIHJlcXVpcmVkIGJlZm9yZSk6XG4gICAgJ0VQU0lMT04saXNGaW5pdGUsaXNJbnRlZ2VyLGlzTmFOLGlzU2FmZUludGVnZXIsTUFYX1NBRkVfSU5URUdFUiwnICtcbiAgICAnTUlOX1NBRkVfSU5URUdFUixwYXJzZUZsb2F0LHBhcnNlSW50LGlzSW50ZWdlcidcbiAgKS5zcGxpdCgnLCcpLCBqID0gMCwga2V5OyBrZXlzLmxlbmd0aCA+IGo7IGorKykge1xuICAgIGlmIChoYXMoQmFzZSwga2V5ID0ga2V5c1tqXSkgJiYgIWhhcygkTnVtYmVyLCBrZXkpKSB7XG4gICAgICBkUCgkTnVtYmVyLCBrZXksIGdPUEQoQmFzZSwga2V5KSk7XG4gICAgfVxuICB9XG4gICROdW1iZXIucHJvdG90eXBlID0gcHJvdG87XG4gIHByb3RvLmNvbnN0cnVjdG9yID0gJE51bWJlcjtcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShnbG9iYWwsIE5VTUJFUiwgJE51bWJlcik7XG59XG4iLCIvLyAyMC4xLjIuMSBOdW1iZXIuRVBTSUxPTlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7IEVQU0lMT046IE1hdGgucG93KDIsIC01MikgfSk7XG4iLCIvLyAyMC4xLjIuMiBOdW1iZXIuaXNGaW5pdGUobnVtYmVyKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBfaXNGaW5pdGUgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5pc0Zpbml0ZTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7XG4gIGlzRmluaXRlOiBmdW5jdGlvbiBpc0Zpbml0ZShpdCkge1xuICAgIHJldHVybiB0eXBlb2YgaXQgPT0gJ251bWJlcicgJiYgX2lzRmluaXRlKGl0KTtcbiAgfVxufSk7XG4iLCIvLyAyMC4xLjIuMyBOdW1iZXIuaXNJbnRlZ2VyKG51bWJlcilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywgeyBpc0ludGVnZXI6IHJlcXVpcmUoJy4vX2lzLWludGVnZXInKSB9KTtcbiIsIi8vIDIwLjEuMi40IE51bWJlci5pc05hTihudW1iZXIpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHtcbiAgaXNOYU46IGZ1bmN0aW9uIGlzTmFOKG51bWJlcikge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICByZXR1cm4gbnVtYmVyICE9IG51bWJlcjtcbiAgfVxufSk7XG4iLCIvLyAyMC4xLjIuNSBOdW1iZXIuaXNTYWZlSW50ZWdlcihudW1iZXIpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGlzSW50ZWdlciA9IHJlcXVpcmUoJy4vX2lzLWludGVnZXInKTtcbnZhciBhYnMgPSBNYXRoLmFicztcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7XG4gIGlzU2FmZUludGVnZXI6IGZ1bmN0aW9uIGlzU2FmZUludGVnZXIobnVtYmVyKSB7XG4gICAgcmV0dXJuIGlzSW50ZWdlcihudW1iZXIpICYmIGFicyhudW1iZXIpIDw9IDB4MWZmZmZmZmZmZmZmZmY7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMS4yLjYgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywgeyBNQVhfU0FGRV9JTlRFR0VSOiAweDFmZmZmZmZmZmZmZmZmIH0pO1xuIiwiLy8gMjAuMS4yLjEwIE51bWJlci5NSU5fU0FGRV9JTlRFR0VSXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHsgTUlOX1NBRkVfSU5URUdFUjogLTB4MWZmZmZmZmZmZmZmZmYgfSk7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fcGFyc2UtZmxvYXQnKTtcbi8vIDIwLjEuMi4xMiBOdW1iZXIucGFyc2VGbG9hdChzdHJpbmcpXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChOdW1iZXIucGFyc2VGbG9hdCAhPSAkcGFyc2VGbG9hdCksICdOdW1iZXInLCB7IHBhcnNlRmxvYXQ6ICRwYXJzZUZsb2F0IH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19wYXJzZS1pbnQnKTtcbi8vIDIwLjEuMi4xMyBOdW1iZXIucGFyc2VJbnQoc3RyaW5nLCByYWRpeClcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKE51bWJlci5wYXJzZUludCAhPSAkcGFyc2VJbnQpLCAnTnVtYmVyJywgeyBwYXJzZUludDogJHBhcnNlSW50IH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgYU51bWJlclZhbHVlID0gcmVxdWlyZSgnLi9fYS1udW1iZXItdmFsdWUnKTtcbnZhciByZXBlYXQgPSByZXF1aXJlKCcuL19zdHJpbmctcmVwZWF0Jyk7XG52YXIgJHRvRml4ZWQgPSAxLjAudG9GaXhlZDtcbnZhciBmbG9vciA9IE1hdGguZmxvb3I7XG52YXIgZGF0YSA9IFswLCAwLCAwLCAwLCAwLCAwXTtcbnZhciBFUlJPUiA9ICdOdW1iZXIudG9GaXhlZDogaW5jb3JyZWN0IGludm9jYXRpb24hJztcbnZhciBaRVJPID0gJzAnO1xuXG52YXIgbXVsdGlwbHkgPSBmdW5jdGlvbiAobiwgYykge1xuICB2YXIgaSA9IC0xO1xuICB2YXIgYzIgPSBjO1xuICB3aGlsZSAoKytpIDwgNikge1xuICAgIGMyICs9IG4gKiBkYXRhW2ldO1xuICAgIGRhdGFbaV0gPSBjMiAlIDFlNztcbiAgICBjMiA9IGZsb29yKGMyIC8gMWU3KTtcbiAgfVxufTtcbnZhciBkaXZpZGUgPSBmdW5jdGlvbiAobikge1xuICB2YXIgaSA9IDY7XG4gIHZhciBjID0gMDtcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgYyArPSBkYXRhW2ldO1xuICAgIGRhdGFbaV0gPSBmbG9vcihjIC8gbik7XG4gICAgYyA9IChjICUgbikgKiAxZTc7XG4gIH1cbn07XG52YXIgbnVtVG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpID0gNjtcbiAgdmFyIHMgPSAnJztcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgaWYgKHMgIT09ICcnIHx8IGkgPT09IDAgfHwgZGF0YVtpXSAhPT0gMCkge1xuICAgICAgdmFyIHQgPSBTdHJpbmcoZGF0YVtpXSk7XG4gICAgICBzID0gcyA9PT0gJycgPyB0IDogcyArIHJlcGVhdC5jYWxsKFpFUk8sIDcgLSB0Lmxlbmd0aCkgKyB0O1xuICAgIH1cbiAgfSByZXR1cm4gcztcbn07XG52YXIgcG93ID0gZnVuY3Rpb24gKHgsIG4sIGFjYykge1xuICByZXR1cm4gbiA9PT0gMCA/IGFjYyA6IG4gJSAyID09PSAxID8gcG93KHgsIG4gLSAxLCBhY2MgKiB4KSA6IHBvdyh4ICogeCwgbiAvIDIsIGFjYyk7XG59O1xudmFyIGxvZyA9IGZ1bmN0aW9uICh4KSB7XG4gIHZhciBuID0gMDtcbiAgdmFyIHgyID0geDtcbiAgd2hpbGUgKHgyID49IDQwOTYpIHtcbiAgICBuICs9IDEyO1xuICAgIHgyIC89IDQwOTY7XG4gIH1cbiAgd2hpbGUgKHgyID49IDIpIHtcbiAgICBuICs9IDE7XG4gICAgeDIgLz0gMjtcbiAgfSByZXR1cm4gbjtcbn07XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKCEhJHRvRml4ZWQgJiYgKFxuICAwLjAwMDA4LnRvRml4ZWQoMykgIT09ICcwLjAwMCcgfHxcbiAgMC45LnRvRml4ZWQoMCkgIT09ICcxJyB8fFxuICAxLjI1NS50b0ZpeGVkKDIpICE9PSAnMS4yNScgfHxcbiAgMTAwMDAwMDAwMDAwMDAwMDEyOC4wLnRvRml4ZWQoMCkgIT09ICcxMDAwMDAwMDAwMDAwMDAwMTI4J1xuKSB8fCAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIC8vIFY4IH4gQW5kcm9pZCA0LjMtXG4gICR0b0ZpeGVkLmNhbGwoe30pO1xufSkpLCAnTnVtYmVyJywge1xuICB0b0ZpeGVkOiBmdW5jdGlvbiB0b0ZpeGVkKGZyYWN0aW9uRGlnaXRzKSB7XG4gICAgdmFyIHggPSBhTnVtYmVyVmFsdWUodGhpcywgRVJST1IpO1xuICAgIHZhciBmID0gdG9JbnRlZ2VyKGZyYWN0aW9uRGlnaXRzKTtcbiAgICB2YXIgcyA9ICcnO1xuICAgIHZhciBtID0gWkVSTztcbiAgICB2YXIgZSwgeiwgaiwgaztcbiAgICBpZiAoZiA8IDAgfHwgZiA+IDIwKSB0aHJvdyBSYW5nZUVycm9yKEVSUk9SKTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgaWYgKHggIT0geCkgcmV0dXJuICdOYU4nO1xuICAgIGlmICh4IDw9IC0xZTIxIHx8IHggPj0gMWUyMSkgcmV0dXJuIFN0cmluZyh4KTtcbiAgICBpZiAoeCA8IDApIHtcbiAgICAgIHMgPSAnLSc7XG4gICAgICB4ID0gLXg7XG4gICAgfVxuICAgIGlmICh4ID4gMWUtMjEpIHtcbiAgICAgIGUgPSBsb2coeCAqIHBvdygyLCA2OSwgMSkpIC0gNjk7XG4gICAgICB6ID0gZSA8IDAgPyB4ICogcG93KDIsIC1lLCAxKSA6IHggLyBwb3coMiwgZSwgMSk7XG4gICAgICB6ICo9IDB4MTAwMDAwMDAwMDAwMDA7XG4gICAgICBlID0gNTIgLSBlO1xuICAgICAgaWYgKGUgPiAwKSB7XG4gICAgICAgIG11bHRpcGx5KDAsIHopO1xuICAgICAgICBqID0gZjtcbiAgICAgICAgd2hpbGUgKGogPj0gNykge1xuICAgICAgICAgIG11bHRpcGx5KDFlNywgMCk7XG4gICAgICAgICAgaiAtPSA3O1xuICAgICAgICB9XG4gICAgICAgIG11bHRpcGx5KHBvdygxMCwgaiwgMSksIDApO1xuICAgICAgICBqID0gZSAtIDE7XG4gICAgICAgIHdoaWxlIChqID49IDIzKSB7XG4gICAgICAgICAgZGl2aWRlKDEgPDwgMjMpO1xuICAgICAgICAgIGogLT0gMjM7XG4gICAgICAgIH1cbiAgICAgICAgZGl2aWRlKDEgPDwgaik7XG4gICAgICAgIG11bHRpcGx5KDEsIDEpO1xuICAgICAgICBkaXZpZGUoMik7XG4gICAgICAgIG0gPSBudW1Ub1N0cmluZygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbXVsdGlwbHkoMCwgeik7XG4gICAgICAgIG11bHRpcGx5KDEgPDwgLWUsIDApO1xuICAgICAgICBtID0gbnVtVG9TdHJpbmcoKSArIHJlcGVhdC5jYWxsKFpFUk8sIGYpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZiA+IDApIHtcbiAgICAgIGsgPSBtLmxlbmd0aDtcbiAgICAgIG0gPSBzICsgKGsgPD0gZiA/ICcwLicgKyByZXBlYXQuY2FsbChaRVJPLCBmIC0gaykgKyBtIDogbS5zbGljZSgwLCBrIC0gZikgKyAnLicgKyBtLnNsaWNlKGsgLSBmKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBzICsgbTtcbiAgICB9IHJldHVybiBtO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBhTnVtYmVyVmFsdWUgPSByZXF1aXJlKCcuL19hLW51bWJlci12YWx1ZScpO1xudmFyICR0b1ByZWNpc2lvbiA9IDEuMC50b1ByZWNpc2lvbjtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoJGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gSUU3LVxuICByZXR1cm4gJHRvUHJlY2lzaW9uLmNhbGwoMSwgdW5kZWZpbmVkKSAhPT0gJzEnO1xufSkgfHwgISRmYWlscyhmdW5jdGlvbiAoKSB7XG4gIC8vIFY4IH4gQW5kcm9pZCA0LjMtXG4gICR0b1ByZWNpc2lvbi5jYWxsKHt9KTtcbn0pKSwgJ051bWJlcicsIHtcbiAgdG9QcmVjaXNpb246IGZ1bmN0aW9uIHRvUHJlY2lzaW9uKHByZWNpc2lvbikge1xuICAgIHZhciB0aGF0ID0gYU51bWJlclZhbHVlKHRoaXMsICdOdW1iZXIjdG9QcmVjaXNpb246IGluY29ycmVjdCBpbnZvY2F0aW9uIScpO1xuICAgIHJldHVybiBwcmVjaXNpb24gPT09IHVuZGVmaW5lZCA/ICR0b1ByZWNpc2lvbi5jYWxsKHRoYXQpIDogJHRvUHJlY2lzaW9uLmNhbGwodGhhdCwgcHJlY2lzaW9uKTtcbiAgfVxufSk7XG4iLCIvLyAxOS4xLjMuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYsICdPYmplY3QnLCB7IGFzc2lnbjogcmVxdWlyZSgnLi9fb2JqZWN0LWFzc2lnbicpIH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbi8vIDE5LjEuMi4yIC8gMTUuMi4zLjUgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7IGNyZWF0ZTogcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpIH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbi8vIDE5LjEuMi4zIC8gMTUuMi4zLjcgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoTywgUHJvcGVydGllcylcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyksICdPYmplY3QnLCB7IGRlZmluZVByb3BlcnRpZXM6IHJlcXVpcmUoJy4vX29iamVjdC1kcHMnKSB9KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4vLyAxOS4xLjIuNCAvIDE1LjIuMy42IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKVxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSwgJ09iamVjdCcsIHsgZGVmaW5lUHJvcGVydHk6IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmYgfSk7XG4iLCIvLyAxOS4xLjIuNSBPYmplY3QuZnJlZXplKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBtZXRhID0gcmVxdWlyZSgnLi9fbWV0YScpLm9uRnJlZXplO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2ZyZWV6ZScsIGZ1bmN0aW9uICgkZnJlZXplKSB7XG4gIHJldHVybiBmdW5jdGlvbiBmcmVlemUoaXQpIHtcbiAgICByZXR1cm4gJGZyZWV6ZSAmJiBpc09iamVjdChpdCkgPyAkZnJlZXplKG1ldGEoaXQpKSA6IGl0O1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuNiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApXG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpLmY7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yJywgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGl0LCBrZXkpIHtcbiAgICByZXR1cm4gJGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0b0lPYmplY3QoaXQpLCBrZXkpO1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuNyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhPKVxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdnZXRPd25Qcm9wZXJ0eU5hbWVzJywgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4tZXh0JykuZjtcbn0pO1xuIiwiLy8gMTkuMS4yLjkgT2JqZWN0LmdldFByb3RvdHlwZU9mKE8pXG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciAkZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnZ2V0UHJvdG90eXBlT2YnLCBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBnZXRQcm90b3R5cGVPZihpdCkge1xuICAgIHJldHVybiAkZ2V0UHJvdG90eXBlT2YodG9PYmplY3QoaXQpKTtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4yLjExIE9iamVjdC5pc0V4dGVuc2libGUoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2lzRXh0ZW5zaWJsZScsIGZ1bmN0aW9uICgkaXNFeHRlbnNpYmxlKSB7XG4gIHJldHVybiBmdW5jdGlvbiBpc0V4dGVuc2libGUoaXQpIHtcbiAgICByZXR1cm4gaXNPYmplY3QoaXQpID8gJGlzRXh0ZW5zaWJsZSA/ICRpc0V4dGVuc2libGUoaXQpIDogdHJ1ZSA6IGZhbHNlO1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuMTIgT2JqZWN0LmlzRnJvemVuKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdpc0Zyb3plbicsIGZ1bmN0aW9uICgkaXNGcm96ZW4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGlzRnJvemVuKGl0KSB7XG4gICAgcmV0dXJuIGlzT2JqZWN0KGl0KSA/ICRpc0Zyb3plbiA/ICRpc0Zyb3plbihpdCkgOiBmYWxzZSA6IHRydWU7XG4gIH07XG59KTtcbiIsIi8vIDE5LjEuMi4xMyBPYmplY3QuaXNTZWFsZWQoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2lzU2VhbGVkJywgZnVuY3Rpb24gKCRpc1NlYWxlZCkge1xuICByZXR1cm4gZnVuY3Rpb24gaXNTZWFsZWQoaXQpIHtcbiAgICByZXR1cm4gaXNPYmplY3QoaXQpID8gJGlzU2VhbGVkID8gJGlzU2VhbGVkKGl0KSA6IGZhbHNlIDogdHJ1ZTtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4zLjEwIE9iamVjdC5pcyh2YWx1ZTEsIHZhbHVlMilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHsgaXM6IHJlcXVpcmUoJy4vX3NhbWUtdmFsdWUnKSB9KTtcbiIsIi8vIDE5LjEuMi4xNCBPYmplY3Qua2V5cyhPKVxudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgJGtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2tleXMnLCBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBrZXlzKGl0KSB7XG4gICAgcmV0dXJuICRrZXlzKHRvT2JqZWN0KGl0KSk7XG4gIH07XG59KTtcbiIsIi8vIDE5LjEuMi4xNSBPYmplY3QucHJldmVudEV4dGVuc2lvbnMoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJykub25GcmVlemU7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgncHJldmVudEV4dGVuc2lvbnMnLCBmdW5jdGlvbiAoJHByZXZlbnRFeHRlbnNpb25zKSB7XG4gIHJldHVybiBmdW5jdGlvbiBwcmV2ZW50RXh0ZW5zaW9ucyhpdCkge1xuICAgIHJldHVybiAkcHJldmVudEV4dGVuc2lvbnMgJiYgaXNPYmplY3QoaXQpID8gJHByZXZlbnRFeHRlbnNpb25zKG1ldGEoaXQpKSA6IGl0O1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuMTcgT2JqZWN0LnNlYWwoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJykub25GcmVlemU7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnc2VhbCcsIGZ1bmN0aW9uICgkc2VhbCkge1xuICByZXR1cm4gZnVuY3Rpb24gc2VhbChpdCkge1xuICAgIHJldHVybiAkc2VhbCAmJiBpc09iamVjdChpdCkgPyAkc2VhbChtZXRhKGl0KSkgOiBpdDtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4zLjE5IE9iamVjdC5zZXRQcm90b3R5cGVPZihPLCBwcm90bylcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHsgc2V0UHJvdG90eXBlT2Y6IHJlcXVpcmUoJy4vX3NldC1wcm90bycpLnNldCB9KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDE5LjEuMy42IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcoKVxudmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuL19jbGFzc29mJyk7XG52YXIgdGVzdCA9IHt9O1xudGVzdFtyZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKV0gPSAneic7XG5pZiAodGVzdCArICcnICE9ICdbb2JqZWN0IHpdJykge1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKE9iamVjdC5wcm90b3R5cGUsICd0b1N0cmluZycsIGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiAnW29iamVjdCAnICsgY2xhc3NvZih0aGlzKSArICddJztcbiAgfSwgdHJ1ZSk7XG59XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fcGFyc2UtZmxvYXQnKTtcbi8vIDE4LjIuNCBwYXJzZUZsb2F0KHN0cmluZylcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5GICogKHBhcnNlRmxvYXQgIT0gJHBhcnNlRmxvYXQpLCB7IHBhcnNlRmxvYXQ6ICRwYXJzZUZsb2F0IH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19wYXJzZS1pbnQnKTtcbi8vIDE4LjIuNSBwYXJzZUludChzdHJpbmcsIHJhZGl4KVxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LkYgKiAocGFyc2VJbnQgIT0gJHBhcnNlSW50KSwgeyBwYXJzZUludDogJHBhcnNlSW50IH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG52YXIgdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKS5zZXQ7XG52YXIgbWljcm90YXNrID0gcmVxdWlyZSgnLi9fbWljcm90YXNrJykoKTtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eU1vZHVsZSA9IHJlcXVpcmUoJy4vX25ldy1wcm9taXNlLWNhcGFiaWxpdHknKTtcbnZhciBwZXJmb3JtID0gcmVxdWlyZSgnLi9fcGVyZm9ybScpO1xudmFyIHVzZXJBZ2VudCA9IHJlcXVpcmUoJy4vX3VzZXItYWdlbnQnKTtcbnZhciBwcm9taXNlUmVzb2x2ZSA9IHJlcXVpcmUoJy4vX3Byb21pc2UtcmVzb2x2ZScpO1xudmFyIFBST01JU0UgPSAnUHJvbWlzZSc7XG52YXIgVHlwZUVycm9yID0gZ2xvYmFsLlR5cGVFcnJvcjtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgdmVyc2lvbnMgPSBwcm9jZXNzICYmIHByb2Nlc3MudmVyc2lvbnM7XG52YXIgdjggPSB2ZXJzaW9ucyAmJiB2ZXJzaW9ucy52OCB8fCAnJztcbnZhciAkUHJvbWlzZSA9IGdsb2JhbFtQUk9NSVNFXTtcbnZhciBpc05vZGUgPSBjbGFzc29mKHByb2Nlc3MpID09ICdwcm9jZXNzJztcbnZhciBlbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcbnZhciBJbnRlcm5hbCwgbmV3R2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5LCBPd25Qcm9taXNlQ2FwYWJpbGl0eSwgV3JhcHBlcjtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmY7XG5cbnZhciBVU0VfTkFUSVZFID0gISFmdW5jdGlvbiAoKSB7XG4gIHRyeSB7XG4gICAgLy8gY29ycmVjdCBzdWJjbGFzc2luZyB3aXRoIEBAc3BlY2llcyBzdXBwb3J0XG4gICAgdmFyIHByb21pc2UgPSAkUHJvbWlzZS5yZXNvbHZlKDEpO1xuICAgIHZhciBGYWtlUHJvbWlzZSA9IChwcm9taXNlLmNvbnN0cnVjdG9yID0ge30pW3JlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyldID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgICAgIGV4ZWMoZW1wdHksIGVtcHR5KTtcbiAgICB9O1xuICAgIC8vIHVuaGFuZGxlZCByZWplY3Rpb25zIHRyYWNraW5nIHN1cHBvcnQsIE5vZGVKUyBQcm9taXNlIHdpdGhvdXQgaXQgZmFpbHMgQEBzcGVjaWVzIHRlc3RcbiAgICByZXR1cm4gKGlzTm9kZSB8fCB0eXBlb2YgUHJvbWlzZVJlamVjdGlvbkV2ZW50ID09ICdmdW5jdGlvbicpXG4gICAgICAmJiBwcm9taXNlLnRoZW4oZW1wdHkpIGluc3RhbmNlb2YgRmFrZVByb21pc2VcbiAgICAgIC8vIHY4IDYuNiAoTm9kZSAxMCBhbmQgQ2hyb21lIDY2KSBoYXZlIGEgYnVnIHdpdGggcmVzb2x2aW5nIGN1c3RvbSB0aGVuYWJsZXNcbiAgICAgIC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTgzMDU2NVxuICAgICAgLy8gd2UgY2FuJ3QgZGV0ZWN0IGl0IHN5bmNocm9ub3VzbHksIHNvIGp1c3QgY2hlY2sgdmVyc2lvbnNcbiAgICAgICYmIHY4LmluZGV4T2YoJzYuNicpICE9PSAwXG4gICAgICAmJiB1c2VyQWdlbnQuaW5kZXhPZignQ2hyb21lLzY2JykgPT09IC0xO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbn0oKTtcblxuLy8gaGVscGVyc1xudmFyIGlzVGhlbmFibGUgPSBmdW5jdGlvbiAoaXQpIHtcbiAgdmFyIHRoZW47XG4gIHJldHVybiBpc09iamVjdChpdCkgJiYgdHlwZW9mICh0aGVuID0gaXQudGhlbikgPT0gJ2Z1bmN0aW9uJyA/IHRoZW4gOiBmYWxzZTtcbn07XG52YXIgbm90aWZ5ID0gZnVuY3Rpb24gKHByb21pc2UsIGlzUmVqZWN0KSB7XG4gIGlmIChwcm9taXNlLl9uKSByZXR1cm47XG4gIHByb21pc2UuX24gPSB0cnVlO1xuICB2YXIgY2hhaW4gPSBwcm9taXNlLl9jO1xuICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3Y7XG4gICAgdmFyIG9rID0gcHJvbWlzZS5fcyA9PSAxO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIgcnVuID0gZnVuY3Rpb24gKHJlYWN0aW9uKSB7XG4gICAgICB2YXIgaGFuZGxlciA9IG9rID8gcmVhY3Rpb24ub2sgOiByZWFjdGlvbi5mYWlsO1xuICAgICAgdmFyIHJlc29sdmUgPSByZWFjdGlvbi5yZXNvbHZlO1xuICAgICAgdmFyIHJlamVjdCA9IHJlYWN0aW9uLnJlamVjdDtcbiAgICAgIHZhciBkb21haW4gPSByZWFjdGlvbi5kb21haW47XG4gICAgICB2YXIgcmVzdWx0LCB0aGVuLCBleGl0ZWQ7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICAgIGlmICghb2spIHtcbiAgICAgICAgICAgIGlmIChwcm9taXNlLl9oID09IDIpIG9uSGFuZGxlVW5oYW5kbGVkKHByb21pc2UpO1xuICAgICAgICAgICAgcHJvbWlzZS5faCA9IDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChoYW5kbGVyID09PSB0cnVlKSByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChkb21haW4pIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgcmVzdWx0ID0gaGFuZGxlcih2YWx1ZSk7IC8vIG1heSB0aHJvd1xuICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICAgICAgICBleGl0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVzdWx0ID09PSByZWFjdGlvbi5wcm9taXNlKSB7XG4gICAgICAgICAgICByZWplY3QoVHlwZUVycm9yKCdQcm9taXNlLWNoYWluIGN5Y2xlJykpO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGhlbiA9IGlzVGhlbmFibGUocmVzdWx0KSkge1xuICAgICAgICAgICAgdGhlbi5jYWxsKHJlc3VsdCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICB9IGVsc2UgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGVsc2UgcmVqZWN0KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGRvbWFpbiAmJiAhZXhpdGVkKSBkb21haW4uZXhpdCgpO1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9XG4gICAgfTtcbiAgICB3aGlsZSAoY2hhaW4ubGVuZ3RoID4gaSkgcnVuKGNoYWluW2krK10pOyAvLyB2YXJpYWJsZSBsZW5ndGggLSBjYW4ndCB1c2UgZm9yRWFjaFxuICAgIHByb21pc2UuX2MgPSBbXTtcbiAgICBwcm9taXNlLl9uID0gZmFsc2U7XG4gICAgaWYgKGlzUmVqZWN0ICYmICFwcm9taXNlLl9oKSBvblVuaGFuZGxlZChwcm9taXNlKTtcbiAgfSk7XG59O1xudmFyIG9uVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgdGFzay5jYWxsKGdsb2JhbCwgZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3Y7XG4gICAgdmFyIHVuaGFuZGxlZCA9IGlzVW5oYW5kbGVkKHByb21pc2UpO1xuICAgIHZhciByZXN1bHQsIGhhbmRsZXIsIGNvbnNvbGU7XG4gICAgaWYgKHVuaGFuZGxlZCkge1xuICAgICAgcmVzdWx0ID0gcGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChpc05vZGUpIHtcbiAgICAgICAgICBwcm9jZXNzLmVtaXQoJ3VuaGFuZGxlZFJlamVjdGlvbicsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGlmIChoYW5kbGVyID0gZ2xvYmFsLm9udW5oYW5kbGVkcmVqZWN0aW9uKSB7XG4gICAgICAgICAgaGFuZGxlcih7IHByb21pc2U6IHByb21pc2UsIHJlYXNvbjogdmFsdWUgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoKGNvbnNvbGUgPSBnbG9iYWwuY29uc29sZSkgJiYgY29uc29sZS5lcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1VuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbicsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBCcm93c2VycyBzaG91bGQgbm90IHRyaWdnZXIgYHJlamVjdGlvbkhhbmRsZWRgIGV2ZW50IGlmIGl0IHdhcyBoYW5kbGVkIGhlcmUsIE5vZGVKUyAtIHNob3VsZFxuICAgICAgcHJvbWlzZS5faCA9IGlzTm9kZSB8fCBpc1VuaGFuZGxlZChwcm9taXNlKSA/IDIgOiAxO1xuICAgIH0gcHJvbWlzZS5fYSA9IHVuZGVmaW5lZDtcbiAgICBpZiAodW5oYW5kbGVkICYmIHJlc3VsdC5lKSB0aHJvdyByZXN1bHQudjtcbiAgfSk7XG59O1xudmFyIGlzVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgcmV0dXJuIHByb21pc2UuX2ggIT09IDEgJiYgKHByb21pc2UuX2EgfHwgcHJvbWlzZS5fYykubGVuZ3RoID09PSAwO1xufTtcbnZhciBvbkhhbmRsZVVuaGFuZGxlZCA9IGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gIHRhc2suY2FsbChnbG9iYWwsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGFuZGxlcjtcbiAgICBpZiAoaXNOb2RlKSB7XG4gICAgICBwcm9jZXNzLmVtaXQoJ3JlamVjdGlvbkhhbmRsZWQnLCBwcm9taXNlKTtcbiAgICB9IGVsc2UgaWYgKGhhbmRsZXIgPSBnbG9iYWwub25yZWplY3Rpb25oYW5kbGVkKSB7XG4gICAgICBoYW5kbGVyKHsgcHJvbWlzZTogcHJvbWlzZSwgcmVhc29uOiBwcm9taXNlLl92IH0pO1xuICAgIH1cbiAgfSk7XG59O1xudmFyICRyZWplY3QgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgdmFyIHByb21pc2UgPSB0aGlzO1xuICBpZiAocHJvbWlzZS5fZCkgcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHByb21pc2UuX3YgPSB2YWx1ZTtcbiAgcHJvbWlzZS5fcyA9IDI7XG4gIGlmICghcHJvbWlzZS5fYSkgcHJvbWlzZS5fYSA9IHByb21pc2UuX2Muc2xpY2UoKTtcbiAgbm90aWZ5KHByb21pc2UsIHRydWUpO1xufTtcbnZhciAkcmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gIHZhciB0aGVuO1xuICBpZiAocHJvbWlzZS5fZCkgcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHRyeSB7XG4gICAgaWYgKHByb21pc2UgPT09IHZhbHVlKSB0aHJvdyBUeXBlRXJyb3IoXCJQcm9taXNlIGNhbid0IGJlIHJlc29sdmVkIGl0c2VsZlwiKTtcbiAgICBpZiAodGhlbiA9IGlzVGhlbmFibGUodmFsdWUpKSB7XG4gICAgICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgd3JhcHBlciA9IHsgX3c6IHByb21pc2UsIF9kOiBmYWxzZSB9OyAvLyB3cmFwXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhlbi5jYWxsKHZhbHVlLCBjdHgoJHJlc29sdmUsIHdyYXBwZXIsIDEpLCBjdHgoJHJlamVjdCwgd3JhcHBlciwgMSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgJHJlamVjdC5jYWxsKHdyYXBwZXIsIGUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvbWlzZS5fdiA9IHZhbHVlO1xuICAgICAgcHJvbWlzZS5fcyA9IDE7XG4gICAgICBub3RpZnkocHJvbWlzZSwgZmFsc2UpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgICRyZWplY3QuY2FsbCh7IF93OiBwcm9taXNlLCBfZDogZmFsc2UgfSwgZSk7IC8vIHdyYXBcbiAgfVxufTtcblxuLy8gY29uc3RydWN0b3IgcG9seWZpbGxcbmlmICghVVNFX05BVElWRSkge1xuICAvLyAyNS40LjMuMSBQcm9taXNlKGV4ZWN1dG9yKVxuICAkUHJvbWlzZSA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICBhbkluc3RhbmNlKHRoaXMsICRQcm9taXNlLCBQUk9NSVNFLCAnX2gnKTtcbiAgICBhRnVuY3Rpb24oZXhlY3V0b3IpO1xuICAgIEludGVybmFsLmNhbGwodGhpcyk7XG4gICAgdHJ5IHtcbiAgICAgIGV4ZWN1dG9yKGN0eCgkcmVzb2x2ZSwgdGhpcywgMSksIGN0eCgkcmVqZWN0LCB0aGlzLCAxKSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAkcmVqZWN0LmNhbGwodGhpcywgZXJyKTtcbiAgICB9XG4gIH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICBJbnRlcm5hbCA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICB0aGlzLl9jID0gW107ICAgICAgICAgICAgIC8vIDwtIGF3YWl0aW5nIHJlYWN0aW9uc1xuICAgIHRoaXMuX2EgPSB1bmRlZmluZWQ7ICAgICAgLy8gPC0gY2hlY2tlZCBpbiBpc1VuaGFuZGxlZCByZWFjdGlvbnNcbiAgICB0aGlzLl9zID0gMDsgICAgICAgICAgICAgIC8vIDwtIHN0YXRlXG4gICAgdGhpcy5fZCA9IGZhbHNlOyAgICAgICAgICAvLyA8LSBkb25lXG4gICAgdGhpcy5fdiA9IHVuZGVmaW5lZDsgICAgICAvLyA8LSB2YWx1ZVxuICAgIHRoaXMuX2ggPSAwOyAgICAgICAgICAgICAgLy8gPC0gcmVqZWN0aW9uIHN0YXRlLCAwIC0gZGVmYXVsdCwgMSAtIGhhbmRsZWQsIDIgLSB1bmhhbmRsZWRcbiAgICB0aGlzLl9uID0gZmFsc2U7ICAgICAgICAgIC8vIDwtIG5vdGlmeVxuICB9O1xuICBJbnRlcm5hbC5wcm90b3R5cGUgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKSgkUHJvbWlzZS5wcm90b3R5cGUsIHtcbiAgICAvLyAyNS40LjUuMyBQcm9taXNlLnByb3RvdHlwZS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKVxuICAgIHRoZW46IGZ1bmN0aW9uIHRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICAgIHZhciByZWFjdGlvbiA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCAkUHJvbWlzZSkpO1xuICAgICAgcmVhY3Rpb24ub2sgPSB0eXBlb2Ygb25GdWxmaWxsZWQgPT0gJ2Z1bmN0aW9uJyA/IG9uRnVsZmlsbGVkIDogdHJ1ZTtcbiAgICAgIHJlYWN0aW9uLmZhaWwgPSB0eXBlb2Ygb25SZWplY3RlZCA9PSAnZnVuY3Rpb24nICYmIG9uUmVqZWN0ZWQ7XG4gICAgICByZWFjdGlvbi5kb21haW4gPSBpc05vZGUgPyBwcm9jZXNzLmRvbWFpbiA6IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuX2MucHVzaChyZWFjdGlvbik7XG4gICAgICBpZiAodGhpcy5fYSkgdGhpcy5fYS5wdXNoKHJlYWN0aW9uKTtcbiAgICAgIGlmICh0aGlzLl9zKSBub3RpZnkodGhpcywgZmFsc2UpO1xuICAgICAgcmV0dXJuIHJlYWN0aW9uLnByb21pc2U7XG4gICAgfSxcbiAgICAvLyAyNS40LjUuMSBQcm9taXNlLnByb3RvdHlwZS5jYXRjaChvblJlamVjdGVkKVxuICAgICdjYXRjaCc6IGZ1bmN0aW9uIChvblJlamVjdGVkKSB7XG4gICAgICByZXR1cm4gdGhpcy50aGVuKHVuZGVmaW5lZCwgb25SZWplY3RlZCk7XG4gICAgfVxuICB9KTtcbiAgT3duUHJvbWlzZUNhcGFiaWxpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHByb21pc2UgPSBuZXcgSW50ZXJuYWwoKTtcbiAgICB0aGlzLnByb21pc2UgPSBwcm9taXNlO1xuICAgIHRoaXMucmVzb2x2ZSA9IGN0eCgkcmVzb2x2ZSwgcHJvbWlzZSwgMSk7XG4gICAgdGhpcy5yZWplY3QgPSBjdHgoJHJlamVjdCwgcHJvbWlzZSwgMSk7XG4gIH07XG4gIG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmYgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uIChDKSB7XG4gICAgcmV0dXJuIEMgPT09ICRQcm9taXNlIHx8IEMgPT09IFdyYXBwZXJcbiAgICAgID8gbmV3IE93blByb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgICA6IG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgfTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgeyBQcm9taXNlOiAkUHJvbWlzZSB9KTtcbnJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJykoJFByb21pc2UsIFBST01JU0UpO1xucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKShQUk9NSVNFKTtcbldyYXBwZXIgPSByZXF1aXJlKCcuL19jb3JlJylbUFJPTUlTRV07XG5cbi8vIHN0YXRpY3NcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIFBST01JU0UsIHtcbiAgLy8gMjUuNC40LjUgUHJvbWlzZS5yZWplY3QocilcbiAgcmVqZWN0OiBmdW5jdGlvbiByZWplY3Qocikge1xuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkodGhpcyk7XG4gICAgdmFyICQkcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgJCRyZWplY3Qocik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChMSUJSQVJZIHx8ICFVU0VfTkFUSVZFKSwgUFJPTUlTRSwge1xuICAvLyAyNS40LjQuNiBQcm9taXNlLnJlc29sdmUoeClcbiAgcmVzb2x2ZTogZnVuY3Rpb24gcmVzb2x2ZSh4KSB7XG4gICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKExJQlJBUlkgJiYgdGhpcyA9PT0gV3JhcHBlciA/ICRQcm9taXNlIDogdGhpcywgeCk7XG4gIH1cbn0pO1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKFVTRV9OQVRJVkUgJiYgcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKShmdW5jdGlvbiAoaXRlcikge1xuICAkUHJvbWlzZS5hbGwoaXRlcilbJ2NhdGNoJ10oZW1wdHkpO1xufSkpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC4xIFByb21pc2UuYWxsKGl0ZXJhYmxlKVxuICBhbGw6IGZ1bmN0aW9uIGFsbChpdGVyYWJsZSkge1xuICAgIHZhciBDID0gdGhpcztcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KEMpO1xuICAgIHZhciByZXNvbHZlID0gY2FwYWJpbGl0eS5yZXNvbHZlO1xuICAgIHZhciByZWplY3QgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICB2YXIgcmVzdWx0ID0gcGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsdWVzID0gW107XG4gICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgdmFyIHJlbWFpbmluZyA9IDE7XG4gICAgICBmb3JPZihpdGVyYWJsZSwgZmFsc2UsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgIHZhciAkaW5kZXggPSBpbmRleCsrO1xuICAgICAgICB2YXIgYWxyZWFkeUNhbGxlZCA9IGZhbHNlO1xuICAgICAgICB2YWx1ZXMucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICByZW1haW5pbmcrKztcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgaWYgKGFscmVhZHlDYWxsZWQpIHJldHVybjtcbiAgICAgICAgICBhbHJlYWR5Q2FsbGVkID0gdHJ1ZTtcbiAgICAgICAgICB2YWx1ZXNbJGluZGV4XSA9IHZhbHVlO1xuICAgICAgICAgIC0tcmVtYWluaW5nIHx8IHJlc29sdmUodmFsdWVzKTtcbiAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgICAgLS1yZW1haW5pbmcgfHwgcmVzb2x2ZSh2YWx1ZXMpO1xuICAgIH0pO1xuICAgIGlmIChyZXN1bHQuZSkgcmVqZWN0KHJlc3VsdC52KTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9LFxuICAvLyAyNS40LjQuNCBQcm9taXNlLnJhY2UoaXRlcmFibGUpXG4gIHJhY2U6IGZ1bmN0aW9uIHJhY2UoaXRlcmFibGUpIHtcbiAgICB2YXIgQyA9IHRoaXM7XG4gICAgdmFyIGNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgICB2YXIgcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgdmFyIHJlc3VsdCA9IHBlcmZvcm0oZnVuY3Rpb24gKCkge1xuICAgICAgZm9yT2YoaXRlcmFibGUsIGZhbHNlLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICBDLnJlc29sdmUocHJvbWlzZSkudGhlbihjYXBhYmlsaXR5LnJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpZiAocmVzdWx0LmUpIHJlamVjdChyZXN1bHQudik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4iLCIvLyAyNi4xLjEgUmVmbGVjdC5hcHBseSh0YXJnZXQsIHRoaXNBcmd1bWVudCwgYXJndW1lbnRzTGlzdClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgckFwcGx5ID0gKHJlcXVpcmUoJy4vX2dsb2JhbCcpLlJlZmxlY3QgfHwge30pLmFwcGx5O1xudmFyIGZBcHBseSA9IEZ1bmN0aW9uLmFwcGx5O1xuLy8gTVMgRWRnZSBhcmd1bWVudHNMaXN0IGFyZ3VtZW50IGlzIG9wdGlvbmFsXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgckFwcGx5KGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfSk7XG59KSwgJ1JlZmxlY3QnLCB7XG4gIGFwcGx5OiBmdW5jdGlvbiBhcHBseSh0YXJnZXQsIHRoaXNBcmd1bWVudCwgYXJndW1lbnRzTGlzdCkge1xuICAgIHZhciBUID0gYUZ1bmN0aW9uKHRhcmdldCk7XG4gICAgdmFyIEwgPSBhbk9iamVjdChhcmd1bWVudHNMaXN0KTtcbiAgICByZXR1cm4gckFwcGx5ID8gckFwcGx5KFQsIHRoaXNBcmd1bWVudCwgTCkgOiBmQXBwbHkuY2FsbChULCB0aGlzQXJndW1lbnQsIEwpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuMiBSZWZsZWN0LmNvbnN0cnVjdCh0YXJnZXQsIGFyZ3VtZW50c0xpc3QgWywgbmV3VGFyZ2V0XSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGJpbmQgPSByZXF1aXJlKCcuL19iaW5kJyk7XG52YXIgckNvbnN0cnVjdCA9IChyZXF1aXJlKCcuL19nbG9iYWwnKS5SZWZsZWN0IHx8IHt9KS5jb25zdHJ1Y3Q7XG5cbi8vIE1TIEVkZ2Ugc3VwcG9ydHMgb25seSAyIGFyZ3VtZW50cyBhbmQgYXJndW1lbnRzTGlzdCBhcmd1bWVudCBpcyBvcHRpb25hbFxuLy8gRkYgTmlnaHRseSBzZXRzIHRoaXJkIGFyZ3VtZW50IGFzIGBuZXcudGFyZ2V0YCwgYnV0IGRvZXMgbm90IGNyZWF0ZSBgdGhpc2AgZnJvbSBpdFxudmFyIE5FV19UQVJHRVRfQlVHID0gZmFpbHMoZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBGKCkgeyAvKiBlbXB0eSAqLyB9XG4gIHJldHVybiAhKHJDb25zdHJ1Y3QoZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9LCBbXSwgRikgaW5zdGFuY2VvZiBGKTtcbn0pO1xudmFyIEFSR1NfQlVHID0gIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgckNvbnN0cnVjdChmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH0pO1xufSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKE5FV19UQVJHRVRfQlVHIHx8IEFSR1NfQlVHKSwgJ1JlZmxlY3QnLCB7XG4gIGNvbnN0cnVjdDogZnVuY3Rpb24gY29uc3RydWN0KFRhcmdldCwgYXJncyAvKiAsIG5ld1RhcmdldCAqLykge1xuICAgIGFGdW5jdGlvbihUYXJnZXQpO1xuICAgIGFuT2JqZWN0KGFyZ3MpO1xuICAgIHZhciBuZXdUYXJnZXQgPSBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IFRhcmdldCA6IGFGdW5jdGlvbihhcmd1bWVudHNbMl0pO1xuICAgIGlmIChBUkdTX0JVRyAmJiAhTkVXX1RBUkdFVF9CVUcpIHJldHVybiByQ29uc3RydWN0KFRhcmdldCwgYXJncywgbmV3VGFyZ2V0KTtcbiAgICBpZiAoVGFyZ2V0ID09IG5ld1RhcmdldCkge1xuICAgICAgLy8gdy9vIGFsdGVyZWQgbmV3VGFyZ2V0LCBvcHRpbWl6YXRpb24gZm9yIDAtNCBhcmd1bWVudHNcbiAgICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSAwOiByZXR1cm4gbmV3IFRhcmdldCgpO1xuICAgICAgICBjYXNlIDE6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0pO1xuICAgICAgICBjYXNlIDI6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgICBjYXNlIDM6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICBjYXNlIDQ6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICAgICAgfVxuICAgICAgLy8gdy9vIGFsdGVyZWQgbmV3VGFyZ2V0LCBsb3Qgb2YgYXJndW1lbnRzIGNhc2VcbiAgICAgIHZhciAkYXJncyA9IFtudWxsXTtcbiAgICAgICRhcmdzLnB1c2guYXBwbHkoJGFyZ3MsIGFyZ3MpO1xuICAgICAgcmV0dXJuIG5ldyAoYmluZC5hcHBseShUYXJnZXQsICRhcmdzKSkoKTtcbiAgICB9XG4gICAgLy8gd2l0aCBhbHRlcmVkIG5ld1RhcmdldCwgbm90IHN1cHBvcnQgYnVpbHQtaW4gY29uc3RydWN0b3JzXG4gICAgdmFyIHByb3RvID0gbmV3VGFyZ2V0LnByb3RvdHlwZTtcbiAgICB2YXIgaW5zdGFuY2UgPSBjcmVhdGUoaXNPYmplY3QocHJvdG8pID8gcHJvdG8gOiBPYmplY3QucHJvdG90eXBlKTtcbiAgICB2YXIgcmVzdWx0ID0gRnVuY3Rpb24uYXBwbHkuY2FsbChUYXJnZXQsIGluc3RhbmNlLCBhcmdzKTtcbiAgICByZXR1cm4gaXNPYmplY3QocmVzdWx0KSA/IHJlc3VsdCA6IGluc3RhbmNlO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuMyBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpXG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xuXG4vLyBNUyBFZGdlIGhhcyBicm9rZW4gUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSAtIHRocm93aW5nIGluc3RlYWQgb2YgcmV0dXJuaW5nIGZhbHNlXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eShkUC5mKHt9LCAxLCB7IHZhbHVlOiAxIH0pLCAxLCB7IHZhbHVlOiAyIH0pO1xufSksICdSZWZsZWN0Jywge1xuICBkZWZpbmVQcm9wZXJ0eTogZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwgYXR0cmlidXRlcykge1xuICAgIGFuT2JqZWN0KHRhcmdldCk7XG4gICAgcHJvcGVydHlLZXkgPSB0b1ByaW1pdGl2ZShwcm9wZXJ0eUtleSwgdHJ1ZSk7XG4gICAgYW5PYmplY3QoYXR0cmlidXRlcyk7XG4gICAgdHJ5IHtcbiAgICAgIGRQLmYodGFyZ2V0LCBwcm9wZXJ0eUtleSwgYXR0cmlidXRlcyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG59KTtcbiIsIi8vIDI2LjEuNCBSZWZsZWN0LmRlbGV0ZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXkpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpLmY7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xuICBkZWxldGVQcm9wZXJ0eTogZnVuY3Rpb24gZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgIHZhciBkZXNjID0gZ09QRChhbk9iamVjdCh0YXJnZXQpLCBwcm9wZXJ0eUtleSk7XG4gICAgcmV0dXJuIGRlc2MgJiYgIWRlc2MuY29uZmlndXJhYmxlID8gZmFsc2UgOiBkZWxldGUgdGFyZ2V0W3Byb3BlcnR5S2V5XTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyAyNi4xLjUgUmVmbGVjdC5lbnVtZXJhdGUodGFyZ2V0KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIEVudW1lcmF0ZSA9IGZ1bmN0aW9uIChpdGVyYXRlZCkge1xuICB0aGlzLl90ID0gYW5PYmplY3QoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgICAgLy8gbmV4dCBpbmRleFxuICB2YXIga2V5cyA9IHRoaXMuX2sgPSBbXTsgICAgICAvLyBrZXlzXG4gIHZhciBrZXk7XG4gIGZvciAoa2V5IGluIGl0ZXJhdGVkKSBrZXlzLnB1c2goa2V5KTtcbn07XG5yZXF1aXJlKCcuL19pdGVyLWNyZWF0ZScpKEVudW1lcmF0ZSwgJ09iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuICB2YXIga2V5cyA9IHRoYXQuX2s7XG4gIHZhciBrZXk7XG4gIGRvIHtcbiAgICBpZiAodGhhdC5faSA+PSBrZXlzLmxlbmd0aCkgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICB9IHdoaWxlICghKChrZXkgPSBrZXlzW3RoYXQuX2krK10pIGluIHRoYXQuX3QpKTtcbiAgcmV0dXJuIHsgdmFsdWU6IGtleSwgZG9uZTogZmFsc2UgfTtcbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIGVudW1lcmF0ZTogZnVuY3Rpb24gZW51bWVyYXRlKHRhcmdldCkge1xuICAgIHJldHVybiBuZXcgRW51bWVyYXRlKHRhcmdldCk7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS43IFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcGVydHlLZXkpXG52YXIgZ09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgIHJldHVybiBnT1BELmYoYW5PYmplY3QodGFyZ2V0KSwgcHJvcGVydHlLZXkpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuOCBSZWZsZWN0LmdldFByb3RvdHlwZU9mKHRhcmdldClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgZ2V0UHJvdG8gPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xuICBnZXRQcm90b3R5cGVPZjogZnVuY3Rpb24gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSB7XG4gICAgcmV0dXJuIGdldFByb3RvKGFuT2JqZWN0KHRhcmdldCkpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuNiBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3BlcnR5S2V5IFssIHJlY2VpdmVyXSlcbnZhciBnT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKTtcbnZhciBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xuXG5mdW5jdGlvbiBnZXQodGFyZ2V0LCBwcm9wZXJ0eUtleSAvKiAsIHJlY2VpdmVyICovKSB7XG4gIHZhciByZWNlaXZlciA9IGFyZ3VtZW50cy5sZW5ndGggPCAzID8gdGFyZ2V0IDogYXJndW1lbnRzWzJdO1xuICB2YXIgZGVzYywgcHJvdG87XG4gIGlmIChhbk9iamVjdCh0YXJnZXQpID09PSByZWNlaXZlcikgcmV0dXJuIHRhcmdldFtwcm9wZXJ0eUtleV07XG4gIGlmIChkZXNjID0gZ09QRC5mKHRhcmdldCwgcHJvcGVydHlLZXkpKSByZXR1cm4gaGFzKGRlc2MsICd2YWx1ZScpXG4gICAgPyBkZXNjLnZhbHVlXG4gICAgOiBkZXNjLmdldCAhPT0gdW5kZWZpbmVkXG4gICAgICA/IGRlc2MuZ2V0LmNhbGwocmVjZWl2ZXIpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKGlzT2JqZWN0KHByb3RvID0gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSkpIHJldHVybiBnZXQocHJvdG8sIHByb3BlcnR5S2V5LCByZWNlaXZlcik7XG59XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHsgZ2V0OiBnZXQgfSk7XG4iLCIvLyAyNi4xLjkgUmVmbGVjdC5oYXModGFyZ2V0LCBwcm9wZXJ0eUtleSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgaGFzOiBmdW5jdGlvbiBoYXModGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgIHJldHVybiBwcm9wZXJ0eUtleSBpbiB0YXJnZXQ7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xMCBSZWZsZWN0LmlzRXh0ZW5zaWJsZSh0YXJnZXQpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgJGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGU7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgaXNFeHRlbnNpYmxlOiBmdW5jdGlvbiBpc0V4dGVuc2libGUodGFyZ2V0KSB7XG4gICAgYW5PYmplY3QodGFyZ2V0KTtcbiAgICByZXR1cm4gJGlzRXh0ZW5zaWJsZSA/ICRpc0V4dGVuc2libGUodGFyZ2V0KSA6IHRydWU7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xMSBSZWZsZWN0Lm93bktleXModGFyZ2V0KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0JywgeyBvd25LZXlzOiByZXF1aXJlKCcuL19vd24ta2V5cycpIH0pO1xuIiwiLy8gMjYuMS4xMiBSZWZsZWN0LnByZXZlbnRFeHRlbnNpb25zKHRhcmdldClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciAkcHJldmVudEV4dGVuc2lvbnMgPSBPYmplY3QucHJldmVudEV4dGVuc2lvbnM7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgcHJldmVudEV4dGVuc2lvbnM6IGZ1bmN0aW9uIHByZXZlbnRFeHRlbnNpb25zKHRhcmdldCkge1xuICAgIGFuT2JqZWN0KHRhcmdldCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmICgkcHJldmVudEV4dGVuc2lvbnMpICRwcmV2ZW50RXh0ZW5zaW9ucyh0YXJnZXQpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxufSk7XG4iLCIvLyAyNi4xLjE0IFJlZmxlY3Quc2V0UHJvdG90eXBlT2YodGFyZ2V0LCBwcm90bylcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgc2V0UHJvdG8gPSByZXF1aXJlKCcuL19zZXQtcHJvdG8nKTtcblxuaWYgKHNldFByb3RvKSAkZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIHNldFByb3RvdHlwZU9mOiBmdW5jdGlvbiBzZXRQcm90b3R5cGVPZih0YXJnZXQsIHByb3RvKSB7XG4gICAgc2V0UHJvdG8uY2hlY2sodGFyZ2V0LCBwcm90byk7XG4gICAgdHJ5IHtcbiAgICAgIHNldFByb3RvLnNldCh0YXJnZXQsIHByb3RvKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xMyBSZWZsZWN0LnNldCh0YXJnZXQsIHByb3BlcnR5S2V5LCBWIFssIHJlY2VpdmVyXSlcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyIGdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxuZnVuY3Rpb24gc2V0KHRhcmdldCwgcHJvcGVydHlLZXksIFYgLyogLCByZWNlaXZlciAqLykge1xuICB2YXIgcmVjZWl2ZXIgPSBhcmd1bWVudHMubGVuZ3RoIDwgNCA/IHRhcmdldCA6IGFyZ3VtZW50c1szXTtcbiAgdmFyIG93bkRlc2MgPSBnT1BELmYoYW5PYmplY3QodGFyZ2V0KSwgcHJvcGVydHlLZXkpO1xuICB2YXIgZXhpc3RpbmdEZXNjcmlwdG9yLCBwcm90bztcbiAgaWYgKCFvd25EZXNjKSB7XG4gICAgaWYgKGlzT2JqZWN0KHByb3RvID0gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSkpIHtcbiAgICAgIHJldHVybiBzZXQocHJvdG8sIHByb3BlcnR5S2V5LCBWLCByZWNlaXZlcik7XG4gICAgfVxuICAgIG93bkRlc2MgPSBjcmVhdGVEZXNjKDApO1xuICB9XG4gIGlmIChoYXMob3duRGVzYywgJ3ZhbHVlJykpIHtcbiAgICBpZiAob3duRGVzYy53cml0YWJsZSA9PT0gZmFsc2UgfHwgIWlzT2JqZWN0KHJlY2VpdmVyKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChleGlzdGluZ0Rlc2NyaXB0b3IgPSBnT1BELmYocmVjZWl2ZXIsIHByb3BlcnR5S2V5KSkge1xuICAgICAgaWYgKGV4aXN0aW5nRGVzY3JpcHRvci5nZXQgfHwgZXhpc3RpbmdEZXNjcmlwdG9yLnNldCB8fCBleGlzdGluZ0Rlc2NyaXB0b3Iud3JpdGFibGUgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gICAgICBleGlzdGluZ0Rlc2NyaXB0b3IudmFsdWUgPSBWO1xuICAgICAgZFAuZihyZWNlaXZlciwgcHJvcGVydHlLZXksIGV4aXN0aW5nRGVzY3JpcHRvcik7XG4gICAgfSBlbHNlIGRQLmYocmVjZWl2ZXIsIHByb3BlcnR5S2V5LCBjcmVhdGVEZXNjKDAsIFYpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gb3duRGVzYy5zZXQgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogKG93bkRlc2Muc2V0LmNhbGwocmVjZWl2ZXIsIFYpLCB0cnVlKTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0JywgeyBzZXQ6IHNldCB9KTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBpbmhlcml0SWZSZXF1aXJlZCA9IHJlcXVpcmUoJy4vX2luaGVyaXQtaWYtcmVxdWlyZWQnKTtcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmY7XG52YXIgZ09QTiA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZjtcbnZhciBpc1JlZ0V4cCA9IHJlcXVpcmUoJy4vX2lzLXJlZ2V4cCcpO1xudmFyICRmbGFncyA9IHJlcXVpcmUoJy4vX2ZsYWdzJyk7XG52YXIgJFJlZ0V4cCA9IGdsb2JhbC5SZWdFeHA7XG52YXIgQmFzZSA9ICRSZWdFeHA7XG52YXIgcHJvdG8gPSAkUmVnRXhwLnByb3RvdHlwZTtcbnZhciByZTEgPSAvYS9nO1xudmFyIHJlMiA9IC9hL2c7XG4vLyBcIm5ld1wiIGNyZWF0ZXMgYSBuZXcgb2JqZWN0LCBvbGQgd2Via2l0IGJ1Z2d5IGhlcmVcbnZhciBDT1JSRUNUX05FVyA9IG5ldyAkUmVnRXhwKHJlMSkgIT09IHJlMTtcblxuaWYgKHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgKCFDT1JSRUNUX05FVyB8fCByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmUyW3JlcXVpcmUoJy4vX3drcycpKCdtYXRjaCcpXSA9IGZhbHNlO1xuICAvLyBSZWdFeHAgY29uc3RydWN0b3IgY2FuIGFsdGVyIGZsYWdzIGFuZCBJc1JlZ0V4cCB3b3JrcyBjb3JyZWN0IHdpdGggQEBtYXRjaFxuICByZXR1cm4gJFJlZ0V4cChyZTEpICE9IHJlMSB8fCAkUmVnRXhwKHJlMikgPT0gcmUyIHx8ICRSZWdFeHAocmUxLCAnaScpICE9ICcvYS9pJztcbn0pKSkge1xuICAkUmVnRXhwID0gZnVuY3Rpb24gUmVnRXhwKHAsIGYpIHtcbiAgICB2YXIgdGlSRSA9IHRoaXMgaW5zdGFuY2VvZiAkUmVnRXhwO1xuICAgIHZhciBwaVJFID0gaXNSZWdFeHAocCk7XG4gICAgdmFyIGZpVSA9IGYgPT09IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gIXRpUkUgJiYgcGlSRSAmJiBwLmNvbnN0cnVjdG9yID09PSAkUmVnRXhwICYmIGZpVSA/IHBcbiAgICAgIDogaW5oZXJpdElmUmVxdWlyZWQoQ09SUkVDVF9ORVdcbiAgICAgICAgPyBuZXcgQmFzZShwaVJFICYmICFmaVUgPyBwLnNvdXJjZSA6IHAsIGYpXG4gICAgICAgIDogQmFzZSgocGlSRSA9IHAgaW5zdGFuY2VvZiAkUmVnRXhwKSA/IHAuc291cmNlIDogcCwgcGlSRSAmJiBmaVUgPyAkZmxhZ3MuY2FsbChwKSA6IGYpXG4gICAgICAsIHRpUkUgPyB0aGlzIDogcHJvdG8sICRSZWdFeHApO1xuICB9O1xuICB2YXIgcHJveHkgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAga2V5IGluICRSZWdFeHAgfHwgZFAoJFJlZ0V4cCwga2V5LCB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIEJhc2Vba2V5XTsgfSxcbiAgICAgIHNldDogZnVuY3Rpb24gKGl0KSB7IEJhc2Vba2V5XSA9IGl0OyB9XG4gICAgfSk7XG4gIH07XG4gIGZvciAodmFyIGtleXMgPSBnT1BOKEJhc2UpLCBpID0gMDsga2V5cy5sZW5ndGggPiBpOykgcHJveHkoa2V5c1tpKytdKTtcbiAgcHJvdG8uY29uc3RydWN0b3IgPSAkUmVnRXhwO1xuICAkUmVnRXhwLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKGdsb2JhbCwgJ1JlZ0V4cCcsICRSZWdFeHApO1xufVxuXG5yZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKCdSZWdFeHAnKTtcbiIsIi8vIDIxLjIuNS4zIGdldCBSZWdFeHAucHJvdG90eXBlLmZsYWdzKClcbmlmIChyZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpICYmIC8uL2cuZmxhZ3MgIT0gJ2cnKSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mKFJlZ0V4cC5wcm90b3R5cGUsICdmbGFncycsIHtcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBnZXQ6IHJlcXVpcmUoJy4vX2ZsYWdzJylcbn0pO1xuIiwiLy8gQEBtYXRjaCBsb2dpY1xucmVxdWlyZSgnLi9fZml4LXJlLXdrcycpKCdtYXRjaCcsIDEsIGZ1bmN0aW9uIChkZWZpbmVkLCBNQVRDSCwgJG1hdGNoKSB7XG4gIC8vIDIxLjEuMy4xMSBTdHJpbmcucHJvdG90eXBlLm1hdGNoKHJlZ2V4cClcbiAgcmV0dXJuIFtmdW5jdGlvbiBtYXRjaChyZWdleHApIHtcbiAgICAndXNlIHN0cmljdCc7XG4gICAgdmFyIE8gPSBkZWZpbmVkKHRoaXMpO1xuICAgIHZhciBmbiA9IHJlZ2V4cCA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiByZWdleHBbTUFUQ0hdO1xuICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkID8gZm4uY2FsbChyZWdleHAsIE8pIDogbmV3IFJlZ0V4cChyZWdleHApW01BVENIXShTdHJpbmcoTykpO1xuICB9LCAkbWF0Y2hdO1xufSk7XG4iLCIvLyBAQHJlcGxhY2UgbG9naWNcbnJlcXVpcmUoJy4vX2ZpeC1yZS13a3MnKSgncmVwbGFjZScsIDIsIGZ1bmN0aW9uIChkZWZpbmVkLCBSRVBMQUNFLCAkcmVwbGFjZSkge1xuICAvLyAyMS4xLjMuMTQgU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlKHNlYXJjaFZhbHVlLCByZXBsYWNlVmFsdWUpXG4gIHJldHVybiBbZnVuY3Rpb24gcmVwbGFjZShzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuICAgIHZhciBPID0gZGVmaW5lZCh0aGlzKTtcbiAgICB2YXIgZm4gPSBzZWFyY2hWYWx1ZSA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBzZWFyY2hWYWx1ZVtSRVBMQUNFXTtcbiAgICByZXR1cm4gZm4gIT09IHVuZGVmaW5lZFxuICAgICAgPyBmbi5jYWxsKHNlYXJjaFZhbHVlLCBPLCByZXBsYWNlVmFsdWUpXG4gICAgICA6ICRyZXBsYWNlLmNhbGwoU3RyaW5nKE8pLCBzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKTtcbiAgfSwgJHJlcGxhY2VdO1xufSk7XG4iLCIvLyBAQHNlYXJjaCBsb2dpY1xucmVxdWlyZSgnLi9fZml4LXJlLXdrcycpKCdzZWFyY2gnLCAxLCBmdW5jdGlvbiAoZGVmaW5lZCwgU0VBUkNILCAkc2VhcmNoKSB7XG4gIC8vIDIxLjEuMy4xNSBTdHJpbmcucHJvdG90eXBlLnNlYXJjaChyZWdleHApXG4gIHJldHVybiBbZnVuY3Rpb24gc2VhcmNoKHJlZ2V4cCkge1xuICAgICd1c2Ugc3RyaWN0JztcbiAgICB2YXIgTyA9IGRlZmluZWQodGhpcyk7XG4gICAgdmFyIGZuID0gcmVnZXhwID09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHJlZ2V4cFtTRUFSQ0hdO1xuICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkID8gZm4uY2FsbChyZWdleHAsIE8pIDogbmV3IFJlZ0V4cChyZWdleHApW1NFQVJDSF0oU3RyaW5nKE8pKTtcbiAgfSwgJHNlYXJjaF07XG59KTtcbiIsIi8vIEBAc3BsaXQgbG9naWNcbnJlcXVpcmUoJy4vX2ZpeC1yZS13a3MnKSgnc3BsaXQnLCAyLCBmdW5jdGlvbiAoZGVmaW5lZCwgU1BMSVQsICRzcGxpdCkge1xuICAndXNlIHN0cmljdCc7XG4gIHZhciBpc1JlZ0V4cCA9IHJlcXVpcmUoJy4vX2lzLXJlZ2V4cCcpO1xuICB2YXIgX3NwbGl0ID0gJHNwbGl0O1xuICB2YXIgJHB1c2ggPSBbXS5wdXNoO1xuICB2YXIgJFNQTElUID0gJ3NwbGl0JztcbiAgdmFyIExFTkdUSCA9ICdsZW5ndGgnO1xuICB2YXIgTEFTVF9JTkRFWCA9ICdsYXN0SW5kZXgnO1xuICBpZiAoXG4gICAgJ2FiYmMnWyRTUExJVF0oLyhiKSovKVsxXSA9PSAnYycgfHxcbiAgICAndGVzdCdbJFNQTElUXSgvKD86KS8sIC0xKVtMRU5HVEhdICE9IDQgfHxcbiAgICAnYWInWyRTUExJVF0oLyg/OmFiKSovKVtMRU5HVEhdICE9IDIgfHxcbiAgICAnLidbJFNQTElUXSgvKC4/KSguPykvKVtMRU5HVEhdICE9IDQgfHxcbiAgICAnLidbJFNQTElUXSgvKCkoKS8pW0xFTkdUSF0gPiAxIHx8XG4gICAgJydbJFNQTElUXSgvLj8vKVtMRU5HVEhdXG4gICkge1xuICAgIHZhciBOUENHID0gLygpPz8vLmV4ZWMoJycpWzFdID09PSB1bmRlZmluZWQ7IC8vIG5vbnBhcnRpY2lwYXRpbmcgY2FwdHVyaW5nIGdyb3VwXG4gICAgLy8gYmFzZWQgb24gZXM1LXNoaW0gaW1wbGVtZW50YXRpb24sIG5lZWQgdG8gcmV3b3JrIGl0XG4gICAgJHNwbGl0ID0gZnVuY3Rpb24gKHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgIHZhciBzdHJpbmcgPSBTdHJpbmcodGhpcyk7XG4gICAgICBpZiAoc2VwYXJhdG9yID09PSB1bmRlZmluZWQgJiYgbGltaXQgPT09IDApIHJldHVybiBbXTtcbiAgICAgIC8vIElmIGBzZXBhcmF0b3JgIGlzIG5vdCBhIHJlZ2V4LCB1c2UgbmF0aXZlIHNwbGl0XG4gICAgICBpZiAoIWlzUmVnRXhwKHNlcGFyYXRvcikpIHJldHVybiBfc3BsaXQuY2FsbChzdHJpbmcsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgICAgdmFyIG91dHB1dCA9IFtdO1xuICAgICAgdmFyIGZsYWdzID0gKHNlcGFyYXRvci5pZ25vcmVDYXNlID8gJ2knIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IubXVsdGlsaW5lID8gJ20nIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IudW5pY29kZSA/ICd1JyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAoc2VwYXJhdG9yLnN0aWNreSA/ICd5JyA6ICcnKTtcbiAgICAgIHZhciBsYXN0TGFzdEluZGV4ID0gMDtcbiAgICAgIHZhciBzcGxpdExpbWl0ID0gbGltaXQgPT09IHVuZGVmaW5lZCA/IDQyOTQ5NjcyOTUgOiBsaW1pdCA+Pj4gMDtcbiAgICAgIC8vIE1ha2UgYGdsb2JhbGAgYW5kIGF2b2lkIGBsYXN0SW5kZXhgIGlzc3VlcyBieSB3b3JraW5nIHdpdGggYSBjb3B5XG4gICAgICB2YXIgc2VwYXJhdG9yQ29weSA9IG5ldyBSZWdFeHAoc2VwYXJhdG9yLnNvdXJjZSwgZmxhZ3MgKyAnZycpO1xuICAgICAgdmFyIHNlcGFyYXRvcjIsIG1hdGNoLCBsYXN0SW5kZXgsIGxhc3RMZW5ndGgsIGk7XG4gICAgICAvLyBEb2Vzbid0IG5lZWQgZmxhZ3MgZ3ksIGJ1dCB0aGV5IGRvbid0IGh1cnRcbiAgICAgIGlmICghTlBDRykgc2VwYXJhdG9yMiA9IG5ldyBSZWdFeHAoJ14nICsgc2VwYXJhdG9yQ29weS5zb3VyY2UgKyAnJCg/IVxcXFxzKScsIGZsYWdzKTtcbiAgICAgIHdoaWxlIChtYXRjaCA9IHNlcGFyYXRvckNvcHkuZXhlYyhzdHJpbmcpKSB7XG4gICAgICAgIC8vIGBzZXBhcmF0b3JDb3B5Lmxhc3RJbmRleGAgaXMgbm90IHJlbGlhYmxlIGNyb3NzLWJyb3dzZXJcbiAgICAgICAgbGFzdEluZGV4ID0gbWF0Y2guaW5kZXggKyBtYXRjaFswXVtMRU5HVEhdO1xuICAgICAgICBpZiAobGFzdEluZGV4ID4gbGFzdExhc3RJbmRleCkge1xuICAgICAgICAgIG91dHB1dC5wdXNoKHN0cmluZy5zbGljZShsYXN0TGFzdEluZGV4LCBtYXRjaC5pbmRleCkpO1xuICAgICAgICAgIC8vIEZpeCBicm93c2VycyB3aG9zZSBgZXhlY2AgbWV0aG9kcyBkb24ndCBjb25zaXN0ZW50bHkgcmV0dXJuIGB1bmRlZmluZWRgIGZvciBOUENHXG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWxvb3AtZnVuY1xuICAgICAgICAgIGlmICghTlBDRyAmJiBtYXRjaFtMRU5HVEhdID4gMSkgbWF0Y2hbMF0ucmVwbGFjZShzZXBhcmF0b3IyLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgYXJndW1lbnRzW0xFTkdUSF0gLSAyOyBpKyspIGlmIChhcmd1bWVudHNbaV0gPT09IHVuZGVmaW5lZCkgbWF0Y2hbaV0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKG1hdGNoW0xFTkdUSF0gPiAxICYmIG1hdGNoLmluZGV4IDwgc3RyaW5nW0xFTkdUSF0pICRwdXNoLmFwcGx5KG91dHB1dCwgbWF0Y2guc2xpY2UoMSkpO1xuICAgICAgICAgIGxhc3RMZW5ndGggPSBtYXRjaFswXVtMRU5HVEhdO1xuICAgICAgICAgIGxhc3RMYXN0SW5kZXggPSBsYXN0SW5kZXg7XG4gICAgICAgICAgaWYgKG91dHB1dFtMRU5HVEhdID49IHNwbGl0TGltaXQpIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZXBhcmF0b3JDb3B5W0xBU1RfSU5ERVhdID09PSBtYXRjaC5pbmRleCkgc2VwYXJhdG9yQ29weVtMQVNUX0lOREVYXSsrOyAvLyBBdm9pZCBhbiBpbmZpbml0ZSBsb29wXG4gICAgICB9XG4gICAgICBpZiAobGFzdExhc3RJbmRleCA9PT0gc3RyaW5nW0xFTkdUSF0pIHtcbiAgICAgICAgaWYgKGxhc3RMZW5ndGggfHwgIXNlcGFyYXRvckNvcHkudGVzdCgnJykpIG91dHB1dC5wdXNoKCcnKTtcbiAgICAgIH0gZWxzZSBvdXRwdXQucHVzaChzdHJpbmcuc2xpY2UobGFzdExhc3RJbmRleCkpO1xuICAgICAgcmV0dXJuIG91dHB1dFtMRU5HVEhdID4gc3BsaXRMaW1pdCA/IG91dHB1dC5zbGljZSgwLCBzcGxpdExpbWl0KSA6IG91dHB1dDtcbiAgICB9O1xuICAvLyBDaGFrcmEsIFY4XG4gIH0gZWxzZSBpZiAoJzAnWyRTUExJVF0odW5kZWZpbmVkLCAwKVtMRU5HVEhdKSB7XG4gICAgJHNwbGl0ID0gZnVuY3Rpb24gKHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgIHJldHVybiBzZXBhcmF0b3IgPT09IHVuZGVmaW5lZCAmJiBsaW1pdCA9PT0gMCA/IFtdIDogX3NwbGl0LmNhbGwodGhpcywgc2VwYXJhdG9yLCBsaW1pdCk7XG4gICAgfTtcbiAgfVxuICAvLyAyMS4xLjMuMTcgU3RyaW5nLnByb3RvdHlwZS5zcGxpdChzZXBhcmF0b3IsIGxpbWl0KVxuICByZXR1cm4gW2Z1bmN0aW9uIHNwbGl0KHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICB2YXIgTyA9IGRlZmluZWQodGhpcyk7XG4gICAgdmFyIGZuID0gc2VwYXJhdG9yID09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHNlcGFyYXRvcltTUExJVF07XG4gICAgcmV0dXJuIGZuICE9PSB1bmRlZmluZWQgPyBmbi5jYWxsKHNlcGFyYXRvciwgTywgbGltaXQpIDogJHNwbGl0LmNhbGwoU3RyaW5nKE8pLCBzZXBhcmF0b3IsIGxpbWl0KTtcbiAgfSwgJHNwbGl0XTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xucmVxdWlyZSgnLi9lczYucmVnZXhwLmZsYWdzJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciAkZmxhZ3MgPSByZXF1aXJlKCcuL19mbGFncycpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciBUT19TVFJJTkcgPSAndG9TdHJpbmcnO1xudmFyICR0b1N0cmluZyA9IC8uL1tUT19TVFJJTkddO1xuXG52YXIgZGVmaW5lID0gZnVuY3Rpb24gKGZuKSB7XG4gIHJlcXVpcmUoJy4vX3JlZGVmaW5lJykoUmVnRXhwLnByb3RvdHlwZSwgVE9fU1RSSU5HLCBmbiwgdHJ1ZSk7XG59O1xuXG4vLyAyMS4yLjUuMTQgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZygpXG5pZiAocmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7IHJldHVybiAkdG9TdHJpbmcuY2FsbCh7IHNvdXJjZTogJ2EnLCBmbGFnczogJ2InIH0pICE9ICcvYS9iJzsgfSkpIHtcbiAgZGVmaW5lKGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHZhciBSID0gYW5PYmplY3QodGhpcyk7XG4gICAgcmV0dXJuICcvJy5jb25jYXQoUi5zb3VyY2UsICcvJyxcbiAgICAgICdmbGFncycgaW4gUiA/IFIuZmxhZ3MgOiAhREVTQ1JJUFRPUlMgJiYgUiBpbnN0YW5jZW9mIFJlZ0V4cCA/ICRmbGFncy5jYWxsKFIpIDogdW5kZWZpbmVkKTtcbiAgfSk7XG4vLyBGRjQ0LSBSZWdFeHAjdG9TdHJpbmcgaGFzIGEgd3JvbmcgbmFtZVxufSBlbHNlIGlmICgkdG9TdHJpbmcubmFtZSAhPSBUT19TVFJJTkcpIHtcbiAgZGVmaW5lKGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiAkdG9TdHJpbmcuY2FsbCh0aGlzKTtcbiAgfSk7XG59XG4iLCIndXNlIHN0cmljdCc7XG52YXIgc3Ryb25nID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbi1zdHJvbmcnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBTRVQgPSAnU2V0JztcblxuLy8gMjMuMiBTZXQgT2JqZWN0c1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uJykoU0VULCBmdW5jdGlvbiAoZ2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBTZXQoKSB7IHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpOyB9O1xufSwge1xuICAvLyAyMy4yLjMuMSBTZXQucHJvdG90eXBlLmFkZCh2YWx1ZSlcbiAgYWRkOiBmdW5jdGlvbiBhZGQodmFsdWUpIHtcbiAgICByZXR1cm4gc3Ryb25nLmRlZih2YWxpZGF0ZSh0aGlzLCBTRVQpLCB2YWx1ZSA9IHZhbHVlID09PSAwID8gMCA6IHZhbHVlLCB2YWx1ZSk7XG4gIH1cbn0sIHN0cm9uZyk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4yIFN0cmluZy5wcm90b3R5cGUuYW5jaG9yKG5hbWUpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdhbmNob3InLCBmdW5jdGlvbiAoY3JlYXRlSFRNTCkge1xuICByZXR1cm4gZnVuY3Rpb24gYW5jaG9yKG5hbWUpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYScsICduYW1lJywgbmFtZSk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjMgU3RyaW5nLnByb3RvdHlwZS5iaWcoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnYmlnJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGJpZygpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYmlnJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuNCBTdHJpbmcucHJvdG90eXBlLmJsaW5rKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2JsaW5rJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGJsaW5rKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdibGluaycsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjUgU3RyaW5nLnByb3RvdHlwZS5ib2xkKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2JvbGQnLCBmdW5jdGlvbiAoY3JlYXRlSFRNTCkge1xuICByZXR1cm4gZnVuY3Rpb24gYm9sZCgpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYicsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGF0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLWF0JykoZmFsc2UpO1xuJGV4cG9ydCgkZXhwb3J0LlAsICdTdHJpbmcnLCB7XG4gIC8vIDIxLjEuMy4zIFN0cmluZy5wcm90b3R5cGUuY29kZVBvaW50QXQocG9zKVxuICBjb2RlUG9pbnRBdDogZnVuY3Rpb24gY29kZVBvaW50QXQocG9zKSB7XG4gICAgcmV0dXJuICRhdCh0aGlzLCBwb3MpO1xuICB9XG59KTtcbiIsIi8vIDIxLjEuMy42IFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGgoc2VhcmNoU3RyaW5nIFssIGVuZFBvc2l0aW9uXSlcbid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBjb250ZXh0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLWNvbnRleHQnKTtcbnZhciBFTkRTX1dJVEggPSAnZW5kc1dpdGgnO1xudmFyICRlbmRzV2l0aCA9ICcnW0VORFNfV0lUSF07XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMtaXMtcmVnZXhwJykoRU5EU19XSVRIKSwgJ1N0cmluZycsIHtcbiAgZW5kc1dpdGg6IGZ1bmN0aW9uIGVuZHNXaXRoKHNlYXJjaFN0cmluZyAvKiAsIGVuZFBvc2l0aW9uID0gQGxlbmd0aCAqLykge1xuICAgIHZhciB0aGF0ID0gY29udGV4dCh0aGlzLCBzZWFyY2hTdHJpbmcsIEVORFNfV0lUSCk7XG4gICAgdmFyIGVuZFBvc2l0aW9uID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQ7XG4gICAgdmFyIGxlbiA9IHRvTGVuZ3RoKHRoYXQubGVuZ3RoKTtcbiAgICB2YXIgZW5kID0gZW5kUG9zaXRpb24gPT09IHVuZGVmaW5lZCA/IGxlbiA6IE1hdGgubWluKHRvTGVuZ3RoKGVuZFBvc2l0aW9uKSwgbGVuKTtcbiAgICB2YXIgc2VhcmNoID0gU3RyaW5nKHNlYXJjaFN0cmluZyk7XG4gICAgcmV0dXJuICRlbmRzV2l0aFxuICAgICAgPyAkZW5kc1dpdGguY2FsbCh0aGF0LCBzZWFyY2gsIGVuZClcbiAgICAgIDogdGhhdC5zbGljZShlbmQgLSBzZWFyY2gubGVuZ3RoLCBlbmQpID09PSBzZWFyY2g7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuNiBTdHJpbmcucHJvdG90eXBlLmZpeGVkKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2ZpeGVkJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZpeGVkKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICd0dCcsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjcgU3RyaW5nLnByb3RvdHlwZS5mb250Y29sb3IoY29sb3IpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdmb250Y29sb3InLCBmdW5jdGlvbiAoY3JlYXRlSFRNTCkge1xuICByZXR1cm4gZnVuY3Rpb24gZm9udGNvbG9yKGNvbG9yKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2ZvbnQnLCAnY29sb3InLCBjb2xvcik7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjggU3RyaW5nLnByb3RvdHlwZS5mb250c2l6ZShzaXplKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnZm9udHNpemUnLCBmdW5jdGlvbiAoY3JlYXRlSFRNTCkge1xuICByZXR1cm4gZnVuY3Rpb24gZm9udHNpemUoc2l6ZSkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdmb250JywgJ3NpemUnLCBzaXplKTtcbiAgfTtcbn0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIGZyb21DaGFyQ29kZSA9IFN0cmluZy5mcm9tQ2hhckNvZGU7XG52YXIgJGZyb21Db2RlUG9pbnQgPSBTdHJpbmcuZnJvbUNvZGVQb2ludDtcblxuLy8gbGVuZ3RoIHNob3VsZCBiZSAxLCBvbGQgRkYgcHJvYmxlbVxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoISEkZnJvbUNvZGVQb2ludCAmJiAkZnJvbUNvZGVQb2ludC5sZW5ndGggIT0gMSksICdTdHJpbmcnLCB7XG4gIC8vIDIxLjEuMi4yIFN0cmluZy5mcm9tQ29kZVBvaW50KC4uLmNvZGVQb2ludHMpXG4gIGZyb21Db2RlUG9pbnQ6IGZ1bmN0aW9uIGZyb21Db2RlUG9pbnQoeCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgdmFyIHJlcyA9IFtdO1xuICAgIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIGNvZGU7XG4gICAgd2hpbGUgKGFMZW4gPiBpKSB7XG4gICAgICBjb2RlID0gK2FyZ3VtZW50c1tpKytdO1xuICAgICAgaWYgKHRvQWJzb2x1dGVJbmRleChjb2RlLCAweDEwZmZmZikgIT09IGNvZGUpIHRocm93IFJhbmdlRXJyb3IoY29kZSArICcgaXMgbm90IGEgdmFsaWQgY29kZSBwb2ludCcpO1xuICAgICAgcmVzLnB1c2goY29kZSA8IDB4MTAwMDBcbiAgICAgICAgPyBmcm9tQ2hhckNvZGUoY29kZSlcbiAgICAgICAgOiBmcm9tQ2hhckNvZGUoKChjb2RlIC09IDB4MTAwMDApID4+IDEwKSArIDB4ZDgwMCwgY29kZSAlIDB4NDAwICsgMHhkYzAwKVxuICAgICAgKTtcbiAgICB9IHJldHVybiByZXMuam9pbignJyk7XG4gIH1cbn0pO1xuIiwiLy8gMjEuMS4zLjcgU3RyaW5nLnByb3RvdHlwZS5pbmNsdWRlcyhzZWFyY2hTdHJpbmcsIHBvc2l0aW9uID0gMClcbid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgY29udGV4dCA9IHJlcXVpcmUoJy4vX3N0cmluZy1jb250ZXh0Jyk7XG52YXIgSU5DTFVERVMgPSAnaW5jbHVkZXMnO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzLWlzLXJlZ2V4cCcpKElOQ0xVREVTKSwgJ1N0cmluZycsIHtcbiAgaW5jbHVkZXM6IGZ1bmN0aW9uIGluY2x1ZGVzKHNlYXJjaFN0cmluZyAvKiAsIHBvc2l0aW9uID0gMCAqLykge1xuICAgIHJldHVybiAhIX5jb250ZXh0KHRoaXMsIHNlYXJjaFN0cmluZywgSU5DTFVERVMpXG4gICAgICAuaW5kZXhPZihzZWFyY2hTdHJpbmcsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy45IFN0cmluZy5wcm90b3R5cGUuaXRhbGljcygpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdpdGFsaWNzJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGl0YWxpY3MoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2knLCAnJywgJycpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGF0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLWF0JykodHJ1ZSk7XG5cbi8vIDIxLjEuMy4yNyBTdHJpbmcucHJvdG90eXBlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoU3RyaW5nLCAnU3RyaW5nJywgZnVuY3Rpb24gKGl0ZXJhdGVkKSB7XG4gIHRoaXMuX3QgPSBTdHJpbmcoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbi8vIDIxLjEuNS4yLjEgJVN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uICgpIHtcbiAgdmFyIE8gPSB0aGlzLl90O1xuICB2YXIgaW5kZXggPSB0aGlzLl9pO1xuICB2YXIgcG9pbnQ7XG4gIGlmIChpbmRleCA+PSBPLmxlbmd0aCkgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICBwb2ludCA9ICRhdChPLCBpbmRleCk7XG4gIHRoaXMuX2kgKz0gcG9pbnQubGVuZ3RoO1xuICByZXR1cm4geyB2YWx1ZTogcG9pbnQsIGRvbmU6IGZhbHNlIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjEwIFN0cmluZy5wcm90b3R5cGUubGluayh1cmwpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdsaW5rJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGxpbmsodXJsKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2EnLCAnaHJlZicsIHVybCk7XG4gIH07XG59KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnU3RyaW5nJywge1xuICAvLyAyMS4xLjIuNCBTdHJpbmcucmF3KGNhbGxTaXRlLCAuLi5zdWJzdGl0dXRpb25zKVxuICByYXc6IGZ1bmN0aW9uIHJhdyhjYWxsU2l0ZSkge1xuICAgIHZhciB0cGwgPSB0b0lPYmplY3QoY2FsbFNpdGUucmF3KTtcbiAgICB2YXIgbGVuID0gdG9MZW5ndGgodHBsLmxlbmd0aCk7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciByZXMgPSBbXTtcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKGxlbiA+IGkpIHtcbiAgICAgIHJlcy5wdXNoKFN0cmluZyh0cGxbaSsrXSkpO1xuICAgICAgaWYgKGkgPCBhTGVuKSByZXMucHVzaChTdHJpbmcoYXJndW1lbnRzW2ldKSk7XG4gICAgfSByZXR1cm4gcmVzLmpvaW4oJycpO1xuICB9XG59KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnU3RyaW5nJywge1xuICAvLyAyMS4xLjMuMTMgU3RyaW5nLnByb3RvdHlwZS5yZXBlYXQoY291bnQpXG4gIHJlcGVhdDogcmVxdWlyZSgnLi9fc3RyaW5nLXJlcGVhdCcpXG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjExIFN0cmluZy5wcm90b3R5cGUuc21hbGwoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnc21hbGwnLCBmdW5jdGlvbiAoY3JlYXRlSFRNTCkge1xuICByZXR1cm4gZnVuY3Rpb24gc21hbGwoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3NtYWxsJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiLy8gMjEuMS4zLjE4IFN0cmluZy5wcm90b3R5cGUuc3RhcnRzV2l0aChzZWFyY2hTdHJpbmcgWywgcG9zaXRpb24gXSlcbid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBjb250ZXh0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLWNvbnRleHQnKTtcbnZhciBTVEFSVFNfV0lUSCA9ICdzdGFydHNXaXRoJztcbnZhciAkc3RhcnRzV2l0aCA9ICcnW1NUQVJUU19XSVRIXTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscy1pcy1yZWdleHAnKShTVEFSVFNfV0lUSCksICdTdHJpbmcnLCB7XG4gIHN0YXJ0c1dpdGg6IGZ1bmN0aW9uIHN0YXJ0c1dpdGgoc2VhcmNoU3RyaW5nIC8qICwgcG9zaXRpb24gPSAwICovKSB7XG4gICAgdmFyIHRoYXQgPSBjb250ZXh0KHRoaXMsIHNlYXJjaFN0cmluZywgU1RBUlRTX1dJVEgpO1xuICAgIHZhciBpbmRleCA9IHRvTGVuZ3RoKE1hdGgubWluKGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLCB0aGF0Lmxlbmd0aCkpO1xuICAgIHZhciBzZWFyY2ggPSBTdHJpbmcoc2VhcmNoU3RyaW5nKTtcbiAgICByZXR1cm4gJHN0YXJ0c1dpdGhcbiAgICAgID8gJHN0YXJ0c1dpdGguY2FsbCh0aGF0LCBzZWFyY2gsIGluZGV4KVxuICAgICAgOiB0aGF0LnNsaWNlKGluZGV4LCBpbmRleCArIHNlYXJjaC5sZW5ndGgpID09PSBzZWFyY2g7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuMTIgU3RyaW5nLnByb3RvdHlwZS5zdHJpa2UoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnc3RyaWtlJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHN0cmlrZSgpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnc3RyaWtlJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuMTMgU3RyaW5nLnByb3RvdHlwZS5zdWIoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnc3ViJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHN1YigpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnc3ViJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuMTQgU3RyaW5nLnByb3RvdHlwZS5zdXAoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnc3VwJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHN1cCgpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnc3VwJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMjEuMS4zLjI1IFN0cmluZy5wcm90b3R5cGUudHJpbSgpXG5yZXF1aXJlKCcuL19zdHJpbmctdHJpbScpKCd0cmltJywgZnVuY3Rpb24gKCR0cmltKSB7XG4gIHJldHVybiBmdW5jdGlvbiB0cmltKCkge1xuICAgIHJldHVybiAkdHJpbSh0aGlzLCAzKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gRUNNQVNjcmlwdCA2IHN5bWJvbHMgc2hpbVxudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIE1FVEEgPSByZXF1aXJlKCcuL19tZXRhJykuS0VZO1xudmFyICRmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgc2hhcmVkID0gcmVxdWlyZSgnLi9fc2hhcmVkJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xudmFyIHdrcyA9IHJlcXVpcmUoJy4vX3drcycpO1xudmFyIHdrc0V4dCA9IHJlcXVpcmUoJy4vX3drcy1leHQnKTtcbnZhciB3a3NEZWZpbmUgPSByZXF1aXJlKCcuL193a3MtZGVmaW5lJyk7XG52YXIgZW51bUtleXMgPSByZXF1aXJlKCcuL19lbnVtLWtleXMnKTtcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnLi9faXMtYXJyYXknKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbnZhciBfY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xudmFyIGdPUE5FeHQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wbi1leHQnKTtcbnZhciAkR09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJyk7XG52YXIgJERQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgJGtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xudmFyIGdPUEQgPSAkR09QRC5mO1xudmFyIGRQID0gJERQLmY7XG52YXIgZ09QTiA9IGdPUE5FeHQuZjtcbnZhciAkU3ltYm9sID0gZ2xvYmFsLlN5bWJvbDtcbnZhciAkSlNPTiA9IGdsb2JhbC5KU09OO1xudmFyIF9zdHJpbmdpZnkgPSAkSlNPTiAmJiAkSlNPTi5zdHJpbmdpZnk7XG52YXIgUFJPVE9UWVBFID0gJ3Byb3RvdHlwZSc7XG52YXIgSElEREVOID0gd2tzKCdfaGlkZGVuJyk7XG52YXIgVE9fUFJJTUlUSVZFID0gd2tzKCd0b1ByaW1pdGl2ZScpO1xudmFyIGlzRW51bSA9IHt9LnByb3BlcnR5SXNFbnVtZXJhYmxlO1xudmFyIFN5bWJvbFJlZ2lzdHJ5ID0gc2hhcmVkKCdzeW1ib2wtcmVnaXN0cnknKTtcbnZhciBBbGxTeW1ib2xzID0gc2hhcmVkKCdzeW1ib2xzJyk7XG52YXIgT1BTeW1ib2xzID0gc2hhcmVkKCdvcC1zeW1ib2xzJyk7XG52YXIgT2JqZWN0UHJvdG8gPSBPYmplY3RbUFJPVE9UWVBFXTtcbnZhciBVU0VfTkFUSVZFID0gdHlwZW9mICRTeW1ib2wgPT0gJ2Z1bmN0aW9uJztcbnZhciBRT2JqZWN0ID0gZ2xvYmFsLlFPYmplY3Q7XG4vLyBEb24ndCB1c2Ugc2V0dGVycyBpbiBRdCBTY3JpcHQsIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8xNzNcbnZhciBzZXR0ZXIgPSAhUU9iamVjdCB8fCAhUU9iamVjdFtQUk9UT1RZUEVdIHx8ICFRT2JqZWN0W1BST1RPVFlQRV0uZmluZENoaWxkO1xuXG4vLyBmYWxsYmFjayBmb3Igb2xkIEFuZHJvaWQsIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD02ODdcbnZhciBzZXRTeW1ib2xEZXNjID0gREVTQ1JJUFRPUlMgJiYgJGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIF9jcmVhdGUoZFAoe30sICdhJywge1xuICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZFAodGhpcywgJ2EnLCB7IHZhbHVlOiA3IH0pLmE7IH1cbiAgfSkpLmEgIT0gNztcbn0pID8gZnVuY3Rpb24gKGl0LCBrZXksIEQpIHtcbiAgdmFyIHByb3RvRGVzYyA9IGdPUEQoT2JqZWN0UHJvdG8sIGtleSk7XG4gIGlmIChwcm90b0Rlc2MpIGRlbGV0ZSBPYmplY3RQcm90b1trZXldO1xuICBkUChpdCwga2V5LCBEKTtcbiAgaWYgKHByb3RvRGVzYyAmJiBpdCAhPT0gT2JqZWN0UHJvdG8pIGRQKE9iamVjdFByb3RvLCBrZXksIHByb3RvRGVzYyk7XG59IDogZFA7XG5cbnZhciB3cmFwID0gZnVuY3Rpb24gKHRhZykge1xuICB2YXIgc3ltID0gQWxsU3ltYm9sc1t0YWddID0gX2NyZWF0ZSgkU3ltYm9sW1BST1RPVFlQRV0pO1xuICBzeW0uX2sgPSB0YWc7XG4gIHJldHVybiBzeW07XG59O1xuXG52YXIgaXNTeW1ib2wgPSBVU0VfTkFUSVZFICYmIHR5cGVvZiAkU3ltYm9sLml0ZXJhdG9yID09ICdzeW1ib2wnID8gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiB0eXBlb2YgaXQgPT0gJ3N5bWJvbCc7XG59IDogZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBpdCBpbnN0YW5jZW9mICRTeW1ib2w7XG59O1xuXG52YXIgJGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkoaXQsIGtleSwgRCkge1xuICBpZiAoaXQgPT09IE9iamVjdFByb3RvKSAkZGVmaW5lUHJvcGVydHkoT1BTeW1ib2xzLCBrZXksIEQpO1xuICBhbk9iamVjdChpdCk7XG4gIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSk7XG4gIGFuT2JqZWN0KEQpO1xuICBpZiAoaGFzKEFsbFN5bWJvbHMsIGtleSkpIHtcbiAgICBpZiAoIUQuZW51bWVyYWJsZSkge1xuICAgICAgaWYgKCFoYXMoaXQsIEhJRERFTikpIGRQKGl0LCBISURERU4sIGNyZWF0ZURlc2MoMSwge30pKTtcbiAgICAgIGl0W0hJRERFTl1ba2V5XSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChoYXMoaXQsIEhJRERFTikgJiYgaXRbSElEREVOXVtrZXldKSBpdFtISURERU5dW2tleV0gPSBmYWxzZTtcbiAgICAgIEQgPSBfY3JlYXRlKEQsIHsgZW51bWVyYWJsZTogY3JlYXRlRGVzYygwLCBmYWxzZSkgfSk7XG4gICAgfSByZXR1cm4gc2V0U3ltYm9sRGVzYyhpdCwga2V5LCBEKTtcbiAgfSByZXR1cm4gZFAoaXQsIGtleSwgRCk7XG59O1xudmFyICRkZWZpbmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyhpdCwgUCkge1xuICBhbk9iamVjdChpdCk7XG4gIHZhciBrZXlzID0gZW51bUtleXMoUCA9IHRvSU9iamVjdChQKSk7XG4gIHZhciBpID0gMDtcbiAgdmFyIGwgPSBrZXlzLmxlbmd0aDtcbiAgdmFyIGtleTtcbiAgd2hpbGUgKGwgPiBpKSAkZGVmaW5lUHJvcGVydHkoaXQsIGtleSA9IGtleXNbaSsrXSwgUFtrZXldKTtcbiAgcmV0dXJuIGl0O1xufTtcbnZhciAkY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKGl0LCBQKSB7XG4gIHJldHVybiBQID09PSB1bmRlZmluZWQgPyBfY3JlYXRlKGl0KSA6ICRkZWZpbmVQcm9wZXJ0aWVzKF9jcmVhdGUoaXQpLCBQKTtcbn07XG52YXIgJHByb3BlcnR5SXNFbnVtZXJhYmxlID0gZnVuY3Rpb24gcHJvcGVydHlJc0VudW1lcmFibGUoa2V5KSB7XG4gIHZhciBFID0gaXNFbnVtLmNhbGwodGhpcywga2V5ID0gdG9QcmltaXRpdmUoa2V5LCB0cnVlKSk7XG4gIGlmICh0aGlzID09PSBPYmplY3RQcm90byAmJiBoYXMoQWxsU3ltYm9scywga2V5KSAmJiAhaGFzKE9QU3ltYm9scywga2V5KSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gRSB8fCAhaGFzKHRoaXMsIGtleSkgfHwgIWhhcyhBbGxTeW1ib2xzLCBrZXkpIHx8IGhhcyh0aGlzLCBISURERU4pICYmIHRoaXNbSElEREVOXVtrZXldID8gRSA6IHRydWU7XG59O1xudmFyICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoaXQsIGtleSkge1xuICBpdCA9IHRvSU9iamVjdChpdCk7XG4gIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSk7XG4gIGlmIChpdCA9PT0gT2JqZWN0UHJvdG8gJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIWhhcyhPUFN5bWJvbHMsIGtleSkpIHJldHVybjtcbiAgdmFyIEQgPSBnT1BEKGl0LCBrZXkpO1xuICBpZiAoRCAmJiBoYXMoQWxsU3ltYm9scywga2V5KSAmJiAhKGhhcyhpdCwgSElEREVOKSAmJiBpdFtISURERU5dW2tleV0pKSBELmVudW1lcmFibGUgPSB0cnVlO1xuICByZXR1cm4gRDtcbn07XG52YXIgJGdldE93blByb3BlcnR5TmFtZXMgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eU5hbWVzKGl0KSB7XG4gIHZhciBuYW1lcyA9IGdPUE4odG9JT2JqZWN0KGl0KSk7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIGkgPSAwO1xuICB2YXIga2V5O1xuICB3aGlsZSAobmFtZXMubGVuZ3RoID4gaSkge1xuICAgIGlmICghaGFzKEFsbFN5bWJvbHMsIGtleSA9IG5hbWVzW2krK10pICYmIGtleSAhPSBISURERU4gJiYga2V5ICE9IE1FVEEpIHJlc3VsdC5wdXNoKGtleSk7XG4gIH0gcmV0dXJuIHJlc3VsdDtcbn07XG52YXIgJGdldE93blByb3BlcnR5U3ltYm9scyA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5U3ltYm9scyhpdCkge1xuICB2YXIgSVNfT1AgPSBpdCA9PT0gT2JqZWN0UHJvdG87XG4gIHZhciBuYW1lcyA9IGdPUE4oSVNfT1AgPyBPUFN5bWJvbHMgOiB0b0lPYmplY3QoaXQpKTtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIgaSA9IDA7XG4gIHZhciBrZXk7XG4gIHdoaWxlIChuYW1lcy5sZW5ndGggPiBpKSB7XG4gICAgaWYgKGhhcyhBbGxTeW1ib2xzLCBrZXkgPSBuYW1lc1tpKytdKSAmJiAoSVNfT1AgPyBoYXMoT2JqZWN0UHJvdG8sIGtleSkgOiB0cnVlKSkgcmVzdWx0LnB1c2goQWxsU3ltYm9sc1trZXldKTtcbiAgfSByZXR1cm4gcmVzdWx0O1xufTtcblxuLy8gMTkuNC4xLjEgU3ltYm9sKFtkZXNjcmlwdGlvbl0pXG5pZiAoIVVTRV9OQVRJVkUpIHtcbiAgJFN5bWJvbCA9IGZ1bmN0aW9uIFN5bWJvbCgpIHtcbiAgICBpZiAodGhpcyBpbnN0YW5jZW9mICRTeW1ib2wpIHRocm93IFR5cGVFcnJvcignU3ltYm9sIGlzIG5vdCBhIGNvbnN0cnVjdG9yIScpO1xuICAgIHZhciB0YWcgPSB1aWQoYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpO1xuICAgIHZhciAkc2V0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBpZiAodGhpcyA9PT0gT2JqZWN0UHJvdG8pICRzZXQuY2FsbChPUFN5bWJvbHMsIHZhbHVlKTtcbiAgICAgIGlmIChoYXModGhpcywgSElEREVOKSAmJiBoYXModGhpc1tISURERU5dLCB0YWcpKSB0aGlzW0hJRERFTl1bdGFnXSA9IGZhbHNlO1xuICAgICAgc2V0U3ltYm9sRGVzYyh0aGlzLCB0YWcsIGNyZWF0ZURlc2MoMSwgdmFsdWUpKTtcbiAgICB9O1xuICAgIGlmIChERVNDUklQVE9SUyAmJiBzZXR0ZXIpIHNldFN5bWJvbERlc2MoT2JqZWN0UHJvdG8sIHRhZywgeyBjb25maWd1cmFibGU6IHRydWUsIHNldDogJHNldCB9KTtcbiAgICByZXR1cm4gd3JhcCh0YWcpO1xuICB9O1xuICByZWRlZmluZSgkU3ltYm9sW1BST1RPVFlQRV0sICd0b1N0cmluZycsIGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLl9rO1xuICB9KTtcblxuICAkR09QRC5mID0gJGdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbiAgJERQLmYgPSAkZGVmaW5lUHJvcGVydHk7XG4gIHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZiA9IGdPUE5FeHQuZiA9ICRnZXRPd25Qcm9wZXJ0eU5hbWVzO1xuICByZXF1aXJlKCcuL19vYmplY3QtcGllJykuZiA9ICRwcm9wZXJ0eUlzRW51bWVyYWJsZTtcbiAgcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKS5mID0gJGdldE93blByb3BlcnR5U3ltYm9scztcblxuICBpZiAoREVTQ1JJUFRPUlMgJiYgIXJlcXVpcmUoJy4vX2xpYnJhcnknKSkge1xuICAgIHJlZGVmaW5lKE9iamVjdFByb3RvLCAncHJvcGVydHlJc0VudW1lcmFibGUnLCAkcHJvcGVydHlJc0VudW1lcmFibGUsIHRydWUpO1xuICB9XG5cbiAgd2tzRXh0LmYgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHJldHVybiB3cmFwKHdrcyhuYW1lKSk7XG4gIH07XG59XG5cbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIHsgU3ltYm9sOiAkU3ltYm9sIH0pO1xuXG5mb3IgKHZhciBlczZTeW1ib2xzID0gKFxuICAvLyAxOS40LjIuMiwgMTkuNC4yLjMsIDE5LjQuMi40LCAxOS40LjIuNiwgMTkuNC4yLjgsIDE5LjQuMi45LCAxOS40LjIuMTAsIDE5LjQuMi4xMSwgMTkuNC4yLjEyLCAxOS40LjIuMTMsIDE5LjQuMi4xNFxuICAnaGFzSW5zdGFuY2UsaXNDb25jYXRTcHJlYWRhYmxlLGl0ZXJhdG9yLG1hdGNoLHJlcGxhY2Usc2VhcmNoLHNwZWNpZXMsc3BsaXQsdG9QcmltaXRpdmUsdG9TdHJpbmdUYWcsdW5zY29wYWJsZXMnXG4pLnNwbGl0KCcsJyksIGogPSAwOyBlczZTeW1ib2xzLmxlbmd0aCA+IGo7KXdrcyhlczZTeW1ib2xzW2orK10pO1xuXG5mb3IgKHZhciB3ZWxsS25vd25TeW1ib2xzID0gJGtleXMod2tzLnN0b3JlKSwgayA9IDA7IHdlbGxLbm93blN5bWJvbHMubGVuZ3RoID4gazspIHdrc0RlZmluZSh3ZWxsS25vd25TeW1ib2xzW2srK10pO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCAnU3ltYm9sJywge1xuICAvLyAxOS40LjIuMSBTeW1ib2wuZm9yKGtleSlcbiAgJ2Zvcic6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gaGFzKFN5bWJvbFJlZ2lzdHJ5LCBrZXkgKz0gJycpXG4gICAgICA/IFN5bWJvbFJlZ2lzdHJ5W2tleV1cbiAgICAgIDogU3ltYm9sUmVnaXN0cnlba2V5XSA9ICRTeW1ib2woa2V5KTtcbiAgfSxcbiAgLy8gMTkuNC4yLjUgU3ltYm9sLmtleUZvcihzeW0pXG4gIGtleUZvcjogZnVuY3Rpb24ga2V5Rm9yKHN5bSkge1xuICAgIGlmICghaXNTeW1ib2woc3ltKSkgdGhyb3cgVHlwZUVycm9yKHN5bSArICcgaXMgbm90IGEgc3ltYm9sIScpO1xuICAgIGZvciAodmFyIGtleSBpbiBTeW1ib2xSZWdpc3RyeSkgaWYgKFN5bWJvbFJlZ2lzdHJ5W2tleV0gPT09IHN5bSkgcmV0dXJuIGtleTtcbiAgfSxcbiAgdXNlU2V0dGVyOiBmdW5jdGlvbiAoKSB7IHNldHRlciA9IHRydWU7IH0sXG4gIHVzZVNpbXBsZTogZnVuY3Rpb24gKCkgeyBzZXR0ZXIgPSBmYWxzZTsgfVxufSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsICdPYmplY3QnLCB7XG4gIC8vIDE5LjEuMi4yIE9iamVjdC5jcmVhdGUoTyBbLCBQcm9wZXJ0aWVzXSlcbiAgY3JlYXRlOiAkY3JlYXRlLFxuICAvLyAxOS4xLjIuNCBPYmplY3QuZGVmaW5lUHJvcGVydHkoTywgUCwgQXR0cmlidXRlcylcbiAgZGVmaW5lUHJvcGVydHk6ICRkZWZpbmVQcm9wZXJ0eSxcbiAgLy8gMTkuMS4yLjMgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoTywgUHJvcGVydGllcylcbiAgZGVmaW5lUHJvcGVydGllczogJGRlZmluZVByb3BlcnRpZXMsXG4gIC8vIDE5LjEuMi42IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUClcbiAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yLFxuICAvLyAxOS4xLjIuNyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhPKVxuICBnZXRPd25Qcm9wZXJ0eU5hbWVzOiAkZ2V0T3duUHJvcGVydHlOYW1lcyxcbiAgLy8gMTkuMS4yLjggT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhPKVxuICBnZXRPd25Qcm9wZXJ0eVN5bWJvbHM6ICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHNcbn0pO1xuXG4vLyAyNC4zLjIgSlNPTi5zdHJpbmdpZnkodmFsdWUgWywgcmVwbGFjZXIgWywgc3BhY2VdXSlcbiRKU09OICYmICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKCFVU0VfTkFUSVZFIHx8ICRmYWlscyhmdW5jdGlvbiAoKSB7XG4gIHZhciBTID0gJFN5bWJvbCgpO1xuICAvLyBNUyBFZGdlIGNvbnZlcnRzIHN5bWJvbCB2YWx1ZXMgdG8gSlNPTiBhcyB7fVxuICAvLyBXZWJLaXQgY29udmVydHMgc3ltYm9sIHZhbHVlcyB0byBKU09OIGFzIG51bGxcbiAgLy8gVjggdGhyb3dzIG9uIGJveGVkIHN5bWJvbHNcbiAgcmV0dXJuIF9zdHJpbmdpZnkoW1NdKSAhPSAnW251bGxdJyB8fCBfc3RyaW5naWZ5KHsgYTogUyB9KSAhPSAne30nIHx8IF9zdHJpbmdpZnkoT2JqZWN0KFMpKSAhPSAne30nO1xufSkpLCAnSlNPTicsIHtcbiAgc3RyaW5naWZ5OiBmdW5jdGlvbiBzdHJpbmdpZnkoaXQpIHtcbiAgICB2YXIgYXJncyA9IFtpdF07XG4gICAgdmFyIGkgPSAxO1xuICAgIHZhciByZXBsYWNlciwgJHJlcGxhY2VyO1xuICAgIHdoaWxlIChhcmd1bWVudHMubGVuZ3RoID4gaSkgYXJncy5wdXNoKGFyZ3VtZW50c1tpKytdKTtcbiAgICAkcmVwbGFjZXIgPSByZXBsYWNlciA9IGFyZ3NbMV07XG4gICAgaWYgKCFpc09iamVjdChyZXBsYWNlcikgJiYgaXQgPT09IHVuZGVmaW5lZCB8fCBpc1N5bWJvbChpdCkpIHJldHVybjsgLy8gSUU4IHJldHVybnMgc3RyaW5nIG9uIHVuZGVmaW5lZFxuICAgIGlmICghaXNBcnJheShyZXBsYWNlcikpIHJlcGxhY2VyID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgIGlmICh0eXBlb2YgJHJlcGxhY2VyID09ICdmdW5jdGlvbicpIHZhbHVlID0gJHJlcGxhY2VyLmNhbGwodGhpcywga2V5LCB2YWx1ZSk7XG4gICAgICBpZiAoIWlzU3ltYm9sKHZhbHVlKSkgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gICAgYXJnc1sxXSA9IHJlcGxhY2VyO1xuICAgIHJldHVybiBfc3RyaW5naWZ5LmFwcGx5KCRKU09OLCBhcmdzKTtcbiAgfVxufSk7XG5cbi8vIDE5LjQuMy40IFN5bWJvbC5wcm90b3R5cGVbQEB0b1ByaW1pdGl2ZV0oaGludClcbiRTeW1ib2xbUFJPVE9UWVBFXVtUT19QUklNSVRJVkVdIHx8IHJlcXVpcmUoJy4vX2hpZGUnKSgkU3ltYm9sW1BST1RPVFlQRV0sIFRPX1BSSU1JVElWRSwgJFN5bWJvbFtQUk9UT1RZUEVdLnZhbHVlT2YpO1xuLy8gMTkuNC4zLjUgU3ltYm9sLnByb3RvdHlwZVtAQHRvU3RyaW5nVGFnXVxuc2V0VG9TdHJpbmdUYWcoJFN5bWJvbCwgJ1N5bWJvbCcpO1xuLy8gMjAuMi4xLjkgTWF0aFtAQHRvU3RyaW5nVGFnXVxuc2V0VG9TdHJpbmdUYWcoTWF0aCwgJ01hdGgnLCB0cnVlKTtcbi8vIDI0LjMuMyBKU09OW0BAdG9TdHJpbmdUYWddXG5zZXRUb1N0cmluZ1RhZyhnbG9iYWwuSlNPTiwgJ0pTT04nLCB0cnVlKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHR5cGVkID0gcmVxdWlyZSgnLi9fdHlwZWQnKTtcbnZhciBidWZmZXIgPSByZXF1aXJlKCcuL190eXBlZC1idWZmZXInKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIEFycmF5QnVmZmVyID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuQXJyYXlCdWZmZXI7XG52YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xudmFyICRBcnJheUJ1ZmZlciA9IGJ1ZmZlci5BcnJheUJ1ZmZlcjtcbnZhciAkRGF0YVZpZXcgPSBidWZmZXIuRGF0YVZpZXc7XG52YXIgJGlzVmlldyA9ICR0eXBlZC5BQlYgJiYgQXJyYXlCdWZmZXIuaXNWaWV3O1xudmFyICRzbGljZSA9ICRBcnJheUJ1ZmZlci5wcm90b3R5cGUuc2xpY2U7XG52YXIgVklFVyA9ICR0eXBlZC5WSUVXO1xudmFyIEFSUkFZX0JVRkZFUiA9ICdBcnJheUJ1ZmZlcic7XG5cbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogKEFycmF5QnVmZmVyICE9PSAkQXJyYXlCdWZmZXIpLCB7IEFycmF5QnVmZmVyOiAkQXJyYXlCdWZmZXIgfSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogISR0eXBlZC5DT05TVFIsIEFSUkFZX0JVRkZFUiwge1xuICAvLyAyNC4xLjMuMSBBcnJheUJ1ZmZlci5pc1ZpZXcoYXJnKVxuICBpc1ZpZXc6IGZ1bmN0aW9uIGlzVmlldyhpdCkge1xuICAgIHJldHVybiAkaXNWaWV3ICYmICRpc1ZpZXcoaXQpIHx8IGlzT2JqZWN0KGl0KSAmJiBWSUVXIGluIGl0O1xuICB9XG59KTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LlUgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuICFuZXcgJEFycmF5QnVmZmVyKDIpLnNsaWNlKDEsIHVuZGVmaW5lZCkuYnl0ZUxlbmd0aDtcbn0pLCBBUlJBWV9CVUZGRVIsIHtcbiAgLy8gMjQuMS40LjMgQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHNsaWNlOiBmdW5jdGlvbiBzbGljZShzdGFydCwgZW5kKSB7XG4gICAgaWYgKCRzbGljZSAhPT0gdW5kZWZpbmVkICYmIGVuZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJHNsaWNlLmNhbGwoYW5PYmplY3QodGhpcyksIHN0YXJ0KTsgLy8gRkYgZml4XG4gICAgdmFyIGxlbiA9IGFuT2JqZWN0KHRoaXMpLmJ5dGVMZW5ndGg7XG4gICAgdmFyIGZpcnN0ID0gdG9BYnNvbHV0ZUluZGV4KHN0YXJ0LCBsZW4pO1xuICAgIHZhciBmaW4gPSB0b0Fic29sdXRlSW5kZXgoZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiBlbmQsIGxlbik7XG4gICAgdmFyIHJlc3VsdCA9IG5ldyAoc3BlY2llc0NvbnN0cnVjdG9yKHRoaXMsICRBcnJheUJ1ZmZlcikpKHRvTGVuZ3RoKGZpbiAtIGZpcnN0KSk7XG4gICAgdmFyIHZpZXdTID0gbmV3ICREYXRhVmlldyh0aGlzKTtcbiAgICB2YXIgdmlld1QgPSBuZXcgJERhdGFWaWV3KHJlc3VsdCk7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB3aGlsZSAoZmlyc3QgPCBmaW4pIHtcbiAgICAgIHZpZXdULnNldFVpbnQ4KGluZGV4KyssIHZpZXdTLmdldFVpbnQ4KGZpcnN0KyspKTtcbiAgICB9IHJldHVybiByZXN1bHQ7XG4gIH1cbn0pO1xuXG5yZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKEFSUkFZX0JVRkZFUik7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fdHlwZWQnKS5BQlYsIHtcbiAgRGF0YVZpZXc6IHJlcXVpcmUoJy4vX3R5cGVkLWJ1ZmZlcicpLkRhdGFWaWV3XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ0Zsb2F0MzInLCA0LCBmdW5jdGlvbiAoaW5pdCkge1xuICByZXR1cm4gZnVuY3Rpb24gRmxvYXQzMkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ0Zsb2F0NjQnLCA4LCBmdW5jdGlvbiAoaW5pdCkge1xuICByZXR1cm4gZnVuY3Rpb24gRmxvYXQ2NEFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ0ludDE2JywgMiwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEludDE2QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pO1xuIiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnSW50MzInLCA0LCBmdW5jdGlvbiAoaW5pdCkge1xuICByZXR1cm4gZnVuY3Rpb24gSW50MzJBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdJbnQ4JywgMSwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEludDhBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdVaW50MTYnLCAyLCBmdW5jdGlvbiAoaW5pdCkge1xuICByZXR1cm4gZnVuY3Rpb24gVWludDE2QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pO1xuIiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnVWludDMyJywgNCwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFVpbnQzMkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ1VpbnQ4JywgMSwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFVpbnQ4QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pO1xuIiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnVWludDgnLCAxLCBmdW5jdGlvbiAoaW5pdCkge1xuICByZXR1cm4gZnVuY3Rpb24gVWludDhDbGFtcGVkQXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0sIHRydWUpO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGVhY2ggPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoMCk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJyk7XG52YXIgYXNzaWduID0gcmVxdWlyZSgnLi9fb2JqZWN0LWFzc2lnbicpO1xudmFyIHdlYWsgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uLXdlYWsnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBXRUFLX01BUCA9ICdXZWFrTWFwJztcbnZhciBnZXRXZWFrID0gbWV0YS5nZXRXZWFrO1xudmFyIGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGU7XG52YXIgdW5jYXVnaHRGcm96ZW5TdG9yZSA9IHdlYWsudWZzdG9yZTtcbnZhciB0bXAgPSB7fTtcbnZhciBJbnRlcm5hbE1hcDtcblxudmFyIHdyYXBwZXIgPSBmdW5jdGlvbiAoZ2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBXZWFrTWFwKCkge1xuICAgIHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpO1xuICB9O1xufTtcblxudmFyIG1ldGhvZHMgPSB7XG4gIC8vIDIzLjMuMy4zIFdlYWtNYXAucHJvdG90eXBlLmdldChrZXkpXG4gIGdldDogZnVuY3Rpb24gZ2V0KGtleSkge1xuICAgIGlmIChpc09iamVjdChrZXkpKSB7XG4gICAgICB2YXIgZGF0YSA9IGdldFdlYWsoa2V5KTtcbiAgICAgIGlmIChkYXRhID09PSB0cnVlKSByZXR1cm4gdW5jYXVnaHRGcm96ZW5TdG9yZSh2YWxpZGF0ZSh0aGlzLCBXRUFLX01BUCkpLmdldChrZXkpO1xuICAgICAgcmV0dXJuIGRhdGEgPyBkYXRhW3RoaXMuX2ldIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgfSxcbiAgLy8gMjMuMy4zLjUgV2Vha01hcC5wcm90b3R5cGUuc2V0KGtleSwgdmFsdWUpXG4gIHNldDogZnVuY3Rpb24gc2V0KGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gd2Vhay5kZWYodmFsaWRhdGUodGhpcywgV0VBS19NQVApLCBrZXksIHZhbHVlKTtcbiAgfVxufTtcblxuLy8gMjMuMyBXZWFrTWFwIE9iamVjdHNcbnZhciAkV2Vha01hcCA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKFdFQUtfTUFQLCB3cmFwcGVyLCBtZXRob2RzLCB3ZWFrLCB0cnVlLCB0cnVlKTtcblxuLy8gSUUxMSBXZWFrTWFwIGZyb3plbiBrZXlzIGZpeFxuaWYgKGZhaWxzKGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyAkV2Vha01hcCgpLnNldCgoT2JqZWN0LmZyZWV6ZSB8fCBPYmplY3QpKHRtcCksIDcpLmdldCh0bXApICE9IDc7IH0pKSB7XG4gIEludGVybmFsTWFwID0gd2Vhay5nZXRDb25zdHJ1Y3Rvcih3cmFwcGVyLCBXRUFLX01BUCk7XG4gIGFzc2lnbihJbnRlcm5hbE1hcC5wcm90b3R5cGUsIG1ldGhvZHMpO1xuICBtZXRhLk5FRUQgPSB0cnVlO1xuICBlYWNoKFsnZGVsZXRlJywgJ2hhcycsICdnZXQnLCAnc2V0J10sIGZ1bmN0aW9uIChrZXkpIHtcbiAgICB2YXIgcHJvdG8gPSAkV2Vha01hcC5wcm90b3R5cGU7XG4gICAgdmFyIG1ldGhvZCA9IHByb3RvW2tleV07XG4gICAgcmVkZWZpbmUocHJvdG8sIGtleSwgZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIC8vIHN0b3JlIGZyb3plbiBvYmplY3RzIG9uIGludGVybmFsIHdlYWttYXAgc2hpbVxuICAgICAgaWYgKGlzT2JqZWN0KGEpICYmICFpc0V4dGVuc2libGUoYSkpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9mKSB0aGlzLl9mID0gbmV3IEludGVybmFsTWFwKCk7XG4gICAgICAgIHZhciByZXN1bHQgPSB0aGlzLl9mW2tleV0oYSwgYik7XG4gICAgICAgIHJldHVybiBrZXkgPT0gJ3NldCcgPyB0aGlzIDogcmVzdWx0O1xuICAgICAgLy8gc3RvcmUgYWxsIHRoZSByZXN0IG9uIG5hdGl2ZSB3ZWFrbWFwXG4gICAgICB9IHJldHVybiBtZXRob2QuY2FsbCh0aGlzLCBhLCBiKTtcbiAgICB9KTtcbiAgfSk7XG59XG4iLCIndXNlIHN0cmljdCc7XG52YXIgd2VhayA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24td2VhaycpO1xudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnLi9fdmFsaWRhdGUtY29sbGVjdGlvbicpO1xudmFyIFdFQUtfU0VUID0gJ1dlYWtTZXQnO1xuXG4vLyAyMy40IFdlYWtTZXQgT2JqZWN0c1xucmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKFdFQUtfU0VULCBmdW5jdGlvbiAoZ2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBXZWFrU2V0KCkgeyByZXR1cm4gZ2V0KHRoaXMsIGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTsgfTtcbn0sIHtcbiAgLy8gMjMuNC4zLjEgV2Vha1NldC5wcm90b3R5cGUuYWRkKHZhbHVlKVxuICBhZGQ6IGZ1bmN0aW9uIGFkZCh2YWx1ZSkge1xuICAgIHJldHVybiB3ZWFrLmRlZih2YWxpZGF0ZSh0aGlzLCBXRUFLX1NFVCksIHZhbHVlLCB0cnVlKTtcbiAgfVxufSwgd2VhaywgZmFsc2UsIHRydWUpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvQXJyYXkucHJvdG90eXBlLmluY2x1ZGVzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRpbmNsdWRlcyA9IHJlcXVpcmUoJy4vX2FycmF5LWluY2x1ZGVzJykodHJ1ZSk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnQXJyYXknLCB7XG4gIGluY2x1ZGVzOiBmdW5jdGlvbiBpbmNsdWRlcyhlbCAvKiAsIGZyb21JbmRleCA9IDAgKi8pIHtcbiAgICByZXR1cm4gJGluY2x1ZGVzKHRoaXMsIGVsLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xuXG5yZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKSgnaW5jbHVkZXMnKTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLW9iamVjdC12YWx1ZXMtZW50cmllc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkZW50cmllcyA9IHJlcXVpcmUoJy4vX29iamVjdC10by1hcnJheScpKHRydWUpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHtcbiAgZW50cmllczogZnVuY3Rpb24gZW50cmllcyhpdCkge1xuICAgIHJldHVybiAkZW50cmllcyhpdCk7XG4gIH1cbn0pO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtb2JqZWN0LWdldG93bnByb3BlcnR5ZGVzY3JpcHRvcnNcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgb3duS2V5cyA9IHJlcXVpcmUoJy4vX293bi1rZXlzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIGdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpO1xudmFyIGNyZWF0ZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fY3JlYXRlLXByb3BlcnR5Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnT2JqZWN0Jywge1xuICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKG9iamVjdCkge1xuICAgIHZhciBPID0gdG9JT2JqZWN0KG9iamVjdCk7XG4gICAgdmFyIGdldERlc2MgPSBnT1BELmY7XG4gICAgdmFyIGtleXMgPSBvd25LZXlzKE8pO1xuICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIGtleSwgZGVzYztcbiAgICB3aGlsZSAoa2V5cy5sZW5ndGggPiBpKSB7XG4gICAgICBkZXNjID0gZ2V0RGVzYyhPLCBrZXkgPSBrZXlzW2krK10pO1xuICAgICAgaWYgKGRlc2MgIT09IHVuZGVmaW5lZCkgY3JlYXRlUHJvcGVydHkocmVzdWx0LCBrZXksIGRlc2MpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLW9iamVjdC12YWx1ZXMtZW50cmllc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkdmFsdWVzID0gcmVxdWlyZSgnLi9fb2JqZWN0LXRvLWFycmF5JykoZmFsc2UpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHtcbiAgdmFsdWVzOiBmdW5jdGlvbiB2YWx1ZXMoaXQpIHtcbiAgICByZXR1cm4gJHZhbHVlcyhpdCk7XG4gIH1cbn0pO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtcHJvbWlzZS1maW5hbGx5XG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xudmFyIHByb21pc2VSZXNvbHZlID0gcmVxdWlyZSgnLi9fcHJvbWlzZS1yZXNvbHZlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5SLCAnUHJvbWlzZScsIHsgJ2ZpbmFsbHknOiBmdW5jdGlvbiAob25GaW5hbGx5KSB7XG4gIHZhciBDID0gc3BlY2llc0NvbnN0cnVjdG9yKHRoaXMsIGNvcmUuUHJvbWlzZSB8fCBnbG9iYWwuUHJvbWlzZSk7XG4gIHZhciBpc0Z1bmN0aW9uID0gdHlwZW9mIG9uRmluYWxseSA9PSAnZnVuY3Rpb24nO1xuICByZXR1cm4gdGhpcy50aGVuKFxuICAgIGlzRnVuY3Rpb24gPyBmdW5jdGlvbiAoeCkge1xuICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKEMsIG9uRmluYWxseSgpKS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHg7IH0pO1xuICAgIH0gOiBvbkZpbmFsbHksXG4gICAgaXNGdW5jdGlvbiA/IGZ1bmN0aW9uIChlKSB7XG4gICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmUoQywgb25GaW5hbGx5KCkpLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyBlOyB9KTtcbiAgICB9IDogb25GaW5hbGx5XG4gICk7XG59IH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtc3RyaW5nLXBhZC1zdGFydC1lbmRcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHBhZCA9IHJlcXVpcmUoJy4vX3N0cmluZy1wYWQnKTtcbnZhciB1c2VyQWdlbnQgPSByZXF1aXJlKCcuL191c2VyLWFnZW50Jyk7XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8yODBcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogL1ZlcnNpb25cXC8xMFxcLlxcZCsoXFwuXFxkKyk/IFNhZmFyaVxcLy8udGVzdCh1c2VyQWdlbnQpLCAnU3RyaW5nJywge1xuICBwYWRFbmQ6IGZ1bmN0aW9uIHBhZEVuZChtYXhMZW5ndGggLyogLCBmaWxsU3RyaW5nID0gJyAnICovKSB7XG4gICAgcmV0dXJuICRwYWQodGhpcywgbWF4TGVuZ3RoLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgZmFsc2UpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLXN0cmluZy1wYWQtc3RhcnQtZW5kXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRwYWQgPSByZXF1aXJlKCcuL19zdHJpbmctcGFkJyk7XG52YXIgdXNlckFnZW50ID0gcmVxdWlyZSgnLi9fdXNlci1hZ2VudCcpO1xuXG4vLyBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvMjgwXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIC9WZXJzaW9uXFwvMTBcXC5cXGQrKFxcLlxcZCspPyBTYWZhcmlcXC8vLnRlc3QodXNlckFnZW50KSwgJ1N0cmluZycsIHtcbiAgcGFkU3RhcnQ6IGZ1bmN0aW9uIHBhZFN0YXJ0KG1heExlbmd0aCAvKiAsIGZpbGxTdHJpbmcgPSAnICcgKi8pIHtcbiAgICByZXR1cm4gJHBhZCh0aGlzLCBtYXhMZW5ndGgsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLCB0cnVlKTtcbiAgfVxufSk7XG4iLCJyZXF1aXJlKCcuL193a3MtZGVmaW5lJykoJ2FzeW5jSXRlcmF0b3InKTtcbiIsInZhciAkaXRlcmF0b3JzID0gcmVxdWlyZSgnLi9lczYuYXJyYXkuaXRlcmF0b3InKTtcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciB3a3MgPSByZXF1aXJlKCcuL193a3MnKTtcbnZhciBJVEVSQVRPUiA9IHdrcygnaXRlcmF0b3InKTtcbnZhciBUT19TVFJJTkdfVEFHID0gd2tzKCd0b1N0cmluZ1RhZycpO1xudmFyIEFycmF5VmFsdWVzID0gSXRlcmF0b3JzLkFycmF5O1xuXG52YXIgRE9NSXRlcmFibGVzID0ge1xuICBDU1NSdWxlTGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIENTU1N0eWxlRGVjbGFyYXRpb246IGZhbHNlLFxuICBDU1NWYWx1ZUxpc3Q6IGZhbHNlLFxuICBDbGllbnRSZWN0TGlzdDogZmFsc2UsXG4gIERPTVJlY3RMaXN0OiBmYWxzZSxcbiAgRE9NU3RyaW5nTGlzdDogZmFsc2UsXG4gIERPTVRva2VuTGlzdDogdHJ1ZSxcbiAgRGF0YVRyYW5zZmVySXRlbUxpc3Q6IGZhbHNlLFxuICBGaWxlTGlzdDogZmFsc2UsXG4gIEhUTUxBbGxDb2xsZWN0aW9uOiBmYWxzZSxcbiAgSFRNTENvbGxlY3Rpb246IGZhbHNlLFxuICBIVE1MRm9ybUVsZW1lbnQ6IGZhbHNlLFxuICBIVE1MU2VsZWN0RWxlbWVudDogZmFsc2UsXG4gIE1lZGlhTGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIE1pbWVUeXBlQXJyYXk6IGZhbHNlLFxuICBOYW1lZE5vZGVNYXA6IGZhbHNlLFxuICBOb2RlTGlzdDogdHJ1ZSxcbiAgUGFpbnRSZXF1ZXN0TGlzdDogZmFsc2UsXG4gIFBsdWdpbjogZmFsc2UsXG4gIFBsdWdpbkFycmF5OiBmYWxzZSxcbiAgU1ZHTGVuZ3RoTGlzdDogZmFsc2UsXG4gIFNWR051bWJlckxpc3Q6IGZhbHNlLFxuICBTVkdQYXRoU2VnTGlzdDogZmFsc2UsXG4gIFNWR1BvaW50TGlzdDogZmFsc2UsXG4gIFNWR1N0cmluZ0xpc3Q6IGZhbHNlLFxuICBTVkdUcmFuc2Zvcm1MaXN0OiBmYWxzZSxcbiAgU291cmNlQnVmZmVyTGlzdDogZmFsc2UsXG4gIFN0eWxlU2hlZXRMaXN0OiB0cnVlLCAvLyBUT0RPOiBOb3Qgc3BlYyBjb21wbGlhbnQsIHNob3VsZCBiZSBmYWxzZS5cbiAgVGV4dFRyYWNrQ3VlTGlzdDogZmFsc2UsXG4gIFRleHRUcmFja0xpc3Q6IGZhbHNlLFxuICBUb3VjaExpc3Q6IGZhbHNlXG59O1xuXG5mb3IgKHZhciBjb2xsZWN0aW9ucyA9IGdldEtleXMoRE9NSXRlcmFibGVzKSwgaSA9IDA7IGkgPCBjb2xsZWN0aW9ucy5sZW5ndGg7IGkrKykge1xuICB2YXIgTkFNRSA9IGNvbGxlY3Rpb25zW2ldO1xuICB2YXIgZXhwbGljaXQgPSBET01JdGVyYWJsZXNbTkFNRV07XG4gIHZhciBDb2xsZWN0aW9uID0gZ2xvYmFsW05BTUVdO1xuICB2YXIgcHJvdG8gPSBDb2xsZWN0aW9uICYmIENvbGxlY3Rpb24ucHJvdG90eXBlO1xuICB2YXIga2V5O1xuICBpZiAocHJvdG8pIHtcbiAgICBpZiAoIXByb3RvW0lURVJBVE9SXSkgaGlkZShwcm90bywgSVRFUkFUT1IsIEFycmF5VmFsdWVzKTtcbiAgICBpZiAoIXByb3RvW1RPX1NUUklOR19UQUddKSBoaWRlKHByb3RvLCBUT19TVFJJTkdfVEFHLCBOQU1FKTtcbiAgICBJdGVyYXRvcnNbTkFNRV0gPSBBcnJheVZhbHVlcztcbiAgICBpZiAoZXhwbGljaXQpIGZvciAoa2V5IGluICRpdGVyYXRvcnMpIGlmICghcHJvdG9ba2V5XSkgcmVkZWZpbmUocHJvdG8sIGtleSwgJGl0ZXJhdG9yc1trZXldLCB0cnVlKTtcbiAgfVxufVxuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKTtcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5CLCB7XG4gIHNldEltbWVkaWF0ZTogJHRhc2suc2V0LFxuICBjbGVhckltbWVkaWF0ZTogJHRhc2suY2xlYXJcbn0pO1xuIiwiLy8gaWU5LSBzZXRUaW1lb3V0ICYgc2V0SW50ZXJ2YWwgYWRkaXRpb25hbCBwYXJhbWV0ZXJzIGZpeFxudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB1c2VyQWdlbnQgPSByZXF1aXJlKCcuL191c2VyLWFnZW50Jyk7XG52YXIgc2xpY2UgPSBbXS5zbGljZTtcbnZhciBNU0lFID0gL01TSUUgLlxcLi8udGVzdCh1c2VyQWdlbnQpOyAvLyA8LSBkaXJ0eSBpZTktIGNoZWNrXG52YXIgd3JhcCA9IGZ1bmN0aW9uIChzZXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChmbiwgdGltZSAvKiAsIC4uLmFyZ3MgKi8pIHtcbiAgICB2YXIgYm91bmRBcmdzID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XG4gICAgdmFyIGFyZ3MgPSBib3VuZEFyZ3MgPyBzbGljZS5jYWxsKGFyZ3VtZW50cywgMikgOiBmYWxzZTtcbiAgICByZXR1cm4gc2V0KGJvdW5kQXJncyA/IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICAgICAgKHR5cGVvZiBmbiA9PSAnZnVuY3Rpb24nID8gZm4gOiBGdW5jdGlvbihmbikpLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH0gOiBmbiwgdGltZSk7XG4gIH07XG59O1xuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LkIgKyAkZXhwb3J0LkYgKiBNU0lFLCB7XG4gIHNldFRpbWVvdXQ6IHdyYXAoZ2xvYmFsLnNldFRpbWVvdXQpLFxuICBzZXRJbnRlcnZhbDogd3JhcChnbG9iYWwuc2V0SW50ZXJ2YWwpXG59KTtcbiIsInJlcXVpcmUoJy4uL21vZHVsZXMvd2ViLnRpbWVycycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy93ZWIuaW1tZWRpYXRlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vbW9kdWxlcy9fY29yZScpO1xuIiwiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4hKGZ1bmN0aW9uKGdsb2JhbCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICB2YXIgT3AgPSBPYmplY3QucHJvdG90eXBlO1xuICB2YXIgaGFzT3duID0gT3AuaGFzT3duUHJvcGVydHk7XG4gIHZhciB1bmRlZmluZWQ7IC8vIE1vcmUgY29tcHJlc3NpYmxlIHRoYW4gdm9pZCAwLlxuICB2YXIgJFN5bWJvbCA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiA/IFN5bWJvbCA6IHt9O1xuICB2YXIgaXRlcmF0b3JTeW1ib2wgPSAkU3ltYm9sLml0ZXJhdG9yIHx8IFwiQEBpdGVyYXRvclwiO1xuICB2YXIgYXN5bmNJdGVyYXRvclN5bWJvbCA9ICRTeW1ib2wuYXN5bmNJdGVyYXRvciB8fCBcIkBAYXN5bmNJdGVyYXRvclwiO1xuICB2YXIgdG9TdHJpbmdUYWdTeW1ib2wgPSAkU3ltYm9sLnRvU3RyaW5nVGFnIHx8IFwiQEB0b1N0cmluZ1RhZ1wiO1xuXG4gIHZhciBpbk1vZHVsZSA9IHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCI7XG4gIHZhciBydW50aW1lID0gZ2xvYmFsLnJlZ2VuZXJhdG9yUnVudGltZTtcbiAgaWYgKHJ1bnRpbWUpIHtcbiAgICBpZiAoaW5Nb2R1bGUpIHtcbiAgICAgIC8vIElmIHJlZ2VuZXJhdG9yUnVudGltZSBpcyBkZWZpbmVkIGdsb2JhbGx5IGFuZCB3ZSdyZSBpbiBhIG1vZHVsZSxcbiAgICAgIC8vIG1ha2UgdGhlIGV4cG9ydHMgb2JqZWN0IGlkZW50aWNhbCB0byByZWdlbmVyYXRvclJ1bnRpbWUuXG4gICAgICBtb2R1bGUuZXhwb3J0cyA9IHJ1bnRpbWU7XG4gICAgfVxuICAgIC8vIERvbid0IGJvdGhlciBldmFsdWF0aW5nIHRoZSByZXN0IG9mIHRoaXMgZmlsZSBpZiB0aGUgcnVudGltZSB3YXNcbiAgICAvLyBhbHJlYWR5IGRlZmluZWQgZ2xvYmFsbHkuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRGVmaW5lIHRoZSBydW50aW1lIGdsb2JhbGx5IChhcyBleHBlY3RlZCBieSBnZW5lcmF0ZWQgY29kZSkgYXMgZWl0aGVyXG4gIC8vIG1vZHVsZS5leHBvcnRzIChpZiB3ZSdyZSBpbiBhIG1vZHVsZSkgb3IgYSBuZXcsIGVtcHR5IG9iamVjdC5cbiAgcnVudGltZSA9IGdsb2JhbC5yZWdlbmVyYXRvclJ1bnRpbWUgPSBpbk1vZHVsZSA/IG1vZHVsZS5leHBvcnRzIDoge307XG5cbiAgZnVuY3Rpb24gd3JhcChpbm5lckZuLCBvdXRlckZuLCBzZWxmLCB0cnlMb2NzTGlzdCkge1xuICAgIC8vIElmIG91dGVyRm4gcHJvdmlkZWQgYW5kIG91dGVyRm4ucHJvdG90eXBlIGlzIGEgR2VuZXJhdG9yLCB0aGVuIG91dGVyRm4ucHJvdG90eXBlIGluc3RhbmNlb2YgR2VuZXJhdG9yLlxuICAgIHZhciBwcm90b0dlbmVyYXRvciA9IG91dGVyRm4gJiYgb3V0ZXJGbi5wcm90b3R5cGUgaW5zdGFuY2VvZiBHZW5lcmF0b3IgPyBvdXRlckZuIDogR2VuZXJhdG9yO1xuICAgIHZhciBnZW5lcmF0b3IgPSBPYmplY3QuY3JlYXRlKHByb3RvR2VuZXJhdG9yLnByb3RvdHlwZSk7XG4gICAgdmFyIGNvbnRleHQgPSBuZXcgQ29udGV4dCh0cnlMb2NzTGlzdCB8fCBbXSk7XG5cbiAgICAvLyBUaGUgLl9pbnZva2UgbWV0aG9kIHVuaWZpZXMgdGhlIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgLm5leHQsXG4gICAgLy8gLnRocm93LCBhbmQgLnJldHVybiBtZXRob2RzLlxuICAgIGdlbmVyYXRvci5faW52b2tlID0gbWFrZUludm9rZU1ldGhvZChpbm5lckZuLCBzZWxmLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBnZW5lcmF0b3I7XG4gIH1cbiAgcnVudGltZS53cmFwID0gd3JhcDtcblxuICAvLyBUcnkvY2F0Y2ggaGVscGVyIHRvIG1pbmltaXplIGRlb3B0aW1pemF0aW9ucy4gUmV0dXJucyBhIGNvbXBsZXRpb25cbiAgLy8gcmVjb3JkIGxpa2UgY29udGV4dC50cnlFbnRyaWVzW2ldLmNvbXBsZXRpb24uIFRoaXMgaW50ZXJmYWNlIGNvdWxkXG4gIC8vIGhhdmUgYmVlbiAoYW5kIHdhcyBwcmV2aW91c2x5KSBkZXNpZ25lZCB0byB0YWtlIGEgY2xvc3VyZSB0byBiZVxuICAvLyBpbnZva2VkIHdpdGhvdXQgYXJndW1lbnRzLCBidXQgaW4gYWxsIHRoZSBjYXNlcyB3ZSBjYXJlIGFib3V0IHdlXG4gIC8vIGFscmVhZHkgaGF2ZSBhbiBleGlzdGluZyBtZXRob2Qgd2Ugd2FudCB0byBjYWxsLCBzbyB0aGVyZSdzIG5vIG5lZWRcbiAgLy8gdG8gY3JlYXRlIGEgbmV3IGZ1bmN0aW9uIG9iamVjdC4gV2UgY2FuIGV2ZW4gZ2V0IGF3YXkgd2l0aCBhc3N1bWluZ1xuICAvLyB0aGUgbWV0aG9kIHRha2VzIGV4YWN0bHkgb25lIGFyZ3VtZW50LCBzaW5jZSB0aGF0IGhhcHBlbnMgdG8gYmUgdHJ1ZVxuICAvLyBpbiBldmVyeSBjYXNlLCBzbyB3ZSBkb24ndCBoYXZlIHRvIHRvdWNoIHRoZSBhcmd1bWVudHMgb2JqZWN0LiBUaGVcbiAgLy8gb25seSBhZGRpdGlvbmFsIGFsbG9jYXRpb24gcmVxdWlyZWQgaXMgdGhlIGNvbXBsZXRpb24gcmVjb3JkLCB3aGljaFxuICAvLyBoYXMgYSBzdGFibGUgc2hhcGUgYW5kIHNvIGhvcGVmdWxseSBzaG91bGQgYmUgY2hlYXAgdG8gYWxsb2NhdGUuXG4gIGZ1bmN0aW9uIHRyeUNhdGNoKGZuLCBvYmosIGFyZykge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcIm5vcm1hbFwiLCBhcmc6IGZuLmNhbGwob2JqLCBhcmcpIH07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcInRocm93XCIsIGFyZzogZXJyIH07XG4gICAgfVxuICB9XG5cbiAgdmFyIEdlblN0YXRlU3VzcGVuZGVkU3RhcnQgPSBcInN1c3BlbmRlZFN0YXJ0XCI7XG4gIHZhciBHZW5TdGF0ZVN1c3BlbmRlZFlpZWxkID0gXCJzdXNwZW5kZWRZaWVsZFwiO1xuICB2YXIgR2VuU3RhdGVFeGVjdXRpbmcgPSBcImV4ZWN1dGluZ1wiO1xuICB2YXIgR2VuU3RhdGVDb21wbGV0ZWQgPSBcImNvbXBsZXRlZFwiO1xuXG4gIC8vIFJldHVybmluZyB0aGlzIG9iamVjdCBmcm9tIHRoZSBpbm5lckZuIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXNcbiAgLy8gYnJlYWtpbmcgb3V0IG9mIHRoZSBkaXNwYXRjaCBzd2l0Y2ggc3RhdGVtZW50LlxuICB2YXIgQ29udGludWVTZW50aW5lbCA9IHt9O1xuXG4gIC8vIER1bW15IGNvbnN0cnVjdG9yIGZ1bmN0aW9ucyB0aGF0IHdlIHVzZSBhcyB0aGUgLmNvbnN0cnVjdG9yIGFuZFxuICAvLyAuY29uc3RydWN0b3IucHJvdG90eXBlIHByb3BlcnRpZXMgZm9yIGZ1bmN0aW9ucyB0aGF0IHJldHVybiBHZW5lcmF0b3JcbiAgLy8gb2JqZWN0cy4gRm9yIGZ1bGwgc3BlYyBjb21wbGlhbmNlLCB5b3UgbWF5IHdpc2ggdG8gY29uZmlndXJlIHlvdXJcbiAgLy8gbWluaWZpZXIgbm90IHRvIG1hbmdsZSB0aGUgbmFtZXMgb2YgdGhlc2UgdHdvIGZ1bmN0aW9ucy5cbiAgZnVuY3Rpb24gR2VuZXJhdG9yKCkge31cbiAgZnVuY3Rpb24gR2VuZXJhdG9yRnVuY3Rpb24oKSB7fVxuICBmdW5jdGlvbiBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZSgpIHt9XG5cbiAgLy8gVGhpcyBpcyBhIHBvbHlmaWxsIGZvciAlSXRlcmF0b3JQcm90b3R5cGUlIGZvciBlbnZpcm9ubWVudHMgdGhhdFxuICAvLyBkb24ndCBuYXRpdmVseSBzdXBwb3J0IGl0LlxuICB2YXIgSXRlcmF0b3JQcm90b3R5cGUgPSB7fTtcbiAgSXRlcmF0b3JQcm90b3R5cGVbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIHZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjtcbiAgdmFyIE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlID0gZ2V0UHJvdG8gJiYgZ2V0UHJvdG8oZ2V0UHJvdG8odmFsdWVzKFtdKSkpO1xuICBpZiAoTmF0aXZlSXRlcmF0b3JQcm90b3R5cGUgJiZcbiAgICAgIE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlICE9PSBPcCAmJlxuICAgICAgaGFzT3duLmNhbGwoTmF0aXZlSXRlcmF0b3JQcm90b3R5cGUsIGl0ZXJhdG9yU3ltYm9sKSkge1xuICAgIC8vIFRoaXMgZW52aXJvbm1lbnQgaGFzIGEgbmF0aXZlICVJdGVyYXRvclByb3RvdHlwZSU7IHVzZSBpdCBpbnN0ZWFkXG4gICAgLy8gb2YgdGhlIHBvbHlmaWxsLlxuICAgIEl0ZXJhdG9yUHJvdG90eXBlID0gTmF0aXZlSXRlcmF0b3JQcm90b3R5cGU7XG4gIH1cblxuICB2YXIgR3AgPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZS5wcm90b3R5cGUgPVxuICAgIEdlbmVyYXRvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEl0ZXJhdG9yUHJvdG90eXBlKTtcbiAgR2VuZXJhdG9yRnVuY3Rpb24ucHJvdG90eXBlID0gR3AuY29uc3RydWN0b3IgPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZTtcbiAgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUuY29uc3RydWN0b3IgPSBHZW5lcmF0b3JGdW5jdGlvbjtcbiAgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGVbdG9TdHJpbmdUYWdTeW1ib2xdID1cbiAgICBHZW5lcmF0b3JGdW5jdGlvbi5kaXNwbGF5TmFtZSA9IFwiR2VuZXJhdG9yRnVuY3Rpb25cIjtcblxuICAvLyBIZWxwZXIgZm9yIGRlZmluaW5nIHRoZSAubmV4dCwgLnRocm93LCBhbmQgLnJldHVybiBtZXRob2RzIG9mIHRoZVxuICAvLyBJdGVyYXRvciBpbnRlcmZhY2UgaW4gdGVybXMgb2YgYSBzaW5nbGUgLl9pbnZva2UgbWV0aG9kLlxuICBmdW5jdGlvbiBkZWZpbmVJdGVyYXRvck1ldGhvZHMocHJvdG90eXBlKSB7XG4gICAgW1wibmV4dFwiLCBcInRocm93XCIsIFwicmV0dXJuXCJdLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICBwcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKGFyZykge1xuICAgICAgICByZXR1cm4gdGhpcy5faW52b2tlKG1ldGhvZCwgYXJnKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBydW50aW1lLmlzR2VuZXJhdG9yRnVuY3Rpb24gPSBmdW5jdGlvbihnZW5GdW4pIHtcbiAgICB2YXIgY3RvciA9IHR5cGVvZiBnZW5GdW4gPT09IFwiZnVuY3Rpb25cIiAmJiBnZW5GdW4uY29uc3RydWN0b3I7XG4gICAgcmV0dXJuIGN0b3JcbiAgICAgID8gY3RvciA9PT0gR2VuZXJhdG9yRnVuY3Rpb24gfHxcbiAgICAgICAgLy8gRm9yIHRoZSBuYXRpdmUgR2VuZXJhdG9yRnVuY3Rpb24gY29uc3RydWN0b3IsIHRoZSBiZXN0IHdlIGNhblxuICAgICAgICAvLyBkbyBpcyB0byBjaGVjayBpdHMgLm5hbWUgcHJvcGVydHkuXG4gICAgICAgIChjdG9yLmRpc3BsYXlOYW1lIHx8IGN0b3IubmFtZSkgPT09IFwiR2VuZXJhdG9yRnVuY3Rpb25cIlxuICAgICAgOiBmYWxzZTtcbiAgfTtcblxuICBydW50aW1lLm1hcmsgPSBmdW5jdGlvbihnZW5GdW4pIHtcbiAgICBpZiAoT2JqZWN0LnNldFByb3RvdHlwZU9mKSB7XG4gICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoZ2VuRnVuLCBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdlbkZ1bi5fX3Byb3RvX18gPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZTtcbiAgICAgIGlmICghKHRvU3RyaW5nVGFnU3ltYm9sIGluIGdlbkZ1bikpIHtcbiAgICAgICAgZ2VuRnVuW3RvU3RyaW5nVGFnU3ltYm9sXSA9IFwiR2VuZXJhdG9yRnVuY3Rpb25cIjtcbiAgICAgIH1cbiAgICB9XG4gICAgZ2VuRnVuLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoR3ApO1xuICAgIHJldHVybiBnZW5GdW47XG4gIH07XG5cbiAgLy8gV2l0aGluIHRoZSBib2R5IG9mIGFueSBhc3luYyBmdW5jdGlvbiwgYGF3YWl0IHhgIGlzIHRyYW5zZm9ybWVkIHRvXG4gIC8vIGB5aWVsZCByZWdlbmVyYXRvclJ1bnRpbWUuYXdyYXAoeClgLCBzbyB0aGF0IHRoZSBydW50aW1lIGNhbiB0ZXN0XG4gIC8vIGBoYXNPd24uY2FsbCh2YWx1ZSwgXCJfX2F3YWl0XCIpYCB0byBkZXRlcm1pbmUgaWYgdGhlIHlpZWxkZWQgdmFsdWUgaXNcbiAgLy8gbWVhbnQgdG8gYmUgYXdhaXRlZC5cbiAgcnVudGltZS5hd3JhcCA9IGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiB7IF9fYXdhaXQ6IGFyZyB9O1xuICB9O1xuXG4gIGZ1bmN0aW9uIEFzeW5jSXRlcmF0b3IoZ2VuZXJhdG9yKSB7XG4gICAgZnVuY3Rpb24gaW52b2tlKG1ldGhvZCwgYXJnLCByZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciByZWNvcmQgPSB0cnlDYXRjaChnZW5lcmF0b3JbbWV0aG9kXSwgZ2VuZXJhdG9yLCBhcmcpO1xuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgcmVqZWN0KHJlY29yZC5hcmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlY29yZC5hcmc7XG4gICAgICAgIHZhciB2YWx1ZSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgaWYgKHZhbHVlICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgICAgIGhhc093bi5jYWxsKHZhbHVlLCBcIl9fYXdhaXRcIikpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlLl9fYXdhaXQpLnRoZW4oZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIGludm9rZShcIm5leHRcIiwgdmFsdWUsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgfSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgICBpbnZva2UoXCJ0aHJvd1wiLCBlcnIsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlKS50aGVuKGZ1bmN0aW9uKHVud3JhcHBlZCkge1xuICAgICAgICAgIC8vIFdoZW4gYSB5aWVsZGVkIFByb21pc2UgaXMgcmVzb2x2ZWQsIGl0cyBmaW5hbCB2YWx1ZSBiZWNvbWVzXG4gICAgICAgICAgLy8gdGhlIC52YWx1ZSBvZiB0aGUgUHJvbWlzZTx7dmFsdWUsZG9uZX0+IHJlc3VsdCBmb3IgdGhlXG4gICAgICAgICAgLy8gY3VycmVudCBpdGVyYXRpb24uIElmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLCBob3dldmVyLCB0aGVcbiAgICAgICAgICAvLyByZXN1bHQgZm9yIHRoaXMgaXRlcmF0aW9uIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgc2FtZVxuICAgICAgICAgIC8vIHJlYXNvbi4gTm90ZSB0aGF0IHJlamVjdGlvbnMgb2YgeWllbGRlZCBQcm9taXNlcyBhcmUgbm90XG4gICAgICAgICAgLy8gdGhyb3duIGJhY2sgaW50byB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uLCBhcyBpcyB0aGUgY2FzZVxuICAgICAgICAgIC8vIHdoZW4gYW4gYXdhaXRlZCBQcm9taXNlIGlzIHJlamVjdGVkLiBUaGlzIGRpZmZlcmVuY2UgaW5cbiAgICAgICAgICAvLyBiZWhhdmlvciBiZXR3ZWVuIHlpZWxkIGFuZCBhd2FpdCBpcyBpbXBvcnRhbnQsIGJlY2F1c2UgaXRcbiAgICAgICAgICAvLyBhbGxvd3MgdGhlIGNvbnN1bWVyIHRvIGRlY2lkZSB3aGF0IHRvIGRvIHdpdGggdGhlIHlpZWxkZWRcbiAgICAgICAgICAvLyByZWplY3Rpb24gKHN3YWxsb3cgaXQgYW5kIGNvbnRpbnVlLCBtYW51YWxseSAudGhyb3cgaXQgYmFja1xuICAgICAgICAgIC8vIGludG8gdGhlIGdlbmVyYXRvciwgYWJhbmRvbiBpdGVyYXRpb24sIHdoYXRldmVyKS4gV2l0aFxuICAgICAgICAgIC8vIGF3YWl0LCBieSBjb250cmFzdCwgdGhlcmUgaXMgbm8gb3Bwb3J0dW5pdHkgdG8gZXhhbWluZSB0aGVcbiAgICAgICAgICAvLyByZWplY3Rpb24gcmVhc29uIG91dHNpZGUgdGhlIGdlbmVyYXRvciBmdW5jdGlvbiwgc28gdGhlXG4gICAgICAgICAgLy8gb25seSBvcHRpb24gaXMgdG8gdGhyb3cgaXQgZnJvbSB0aGUgYXdhaXQgZXhwcmVzc2lvbiwgYW5kXG4gICAgICAgICAgLy8gbGV0IHRoZSBnZW5lcmF0b3IgZnVuY3Rpb24gaGFuZGxlIHRoZSBleGNlcHRpb24uXG4gICAgICAgICAgcmVzdWx0LnZhbHVlID0gdW53cmFwcGVkO1xuICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcHJldmlvdXNQcm9taXNlO1xuXG4gICAgZnVuY3Rpb24gZW5xdWV1ZShtZXRob2QsIGFyZykge1xuICAgICAgZnVuY3Rpb24gY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmcoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICBpbnZva2UobWV0aG9kLCBhcmcsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcHJldmlvdXNQcm9taXNlID1cbiAgICAgICAgLy8gSWYgZW5xdWV1ZSBoYXMgYmVlbiBjYWxsZWQgYmVmb3JlLCB0aGVuIHdlIHdhbnQgdG8gd2FpdCB1bnRpbFxuICAgICAgICAvLyBhbGwgcHJldmlvdXMgUHJvbWlzZXMgaGF2ZSBiZWVuIHJlc29sdmVkIGJlZm9yZSBjYWxsaW5nIGludm9rZSxcbiAgICAgICAgLy8gc28gdGhhdCByZXN1bHRzIGFyZSBhbHdheXMgZGVsaXZlcmVkIGluIHRoZSBjb3JyZWN0IG9yZGVyLiBJZlxuICAgICAgICAvLyBlbnF1ZXVlIGhhcyBub3QgYmVlbiBjYWxsZWQgYmVmb3JlLCB0aGVuIGl0IGlzIGltcG9ydGFudCB0b1xuICAgICAgICAvLyBjYWxsIGludm9rZSBpbW1lZGlhdGVseSwgd2l0aG91dCB3YWl0aW5nIG9uIGEgY2FsbGJhY2sgdG8gZmlyZSxcbiAgICAgICAgLy8gc28gdGhhdCB0aGUgYXN5bmMgZ2VuZXJhdG9yIGZ1bmN0aW9uIGhhcyB0aGUgb3Bwb3J0dW5pdHkgdG8gZG9cbiAgICAgICAgLy8gYW55IG5lY2Vzc2FyeSBzZXR1cCBpbiBhIHByZWRpY3RhYmxlIHdheS4gVGhpcyBwcmVkaWN0YWJpbGl0eVxuICAgICAgICAvLyBpcyB3aHkgdGhlIFByb21pc2UgY29uc3RydWN0b3Igc3luY2hyb25vdXNseSBpbnZva2VzIGl0c1xuICAgICAgICAvLyBleGVjdXRvciBjYWxsYmFjaywgYW5kIHdoeSBhc3luYyBmdW5jdGlvbnMgc3luY2hyb25vdXNseVxuICAgICAgICAvLyBleGVjdXRlIGNvZGUgYmVmb3JlIHRoZSBmaXJzdCBhd2FpdC4gU2luY2Ugd2UgaW1wbGVtZW50IHNpbXBsZVxuICAgICAgICAvLyBhc3luYyBmdW5jdGlvbnMgaW4gdGVybXMgb2YgYXN5bmMgZ2VuZXJhdG9ycywgaXQgaXMgZXNwZWNpYWxseVxuICAgICAgICAvLyBpbXBvcnRhbnQgdG8gZ2V0IHRoaXMgcmlnaHQsIGV2ZW4gdGhvdWdoIGl0IHJlcXVpcmVzIGNhcmUuXG4gICAgICAgIHByZXZpb3VzUHJvbWlzZSA/IHByZXZpb3VzUHJvbWlzZS50aGVuKFxuICAgICAgICAgIGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnLFxuICAgICAgICAgIC8vIEF2b2lkIHByb3BhZ2F0aW5nIGZhaWx1cmVzIHRvIFByb21pc2VzIHJldHVybmVkIGJ5IGxhdGVyXG4gICAgICAgICAgLy8gaW52b2NhdGlvbnMgb2YgdGhlIGl0ZXJhdG9yLlxuICAgICAgICAgIGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnXG4gICAgICAgICkgOiBjYWxsSW52b2tlV2l0aE1ldGhvZEFuZEFyZygpO1xuICAgIH1cblxuICAgIC8vIERlZmluZSB0aGUgdW5pZmllZCBoZWxwZXIgbWV0aG9kIHRoYXQgaXMgdXNlZCB0byBpbXBsZW1lbnQgLm5leHQsXG4gICAgLy8gLnRocm93LCBhbmQgLnJldHVybiAoc2VlIGRlZmluZUl0ZXJhdG9yTWV0aG9kcykuXG4gICAgdGhpcy5faW52b2tlID0gZW5xdWV1ZTtcbiAgfVxuXG4gIGRlZmluZUl0ZXJhdG9yTWV0aG9kcyhBc3luY0l0ZXJhdG9yLnByb3RvdHlwZSk7XG4gIEFzeW5jSXRlcmF0b3IucHJvdG90eXBlW2FzeW5jSXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuICBydW50aW1lLkFzeW5jSXRlcmF0b3IgPSBBc3luY0l0ZXJhdG9yO1xuXG4gIC8vIE5vdGUgdGhhdCBzaW1wbGUgYXN5bmMgZnVuY3Rpb25zIGFyZSBpbXBsZW1lbnRlZCBvbiB0b3Agb2ZcbiAgLy8gQXN5bmNJdGVyYXRvciBvYmplY3RzOyB0aGV5IGp1c3QgcmV0dXJuIGEgUHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9mXG4gIC8vIHRoZSBmaW5hbCByZXN1bHQgcHJvZHVjZWQgYnkgdGhlIGl0ZXJhdG9yLlxuICBydW50aW1lLmFzeW5jID0gZnVuY3Rpb24oaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpIHtcbiAgICB2YXIgaXRlciA9IG5ldyBBc3luY0l0ZXJhdG9yKFxuICAgICAgd3JhcChpbm5lckZuLCBvdXRlckZuLCBzZWxmLCB0cnlMb2NzTGlzdClcbiAgICApO1xuXG4gICAgcmV0dXJuIHJ1bnRpbWUuaXNHZW5lcmF0b3JGdW5jdGlvbihvdXRlckZuKVxuICAgICAgPyBpdGVyIC8vIElmIG91dGVyRm4gaXMgYSBnZW5lcmF0b3IsIHJldHVybiB0aGUgZnVsbCBpdGVyYXRvci5cbiAgICAgIDogaXRlci5uZXh0KCkudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0LmRvbmUgPyByZXN1bHQudmFsdWUgOiBpdGVyLm5leHQoKTtcbiAgICAgICAgfSk7XG4gIH07XG5cbiAgZnVuY3Rpb24gbWFrZUludm9rZU1ldGhvZChpbm5lckZuLCBzZWxmLCBjb250ZXh0KSB7XG4gICAgdmFyIHN0YXRlID0gR2VuU3RhdGVTdXNwZW5kZWRTdGFydDtcblxuICAgIHJldHVybiBmdW5jdGlvbiBpbnZva2UobWV0aG9kLCBhcmcpIHtcbiAgICAgIGlmIChzdGF0ZSA9PT0gR2VuU3RhdGVFeGVjdXRpbmcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgcnVubmluZ1wiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN0YXRlID09PSBHZW5TdGF0ZUNvbXBsZXRlZCkge1xuICAgICAgICBpZiAobWV0aG9kID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICB0aHJvdyBhcmc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBCZSBmb3JnaXZpbmcsIHBlciAyNS4zLjMuMy4zIG9mIHRoZSBzcGVjOlxuICAgICAgICAvLyBodHRwczovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtZ2VuZXJhdG9ycmVzdW1lXG4gICAgICAgIHJldHVybiBkb25lUmVzdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRleHQubWV0aG9kID0gbWV0aG9kO1xuICAgICAgY29udGV4dC5hcmcgPSBhcmc7XG5cbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIHZhciBkZWxlZ2F0ZSA9IGNvbnRleHQuZGVsZWdhdGU7XG4gICAgICAgIGlmIChkZWxlZ2F0ZSkge1xuICAgICAgICAgIHZhciBkZWxlZ2F0ZVJlc3VsdCA9IG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpO1xuICAgICAgICAgIGlmIChkZWxlZ2F0ZVJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGRlbGVnYXRlUmVzdWx0ID09PSBDb250aW51ZVNlbnRpbmVsKSBjb250aW51ZTtcbiAgICAgICAgICAgIHJldHVybiBkZWxlZ2F0ZVJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29udGV4dC5tZXRob2QgPT09IFwibmV4dFwiKSB7XG4gICAgICAgICAgLy8gU2V0dGluZyBjb250ZXh0Ll9zZW50IGZvciBsZWdhY3kgc3VwcG9ydCBvZiBCYWJlbCdzXG4gICAgICAgICAgLy8gZnVuY3Rpb24uc2VudCBpbXBsZW1lbnRhdGlvbi5cbiAgICAgICAgICBjb250ZXh0LnNlbnQgPSBjb250ZXh0Ll9zZW50ID0gY29udGV4dC5hcmc7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgaWYgKHN0YXRlID09PSBHZW5TdGF0ZVN1c3BlbmRlZFN0YXJ0KSB7XG4gICAgICAgICAgICBzdGF0ZSA9IEdlblN0YXRlQ29tcGxldGVkO1xuICAgICAgICAgICAgdGhyb3cgY29udGV4dC5hcmc7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29udGV4dC5kaXNwYXRjaEV4Y2VwdGlvbihjb250ZXh0LmFyZyk7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJyZXR1cm5cIikge1xuICAgICAgICAgIGNvbnRleHQuYWJydXB0KFwicmV0dXJuXCIsIGNvbnRleHQuYXJnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXRlID0gR2VuU3RhdGVFeGVjdXRpbmc7XG5cbiAgICAgICAgdmFyIHJlY29yZCA9IHRyeUNhdGNoKGlubmVyRm4sIHNlbGYsIGNvbnRleHQpO1xuICAgICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwibm9ybWFsXCIpIHtcbiAgICAgICAgICAvLyBJZiBhbiBleGNlcHRpb24gaXMgdGhyb3duIGZyb20gaW5uZXJGbiwgd2UgbGVhdmUgc3RhdGUgPT09XG4gICAgICAgICAgLy8gR2VuU3RhdGVFeGVjdXRpbmcgYW5kIGxvb3AgYmFjayBmb3IgYW5vdGhlciBpbnZvY2F0aW9uLlxuICAgICAgICAgIHN0YXRlID0gY29udGV4dC5kb25lXG4gICAgICAgICAgICA/IEdlblN0YXRlQ29tcGxldGVkXG4gICAgICAgICAgICA6IEdlblN0YXRlU3VzcGVuZGVkWWllbGQ7XG5cbiAgICAgICAgICBpZiAocmVjb3JkLmFyZyA9PT0gQ29udGludWVTZW50aW5lbCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbHVlOiByZWNvcmQuYXJnLFxuICAgICAgICAgICAgZG9uZTogY29udGV4dC5kb25lXG4gICAgICAgICAgfTtcblxuICAgICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICBzdGF0ZSA9IEdlblN0YXRlQ29tcGxldGVkO1xuICAgICAgICAgIC8vIERpc3BhdGNoIHRoZSBleGNlcHRpb24gYnkgbG9vcGluZyBiYWNrIGFyb3VuZCB0byB0aGVcbiAgICAgICAgICAvLyBjb250ZXh0LmRpc3BhdGNoRXhjZXB0aW9uKGNvbnRleHQuYXJnKSBjYWxsIGFib3ZlLlxuICAgICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgICAgIGNvbnRleHQuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvLyBDYWxsIGRlbGVnYXRlLml0ZXJhdG9yW2NvbnRleHQubWV0aG9kXShjb250ZXh0LmFyZykgYW5kIGhhbmRsZSB0aGVcbiAgLy8gcmVzdWx0LCBlaXRoZXIgYnkgcmV0dXJuaW5nIGEgeyB2YWx1ZSwgZG9uZSB9IHJlc3VsdCBmcm9tIHRoZVxuICAvLyBkZWxlZ2F0ZSBpdGVyYXRvciwgb3IgYnkgbW9kaWZ5aW5nIGNvbnRleHQubWV0aG9kIGFuZCBjb250ZXh0LmFyZyxcbiAgLy8gc2V0dGluZyBjb250ZXh0LmRlbGVnYXRlIHRvIG51bGwsIGFuZCByZXR1cm5pbmcgdGhlIENvbnRpbnVlU2VudGluZWwuXG4gIGZ1bmN0aW9uIG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpIHtcbiAgICB2YXIgbWV0aG9kID0gZGVsZWdhdGUuaXRlcmF0b3JbY29udGV4dC5tZXRob2RdO1xuICAgIGlmIChtZXRob2QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gQSAudGhyb3cgb3IgLnJldHVybiB3aGVuIHRoZSBkZWxlZ2F0ZSBpdGVyYXRvciBoYXMgbm8gLnRocm93XG4gICAgICAvLyBtZXRob2QgYWx3YXlzIHRlcm1pbmF0ZXMgdGhlIHlpZWxkKiBsb29wLlxuICAgICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG5cbiAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIGlmIChkZWxlZ2F0ZS5pdGVyYXRvci5yZXR1cm4pIHtcbiAgICAgICAgICAvLyBJZiB0aGUgZGVsZWdhdGUgaXRlcmF0b3IgaGFzIGEgcmV0dXJuIG1ldGhvZCwgZ2l2ZSBpdCBhXG4gICAgICAgICAgLy8gY2hhbmNlIHRvIGNsZWFuIHVwLlxuICAgICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJyZXR1cm5cIjtcbiAgICAgICAgICBjb250ZXh0LmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBtYXliZUludm9rZURlbGVnYXRlKGRlbGVnYXRlLCBjb250ZXh0KTtcblxuICAgICAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICAvLyBJZiBtYXliZUludm9rZURlbGVnYXRlKGNvbnRleHQpIGNoYW5nZWQgY29udGV4dC5tZXRob2QgZnJvbVxuICAgICAgICAgICAgLy8gXCJyZXR1cm5cIiB0byBcInRocm93XCIsIGxldCB0aGF0IG92ZXJyaWRlIHRoZSBUeXBlRXJyb3IgYmVsb3cuXG4gICAgICAgICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgICAgY29udGV4dC5hcmcgPSBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgIFwiVGhlIGl0ZXJhdG9yIGRvZXMgbm90IHByb3ZpZGUgYSAndGhyb3cnIG1ldGhvZFwiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuXG4gICAgdmFyIHJlY29yZCA9IHRyeUNhdGNoKG1ldGhvZCwgZGVsZWdhdGUuaXRlcmF0b3IsIGNvbnRleHQuYXJnKTtcblxuICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgIGNvbnRleHQuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuXG4gICAgdmFyIGluZm8gPSByZWNvcmQuYXJnO1xuXG4gICAgaWYgKCEgaW5mbykge1xuICAgICAgY29udGV4dC5tZXRob2QgPSBcInRocm93XCI7XG4gICAgICBjb250ZXh0LmFyZyA9IG5ldyBUeXBlRXJyb3IoXCJpdGVyYXRvciByZXN1bHQgaXMgbm90IGFuIG9iamVjdFwiKTtcbiAgICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuXG4gICAgaWYgKGluZm8uZG9uZSkge1xuICAgICAgLy8gQXNzaWduIHRoZSByZXN1bHQgb2YgdGhlIGZpbmlzaGVkIGRlbGVnYXRlIHRvIHRoZSB0ZW1wb3JhcnlcbiAgICAgIC8vIHZhcmlhYmxlIHNwZWNpZmllZCBieSBkZWxlZ2F0ZS5yZXN1bHROYW1lIChzZWUgZGVsZWdhdGVZaWVsZCkuXG4gICAgICBjb250ZXh0W2RlbGVnYXRlLnJlc3VsdE5hbWVdID0gaW5mby52YWx1ZTtcblxuICAgICAgLy8gUmVzdW1lIGV4ZWN1dGlvbiBhdCB0aGUgZGVzaXJlZCBsb2NhdGlvbiAoc2VlIGRlbGVnYXRlWWllbGQpLlxuICAgICAgY29udGV4dC5uZXh0ID0gZGVsZWdhdGUubmV4dExvYztcblxuICAgICAgLy8gSWYgY29udGV4dC5tZXRob2Qgd2FzIFwidGhyb3dcIiBidXQgdGhlIGRlbGVnYXRlIGhhbmRsZWQgdGhlXG4gICAgICAvLyBleGNlcHRpb24sIGxldCB0aGUgb3V0ZXIgZ2VuZXJhdG9yIHByb2NlZWQgbm9ybWFsbHkuIElmXG4gICAgICAvLyBjb250ZXh0Lm1ldGhvZCB3YXMgXCJuZXh0XCIsIGZvcmdldCBjb250ZXh0LmFyZyBzaW5jZSBpdCBoYXMgYmVlblxuICAgICAgLy8gXCJjb25zdW1lZFwiIGJ5IHRoZSBkZWxlZ2F0ZSBpdGVyYXRvci4gSWYgY29udGV4dC5tZXRob2Qgd2FzXG4gICAgICAvLyBcInJldHVyblwiLCBhbGxvdyB0aGUgb3JpZ2luYWwgLnJldHVybiBjYWxsIHRvIGNvbnRpbnVlIGluIHRoZVxuICAgICAgLy8gb3V0ZXIgZ2VuZXJhdG9yLlxuICAgICAgaWYgKGNvbnRleHQubWV0aG9kICE9PSBcInJldHVyblwiKSB7XG4gICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJuZXh0XCI7XG4gICAgICAgIGNvbnRleHQuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFJlLXlpZWxkIHRoZSByZXN1bHQgcmV0dXJuZWQgYnkgdGhlIGRlbGVnYXRlIG1ldGhvZC5cbiAgICAgIHJldHVybiBpbmZvO1xuICAgIH1cblxuICAgIC8vIFRoZSBkZWxlZ2F0ZSBpdGVyYXRvciBpcyBmaW5pc2hlZCwgc28gZm9yZ2V0IGl0IGFuZCBjb250aW51ZSB3aXRoXG4gICAgLy8gdGhlIG91dGVyIGdlbmVyYXRvci5cbiAgICBjb250ZXh0LmRlbGVnYXRlID0gbnVsbDtcbiAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgfVxuXG4gIC8vIERlZmluZSBHZW5lcmF0b3IucHJvdG90eXBlLntuZXh0LHRocm93LHJldHVybn0gaW4gdGVybXMgb2YgdGhlXG4gIC8vIHVuaWZpZWQgLl9pbnZva2UgaGVscGVyIG1ldGhvZC5cbiAgZGVmaW5lSXRlcmF0b3JNZXRob2RzKEdwKTtcblxuICBHcFt0b1N0cmluZ1RhZ1N5bWJvbF0gPSBcIkdlbmVyYXRvclwiO1xuXG4gIC8vIEEgR2VuZXJhdG9yIHNob3VsZCBhbHdheXMgcmV0dXJuIGl0c2VsZiBhcyB0aGUgaXRlcmF0b3Igb2JqZWN0IHdoZW4gdGhlXG4gIC8vIEBAaXRlcmF0b3IgZnVuY3Rpb24gaXMgY2FsbGVkIG9uIGl0LiBTb21lIGJyb3dzZXJzJyBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlXG4gIC8vIGl0ZXJhdG9yIHByb3RvdHlwZSBjaGFpbiBpbmNvcnJlY3RseSBpbXBsZW1lbnQgdGhpcywgY2F1c2luZyB0aGUgR2VuZXJhdG9yXG4gIC8vIG9iamVjdCB0byBub3QgYmUgcmV0dXJuZWQgZnJvbSB0aGlzIGNhbGwuIFRoaXMgZW5zdXJlcyB0aGF0IGRvZXNuJ3QgaGFwcGVuLlxuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlZ2VuZXJhdG9yL2lzc3Vlcy8yNzQgZm9yIG1vcmUgZGV0YWlscy5cbiAgR3BbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgR3AudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IEdlbmVyYXRvcl1cIjtcbiAgfTtcblxuICBmdW5jdGlvbiBwdXNoVHJ5RW50cnkobG9jcykge1xuICAgIHZhciBlbnRyeSA9IHsgdHJ5TG9jOiBsb2NzWzBdIH07XG5cbiAgICBpZiAoMSBpbiBsb2NzKSB7XG4gICAgICBlbnRyeS5jYXRjaExvYyA9IGxvY3NbMV07XG4gICAgfVxuXG4gICAgaWYgKDIgaW4gbG9jcykge1xuICAgICAgZW50cnkuZmluYWxseUxvYyA9IGxvY3NbMl07XG4gICAgICBlbnRyeS5hZnRlckxvYyA9IGxvY3NbM107XG4gICAgfVxuXG4gICAgdGhpcy50cnlFbnRyaWVzLnB1c2goZW50cnkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzZXRUcnlFbnRyeShlbnRyeSkge1xuICAgIHZhciByZWNvcmQgPSBlbnRyeS5jb21wbGV0aW9uIHx8IHt9O1xuICAgIHJlY29yZC50eXBlID0gXCJub3JtYWxcIjtcbiAgICBkZWxldGUgcmVjb3JkLmFyZztcbiAgICBlbnRyeS5jb21wbGV0aW9uID0gcmVjb3JkO1xuICB9XG5cbiAgZnVuY3Rpb24gQ29udGV4dCh0cnlMb2NzTGlzdCkge1xuICAgIC8vIFRoZSByb290IGVudHJ5IG9iamVjdCAoZWZmZWN0aXZlbHkgYSB0cnkgc3RhdGVtZW50IHdpdGhvdXQgYSBjYXRjaFxuICAgIC8vIG9yIGEgZmluYWxseSBibG9jaykgZ2l2ZXMgdXMgYSBwbGFjZSB0byBzdG9yZSB2YWx1ZXMgdGhyb3duIGZyb21cbiAgICAvLyBsb2NhdGlvbnMgd2hlcmUgdGhlcmUgaXMgbm8gZW5jbG9zaW5nIHRyeSBzdGF0ZW1lbnQuXG4gICAgdGhpcy50cnlFbnRyaWVzID0gW3sgdHJ5TG9jOiBcInJvb3RcIiB9XTtcbiAgICB0cnlMb2NzTGlzdC5mb3JFYWNoKHB1c2hUcnlFbnRyeSwgdGhpcyk7XG4gICAgdGhpcy5yZXNldCh0cnVlKTtcbiAgfVxuXG4gIHJ1bnRpbWUua2V5cyA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgfVxuICAgIGtleXMucmV2ZXJzZSgpO1xuXG4gICAgLy8gUmF0aGVyIHRoYW4gcmV0dXJuaW5nIGFuIG9iamVjdCB3aXRoIGEgbmV4dCBtZXRob2QsIHdlIGtlZXBcbiAgICAvLyB0aGluZ3Mgc2ltcGxlIGFuZCByZXR1cm4gdGhlIG5leHQgZnVuY3Rpb24gaXRzZWxmLlxuICAgIHJldHVybiBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgd2hpbGUgKGtleXMubGVuZ3RoKSB7XG4gICAgICAgIHZhciBrZXkgPSBrZXlzLnBvcCgpO1xuICAgICAgICBpZiAoa2V5IGluIG9iamVjdCkge1xuICAgICAgICAgIG5leHQudmFsdWUgPSBrZXk7XG4gICAgICAgICAgbmV4dC5kb25lID0gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVG8gYXZvaWQgY3JlYXRpbmcgYW4gYWRkaXRpb25hbCBvYmplY3QsIHdlIGp1c3QgaGFuZyB0aGUgLnZhbHVlXG4gICAgICAvLyBhbmQgLmRvbmUgcHJvcGVydGllcyBvZmYgdGhlIG5leHQgZnVuY3Rpb24gb2JqZWN0IGl0c2VsZi4gVGhpc1xuICAgICAgLy8gYWxzbyBlbnN1cmVzIHRoYXQgdGhlIG1pbmlmaWVyIHdpbGwgbm90IGFub255bWl6ZSB0aGUgZnVuY3Rpb24uXG4gICAgICBuZXh0LmRvbmUgPSB0cnVlO1xuICAgICAgcmV0dXJuIG5leHQ7XG4gICAgfTtcbiAgfTtcblxuICBmdW5jdGlvbiB2YWx1ZXMoaXRlcmFibGUpIHtcbiAgICBpZiAoaXRlcmFibGUpIHtcbiAgICAgIHZhciBpdGVyYXRvck1ldGhvZCA9IGl0ZXJhYmxlW2l0ZXJhdG9yU3ltYm9sXTtcbiAgICAgIGlmIChpdGVyYXRvck1ldGhvZCkge1xuICAgICAgICByZXR1cm4gaXRlcmF0b3JNZXRob2QuY2FsbChpdGVyYWJsZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgaXRlcmFibGUubmV4dCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBpdGVyYWJsZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc05hTihpdGVyYWJsZS5sZW5ndGgpKSB7XG4gICAgICAgIHZhciBpID0gLTEsIG5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgICAgIHdoaWxlICgrK2kgPCBpdGVyYWJsZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd24uY2FsbChpdGVyYWJsZSwgaSkpIHtcbiAgICAgICAgICAgICAgbmV4dC52YWx1ZSA9IGl0ZXJhYmxlW2ldO1xuICAgICAgICAgICAgICBuZXh0LmRvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbmV4dC52YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBuZXh0LmRvbmUgPSB0cnVlO1xuXG4gICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIG5leHQubmV4dCA9IG5leHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIGFuIGl0ZXJhdG9yIHdpdGggbm8gdmFsdWVzLlxuICAgIHJldHVybiB7IG5leHQ6IGRvbmVSZXN1bHQgfTtcbiAgfVxuICBydW50aW1lLnZhbHVlcyA9IHZhbHVlcztcblxuICBmdW5jdGlvbiBkb25lUmVzdWx0KCkge1xuICAgIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfTtcbiAgfVxuXG4gIENvbnRleHQucHJvdG90eXBlID0ge1xuICAgIGNvbnN0cnVjdG9yOiBDb250ZXh0LFxuXG4gICAgcmVzZXQ6IGZ1bmN0aW9uKHNraXBUZW1wUmVzZXQpIHtcbiAgICAgIHRoaXMucHJldiA9IDA7XG4gICAgICB0aGlzLm5leHQgPSAwO1xuICAgICAgLy8gUmVzZXR0aW5nIGNvbnRleHQuX3NlbnQgZm9yIGxlZ2FjeSBzdXBwb3J0IG9mIEJhYmVsJ3NcbiAgICAgIC8vIGZ1bmN0aW9uLnNlbnQgaW1wbGVtZW50YXRpb24uXG4gICAgICB0aGlzLnNlbnQgPSB0aGlzLl9zZW50ID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5kb25lID0gZmFsc2U7XG4gICAgICB0aGlzLmRlbGVnYXRlID0gbnVsbDtcblxuICAgICAgdGhpcy5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgIHRoaXMuYXJnID0gdW5kZWZpbmVkO1xuXG4gICAgICB0aGlzLnRyeUVudHJpZXMuZm9yRWFjaChyZXNldFRyeUVudHJ5KTtcblxuICAgICAgaWYgKCFza2lwVGVtcFJlc2V0KSB7XG4gICAgICAgIGZvciAodmFyIG5hbWUgaW4gdGhpcykge1xuICAgICAgICAgIC8vIE5vdCBzdXJlIGFib3V0IHRoZSBvcHRpbWFsIG9yZGVyIG9mIHRoZXNlIGNvbmRpdGlvbnM6XG4gICAgICAgICAgaWYgKG5hbWUuY2hhckF0KDApID09PSBcInRcIiAmJlxuICAgICAgICAgICAgICBoYXNPd24uY2FsbCh0aGlzLCBuYW1lKSAmJlxuICAgICAgICAgICAgICAhaXNOYU4oK25hbWUuc2xpY2UoMSkpKSB7XG4gICAgICAgICAgICB0aGlzW25hbWVdID0gdW5kZWZpbmVkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBzdG9wOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuZG9uZSA9IHRydWU7XG5cbiAgICAgIHZhciByb290RW50cnkgPSB0aGlzLnRyeUVudHJpZXNbMF07XG4gICAgICB2YXIgcm9vdFJlY29yZCA9IHJvb3RFbnRyeS5jb21wbGV0aW9uO1xuICAgICAgaWYgKHJvb3RSZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIHRocm93IHJvb3RSZWNvcmQuYXJnO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5ydmFsO1xuICAgIH0sXG5cbiAgICBkaXNwYXRjaEV4Y2VwdGlvbjogZnVuY3Rpb24oZXhjZXB0aW9uKSB7XG4gICAgICBpZiAodGhpcy5kb25lKSB7XG4gICAgICAgIHRocm93IGV4Y2VwdGlvbjtcbiAgICAgIH1cblxuICAgICAgdmFyIGNvbnRleHQgPSB0aGlzO1xuICAgICAgZnVuY3Rpb24gaGFuZGxlKGxvYywgY2F1Z2h0KSB7XG4gICAgICAgIHJlY29yZC50eXBlID0gXCJ0aHJvd1wiO1xuICAgICAgICByZWNvcmQuYXJnID0gZXhjZXB0aW9uO1xuICAgICAgICBjb250ZXh0Lm5leHQgPSBsb2M7XG5cbiAgICAgICAgaWYgKGNhdWdodCkge1xuICAgICAgICAgIC8vIElmIHRoZSBkaXNwYXRjaGVkIGV4Y2VwdGlvbiB3YXMgY2F1Z2h0IGJ5IGEgY2F0Y2ggYmxvY2ssXG4gICAgICAgICAgLy8gdGhlbiBsZXQgdGhhdCBjYXRjaCBibG9jayBoYW5kbGUgdGhlIGV4Y2VwdGlvbiBub3JtYWxseS5cbiAgICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgICAgIGNvbnRleHQuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICEhIGNhdWdodDtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIHZhciByZWNvcmQgPSBlbnRyeS5jb21wbGV0aW9uO1xuXG4gICAgICAgIGlmIChlbnRyeS50cnlMb2MgPT09IFwicm9vdFwiKSB7XG4gICAgICAgICAgLy8gRXhjZXB0aW9uIHRocm93biBvdXRzaWRlIG9mIGFueSB0cnkgYmxvY2sgdGhhdCBjb3VsZCBoYW5kbGVcbiAgICAgICAgICAvLyBpdCwgc28gc2V0IHRoZSBjb21wbGV0aW9uIHZhbHVlIG9mIHRoZSBlbnRpcmUgZnVuY3Rpb24gdG9cbiAgICAgICAgICAvLyB0aHJvdyB0aGUgZXhjZXB0aW9uLlxuICAgICAgICAgIHJldHVybiBoYW5kbGUoXCJlbmRcIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW50cnkudHJ5TG9jIDw9IHRoaXMucHJldikge1xuICAgICAgICAgIHZhciBoYXNDYXRjaCA9IGhhc093bi5jYWxsKGVudHJ5LCBcImNhdGNoTG9jXCIpO1xuICAgICAgICAgIHZhciBoYXNGaW5hbGx5ID0gaGFzT3duLmNhbGwoZW50cnksIFwiZmluYWxseUxvY1wiKTtcblxuICAgICAgICAgIGlmIChoYXNDYXRjaCAmJiBoYXNGaW5hbGx5KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcmV2IDwgZW50cnkuY2F0Y2hMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5jYXRjaExvYywgdHJ1ZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJldiA8IGVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5maW5hbGx5TG9jKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0gZWxzZSBpZiAoaGFzQ2F0Y2gpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXYgPCBlbnRyeS5jYXRjaExvYykge1xuICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlKGVudHJ5LmNhdGNoTG9jLCB0cnVlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0gZWxzZSBpZiAoaGFzRmluYWxseSkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJldiA8IGVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5maW5hbGx5TG9jKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0cnkgc3RhdGVtZW50IHdpdGhvdXQgY2F0Y2ggb3IgZmluYWxseVwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYWJydXB0OiBmdW5jdGlvbih0eXBlLCBhcmcpIHtcbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICBpZiAoZW50cnkudHJ5TG9jIDw9IHRoaXMucHJldiAmJlxuICAgICAgICAgICAgaGFzT3duLmNhbGwoZW50cnksIFwiZmluYWxseUxvY1wiKSAmJlxuICAgICAgICAgICAgdGhpcy5wcmV2IDwgZW50cnkuZmluYWxseUxvYykge1xuICAgICAgICAgIHZhciBmaW5hbGx5RW50cnkgPSBlbnRyeTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZmluYWxseUVudHJ5ICYmXG4gICAgICAgICAgKHR5cGUgPT09IFwiYnJlYWtcIiB8fFxuICAgICAgICAgICB0eXBlID09PSBcImNvbnRpbnVlXCIpICYmXG4gICAgICAgICAgZmluYWxseUVudHJ5LnRyeUxvYyA8PSBhcmcgJiZcbiAgICAgICAgICBhcmcgPD0gZmluYWxseUVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgLy8gSWdub3JlIHRoZSBmaW5hbGx5IGVudHJ5IGlmIGNvbnRyb2wgaXMgbm90IGp1bXBpbmcgdG8gYVxuICAgICAgICAvLyBsb2NhdGlvbiBvdXRzaWRlIHRoZSB0cnkvY2F0Y2ggYmxvY2suXG4gICAgICAgIGZpbmFsbHlFbnRyeSA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIHZhciByZWNvcmQgPSBmaW5hbGx5RW50cnkgPyBmaW5hbGx5RW50cnkuY29tcGxldGlvbiA6IHt9O1xuICAgICAgcmVjb3JkLnR5cGUgPSB0eXBlO1xuICAgICAgcmVjb3JkLmFyZyA9IGFyZztcblxuICAgICAgaWYgKGZpbmFsbHlFbnRyeSkge1xuICAgICAgICB0aGlzLm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgICB0aGlzLm5leHQgPSBmaW5hbGx5RW50cnkuZmluYWxseUxvYztcbiAgICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmNvbXBsZXRlKHJlY29yZCk7XG4gICAgfSxcblxuICAgIGNvbXBsZXRlOiBmdW5jdGlvbihyZWNvcmQsIGFmdGVyTG9jKSB7XG4gICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICB0aHJvdyByZWNvcmQuYXJnO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwiYnJlYWtcIiB8fFxuICAgICAgICAgIHJlY29yZC50eXBlID09PSBcImNvbnRpbnVlXCIpIHtcbiAgICAgICAgdGhpcy5uZXh0ID0gcmVjb3JkLmFyZztcbiAgICAgIH0gZWxzZSBpZiAocmVjb3JkLnR5cGUgPT09IFwicmV0dXJuXCIpIHtcbiAgICAgICAgdGhpcy5ydmFsID0gdGhpcy5hcmcgPSByZWNvcmQuYXJnO1xuICAgICAgICB0aGlzLm1ldGhvZCA9IFwicmV0dXJuXCI7XG4gICAgICAgIHRoaXMubmV4dCA9IFwiZW5kXCI7XG4gICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcIm5vcm1hbFwiICYmIGFmdGVyTG9jKSB7XG4gICAgICAgIHRoaXMubmV4dCA9IGFmdGVyTG9jO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9LFxuXG4gICAgZmluaXNoOiBmdW5jdGlvbihmaW5hbGx5TG9jKSB7XG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50cnlFbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMudHJ5RW50cmllc1tpXTtcbiAgICAgICAgaWYgKGVudHJ5LmZpbmFsbHlMb2MgPT09IGZpbmFsbHlMb2MpIHtcbiAgICAgICAgICB0aGlzLmNvbXBsZXRlKGVudHJ5LmNvbXBsZXRpb24sIGVudHJ5LmFmdGVyTG9jKTtcbiAgICAgICAgICByZXNldFRyeUVudHJ5KGVudHJ5KTtcbiAgICAgICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBcImNhdGNoXCI6IGZ1bmN0aW9uKHRyeUxvYykge1xuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIGlmIChlbnRyeS50cnlMb2MgPT09IHRyeUxvYykge1xuICAgICAgICAgIHZhciByZWNvcmQgPSBlbnRyeS5jb21wbGV0aW9uO1xuICAgICAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICB2YXIgdGhyb3duID0gcmVjb3JkLmFyZztcbiAgICAgICAgICAgIHJlc2V0VHJ5RW50cnkoZW50cnkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhyb3duO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFRoZSBjb250ZXh0LmNhdGNoIG1ldGhvZCBtdXN0IG9ubHkgYmUgY2FsbGVkIHdpdGggYSBsb2NhdGlvblxuICAgICAgLy8gYXJndW1lbnQgdGhhdCBjb3JyZXNwb25kcyB0byBhIGtub3duIGNhdGNoIGJsb2NrLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaWxsZWdhbCBjYXRjaCBhdHRlbXB0XCIpO1xuICAgIH0sXG5cbiAgICBkZWxlZ2F0ZVlpZWxkOiBmdW5jdGlvbihpdGVyYWJsZSwgcmVzdWx0TmFtZSwgbmV4dExvYykge1xuICAgICAgdGhpcy5kZWxlZ2F0ZSA9IHtcbiAgICAgICAgaXRlcmF0b3I6IHZhbHVlcyhpdGVyYWJsZSksXG4gICAgICAgIHJlc3VsdE5hbWU6IHJlc3VsdE5hbWUsXG4gICAgICAgIG5leHRMb2M6IG5leHRMb2NcbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLm1ldGhvZCA9PT0gXCJuZXh0XCIpIHtcbiAgICAgICAgLy8gRGVsaWJlcmF0ZWx5IGZvcmdldCB0aGUgbGFzdCBzZW50IHZhbHVlIHNvIHRoYXQgd2UgZG9uJ3RcbiAgICAgICAgLy8gYWNjaWRlbnRhbGx5IHBhc3MgaXQgb24gdG8gdGhlIGRlbGVnYXRlLlxuICAgICAgICB0aGlzLmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuICB9O1xufSkoXG4gIC8vIEluIHNsb3BweSBtb2RlLCB1bmJvdW5kIGB0aGlzYCByZWZlcnMgdG8gdGhlIGdsb2JhbCBvYmplY3QsIGZhbGxiYWNrIHRvXG4gIC8vIEZ1bmN0aW9uIGNvbnN0cnVjdG9yIGlmIHdlJ3JlIGluIGdsb2JhbCBzdHJpY3QgbW9kZS4gVGhhdCBpcyBzYWRseSBhIGZvcm1cbiAgLy8gb2YgaW5kaXJlY3QgZXZhbCB3aGljaCB2aW9sYXRlcyBDb250ZW50IFNlY3VyaXR5IFBvbGljeS5cbiAgKGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcyB9KSgpIHx8IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKVxuKTtcbiIsImZ1bmN0aW9uIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IodGFyZ2V0LCBwcm9wZXJ0eSwgZGVjb3JhdG9ycywgZGVzY3JpcHRvciwgY29udGV4dCkge1xuICB2YXIgZGVzYyA9IHt9O1xuICBPYmplY3RbJ2tlJyArICd5cyddKGRlc2NyaXB0b3IpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIGRlc2Nba2V5XSA9IGRlc2NyaXB0b3Jba2V5XTtcbiAgfSk7XG4gIGRlc2MuZW51bWVyYWJsZSA9ICEhZGVzYy5lbnVtZXJhYmxlO1xuICBkZXNjLmNvbmZpZ3VyYWJsZSA9ICEhZGVzYy5jb25maWd1cmFibGU7XG5cbiAgaWYgKCd2YWx1ZScgaW4gZGVzYyB8fCBkZXNjLmluaXRpYWxpemVyKSB7XG4gICAgZGVzYy53cml0YWJsZSA9IHRydWU7XG4gIH1cblxuICBkZXNjID0gZGVjb3JhdG9ycy5zbGljZSgpLnJldmVyc2UoKS5yZWR1Y2UoZnVuY3Rpb24gKGRlc2MsIGRlY29yYXRvcikge1xuICAgIHJldHVybiBkZWNvcmF0b3IodGFyZ2V0LCBwcm9wZXJ0eSwgZGVzYykgfHwgZGVzYztcbiAgfSwgZGVzYyk7XG5cbiAgaWYgKGNvbnRleHQgJiYgZGVzYy5pbml0aWFsaXplciAhPT0gdm9pZCAwKSB7XG4gICAgZGVzYy52YWx1ZSA9IGRlc2MuaW5pdGlhbGl6ZXIgPyBkZXNjLmluaXRpYWxpemVyLmNhbGwoY29udGV4dCkgOiB2b2lkIDA7XG4gICAgZGVzYy5pbml0aWFsaXplciA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmIChkZXNjLmluaXRpYWxpemVyID09PSB2b2lkIDApIHtcbiAgICBPYmplY3RbJ2RlZmluZScgKyAnUHJvcGVydHknXSh0YXJnZXQsIHByb3BlcnR5LCBkZXNjKTtcbiAgICBkZXNjID0gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBkZXNjO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9hcHBseURlY29yYXRlZERlc2NyaXB0b3I7IiwiZnVuY3Rpb24gX2FycmF5V2l0aEhvbGVzKGFycikge1xuICBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSByZXR1cm4gYXJyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9hcnJheVdpdGhIb2xlczsiLCJmdW5jdGlvbiBfYXJyYXlXaXRob3V0SG9sZXMoYXJyKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGFycikpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgYXJyMiA9IG5ldyBBcnJheShhcnIubGVuZ3RoKTsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgYXJyMltpXSA9IGFycltpXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXJyMjtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9hcnJheVdpdGhvdXRIb2xlczsiLCJmdW5jdGlvbiBfYXNzZXJ0VGhpc0luaXRpYWxpemVkKHNlbGYpIHtcbiAgaWYgKHNlbGYgPT09IHZvaWQgMCkge1xuICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZFwiKTtcbiAgfVxuXG4gIHJldHVybiBzZWxmO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQ7IiwiZnVuY3Rpb24gYXN5bmNHZW5lcmF0b3JTdGVwKGdlbiwgcmVzb2x2ZSwgcmVqZWN0LCBfbmV4dCwgX3Rocm93LCBrZXksIGFyZykge1xuICB0cnkge1xuICAgIHZhciBpbmZvID0gZ2VuW2tleV0oYXJnKTtcbiAgICB2YXIgdmFsdWUgPSBpbmZvLnZhbHVlO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJlamVjdChlcnJvcik7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGluZm8uZG9uZSkge1xuICAgIHJlc29sdmUodmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIFByb21pc2UucmVzb2x2ZSh2YWx1ZSkudGhlbihfbmV4dCwgX3Rocm93KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfYXN5bmNUb0dlbmVyYXRvcihmbikge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcyxcbiAgICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgdmFyIGdlbiA9IGZuLmFwcGx5KHNlbGYsIGFyZ3MpO1xuXG4gICAgICBmdW5jdGlvbiBfbmV4dCh2YWx1ZSkge1xuICAgICAgICBhc3luY0dlbmVyYXRvclN0ZXAoZ2VuLCByZXNvbHZlLCByZWplY3QsIF9uZXh0LCBfdGhyb3csIFwibmV4dFwiLCB2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIF90aHJvdyhlcnIpIHtcbiAgICAgICAgYXN5bmNHZW5lcmF0b3JTdGVwKGdlbiwgcmVzb2x2ZSwgcmVqZWN0LCBfbmV4dCwgX3Rocm93LCBcInRocm93XCIsIGVycik7XG4gICAgICB9XG5cbiAgICAgIF9uZXh0KHVuZGVmaW5lZCk7XG4gICAgfSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2FzeW5jVG9HZW5lcmF0b3I7IiwiZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3Rvcikge1xuICBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfY2xhc3NDYWxsQ2hlY2s7IiwidmFyIHNldFByb3RvdHlwZU9mID0gcmVxdWlyZShcIi4vc2V0UHJvdG90eXBlT2ZcIik7XG5cbmZ1bmN0aW9uIGlzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpIHtcbiAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlO1xuICBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlO1xuXG4gIHRyeSB7XG4gICAgRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChEYXRlLCBbXSwgZnVuY3Rpb24gKCkge30pKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfY29uc3RydWN0KFBhcmVudCwgYXJncywgQ2xhc3MpIHtcbiAgaWYgKGlzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBfY29uc3RydWN0ID0gUmVmbGVjdC5jb25zdHJ1Y3Q7XG4gIH0gZWxzZSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBfY29uc3RydWN0ID0gZnVuY3Rpb24gX2NvbnN0cnVjdChQYXJlbnQsIGFyZ3MsIENsYXNzKSB7XG4gICAgICB2YXIgYSA9IFtudWxsXTtcbiAgICAgIGEucHVzaC5hcHBseShhLCBhcmdzKTtcbiAgICAgIHZhciBDb25zdHJ1Y3RvciA9IEZ1bmN0aW9uLmJpbmQuYXBwbHkoUGFyZW50LCBhKTtcbiAgICAgIHZhciBpbnN0YW5jZSA9IG5ldyBDb25zdHJ1Y3RvcigpO1xuICAgICAgaWYgKENsYXNzKSBzZXRQcm90b3R5cGVPZihpbnN0YW5jZSwgQ2xhc3MucHJvdG90eXBlKTtcbiAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIF9jb25zdHJ1Y3QuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfY29uc3RydWN0OyIsImZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07XG4gICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlO1xuICAgIGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTtcbiAgICBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gIGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpO1xuICBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7XG4gIHJldHVybiBDb25zdHJ1Y3Rvcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfY3JlYXRlQ2xhc3M7IiwiZnVuY3Rpb24gX2RlZmluZVByb3BlcnR5KG9iaiwga2V5LCB2YWx1ZSkge1xuICBpZiAoa2V5IGluIG9iaikge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgb2JqW2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIHJldHVybiBvYmo7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2RlZmluZVByb3BlcnR5OyIsImZ1bmN0aW9uIF9nZXRQcm90b3R5cGVPZihvKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gX2dldFByb3RvdHlwZU9mID0gT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LmdldFByb3RvdHlwZU9mIDogZnVuY3Rpb24gX2dldFByb3RvdHlwZU9mKG8pIHtcbiAgICByZXR1cm4gby5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKG8pO1xuICB9O1xuICByZXR1cm4gX2dldFByb3RvdHlwZU9mKG8pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9nZXRQcm90b3R5cGVPZjsiLCJ2YXIgc2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKFwiLi9zZXRQcm90b3R5cGVPZlwiKTtcblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7XG4gIGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb25cIik7XG4gIH1cblxuICBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHtcbiAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgdmFsdWU6IHN1YkNsYXNzLFxuICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9XG4gIH0pO1xuICBpZiAoc3VwZXJDbGFzcykgc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9pbmhlcml0czsiLCJmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikge1xuICByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDoge1xuICAgIGRlZmF1bHQ6IG9ialxuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQ7IiwiZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7XG4gIGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHtcbiAgICByZXR1cm4gb2JqO1xuICB9IGVsc2Uge1xuICAgIHZhciBuZXdPYmogPSB7fTtcblxuICAgIGlmIChvYmogIT0gbnVsbCkge1xuICAgICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICAgIHZhciBkZXNjID0gT2JqZWN0LmRlZmluZVByb3BlcnR5ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KSA6IHt9O1xuXG4gICAgICAgICAgaWYgKGRlc2MuZ2V0IHx8IGRlc2Muc2V0KSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobmV3T2JqLCBrZXksIGRlc2MpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdPYmpba2V5XSA9IG9ialtrZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIG5ld09iai5kZWZhdWx0ID0gb2JqO1xuICAgIHJldHVybiBuZXdPYmo7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZDsiLCJmdW5jdGlvbiBfaXNOYXRpdmVGdW5jdGlvbihmbikge1xuICByZXR1cm4gRnVuY3Rpb24udG9TdHJpbmcuY2FsbChmbikuaW5kZXhPZihcIltuYXRpdmUgY29kZV1cIikgIT09IC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9pc05hdGl2ZUZ1bmN0aW9uOyIsImZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXkoaXRlcikge1xuICBpZiAoU3ltYm9sLml0ZXJhdG9yIGluIE9iamVjdChpdGVyKSB8fCBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaXRlcikgPT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHJldHVybiBBcnJheS5mcm9tKGl0ZXIpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9pdGVyYWJsZVRvQXJyYXk7IiwiZnVuY3Rpb24gX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkge1xuICB2YXIgX2FyciA9IFtdO1xuICB2YXIgX24gPSB0cnVlO1xuICB2YXIgX2QgPSBmYWxzZTtcbiAgdmFyIF9lID0gdW5kZWZpbmVkO1xuXG4gIHRyeSB7XG4gICAgZm9yICh2YXIgX2kgPSBhcnJbU3ltYm9sLml0ZXJhdG9yXSgpLCBfczsgIShfbiA9IChfcyA9IF9pLm5leHQoKSkuZG9uZSk7IF9uID0gdHJ1ZSkge1xuICAgICAgX2Fyci5wdXNoKF9zLnZhbHVlKTtcblxuICAgICAgaWYgKGkgJiYgX2Fyci5sZW5ndGggPT09IGkpIGJyZWFrO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgX2QgPSB0cnVlO1xuICAgIF9lID0gZXJyO1xuICB9IGZpbmFsbHkge1xuICAgIHRyeSB7XG4gICAgICBpZiAoIV9uICYmIF9pW1wicmV0dXJuXCJdICE9IG51bGwpIF9pW1wicmV0dXJuXCJdKCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmIChfZCkgdGhyb3cgX2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIF9hcnI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2l0ZXJhYmxlVG9BcnJheUxpbWl0OyIsImZ1bmN0aW9uIF9ub25JdGVyYWJsZVJlc3QoKSB7XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gZGVzdHJ1Y3R1cmUgbm9uLWl0ZXJhYmxlIGluc3RhbmNlXCIpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9ub25JdGVyYWJsZVJlc3Q7IiwiZnVuY3Rpb24gX25vbkl0ZXJhYmxlU3ByZWFkKCkge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIHNwcmVhZCBub24taXRlcmFibGUgaW5zdGFuY2VcIik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX25vbkl0ZXJhYmxlU3ByZWFkOyIsInZhciBkZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoXCIuL2RlZmluZVByb3BlcnR5XCIpO1xuXG5mdW5jdGlvbiBfb2JqZWN0U3ByZWFkKHRhcmdldCkge1xuICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV0gIT0gbnVsbCA/IGFyZ3VtZW50c1tpXSA6IHt9O1xuICAgIHZhciBvd25LZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblxuICAgIGlmICh0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgb3duS2V5cyA9IG93bktleXMuY29uY2F0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoc291cmNlKS5maWx0ZXIoZnVuY3Rpb24gKHN5bSkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzb3VyY2UsIHN5bSkuZW51bWVyYWJsZTtcbiAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBvd25LZXlzLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHNvdXJjZVtrZXldKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX29iamVjdFNwcmVhZDsiLCJ2YXIgX3R5cGVvZiA9IHJlcXVpcmUoXCIuLi9oZWxwZXJzL3R5cGVvZlwiKTtcblxudmFyIGFzc2VydFRoaXNJbml0aWFsaXplZCA9IHJlcXVpcmUoXCIuL2Fzc2VydFRoaXNJbml0aWFsaXplZFwiKTtcblxuZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkge1xuICBpZiAoY2FsbCAmJiAoX3R5cGVvZihjYWxsKSA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgY2FsbCA9PT0gXCJmdW5jdGlvblwiKSkge1xuICAgIHJldHVybiBjYWxsO1xuICB9XG5cbiAgcmV0dXJuIGFzc2VydFRoaXNJbml0aWFsaXplZChzZWxmKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjsiLCJmdW5jdGlvbiBfc2V0UHJvdG90eXBlT2YobywgcCkge1xuICBtb2R1bGUuZXhwb3J0cyA9IF9zZXRQcm90b3R5cGVPZiA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiBfc2V0UHJvdG90eXBlT2YobywgcCkge1xuICAgIG8uX19wcm90b19fID0gcDtcbiAgICByZXR1cm4gbztcbiAgfTtcblxuICByZXR1cm4gX3NldFByb3RvdHlwZU9mKG8sIHApO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9zZXRQcm90b3R5cGVPZjsiLCJ2YXIgYXJyYXlXaXRoSG9sZXMgPSByZXF1aXJlKFwiLi9hcnJheVdpdGhIb2xlc1wiKTtcblxudmFyIGl0ZXJhYmxlVG9BcnJheUxpbWl0ID0gcmVxdWlyZShcIi4vaXRlcmFibGVUb0FycmF5TGltaXRcIik7XG5cbnZhciBub25JdGVyYWJsZVJlc3QgPSByZXF1aXJlKFwiLi9ub25JdGVyYWJsZVJlc3RcIik7XG5cbmZ1bmN0aW9uIF9zbGljZWRUb0FycmF5KGFyciwgaSkge1xuICByZXR1cm4gYXJyYXlXaXRoSG9sZXMoYXJyKSB8fCBpdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHx8IG5vbkl0ZXJhYmxlUmVzdCgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9zbGljZWRUb0FycmF5OyIsInZhciBhcnJheVdpdGhIb2xlcyA9IHJlcXVpcmUoXCIuL2FycmF5V2l0aEhvbGVzXCIpO1xuXG52YXIgaXRlcmFibGVUb0FycmF5ID0gcmVxdWlyZShcIi4vaXRlcmFibGVUb0FycmF5XCIpO1xuXG52YXIgbm9uSXRlcmFibGVSZXN0ID0gcmVxdWlyZShcIi4vbm9uSXRlcmFibGVSZXN0XCIpO1xuXG5mdW5jdGlvbiBfdG9BcnJheShhcnIpIHtcbiAgcmV0dXJuIGFycmF5V2l0aEhvbGVzKGFycikgfHwgaXRlcmFibGVUb0FycmF5KGFycikgfHwgbm9uSXRlcmFibGVSZXN0KCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX3RvQXJyYXk7IiwidmFyIGFycmF5V2l0aG91dEhvbGVzID0gcmVxdWlyZShcIi4vYXJyYXlXaXRob3V0SG9sZXNcIik7XG5cbnZhciBpdGVyYWJsZVRvQXJyYXkgPSByZXF1aXJlKFwiLi9pdGVyYWJsZVRvQXJyYXlcIik7XG5cbnZhciBub25JdGVyYWJsZVNwcmVhZCA9IHJlcXVpcmUoXCIuL25vbkl0ZXJhYmxlU3ByZWFkXCIpO1xuXG5mdW5jdGlvbiBfdG9Db25zdW1hYmxlQXJyYXkoYXJyKSB7XG4gIHJldHVybiBhcnJheVdpdGhvdXRIb2xlcyhhcnIpIHx8IGl0ZXJhYmxlVG9BcnJheShhcnIpIHx8IG5vbkl0ZXJhYmxlU3ByZWFkKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX3RvQ29uc3VtYWJsZUFycmF5OyIsImZ1bmN0aW9uIF90eXBlb2YyKG9iaikgeyBpZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIpIHsgX3R5cGVvZjIgPSBmdW5jdGlvbiBfdHlwZW9mMihvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH07IH0gZWxzZSB7IF90eXBlb2YyID0gZnVuY3Rpb24gX3R5cGVvZjIob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9OyB9IHJldHVybiBfdHlwZW9mMihvYmopOyB9XG5cbmZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7XG4gIGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgX3R5cGVvZjIoU3ltYm9sLml0ZXJhdG9yKSA9PT0gXCJzeW1ib2xcIikge1xuICAgIG1vZHVsZS5leHBvcnRzID0gX3R5cGVvZiA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7XG4gICAgICByZXR1cm4gX3R5cGVvZjIob2JqKTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIG1vZHVsZS5leHBvcnRzID0gX3R5cGVvZiA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7XG4gICAgICByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogX3R5cGVvZjIob2JqKTtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIF90eXBlb2Yob2JqKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfdHlwZW9mOyIsInZhciBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoXCIuL2dldFByb3RvdHlwZU9mXCIpO1xuXG52YXIgc2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKFwiLi9zZXRQcm90b3R5cGVPZlwiKTtcblxudmFyIGlzTmF0aXZlRnVuY3Rpb24gPSByZXF1aXJlKFwiLi9pc05hdGl2ZUZ1bmN0aW9uXCIpO1xuXG52YXIgY29uc3RydWN0ID0gcmVxdWlyZShcIi4vY29uc3RydWN0XCIpO1xuXG5mdW5jdGlvbiBfd3JhcE5hdGl2ZVN1cGVyKENsYXNzKSB7XG4gIHZhciBfY2FjaGUgPSB0eXBlb2YgTWFwID09PSBcImZ1bmN0aW9uXCIgPyBuZXcgTWFwKCkgOiB1bmRlZmluZWQ7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBfd3JhcE5hdGl2ZVN1cGVyID0gZnVuY3Rpb24gX3dyYXBOYXRpdmVTdXBlcihDbGFzcykge1xuICAgIGlmIChDbGFzcyA9PT0gbnVsbCB8fCAhaXNOYXRpdmVGdW5jdGlvbihDbGFzcykpIHJldHVybiBDbGFzcztcblxuICAgIGlmICh0eXBlb2YgQ2xhc3MgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uXCIpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgX2NhY2hlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICBpZiAoX2NhY2hlLmhhcyhDbGFzcykpIHJldHVybiBfY2FjaGUuZ2V0KENsYXNzKTtcblxuICAgICAgX2NhY2hlLnNldChDbGFzcywgV3JhcHBlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gV3JhcHBlcigpIHtcbiAgICAgIHJldHVybiBjb25zdHJ1Y3QoQ2xhc3MsIGFyZ3VtZW50cywgZ2V0UHJvdG90eXBlT2YodGhpcykuY29uc3RydWN0b3IpO1xuICAgIH1cblxuICAgIFdyYXBwZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShDbGFzcy5wcm90b3R5cGUsIHtcbiAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgIHZhbHVlOiBXcmFwcGVyLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBzZXRQcm90b3R5cGVPZihXcmFwcGVyLCBDbGFzcyk7XG4gIH07XG5cbiAgcmV0dXJuIF93cmFwTmF0aXZlU3VwZXIoQ2xhc3MpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF93cmFwTmF0aXZlU3VwZXI7IiwiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4vLyBUaGlzIG1ldGhvZCBvZiBvYnRhaW5pbmcgYSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBvYmplY3QgbmVlZHMgdG8gYmVcbi8vIGtlcHQgaWRlbnRpY2FsIHRvIHRoZSB3YXkgaXQgaXMgb2J0YWluZWQgaW4gcnVudGltZS5qc1xudmFyIGcgPSAoZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzIHx8ICh0eXBlb2Ygc2VsZiA9PT0gXCJvYmplY3RcIiAmJiBzZWxmKTtcbn0pKCkgfHwgRnVuY3Rpb24oXCJyZXR1cm4gdGhpc1wiKSgpO1xuXG4vLyBVc2UgYGdldE93blByb3BlcnR5TmFtZXNgIGJlY2F1c2Ugbm90IGFsbCBicm93c2VycyBzdXBwb3J0IGNhbGxpbmdcbi8vIGBoYXNPd25Qcm9wZXJ0eWAgb24gdGhlIGdsb2JhbCBgc2VsZmAgb2JqZWN0IGluIGEgd29ya2VyLiBTZWUgIzE4My5cbnZhciBoYWRSdW50aW1lID0gZy5yZWdlbmVyYXRvclJ1bnRpbWUgJiZcbiAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoZykuaW5kZXhPZihcInJlZ2VuZXJhdG9yUnVudGltZVwiKSA+PSAwO1xuXG4vLyBTYXZlIHRoZSBvbGQgcmVnZW5lcmF0b3JSdW50aW1lIGluIGNhc2UgaXQgbmVlZHMgdG8gYmUgcmVzdG9yZWQgbGF0ZXIuXG52YXIgb2xkUnVudGltZSA9IGhhZFJ1bnRpbWUgJiYgZy5yZWdlbmVyYXRvclJ1bnRpbWU7XG5cbi8vIEZvcmNlIHJlZXZhbHV0YXRpb24gb2YgcnVudGltZS5qcy5cbmcucmVnZW5lcmF0b3JSdW50aW1lID0gdW5kZWZpbmVkO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL3J1bnRpbWVcIik7XG5cbmlmIChoYWRSdW50aW1lKSB7XG4gIC8vIFJlc3RvcmUgdGhlIG9yaWdpbmFsIHJ1bnRpbWUuXG4gIGcucmVnZW5lcmF0b3JSdW50aW1lID0gb2xkUnVudGltZTtcbn0gZWxzZSB7XG4gIC8vIFJlbW92ZSB0aGUgZ2xvYmFsIHByb3BlcnR5IGFkZGVkIGJ5IHJ1bnRpbWUuanMuXG4gIHRyeSB7XG4gICAgZGVsZXRlIGcucmVnZW5lcmF0b3JSdW50aW1lO1xuICB9IGNhdGNoKGUpIHtcbiAgICBnLnJlZ2VuZXJhdG9yUnVudGltZSA9IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4hKGZ1bmN0aW9uKGdsb2JhbCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICB2YXIgT3AgPSBPYmplY3QucHJvdG90eXBlO1xuICB2YXIgaGFzT3duID0gT3AuaGFzT3duUHJvcGVydHk7XG4gIHZhciB1bmRlZmluZWQ7IC8vIE1vcmUgY29tcHJlc3NpYmxlIHRoYW4gdm9pZCAwLlxuICB2YXIgJFN5bWJvbCA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiA/IFN5bWJvbCA6IHt9O1xuICB2YXIgaXRlcmF0b3JTeW1ib2wgPSAkU3ltYm9sLml0ZXJhdG9yIHx8IFwiQEBpdGVyYXRvclwiO1xuICB2YXIgYXN5bmNJdGVyYXRvclN5bWJvbCA9ICRTeW1ib2wuYXN5bmNJdGVyYXRvciB8fCBcIkBAYXN5bmNJdGVyYXRvclwiO1xuICB2YXIgdG9TdHJpbmdUYWdTeW1ib2wgPSAkU3ltYm9sLnRvU3RyaW5nVGFnIHx8IFwiQEB0b1N0cmluZ1RhZ1wiO1xuXG4gIHZhciBpbk1vZHVsZSA9IHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCI7XG4gIHZhciBydW50aW1lID0gZ2xvYmFsLnJlZ2VuZXJhdG9yUnVudGltZTtcbiAgaWYgKHJ1bnRpbWUpIHtcbiAgICBpZiAoaW5Nb2R1bGUpIHtcbiAgICAgIC8vIElmIHJlZ2VuZXJhdG9yUnVudGltZSBpcyBkZWZpbmVkIGdsb2JhbGx5IGFuZCB3ZSdyZSBpbiBhIG1vZHVsZSxcbiAgICAgIC8vIG1ha2UgdGhlIGV4cG9ydHMgb2JqZWN0IGlkZW50aWNhbCB0byByZWdlbmVyYXRvclJ1bnRpbWUuXG4gICAgICBtb2R1bGUuZXhwb3J0cyA9IHJ1bnRpbWU7XG4gICAgfVxuICAgIC8vIERvbid0IGJvdGhlciBldmFsdWF0aW5nIHRoZSByZXN0IG9mIHRoaXMgZmlsZSBpZiB0aGUgcnVudGltZSB3YXNcbiAgICAvLyBhbHJlYWR5IGRlZmluZWQgZ2xvYmFsbHkuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRGVmaW5lIHRoZSBydW50aW1lIGdsb2JhbGx5IChhcyBleHBlY3RlZCBieSBnZW5lcmF0ZWQgY29kZSkgYXMgZWl0aGVyXG4gIC8vIG1vZHVsZS5leHBvcnRzIChpZiB3ZSdyZSBpbiBhIG1vZHVsZSkgb3IgYSBuZXcsIGVtcHR5IG9iamVjdC5cbiAgcnVudGltZSA9IGdsb2JhbC5yZWdlbmVyYXRvclJ1bnRpbWUgPSBpbk1vZHVsZSA/IG1vZHVsZS5leHBvcnRzIDoge307XG5cbiAgZnVuY3Rpb24gd3JhcChpbm5lckZuLCBvdXRlckZuLCBzZWxmLCB0cnlMb2NzTGlzdCkge1xuICAgIC8vIElmIG91dGVyRm4gcHJvdmlkZWQgYW5kIG91dGVyRm4ucHJvdG90eXBlIGlzIGEgR2VuZXJhdG9yLCB0aGVuIG91dGVyRm4ucHJvdG90eXBlIGluc3RhbmNlb2YgR2VuZXJhdG9yLlxuICAgIHZhciBwcm90b0dlbmVyYXRvciA9IG91dGVyRm4gJiYgb3V0ZXJGbi5wcm90b3R5cGUgaW5zdGFuY2VvZiBHZW5lcmF0b3IgPyBvdXRlckZuIDogR2VuZXJhdG9yO1xuICAgIHZhciBnZW5lcmF0b3IgPSBPYmplY3QuY3JlYXRlKHByb3RvR2VuZXJhdG9yLnByb3RvdHlwZSk7XG4gICAgdmFyIGNvbnRleHQgPSBuZXcgQ29udGV4dCh0cnlMb2NzTGlzdCB8fCBbXSk7XG5cbiAgICAvLyBUaGUgLl9pbnZva2UgbWV0aG9kIHVuaWZpZXMgdGhlIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgLm5leHQsXG4gICAgLy8gLnRocm93LCBhbmQgLnJldHVybiBtZXRob2RzLlxuICAgIGdlbmVyYXRvci5faW52b2tlID0gbWFrZUludm9rZU1ldGhvZChpbm5lckZuLCBzZWxmLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBnZW5lcmF0b3I7XG4gIH1cbiAgcnVudGltZS53cmFwID0gd3JhcDtcblxuICAvLyBUcnkvY2F0Y2ggaGVscGVyIHRvIG1pbmltaXplIGRlb3B0aW1pemF0aW9ucy4gUmV0dXJucyBhIGNvbXBsZXRpb25cbiAgLy8gcmVjb3JkIGxpa2UgY29udGV4dC50cnlFbnRyaWVzW2ldLmNvbXBsZXRpb24uIFRoaXMgaW50ZXJmYWNlIGNvdWxkXG4gIC8vIGhhdmUgYmVlbiAoYW5kIHdhcyBwcmV2aW91c2x5KSBkZXNpZ25lZCB0byB0YWtlIGEgY2xvc3VyZSB0byBiZVxuICAvLyBpbnZva2VkIHdpdGhvdXQgYXJndW1lbnRzLCBidXQgaW4gYWxsIHRoZSBjYXNlcyB3ZSBjYXJlIGFib3V0IHdlXG4gIC8vIGFscmVhZHkgaGF2ZSBhbiBleGlzdGluZyBtZXRob2Qgd2Ugd2FudCB0byBjYWxsLCBzbyB0aGVyZSdzIG5vIG5lZWRcbiAgLy8gdG8gY3JlYXRlIGEgbmV3IGZ1bmN0aW9uIG9iamVjdC4gV2UgY2FuIGV2ZW4gZ2V0IGF3YXkgd2l0aCBhc3N1bWluZ1xuICAvLyB0aGUgbWV0aG9kIHRha2VzIGV4YWN0bHkgb25lIGFyZ3VtZW50LCBzaW5jZSB0aGF0IGhhcHBlbnMgdG8gYmUgdHJ1ZVxuICAvLyBpbiBldmVyeSBjYXNlLCBzbyB3ZSBkb24ndCBoYXZlIHRvIHRvdWNoIHRoZSBhcmd1bWVudHMgb2JqZWN0LiBUaGVcbiAgLy8gb25seSBhZGRpdGlvbmFsIGFsbG9jYXRpb24gcmVxdWlyZWQgaXMgdGhlIGNvbXBsZXRpb24gcmVjb3JkLCB3aGljaFxuICAvLyBoYXMgYSBzdGFibGUgc2hhcGUgYW5kIHNvIGhvcGVmdWxseSBzaG91bGQgYmUgY2hlYXAgdG8gYWxsb2NhdGUuXG4gIGZ1bmN0aW9uIHRyeUNhdGNoKGZuLCBvYmosIGFyZykge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcIm5vcm1hbFwiLCBhcmc6IGZuLmNhbGwob2JqLCBhcmcpIH07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcInRocm93XCIsIGFyZzogZXJyIH07XG4gICAgfVxuICB9XG5cbiAgdmFyIEdlblN0YXRlU3VzcGVuZGVkU3RhcnQgPSBcInN1c3BlbmRlZFN0YXJ0XCI7XG4gIHZhciBHZW5TdGF0ZVN1c3BlbmRlZFlpZWxkID0gXCJzdXNwZW5kZWRZaWVsZFwiO1xuICB2YXIgR2VuU3RhdGVFeGVjdXRpbmcgPSBcImV4ZWN1dGluZ1wiO1xuICB2YXIgR2VuU3RhdGVDb21wbGV0ZWQgPSBcImNvbXBsZXRlZFwiO1xuXG4gIC8vIFJldHVybmluZyB0aGlzIG9iamVjdCBmcm9tIHRoZSBpbm5lckZuIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXNcbiAgLy8gYnJlYWtpbmcgb3V0IG9mIHRoZSBkaXNwYXRjaCBzd2l0Y2ggc3RhdGVtZW50LlxuICB2YXIgQ29udGludWVTZW50aW5lbCA9IHt9O1xuXG4gIC8vIER1bW15IGNvbnN0cnVjdG9yIGZ1bmN0aW9ucyB0aGF0IHdlIHVzZSBhcyB0aGUgLmNvbnN0cnVjdG9yIGFuZFxuICAvLyAuY29uc3RydWN0b3IucHJvdG90eXBlIHByb3BlcnRpZXMgZm9yIGZ1bmN0aW9ucyB0aGF0IHJldHVybiBHZW5lcmF0b3JcbiAgLy8gb2JqZWN0cy4gRm9yIGZ1bGwgc3BlYyBjb21wbGlhbmNlLCB5b3UgbWF5IHdpc2ggdG8gY29uZmlndXJlIHlvdXJcbiAgLy8gbWluaWZpZXIgbm90IHRvIG1hbmdsZSB0aGUgbmFtZXMgb2YgdGhlc2UgdHdvIGZ1bmN0aW9ucy5cbiAgZnVuY3Rpb24gR2VuZXJhdG9yKCkge31cbiAgZnVuY3Rpb24gR2VuZXJhdG9yRnVuY3Rpb24oKSB7fVxuICBmdW5jdGlvbiBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZSgpIHt9XG5cbiAgLy8gVGhpcyBpcyBhIHBvbHlmaWxsIGZvciAlSXRlcmF0b3JQcm90b3R5cGUlIGZvciBlbnZpcm9ubWVudHMgdGhhdFxuICAvLyBkb24ndCBuYXRpdmVseSBzdXBwb3J0IGl0LlxuICB2YXIgSXRlcmF0b3JQcm90b3R5cGUgPSB7fTtcbiAgSXRlcmF0b3JQcm90b3R5cGVbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIHZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjtcbiAgdmFyIE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlID0gZ2V0UHJvdG8gJiYgZ2V0UHJvdG8oZ2V0UHJvdG8odmFsdWVzKFtdKSkpO1xuICBpZiAoTmF0aXZlSXRlcmF0b3JQcm90b3R5cGUgJiZcbiAgICAgIE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlICE9PSBPcCAmJlxuICAgICAgaGFzT3duLmNhbGwoTmF0aXZlSXRlcmF0b3JQcm90b3R5cGUsIGl0ZXJhdG9yU3ltYm9sKSkge1xuICAgIC8vIFRoaXMgZW52aXJvbm1lbnQgaGFzIGEgbmF0aXZlICVJdGVyYXRvclByb3RvdHlwZSU7IHVzZSBpdCBpbnN0ZWFkXG4gICAgLy8gb2YgdGhlIHBvbHlmaWxsLlxuICAgIEl0ZXJhdG9yUHJvdG90eXBlID0gTmF0aXZlSXRlcmF0b3JQcm90b3R5cGU7XG4gIH1cblxuICB2YXIgR3AgPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZS5wcm90b3R5cGUgPVxuICAgIEdlbmVyYXRvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEl0ZXJhdG9yUHJvdG90eXBlKTtcbiAgR2VuZXJhdG9yRnVuY3Rpb24ucHJvdG90eXBlID0gR3AuY29uc3RydWN0b3IgPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZTtcbiAgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUuY29uc3RydWN0b3IgPSBHZW5lcmF0b3JGdW5jdGlvbjtcbiAgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGVbdG9TdHJpbmdUYWdTeW1ib2xdID1cbiAgICBHZW5lcmF0b3JGdW5jdGlvbi5kaXNwbGF5TmFtZSA9IFwiR2VuZXJhdG9yRnVuY3Rpb25cIjtcblxuICAvLyBIZWxwZXIgZm9yIGRlZmluaW5nIHRoZSAubmV4dCwgLnRocm93LCBhbmQgLnJldHVybiBtZXRob2RzIG9mIHRoZVxuICAvLyBJdGVyYXRvciBpbnRlcmZhY2UgaW4gdGVybXMgb2YgYSBzaW5nbGUgLl9pbnZva2UgbWV0aG9kLlxuICBmdW5jdGlvbiBkZWZpbmVJdGVyYXRvck1ldGhvZHMocHJvdG90eXBlKSB7XG4gICAgW1wibmV4dFwiLCBcInRocm93XCIsIFwicmV0dXJuXCJdLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICBwcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKGFyZykge1xuICAgICAgICByZXR1cm4gdGhpcy5faW52b2tlKG1ldGhvZCwgYXJnKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBydW50aW1lLmlzR2VuZXJhdG9yRnVuY3Rpb24gPSBmdW5jdGlvbihnZW5GdW4pIHtcbiAgICB2YXIgY3RvciA9IHR5cGVvZiBnZW5GdW4gPT09IFwiZnVuY3Rpb25cIiAmJiBnZW5GdW4uY29uc3RydWN0b3I7XG4gICAgcmV0dXJuIGN0b3JcbiAgICAgID8gY3RvciA9PT0gR2VuZXJhdG9yRnVuY3Rpb24gfHxcbiAgICAgICAgLy8gRm9yIHRoZSBuYXRpdmUgR2VuZXJhdG9yRnVuY3Rpb24gY29uc3RydWN0b3IsIHRoZSBiZXN0IHdlIGNhblxuICAgICAgICAvLyBkbyBpcyB0byBjaGVjayBpdHMgLm5hbWUgcHJvcGVydHkuXG4gICAgICAgIChjdG9yLmRpc3BsYXlOYW1lIHx8IGN0b3IubmFtZSkgPT09IFwiR2VuZXJhdG9yRnVuY3Rpb25cIlxuICAgICAgOiBmYWxzZTtcbiAgfTtcblxuICBydW50aW1lLm1hcmsgPSBmdW5jdGlvbihnZW5GdW4pIHtcbiAgICBpZiAoT2JqZWN0LnNldFByb3RvdHlwZU9mKSB7XG4gICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoZ2VuRnVuLCBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdlbkZ1bi5fX3Byb3RvX18gPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZTtcbiAgICAgIGlmICghKHRvU3RyaW5nVGFnU3ltYm9sIGluIGdlbkZ1bikpIHtcbiAgICAgICAgZ2VuRnVuW3RvU3RyaW5nVGFnU3ltYm9sXSA9IFwiR2VuZXJhdG9yRnVuY3Rpb25cIjtcbiAgICAgIH1cbiAgICB9XG4gICAgZ2VuRnVuLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoR3ApO1xuICAgIHJldHVybiBnZW5GdW47XG4gIH07XG5cbiAgLy8gV2l0aGluIHRoZSBib2R5IG9mIGFueSBhc3luYyBmdW5jdGlvbiwgYGF3YWl0IHhgIGlzIHRyYW5zZm9ybWVkIHRvXG4gIC8vIGB5aWVsZCByZWdlbmVyYXRvclJ1bnRpbWUuYXdyYXAoeClgLCBzbyB0aGF0IHRoZSBydW50aW1lIGNhbiB0ZXN0XG4gIC8vIGBoYXNPd24uY2FsbCh2YWx1ZSwgXCJfX2F3YWl0XCIpYCB0byBkZXRlcm1pbmUgaWYgdGhlIHlpZWxkZWQgdmFsdWUgaXNcbiAgLy8gbWVhbnQgdG8gYmUgYXdhaXRlZC5cbiAgcnVudGltZS5hd3JhcCA9IGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiB7IF9fYXdhaXQ6IGFyZyB9O1xuICB9O1xuXG4gIGZ1bmN0aW9uIEFzeW5jSXRlcmF0b3IoZ2VuZXJhdG9yKSB7XG4gICAgZnVuY3Rpb24gaW52b2tlKG1ldGhvZCwgYXJnLCByZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciByZWNvcmQgPSB0cnlDYXRjaChnZW5lcmF0b3JbbWV0aG9kXSwgZ2VuZXJhdG9yLCBhcmcpO1xuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgcmVqZWN0KHJlY29yZC5hcmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlY29yZC5hcmc7XG4gICAgICAgIHZhciB2YWx1ZSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgaWYgKHZhbHVlICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgICAgIGhhc093bi5jYWxsKHZhbHVlLCBcIl9fYXdhaXRcIikpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlLl9fYXdhaXQpLnRoZW4oZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIGludm9rZShcIm5leHRcIiwgdmFsdWUsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgfSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgICBpbnZva2UoXCJ0aHJvd1wiLCBlcnIsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlKS50aGVuKGZ1bmN0aW9uKHVud3JhcHBlZCkge1xuICAgICAgICAgIC8vIFdoZW4gYSB5aWVsZGVkIFByb21pc2UgaXMgcmVzb2x2ZWQsIGl0cyBmaW5hbCB2YWx1ZSBiZWNvbWVzXG4gICAgICAgICAgLy8gdGhlIC52YWx1ZSBvZiB0aGUgUHJvbWlzZTx7dmFsdWUsZG9uZX0+IHJlc3VsdCBmb3IgdGhlXG4gICAgICAgICAgLy8gY3VycmVudCBpdGVyYXRpb24uXG4gICAgICAgICAgcmVzdWx0LnZhbHVlID0gdW53cmFwcGVkO1xuICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfSwgZnVuY3Rpb24oZXJyb3IpIHtcbiAgICAgICAgICAvLyBJZiBhIHJlamVjdGVkIFByb21pc2Ugd2FzIHlpZWxkZWQsIHRocm93IHRoZSByZWplY3Rpb24gYmFja1xuICAgICAgICAgIC8vIGludG8gdGhlIGFzeW5jIGdlbmVyYXRvciBmdW5jdGlvbiBzbyBpdCBjYW4gYmUgaGFuZGxlZCB0aGVyZS5cbiAgICAgICAgICByZXR1cm4gaW52b2tlKFwidGhyb3dcIiwgZXJyb3IsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBwcmV2aW91c1Byb21pc2U7XG5cbiAgICBmdW5jdGlvbiBlbnF1ZXVlKG1ldGhvZCwgYXJnKSB7XG4gICAgICBmdW5jdGlvbiBjYWxsSW52b2tlV2l0aE1ldGhvZEFuZEFyZygpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgIGludm9rZShtZXRob2QsIGFyZywgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwcmV2aW91c1Byb21pc2UgPVxuICAgICAgICAvLyBJZiBlbnF1ZXVlIGhhcyBiZWVuIGNhbGxlZCBiZWZvcmUsIHRoZW4gd2Ugd2FudCB0byB3YWl0IHVudGlsXG4gICAgICAgIC8vIGFsbCBwcmV2aW91cyBQcm9taXNlcyBoYXZlIGJlZW4gcmVzb2x2ZWQgYmVmb3JlIGNhbGxpbmcgaW52b2tlLFxuICAgICAgICAvLyBzbyB0aGF0IHJlc3VsdHMgYXJlIGFsd2F5cyBkZWxpdmVyZWQgaW4gdGhlIGNvcnJlY3Qgb3JkZXIuIElmXG4gICAgICAgIC8vIGVucXVldWUgaGFzIG5vdCBiZWVuIGNhbGxlZCBiZWZvcmUsIHRoZW4gaXQgaXMgaW1wb3J0YW50IHRvXG4gICAgICAgIC8vIGNhbGwgaW52b2tlIGltbWVkaWF0ZWx5LCB3aXRob3V0IHdhaXRpbmcgb24gYSBjYWxsYmFjayB0byBmaXJlLFxuICAgICAgICAvLyBzbyB0aGF0IHRoZSBhc3luYyBnZW5lcmF0b3IgZnVuY3Rpb24gaGFzIHRoZSBvcHBvcnR1bml0eSB0byBkb1xuICAgICAgICAvLyBhbnkgbmVjZXNzYXJ5IHNldHVwIGluIGEgcHJlZGljdGFibGUgd2F5LiBUaGlzIHByZWRpY3RhYmlsaXR5XG4gICAgICAgIC8vIGlzIHdoeSB0aGUgUHJvbWlzZSBjb25zdHJ1Y3RvciBzeW5jaHJvbm91c2x5IGludm9rZXMgaXRzXG4gICAgICAgIC8vIGV4ZWN1dG9yIGNhbGxiYWNrLCBhbmQgd2h5IGFzeW5jIGZ1bmN0aW9ucyBzeW5jaHJvbm91c2x5XG4gICAgICAgIC8vIGV4ZWN1dGUgY29kZSBiZWZvcmUgdGhlIGZpcnN0IGF3YWl0LiBTaW5jZSB3ZSBpbXBsZW1lbnQgc2ltcGxlXG4gICAgICAgIC8vIGFzeW5jIGZ1bmN0aW9ucyBpbiB0ZXJtcyBvZiBhc3luYyBnZW5lcmF0b3JzLCBpdCBpcyBlc3BlY2lhbGx5XG4gICAgICAgIC8vIGltcG9ydGFudCB0byBnZXQgdGhpcyByaWdodCwgZXZlbiB0aG91Z2ggaXQgcmVxdWlyZXMgY2FyZS5cbiAgICAgICAgcHJldmlvdXNQcm9taXNlID8gcHJldmlvdXNQcm9taXNlLnRoZW4oXG4gICAgICAgICAgY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmcsXG4gICAgICAgICAgLy8gQXZvaWQgcHJvcGFnYXRpbmcgZmFpbHVyZXMgdG8gUHJvbWlzZXMgcmV0dXJuZWQgYnkgbGF0ZXJcbiAgICAgICAgICAvLyBpbnZvY2F0aW9ucyBvZiB0aGUgaXRlcmF0b3IuXG4gICAgICAgICAgY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmdcbiAgICAgICAgKSA6IGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnKCk7XG4gICAgfVxuXG4gICAgLy8gRGVmaW5lIHRoZSB1bmlmaWVkIGhlbHBlciBtZXRob2QgdGhhdCBpcyB1c2VkIHRvIGltcGxlbWVudCAubmV4dCxcbiAgICAvLyAudGhyb3csIGFuZCAucmV0dXJuIChzZWUgZGVmaW5lSXRlcmF0b3JNZXRob2RzKS5cbiAgICB0aGlzLl9pbnZva2UgPSBlbnF1ZXVlO1xuICB9XG5cbiAgZGVmaW5lSXRlcmF0b3JNZXRob2RzKEFzeW5jSXRlcmF0b3IucHJvdG90eXBlKTtcbiAgQXN5bmNJdGVyYXRvci5wcm90b3R5cGVbYXN5bmNJdGVyYXRvclN5bWJvbF0gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG4gIHJ1bnRpbWUuQXN5bmNJdGVyYXRvciA9IEFzeW5jSXRlcmF0b3I7XG5cbiAgLy8gTm90ZSB0aGF0IHNpbXBsZSBhc3luYyBmdW5jdGlvbnMgYXJlIGltcGxlbWVudGVkIG9uIHRvcCBvZlxuICAvLyBBc3luY0l0ZXJhdG9yIG9iamVjdHM7IHRoZXkganVzdCByZXR1cm4gYSBQcm9taXNlIGZvciB0aGUgdmFsdWUgb2ZcbiAgLy8gdGhlIGZpbmFsIHJlc3VsdCBwcm9kdWNlZCBieSB0aGUgaXRlcmF0b3IuXG4gIHJ1bnRpbWUuYXN5bmMgPSBmdW5jdGlvbihpbm5lckZuLCBvdXRlckZuLCBzZWxmLCB0cnlMb2NzTGlzdCkge1xuICAgIHZhciBpdGVyID0gbmV3IEFzeW5jSXRlcmF0b3IoXG4gICAgICB3cmFwKGlubmVyRm4sIG91dGVyRm4sIHNlbGYsIHRyeUxvY3NMaXN0KVxuICAgICk7XG5cbiAgICByZXR1cm4gcnVudGltZS5pc0dlbmVyYXRvckZ1bmN0aW9uKG91dGVyRm4pXG4gICAgICA/IGl0ZXIgLy8gSWYgb3V0ZXJGbiBpcyBhIGdlbmVyYXRvciwgcmV0dXJuIHRoZSBmdWxsIGl0ZXJhdG9yLlxuICAgICAgOiBpdGVyLm5leHQoKS50aGVuKGZ1bmN0aW9uKHJlc3VsdCkge1xuICAgICAgICAgIHJldHVybiByZXN1bHQuZG9uZSA/IHJlc3VsdC52YWx1ZSA6IGl0ZXIubmV4dCgpO1xuICAgICAgICB9KTtcbiAgfTtcblxuICBmdW5jdGlvbiBtYWtlSW52b2tlTWV0aG9kKGlubmVyRm4sIHNlbGYsIGNvbnRleHQpIHtcbiAgICB2YXIgc3RhdGUgPSBHZW5TdGF0ZVN1c3BlbmRlZFN0YXJ0O1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIGludm9rZShtZXRob2QsIGFyZykge1xuICAgICAgaWYgKHN0YXRlID09PSBHZW5TdGF0ZUV4ZWN1dGluZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBydW5uaW5nXCIpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3RhdGUgPT09IEdlblN0YXRlQ29tcGxldGVkKSB7XG4gICAgICAgIGlmIChtZXRob2QgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgIHRocm93IGFyZztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJlIGZvcmdpdmluZywgcGVyIDI1LjMuMy4zLjMgb2YgdGhlIHNwZWM6XG4gICAgICAgIC8vIGh0dHBzOi8vcGVvcGxlLm1vemlsbGEub3JnL35qb3JlbmRvcmZmL2VzNi1kcmFmdC5odG1sI3NlYy1nZW5lcmF0b3JyZXN1bWVcbiAgICAgICAgcmV0dXJuIGRvbmVSZXN1bHQoKTtcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5tZXRob2QgPSBtZXRob2Q7XG4gICAgICBjb250ZXh0LmFyZyA9IGFyZztcblxuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgdmFyIGRlbGVnYXRlID0gY29udGV4dC5kZWxlZ2F0ZTtcbiAgICAgICAgaWYgKGRlbGVnYXRlKSB7XG4gICAgICAgICAgdmFyIGRlbGVnYXRlUmVzdWx0ID0gbWF5YmVJbnZva2VEZWxlZ2F0ZShkZWxlZ2F0ZSwgY29udGV4dCk7XG4gICAgICAgICAgaWYgKGRlbGVnYXRlUmVzdWx0KSB7XG4gICAgICAgICAgICBpZiAoZGVsZWdhdGVSZXN1bHQgPT09IENvbnRpbnVlU2VudGluZWwpIGNvbnRpbnVlO1xuICAgICAgICAgICAgcmV0dXJuIGRlbGVnYXRlUmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJuZXh0XCIpIHtcbiAgICAgICAgICAvLyBTZXR0aW5nIGNvbnRleHQuX3NlbnQgZm9yIGxlZ2FjeSBzdXBwb3J0IG9mIEJhYmVsJ3NcbiAgICAgICAgICAvLyBmdW5jdGlvbi5zZW50IGltcGxlbWVudGF0aW9uLlxuICAgICAgICAgIGNvbnRleHQuc2VudCA9IGNvbnRleHQuX3NlbnQgPSBjb250ZXh0LmFyZztcblxuICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHQubWV0aG9kID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICBpZiAoc3RhdGUgPT09IEdlblN0YXRlU3VzcGVuZGVkU3RhcnQpIHtcbiAgICAgICAgICAgIHN0YXRlID0gR2VuU3RhdGVDb21wbGV0ZWQ7XG4gICAgICAgICAgICB0aHJvdyBjb250ZXh0LmFyZztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb250ZXh0LmRpc3BhdGNoRXhjZXB0aW9uKGNvbnRleHQuYXJnKTtcblxuICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHQubWV0aG9kID09PSBcInJldHVyblwiKSB7XG4gICAgICAgICAgY29udGV4dC5hYnJ1cHQoXCJyZXR1cm5cIiwgY29udGV4dC5hcmcpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RhdGUgPSBHZW5TdGF0ZUV4ZWN1dGluZztcblxuICAgICAgICB2YXIgcmVjb3JkID0gdHJ5Q2F0Y2goaW5uZXJGbiwgc2VsZiwgY29udGV4dCk7XG4gICAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJub3JtYWxcIikge1xuICAgICAgICAgIC8vIElmIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24gZnJvbSBpbm5lckZuLCB3ZSBsZWF2ZSBzdGF0ZSA9PT1cbiAgICAgICAgICAvLyBHZW5TdGF0ZUV4ZWN1dGluZyBhbmQgbG9vcCBiYWNrIGZvciBhbm90aGVyIGludm9jYXRpb24uXG4gICAgICAgICAgc3RhdGUgPSBjb250ZXh0LmRvbmVcbiAgICAgICAgICAgID8gR2VuU3RhdGVDb21wbGV0ZWRcbiAgICAgICAgICAgIDogR2VuU3RhdGVTdXNwZW5kZWRZaWVsZDtcblxuICAgICAgICAgIGlmIChyZWNvcmQuYXJnID09PSBDb250aW51ZVNlbnRpbmVsKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsdWU6IHJlY29yZC5hcmcsXG4gICAgICAgICAgICBkb25lOiBjb250ZXh0LmRvbmVcbiAgICAgICAgICB9O1xuXG4gICAgICAgIH0gZWxzZSBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgIHN0YXRlID0gR2VuU3RhdGVDb21wbGV0ZWQ7XG4gICAgICAgICAgLy8gRGlzcGF0Y2ggdGhlIGV4Y2VwdGlvbiBieSBsb29waW5nIGJhY2sgYXJvdW5kIHRvIHRoZVxuICAgICAgICAgIC8vIGNvbnRleHQuZGlzcGF0Y2hFeGNlcHRpb24oY29udGV4dC5hcmcpIGNhbGwgYWJvdmUuXG4gICAgICAgICAgY29udGV4dC5tZXRob2QgPSBcInRocm93XCI7XG4gICAgICAgICAgY29udGV4dC5hcmcgPSByZWNvcmQuYXJnO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8vIENhbGwgZGVsZWdhdGUuaXRlcmF0b3JbY29udGV4dC5tZXRob2RdKGNvbnRleHQuYXJnKSBhbmQgaGFuZGxlIHRoZVxuICAvLyByZXN1bHQsIGVpdGhlciBieSByZXR1cm5pbmcgYSB7IHZhbHVlLCBkb25lIH0gcmVzdWx0IGZyb20gdGhlXG4gIC8vIGRlbGVnYXRlIGl0ZXJhdG9yLCBvciBieSBtb2RpZnlpbmcgY29udGV4dC5tZXRob2QgYW5kIGNvbnRleHQuYXJnLFxuICAvLyBzZXR0aW5nIGNvbnRleHQuZGVsZWdhdGUgdG8gbnVsbCwgYW5kIHJldHVybmluZyB0aGUgQ29udGludWVTZW50aW5lbC5cbiAgZnVuY3Rpb24gbWF5YmVJbnZva2VEZWxlZ2F0ZShkZWxlZ2F0ZSwgY29udGV4dCkge1xuICAgIHZhciBtZXRob2QgPSBkZWxlZ2F0ZS5pdGVyYXRvcltjb250ZXh0Lm1ldGhvZF07XG4gICAgaWYgKG1ldGhvZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBBIC50aHJvdyBvciAucmV0dXJuIHdoZW4gdGhlIGRlbGVnYXRlIGl0ZXJhdG9yIGhhcyBubyAudGhyb3dcbiAgICAgIC8vIG1ldGhvZCBhbHdheXMgdGVybWluYXRlcyB0aGUgeWllbGQqIGxvb3AuXG4gICAgICBjb250ZXh0LmRlbGVnYXRlID0gbnVsbDtcblxuICAgICAgaWYgKGNvbnRleHQubWV0aG9kID09PSBcInRocm93XCIpIHtcbiAgICAgICAgaWYgKGRlbGVnYXRlLml0ZXJhdG9yLnJldHVybikge1xuICAgICAgICAgIC8vIElmIHRoZSBkZWxlZ2F0ZSBpdGVyYXRvciBoYXMgYSByZXR1cm4gbWV0aG9kLCBnaXZlIGl0IGFcbiAgICAgICAgICAvLyBjaGFuY2UgdG8gY2xlYW4gdXAuXG4gICAgICAgICAgY29udGV4dC5tZXRob2QgPSBcInJldHVyblwiO1xuICAgICAgICAgIGNvbnRleHQuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgICAgIG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpO1xuXG4gICAgICAgICAgaWYgKGNvbnRleHQubWV0aG9kID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgIC8vIElmIG1heWJlSW52b2tlRGVsZWdhdGUoY29udGV4dCkgY2hhbmdlZCBjb250ZXh0Lm1ldGhvZCBmcm9tXG4gICAgICAgICAgICAvLyBcInJldHVyblwiIHRvIFwidGhyb3dcIiwgbGV0IHRoYXQgb3ZlcnJpZGUgdGhlIFR5cGVFcnJvciBiZWxvdy5cbiAgICAgICAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgICBjb250ZXh0LmFyZyA9IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgXCJUaGUgaXRlcmF0b3IgZG9lcyBub3QgcHJvdmlkZSBhICd0aHJvdycgbWV0aG9kXCIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9XG5cbiAgICB2YXIgcmVjb3JkID0gdHJ5Q2F0Y2gobWV0aG9kLCBkZWxlZ2F0ZS5pdGVyYXRvciwgY29udGV4dC5hcmcpO1xuXG4gICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgY29udGV4dC5hcmcgPSByZWNvcmQuYXJnO1xuICAgICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9XG5cbiAgICB2YXIgaW5mbyA9IHJlY29yZC5hcmc7XG5cbiAgICBpZiAoISBpbmZvKSB7XG4gICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgIGNvbnRleHQuYXJnID0gbmV3IFR5cGVFcnJvcihcIml0ZXJhdG9yIHJlc3VsdCBpcyBub3QgYW4gb2JqZWN0XCIpO1xuICAgICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9XG5cbiAgICBpZiAoaW5mby5kb25lKSB7XG4gICAgICAvLyBBc3NpZ24gdGhlIHJlc3VsdCBvZiB0aGUgZmluaXNoZWQgZGVsZWdhdGUgdG8gdGhlIHRlbXBvcmFyeVxuICAgICAgLy8gdmFyaWFibGUgc3BlY2lmaWVkIGJ5IGRlbGVnYXRlLnJlc3VsdE5hbWUgKHNlZSBkZWxlZ2F0ZVlpZWxkKS5cbiAgICAgIGNvbnRleHRbZGVsZWdhdGUucmVzdWx0TmFtZV0gPSBpbmZvLnZhbHVlO1xuXG4gICAgICAvLyBSZXN1bWUgZXhlY3V0aW9uIGF0IHRoZSBkZXNpcmVkIGxvY2F0aW9uIChzZWUgZGVsZWdhdGVZaWVsZCkuXG4gICAgICBjb250ZXh0Lm5leHQgPSBkZWxlZ2F0ZS5uZXh0TG9jO1xuXG4gICAgICAvLyBJZiBjb250ZXh0Lm1ldGhvZCB3YXMgXCJ0aHJvd1wiIGJ1dCB0aGUgZGVsZWdhdGUgaGFuZGxlZCB0aGVcbiAgICAgIC8vIGV4Y2VwdGlvbiwgbGV0IHRoZSBvdXRlciBnZW5lcmF0b3IgcHJvY2VlZCBub3JtYWxseS4gSWZcbiAgICAgIC8vIGNvbnRleHQubWV0aG9kIHdhcyBcIm5leHRcIiwgZm9yZ2V0IGNvbnRleHQuYXJnIHNpbmNlIGl0IGhhcyBiZWVuXG4gICAgICAvLyBcImNvbnN1bWVkXCIgYnkgdGhlIGRlbGVnYXRlIGl0ZXJhdG9yLiBJZiBjb250ZXh0Lm1ldGhvZCB3YXNcbiAgICAgIC8vIFwicmV0dXJuXCIsIGFsbG93IHRoZSBvcmlnaW5hbCAucmV0dXJuIGNhbGwgdG8gY29udGludWUgaW4gdGhlXG4gICAgICAvLyBvdXRlciBnZW5lcmF0b3IuXG4gICAgICBpZiAoY29udGV4dC5tZXRob2QgIT09IFwicmV0dXJuXCIpIHtcbiAgICAgICAgY29udGV4dC5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgICAgY29udGV4dC5hcmcgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmUteWllbGQgdGhlIHJlc3VsdCByZXR1cm5lZCBieSB0aGUgZGVsZWdhdGUgbWV0aG9kLlxuICAgICAgcmV0dXJuIGluZm87XG4gICAgfVxuXG4gICAgLy8gVGhlIGRlbGVnYXRlIGl0ZXJhdG9yIGlzIGZpbmlzaGVkLCBzbyBmb3JnZXQgaXQgYW5kIGNvbnRpbnVlIHdpdGhcbiAgICAvLyB0aGUgb3V0ZXIgZ2VuZXJhdG9yLlxuICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICB9XG5cbiAgLy8gRGVmaW5lIEdlbmVyYXRvci5wcm90b3R5cGUue25leHQsdGhyb3cscmV0dXJufSBpbiB0ZXJtcyBvZiB0aGVcbiAgLy8gdW5pZmllZCAuX2ludm9rZSBoZWxwZXIgbWV0aG9kLlxuICBkZWZpbmVJdGVyYXRvck1ldGhvZHMoR3ApO1xuXG4gIEdwW3RvU3RyaW5nVGFnU3ltYm9sXSA9IFwiR2VuZXJhdG9yXCI7XG5cbiAgLy8gQSBHZW5lcmF0b3Igc2hvdWxkIGFsd2F5cyByZXR1cm4gaXRzZWxmIGFzIHRoZSBpdGVyYXRvciBvYmplY3Qgd2hlbiB0aGVcbiAgLy8gQEBpdGVyYXRvciBmdW5jdGlvbiBpcyBjYWxsZWQgb24gaXQuIFNvbWUgYnJvd3NlcnMnIGltcGxlbWVudGF0aW9ucyBvZiB0aGVcbiAgLy8gaXRlcmF0b3IgcHJvdG90eXBlIGNoYWluIGluY29ycmVjdGx5IGltcGxlbWVudCB0aGlzLCBjYXVzaW5nIHRoZSBHZW5lcmF0b3JcbiAgLy8gb2JqZWN0IHRvIG5vdCBiZSByZXR1cm5lZCBmcm9tIHRoaXMgY2FsbC4gVGhpcyBlbnN1cmVzIHRoYXQgZG9lc24ndCBoYXBwZW4uXG4gIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVnZW5lcmF0b3IvaXNzdWVzLzI3NCBmb3IgbW9yZSBkZXRhaWxzLlxuICBHcFtpdGVyYXRvclN5bWJvbF0gPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBHcC50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBcIltvYmplY3QgR2VuZXJhdG9yXVwiO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHB1c2hUcnlFbnRyeShsb2NzKSB7XG4gICAgdmFyIGVudHJ5ID0geyB0cnlMb2M6IGxvY3NbMF0gfTtcblxuICAgIGlmICgxIGluIGxvY3MpIHtcbiAgICAgIGVudHJ5LmNhdGNoTG9jID0gbG9jc1sxXTtcbiAgICB9XG5cbiAgICBpZiAoMiBpbiBsb2NzKSB7XG4gICAgICBlbnRyeS5maW5hbGx5TG9jID0gbG9jc1syXTtcbiAgICAgIGVudHJ5LmFmdGVyTG9jID0gbG9jc1szXTtcbiAgICB9XG5cbiAgICB0aGlzLnRyeUVudHJpZXMucHVzaChlbnRyeSk7XG4gIH1cblxuICBmdW5jdGlvbiByZXNldFRyeUVudHJ5KGVudHJ5KSB7XG4gICAgdmFyIHJlY29yZCA9IGVudHJ5LmNvbXBsZXRpb24gfHwge307XG4gICAgcmVjb3JkLnR5cGUgPSBcIm5vcm1hbFwiO1xuICAgIGRlbGV0ZSByZWNvcmQuYXJnO1xuICAgIGVudHJ5LmNvbXBsZXRpb24gPSByZWNvcmQ7XG4gIH1cblxuICBmdW5jdGlvbiBDb250ZXh0KHRyeUxvY3NMaXN0KSB7XG4gICAgLy8gVGhlIHJvb3QgZW50cnkgb2JqZWN0IChlZmZlY3RpdmVseSBhIHRyeSBzdGF0ZW1lbnQgd2l0aG91dCBhIGNhdGNoXG4gICAgLy8gb3IgYSBmaW5hbGx5IGJsb2NrKSBnaXZlcyB1cyBhIHBsYWNlIHRvIHN0b3JlIHZhbHVlcyB0aHJvd24gZnJvbVxuICAgIC8vIGxvY2F0aW9ucyB3aGVyZSB0aGVyZSBpcyBubyBlbmNsb3NpbmcgdHJ5IHN0YXRlbWVudC5cbiAgICB0aGlzLnRyeUVudHJpZXMgPSBbeyB0cnlMb2M6IFwicm9vdFwiIH1dO1xuICAgIHRyeUxvY3NMaXN0LmZvckVhY2gocHVzaFRyeUVudHJ5LCB0aGlzKTtcbiAgICB0aGlzLnJlc2V0KHRydWUpO1xuICB9XG5cbiAgcnVudGltZS5rZXlzID0gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgdmFyIGtleXMgPSBbXTtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICB9XG4gICAga2V5cy5yZXZlcnNlKCk7XG5cbiAgICAvLyBSYXRoZXIgdGhhbiByZXR1cm5pbmcgYW4gb2JqZWN0IHdpdGggYSBuZXh0IG1ldGhvZCwgd2Uga2VlcFxuICAgIC8vIHRoaW5ncyBzaW1wbGUgYW5kIHJldHVybiB0aGUgbmV4dCBmdW5jdGlvbiBpdHNlbGYuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIG5leHQoKSB7XG4gICAgICB3aGlsZSAoa2V5cy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXMucG9wKCk7XG4gICAgICAgIGlmIChrZXkgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgbmV4dC52YWx1ZSA9IGtleTtcbiAgICAgICAgICBuZXh0LmRvbmUgPSBmYWxzZTtcbiAgICAgICAgICByZXR1cm4gbmV4dDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUbyBhdm9pZCBjcmVhdGluZyBhbiBhZGRpdGlvbmFsIG9iamVjdCwgd2UganVzdCBoYW5nIHRoZSAudmFsdWVcbiAgICAgIC8vIGFuZCAuZG9uZSBwcm9wZXJ0aWVzIG9mZiB0aGUgbmV4dCBmdW5jdGlvbiBvYmplY3QgaXRzZWxmLiBUaGlzXG4gICAgICAvLyBhbHNvIGVuc3VyZXMgdGhhdCB0aGUgbWluaWZpZXIgd2lsbCBub3QgYW5vbnltaXplIHRoZSBmdW5jdGlvbi5cbiAgICAgIG5leHQuZG9uZSA9IHRydWU7XG4gICAgICByZXR1cm4gbmV4dDtcbiAgICB9O1xuICB9O1xuXG4gIGZ1bmN0aW9uIHZhbHVlcyhpdGVyYWJsZSkge1xuICAgIGlmIChpdGVyYWJsZSkge1xuICAgICAgdmFyIGl0ZXJhdG9yTWV0aG9kID0gaXRlcmFibGVbaXRlcmF0b3JTeW1ib2xdO1xuICAgICAgaWYgKGl0ZXJhdG9yTWV0aG9kKSB7XG4gICAgICAgIHJldHVybiBpdGVyYXRvck1ldGhvZC5jYWxsKGl0ZXJhYmxlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBpdGVyYWJsZS5uZXh0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhYmxlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWlzTmFOKGl0ZXJhYmxlLmxlbmd0aCkpIHtcbiAgICAgICAgdmFyIGkgPSAtMSwgbmV4dCA9IGZ1bmN0aW9uIG5leHQoKSB7XG4gICAgICAgICAgd2hpbGUgKCsraSA8IGl0ZXJhYmxlLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKGl0ZXJhYmxlLCBpKSkge1xuICAgICAgICAgICAgICBuZXh0LnZhbHVlID0gaXRlcmFibGVbaV07XG4gICAgICAgICAgICAgIG5leHQuZG9uZSA9IGZhbHNlO1xuICAgICAgICAgICAgICByZXR1cm4gbmV4dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBuZXh0LnZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICAgIG5leHQuZG9uZSA9IHRydWU7XG5cbiAgICAgICAgICByZXR1cm4gbmV4dDtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gbmV4dC5uZXh0ID0gbmV4dDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gYW4gaXRlcmF0b3Igd2l0aCBubyB2YWx1ZXMuXG4gICAgcmV0dXJuIHsgbmV4dDogZG9uZVJlc3VsdCB9O1xuICB9XG4gIHJ1bnRpbWUudmFsdWVzID0gdmFsdWVzO1xuXG4gIGZ1bmN0aW9uIGRvbmVSZXN1bHQoKSB7XG4gICAgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICB9XG5cbiAgQ29udGV4dC5wcm90b3R5cGUgPSB7XG4gICAgY29uc3RydWN0b3I6IENvbnRleHQsXG5cbiAgICByZXNldDogZnVuY3Rpb24oc2tpcFRlbXBSZXNldCkge1xuICAgICAgdGhpcy5wcmV2ID0gMDtcbiAgICAgIHRoaXMubmV4dCA9IDA7XG4gICAgICAvLyBSZXNldHRpbmcgY29udGV4dC5fc2VudCBmb3IgbGVnYWN5IHN1cHBvcnQgb2YgQmFiZWwnc1xuICAgICAgLy8gZnVuY3Rpb24uc2VudCBpbXBsZW1lbnRhdGlvbi5cbiAgICAgIHRoaXMuc2VudCA9IHRoaXMuX3NlbnQgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLmRvbmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuZGVsZWdhdGUgPSBudWxsO1xuXG4gICAgICB0aGlzLm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgdGhpcy5hcmcgPSB1bmRlZmluZWQ7XG5cbiAgICAgIHRoaXMudHJ5RW50cmllcy5mb3JFYWNoKHJlc2V0VHJ5RW50cnkpO1xuXG4gICAgICBpZiAoIXNraXBUZW1wUmVzZXQpIHtcbiAgICAgICAgZm9yICh2YXIgbmFtZSBpbiB0aGlzKSB7XG4gICAgICAgICAgLy8gTm90IHN1cmUgYWJvdXQgdGhlIG9wdGltYWwgb3JkZXIgb2YgdGhlc2UgY29uZGl0aW9uczpcbiAgICAgICAgICBpZiAobmFtZS5jaGFyQXQoMCkgPT09IFwidFwiICYmXG4gICAgICAgICAgICAgIGhhc093bi5jYWxsKHRoaXMsIG5hbWUpICYmXG4gICAgICAgICAgICAgICFpc05hTigrbmFtZS5zbGljZSgxKSkpIHtcbiAgICAgICAgICAgIHRoaXNbbmFtZV0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIHN0b3A6IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5kb25lID0gdHJ1ZTtcblxuICAgICAgdmFyIHJvb3RFbnRyeSA9IHRoaXMudHJ5RW50cmllc1swXTtcbiAgICAgIHZhciByb290UmVjb3JkID0gcm9vdEVudHJ5LmNvbXBsZXRpb247XG4gICAgICBpZiAocm9vdFJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgdGhyb3cgcm9vdFJlY29yZC5hcmc7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnJ2YWw7XG4gICAgfSxcblxuICAgIGRpc3BhdGNoRXhjZXB0aW9uOiBmdW5jdGlvbihleGNlcHRpb24pIHtcbiAgICAgIGlmICh0aGlzLmRvbmUpIHtcbiAgICAgICAgdGhyb3cgZXhjZXB0aW9uO1xuICAgICAgfVxuXG4gICAgICB2YXIgY29udGV4dCA9IHRoaXM7XG4gICAgICBmdW5jdGlvbiBoYW5kbGUobG9jLCBjYXVnaHQpIHtcbiAgICAgICAgcmVjb3JkLnR5cGUgPSBcInRocm93XCI7XG4gICAgICAgIHJlY29yZC5hcmcgPSBleGNlcHRpb247XG4gICAgICAgIGNvbnRleHQubmV4dCA9IGxvYztcblxuICAgICAgICBpZiAoY2F1Z2h0KSB7XG4gICAgICAgICAgLy8gSWYgdGhlIGRpc3BhdGNoZWQgZXhjZXB0aW9uIHdhcyBjYXVnaHQgYnkgYSBjYXRjaCBibG9jayxcbiAgICAgICAgICAvLyB0aGVuIGxldCB0aGF0IGNhdGNoIGJsb2NrIGhhbmRsZSB0aGUgZXhjZXB0aW9uIG5vcm1hbGx5LlxuICAgICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJuZXh0XCI7XG4gICAgICAgICAgY29udGV4dC5hcmcgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gISEgY2F1Z2h0O1xuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50cnlFbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMudHJ5RW50cmllc1tpXTtcbiAgICAgICAgdmFyIHJlY29yZCA9IGVudHJ5LmNvbXBsZXRpb247XG5cbiAgICAgICAgaWYgKGVudHJ5LnRyeUxvYyA9PT0gXCJyb290XCIpIHtcbiAgICAgICAgICAvLyBFeGNlcHRpb24gdGhyb3duIG91dHNpZGUgb2YgYW55IHRyeSBibG9jayB0aGF0IGNvdWxkIGhhbmRsZVxuICAgICAgICAgIC8vIGl0LCBzbyBzZXQgdGhlIGNvbXBsZXRpb24gdmFsdWUgb2YgdGhlIGVudGlyZSBmdW5jdGlvbiB0b1xuICAgICAgICAgIC8vIHRocm93IHRoZSBleGNlcHRpb24uXG4gICAgICAgICAgcmV0dXJuIGhhbmRsZShcImVuZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbnRyeS50cnlMb2MgPD0gdGhpcy5wcmV2KSB7XG4gICAgICAgICAgdmFyIGhhc0NhdGNoID0gaGFzT3duLmNhbGwoZW50cnksIFwiY2F0Y2hMb2NcIik7XG4gICAgICAgICAgdmFyIGhhc0ZpbmFsbHkgPSBoYXNPd24uY2FsbChlbnRyeSwgXCJmaW5hbGx5TG9jXCIpO1xuXG4gICAgICAgICAgaWYgKGhhc0NhdGNoICYmIGhhc0ZpbmFsbHkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXYgPCBlbnRyeS5jYXRjaExvYykge1xuICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlKGVudHJ5LmNhdGNoTG9jLCB0cnVlKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcmV2IDwgZW50cnkuZmluYWxseUxvYykge1xuICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlKGVudHJ5LmZpbmFsbHlMb2MpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgfSBlbHNlIGlmIChoYXNDYXRjaCkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJldiA8IGVudHJ5LmNhdGNoTG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuY2F0Y2hMb2MsIHRydWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgfSBlbHNlIGlmIChoYXNGaW5hbGx5KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcmV2IDwgZW50cnkuZmluYWxseUxvYykge1xuICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlKGVudHJ5LmZpbmFsbHlMb2MpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInRyeSBzdGF0ZW1lbnQgd2l0aG91dCBjYXRjaCBvciBmaW5hbGx5XCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBhYnJ1cHQ6IGZ1bmN0aW9uKHR5cGUsIGFyZykge1xuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIGlmIChlbnRyeS50cnlMb2MgPD0gdGhpcy5wcmV2ICYmXG4gICAgICAgICAgICBoYXNPd24uY2FsbChlbnRyeSwgXCJmaW5hbGx5TG9jXCIpICYmXG4gICAgICAgICAgICB0aGlzLnByZXYgPCBlbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgICAgdmFyIGZpbmFsbHlFbnRyeSA9IGVudHJ5O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChmaW5hbGx5RW50cnkgJiZcbiAgICAgICAgICAodHlwZSA9PT0gXCJicmVha1wiIHx8XG4gICAgICAgICAgIHR5cGUgPT09IFwiY29udGludWVcIikgJiZcbiAgICAgICAgICBmaW5hbGx5RW50cnkudHJ5TG9jIDw9IGFyZyAmJlxuICAgICAgICAgIGFyZyA8PSBmaW5hbGx5RW50cnkuZmluYWxseUxvYykge1xuICAgICAgICAvLyBJZ25vcmUgdGhlIGZpbmFsbHkgZW50cnkgaWYgY29udHJvbCBpcyBub3QganVtcGluZyB0byBhXG4gICAgICAgIC8vIGxvY2F0aW9uIG91dHNpZGUgdGhlIHRyeS9jYXRjaCBibG9jay5cbiAgICAgICAgZmluYWxseUVudHJ5ID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgdmFyIHJlY29yZCA9IGZpbmFsbHlFbnRyeSA/IGZpbmFsbHlFbnRyeS5jb21wbGV0aW9uIDoge307XG4gICAgICByZWNvcmQudHlwZSA9IHR5cGU7XG4gICAgICByZWNvcmQuYXJnID0gYXJnO1xuXG4gICAgICBpZiAoZmluYWxseUVudHJ5KSB7XG4gICAgICAgIHRoaXMubWV0aG9kID0gXCJuZXh0XCI7XG4gICAgICAgIHRoaXMubmV4dCA9IGZpbmFsbHlFbnRyeS5maW5hbGx5TG9jO1xuICAgICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuY29tcGxldGUocmVjb3JkKTtcbiAgICB9LFxuXG4gICAgY29tcGxldGU6IGZ1bmN0aW9uKHJlY29yZCwgYWZ0ZXJMb2MpIHtcbiAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIHRocm93IHJlY29yZC5hcmc7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJicmVha1wiIHx8XG4gICAgICAgICAgcmVjb3JkLnR5cGUgPT09IFwiY29udGludWVcIikge1xuICAgICAgICB0aGlzLm5leHQgPSByZWNvcmQuYXJnO1xuICAgICAgfSBlbHNlIGlmIChyZWNvcmQudHlwZSA9PT0gXCJyZXR1cm5cIikge1xuICAgICAgICB0aGlzLnJ2YWwgPSB0aGlzLmFyZyA9IHJlY29yZC5hcmc7XG4gICAgICAgIHRoaXMubWV0aG9kID0gXCJyZXR1cm5cIjtcbiAgICAgICAgdGhpcy5uZXh0ID0gXCJlbmRcIjtcbiAgICAgIH0gZWxzZSBpZiAocmVjb3JkLnR5cGUgPT09IFwibm9ybWFsXCIgJiYgYWZ0ZXJMb2MpIHtcbiAgICAgICAgdGhpcy5uZXh0ID0gYWZ0ZXJMb2M7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH0sXG5cbiAgICBmaW5pc2g6IGZ1bmN0aW9uKGZpbmFsbHlMb2MpIHtcbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICBpZiAoZW50cnkuZmluYWxseUxvYyA9PT0gZmluYWxseUxvYykge1xuICAgICAgICAgIHRoaXMuY29tcGxldGUoZW50cnkuY29tcGxldGlvbiwgZW50cnkuYWZ0ZXJMb2MpO1xuICAgICAgICAgIHJlc2V0VHJ5RW50cnkoZW50cnkpO1xuICAgICAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIFwiY2F0Y2hcIjogZnVuY3Rpb24odHJ5TG9jKSB7XG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50cnlFbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMudHJ5RW50cmllc1tpXTtcbiAgICAgICAgaWYgKGVudHJ5LnRyeUxvYyA9PT0gdHJ5TG9jKSB7XG4gICAgICAgICAgdmFyIHJlY29yZCA9IGVudHJ5LmNvbXBsZXRpb247XG4gICAgICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgIHZhciB0aHJvd24gPSByZWNvcmQuYXJnO1xuICAgICAgICAgICAgcmVzZXRUcnlFbnRyeShlbnRyeSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aHJvd247XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVGhlIGNvbnRleHQuY2F0Y2ggbWV0aG9kIG11c3Qgb25seSBiZSBjYWxsZWQgd2l0aCBhIGxvY2F0aW9uXG4gICAgICAvLyBhcmd1bWVudCB0aGF0IGNvcnJlc3BvbmRzIHRvIGEga25vd24gY2F0Y2ggYmxvY2suXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpbGxlZ2FsIGNhdGNoIGF0dGVtcHRcIik7XG4gICAgfSxcblxuICAgIGRlbGVnYXRlWWllbGQ6IGZ1bmN0aW9uKGl0ZXJhYmxlLCByZXN1bHROYW1lLCBuZXh0TG9jKSB7XG4gICAgICB0aGlzLmRlbGVnYXRlID0ge1xuICAgICAgICBpdGVyYXRvcjogdmFsdWVzKGl0ZXJhYmxlKSxcbiAgICAgICAgcmVzdWx0TmFtZTogcmVzdWx0TmFtZSxcbiAgICAgICAgbmV4dExvYzogbmV4dExvY1xuICAgICAgfTtcblxuICAgICAgaWYgKHRoaXMubWV0aG9kID09PSBcIm5leHRcIikge1xuICAgICAgICAvLyBEZWxpYmVyYXRlbHkgZm9yZ2V0IHRoZSBsYXN0IHNlbnQgdmFsdWUgc28gdGhhdCB3ZSBkb24ndFxuICAgICAgICAvLyBhY2NpZGVudGFsbHkgcGFzcyBpdCBvbiB0byB0aGUgZGVsZWdhdGUuXG4gICAgICAgIHRoaXMuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9XG4gIH07XG59KShcbiAgLy8gSW4gc2xvcHB5IG1vZGUsIHVuYm91bmQgYHRoaXNgIHJlZmVycyB0byB0aGUgZ2xvYmFsIG9iamVjdCwgZmFsbGJhY2sgdG9cbiAgLy8gRnVuY3Rpb24gY29uc3RydWN0b3IgaWYgd2UncmUgaW4gZ2xvYmFsIHN0cmljdCBtb2RlLiBUaGF0IGlzIHNhZGx5IGEgZm9ybVxuICAvLyBvZiBpbmRpcmVjdCBldmFsIHdoaWNoIHZpb2xhdGVzIENvbnRlbnQgU2VjdXJpdHkgUG9saWN5LlxuICAoZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMgfHwgKHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiICYmIHNlbGYpO1xuICB9KSgpIHx8IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKVxuKTtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlZ2VuZXJhdG9yLXJ1bnRpbWVcIik7XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIG9iamVjdENyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgb2JqZWN0Q3JlYXRlUG9seWZpbGxcbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgb2JqZWN0S2V5c1BvbHlmaWxsXG52YXIgYmluZCA9IEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIHx8IGZ1bmN0aW9uQmluZFBvbHlmaWxsXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLCAnX2V2ZW50cycpKSB7XG4gICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbnZhciBkZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbnZhciBoYXNEZWZpbmVQcm9wZXJ0eTtcbnRyeSB7XG4gIHZhciBvID0ge307XG4gIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCAneCcsIHsgdmFsdWU6IDAgfSk7XG4gIGhhc0RlZmluZVByb3BlcnR5ID0gby54ID09PSAwO1xufSBjYXRjaCAoZXJyKSB7IGhhc0RlZmluZVByb3BlcnR5ID0gZmFsc2UgfVxuaWYgKGhhc0RlZmluZVByb3BlcnR5KSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudEVtaXR0ZXIsICdkZWZhdWx0TWF4TGlzdGVuZXJzJywge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGlucHV0IGlzIGEgcG9zaXRpdmUgbnVtYmVyICh3aG9zZSB2YWx1ZSBpcyB6ZXJvIG9yXG4gICAgICAvLyBncmVhdGVyIGFuZCBub3QgYSBOYU4pLlxuICAgICAgaWYgKHR5cGVvZiBhcmcgIT09ICdudW1iZXInIHx8IGFyZyA8IDAgfHwgYXJnICE9PSBhcmcpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZGVmYXVsdE1heExpc3RlbmVyc1wiIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgICAgIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBhcmc7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gZGVmYXVsdE1heExpc3RlbmVycztcbn1cblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKG4pIHtcbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcIm5cIiBhcmd1bWVudCBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gJGdldE1heExpc3RlbmVycyh0aGF0KSB7XG4gIGlmICh0aGF0Ll9tYXhMaXN0ZW5lcnMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIHJldHVybiB0aGF0Ll9tYXhMaXN0ZW5lcnM7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZ2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gJGdldE1heExpc3RlbmVycyh0aGlzKTtcbn07XG5cbi8vIFRoZXNlIHN0YW5kYWxvbmUgZW1pdCogZnVuY3Rpb25zIGFyZSB1c2VkIHRvIG9wdGltaXplIGNhbGxpbmcgb2YgZXZlbnRcbi8vIGhhbmRsZXJzIGZvciBmYXN0IGNhc2VzIGJlY2F1c2UgZW1pdCgpIGl0c2VsZiBvZnRlbiBoYXMgYSB2YXJpYWJsZSBudW1iZXIgb2Zcbi8vIGFyZ3VtZW50cyBhbmQgY2FuIGJlIGRlb3B0aW1pemVkIGJlY2F1c2Ugb2YgdGhhdC4gVGhlc2UgZnVuY3Rpb25zIGFsd2F5cyBoYXZlXG4vLyB0aGUgc2FtZSBudW1iZXIgb2YgYXJndW1lbnRzIGFuZCB0aHVzIGRvIG5vdCBnZXQgZGVvcHRpbWl6ZWQsIHNvIHRoZSBjb2RlXG4vLyBpbnNpZGUgdGhlbSBjYW4gZXhlY3V0ZSBmYXN0ZXIuXG5mdW5jdGlvbiBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCBzZWxmKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMikge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMik7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJncykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICB9XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQodHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgZXZlbnRzO1xuICB2YXIgZG9FcnJvciA9ICh0eXBlID09PSAnZXJyb3InKTtcblxuICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gIGlmIChldmVudHMpXG4gICAgZG9FcnJvciA9IChkb0Vycm9yICYmIGV2ZW50cy5lcnJvciA9PSBudWxsKTtcbiAgZWxzZSBpZiAoIWRvRXJyb3IpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKGRvRXJyb3IpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpXG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuaGFuZGxlZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoIWhhbmRsZXIpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBpc0ZuID0gdHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbic7XG4gIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHN3aXRjaCAobGVuKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgY2FzZSAxOlxuICAgICAgZW1pdE5vbmUoaGFuZGxlciwgaXNGbiwgdGhpcyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDI6XG4gICAgICBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDM6XG4gICAgICBlbWl0VHdvKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNDpcbiAgICAgIGVtaXRUaHJlZShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSwgYXJndW1lbnRzWzNdKTtcbiAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgZGVmYXVsdDpcbiAgICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIF9hZGRMaXN0ZW5lcih0YXJnZXQsIHR5cGUsIGxpc3RlbmVyLCBwcmVwZW5kKSB7XG4gIHZhciBtO1xuICB2YXIgZXZlbnRzO1xuICB2YXIgZXhpc3Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gIGlmICghZXZlbnRzKSB7XG4gICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lcikge1xuICAgICAgdGFyZ2V0LmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA/IGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gICAgICAvLyBSZS1hc3NpZ24gYGV2ZW50c2AgYmVjYXVzZSBhIG5ld0xpc3RlbmVyIGhhbmRsZXIgY291bGQgaGF2ZSBjYXVzZWQgdGhlXG4gICAgICAvLyB0aGlzLl9ldmVudHMgdG8gYmUgYXNzaWduZWQgdG8gYSBuZXcgb2JqZWN0XG4gICAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgICB9XG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV07XG4gIH1cblxuICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICArK3RhcmdldC5fZXZlbnRzQ291bnQ7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBleGlzdGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9XG4gICAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICAgIGlmIChwcmVwZW5kKSB7XG4gICAgICAgIGV4aXN0aW5nLnVuc2hpZnQobGlzdGVuZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBpZiAoIWV4aXN0aW5nLndhcm5lZCkge1xuICAgICAgbSA9ICRnZXRNYXhMaXN0ZW5lcnModGFyZ2V0KTtcbiAgICAgIGlmIChtICYmIG0gPiAwICYmIGV4aXN0aW5nLmxlbmd0aCA+IG0pIHtcbiAgICAgICAgZXhpc3Rpbmcud2FybmVkID0gdHJ1ZTtcbiAgICAgICAgdmFyIHcgPSBuZXcgRXJyb3IoJ1Bvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgbGVhayBkZXRlY3RlZC4gJyArXG4gICAgICAgICAgICBleGlzdGluZy5sZW5ndGggKyAnIFwiJyArIFN0cmluZyh0eXBlKSArICdcIiBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAnYWRkZWQuIFVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvICcgK1xuICAgICAgICAgICAgJ2luY3JlYXNlIGxpbWl0LicpO1xuICAgICAgICB3Lm5hbWUgPSAnTWF4TGlzdGVuZXJzRXhjZWVkZWRXYXJuaW5nJztcbiAgICAgICAgdy5lbWl0dGVyID0gdGFyZ2V0O1xuICAgICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgICB3LmNvdW50ID0gZXhpc3RpbmcubGVuZ3RoO1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgPT09ICdvYmplY3QnICYmIGNvbnNvbGUud2Fybikge1xuICAgICAgICAgIGNvbnNvbGUud2FybignJXM6ICVzJywgdy5uYW1lLCB3Lm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgICB9O1xuXG5mdW5jdGlvbiBvbmNlV3JhcHBlcigpIHtcbiAgaWYgKCF0aGlzLmZpcmVkKSB7XG4gICAgdGhpcy50YXJnZXQucmVtb3ZlTGlzdGVuZXIodGhpcy50eXBlLCB0aGlzLndyYXBGbik7XG4gICAgdGhpcy5maXJlZCA9IHRydWU7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0pO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLFxuICAgICAgICAgICAgYXJndW1lbnRzWzJdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgdGhpcy5saXN0ZW5lci5hcHBseSh0aGlzLnRhcmdldCwgYXJncyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IGJpbmQuY2FsbChvbmNlV3JhcHBlciwgc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgdGhpcy5wcmVwZW5kTGlzdGVuZXIodHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4vLyBFbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWYgYW5kIG9ubHkgaWYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBsaXN0LCBldmVudHMsIHBvc2l0aW9uLCBpLCBvcmlnaW5hbExpc3RlbmVyO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgbGlzdCA9IGV2ZW50c1t0eXBlXTtcbiAgICAgIGlmICghbGlzdClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0Lmxpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGlzdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwb3NpdGlvbiA9IC0xO1xuXG4gICAgICAgIGZvciAoaSA9IGxpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHwgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsTGlzdGVuZXIgPSBsaXN0W2ldLmxpc3RlbmVyO1xuICAgICAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgICBpZiAocG9zaXRpb24gPT09IDApXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcblxuICAgICAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpXG4gICAgICAgICAgZXZlbnRzW3R5cGVdID0gbGlzdFswXTtcblxuICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBvcmlnaW5hbExpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICAgICAgaWYgKCFldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSkge1xuICAgICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBvYmplY3RLZXlzKGV2ZW50cyk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGxpc3RlbmVycyA9IGV2ZW50c1t0eXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gTElGTyBvcmRlclxuICAgICAgICBmb3IgKGkgPSBsaXN0ZW5lcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuZnVuY3Rpb24gX2xpc3RlbmVycyh0YXJnZXQsIHR5cGUsIHVud3JhcCkge1xuICB2YXIgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG5cbiAgaWYgKCFldmVudHMpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuICBpZiAoIWV2bGlzdGVuZXIpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/IHVud3JhcExpc3RlbmVycyhldmxpc3RlbmVyKSA6IGFycmF5Q2xvbmUoZXZsaXN0ZW5lciwgZXZsaXN0ZW5lci5sZW5ndGgpO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIHRydWUpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yYXdMaXN0ZW5lcnMgPSBmdW5jdGlvbiByYXdMaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLmxpc3RlbmVyQ291bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBsaXN0ZW5lckNvdW50LmNhbGwoZW1pdHRlciwgdHlwZSk7XG4gIH1cbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGxpc3RlbmVyQ291bnQ7XG5mdW5jdGlvbiBsaXN0ZW5lckNvdW50KHR5cGUpIHtcbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG5cbiAgICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSBpZiAoZXZsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdC5vd25LZXlzKHRoaXMuX2V2ZW50cykgOiBbXTtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbmZ1bmN0aW9uIHNwbGljZU9uZShsaXN0LCBpbmRleCkge1xuICBmb3IgKHZhciBpID0gaW5kZXgsIGsgPSBpICsgMSwgbiA9IGxpc3QubGVuZ3RoOyBrIDwgbjsgaSArPSAxLCBrICs9IDEpXG4gICAgbGlzdFtpXSA9IGxpc3Rba107XG4gIGxpc3QucG9wKCk7XG59XG5cbmZ1bmN0aW9uIGFycmF5Q2xvbmUoYXJyLCBuKSB7XG4gIHZhciBjb3B5ID0gbmV3IEFycmF5KG4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSlcbiAgICBjb3B5W2ldID0gYXJyW2ldO1xuICByZXR1cm4gY29weTtcbn1cblxuZnVuY3Rpb24gdW53cmFwTGlzdGVuZXJzKGFycikge1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGFyci5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJldC5sZW5ndGg7ICsraSkge1xuICAgIHJldFtpXSA9IGFycltpXS5saXN0ZW5lciB8fCBhcnJbaV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gb2JqZWN0Q3JlYXRlUG9seWZpbGwocHJvdG8pIHtcbiAgdmFyIEYgPSBmdW5jdGlvbigpIHt9O1xuICBGLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXR1cm4gbmV3IEY7XG59XG5mdW5jdGlvbiBvYmplY3RLZXlzUG9seWZpbGwob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGsgaW4gb2JqKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgaykpIHtcbiAgICBrZXlzLnB1c2goayk7XG4gIH1cbiAgcmV0dXJuIGs7XG59XG5mdW5jdGlvbiBmdW5jdGlvbkJpbmRQb2x5ZmlsbChjb250ZXh0KSB7XG4gIHZhciBmbiA9IHRoaXM7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGNvbnRleHQsIGFyZ3VtZW50cyk7XG4gIH07XG59XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbnRlcm9wUmVxdWlyZURlZmF1bHRcIik7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlV2lsZGNhcmRcIik7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBleHBvcnRzLlNVUFBPUlRFRF9QUk9UT0NPTF9WRVJTSU9OID0gdm9pZCAwO1xuXG52YXIgX3JlZ2VuZXJhdG9yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvcmVnZW5lcmF0b3JcIikpO1xuXG52YXIgX2FzeW5jVG9HZW5lcmF0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yXCIpKTtcblxudmFyIF9vYmplY3RTcHJlYWQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9vYmplY3RTcHJlYWRcIikpO1xuXG52YXIgX2NsYXNzQ2FsbENoZWNrMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2tcIikpO1xuXG52YXIgX2NyZWF0ZUNsYXNzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY3JlYXRlQ2xhc3NcIikpO1xuXG52YXIgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvclwiKSk7XG5cbnZhciBfdXRpbHMgPSByZXF1aXJlKFwiLi91dGlsc1wiKTtcblxudmFyIF9odHRwID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9odHRwXCIpKTtcblxudmFyIF9lbmRwb2ludCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vZW5kcG9pbnRcIikpO1xuXG52YXIgcmVxdWVzdHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChyZXF1aXJlKFwiLi9yZXF1ZXN0c1wiKSk7XG5cbnZhciBfYmF0Y2gyID0gcmVxdWlyZShcIi4vYmF0Y2hcIik7XG5cbnZhciBfYnVja2V0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9idWNrZXRcIikpO1xuXG52YXIgX2RlYywgX2RlYzIsIF9kZWMzLCBfZGVjNCwgX2RlYzUsIF9kZWM2LCBfZGVjNywgX2NsYXNzO1xuXG4vKipcbiAqIEN1cnJlbnRseSBzdXBwb3J0ZWQgcHJvdG9jb2wgdmVyc2lvbi5cbiAqIEB0eXBlIHtTdHJpbmd9XG4gKi9cbnZhciBTVVBQT1JURURfUFJPVE9DT0xfVkVSU0lPTiA9IFwidjFcIjtcbi8qKlxuICogSGlnaCBsZXZlbCBIVFRQIGNsaWVudCBmb3IgdGhlIEtpbnRvIEFQSS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgY2xpZW50ID0gbmV3IEtpbnRvQ2xpZW50KFwiaHR0cHM6Ly9raW50by5kZXYubW96YXdzLm5ldC92MVwiKTtcbiAqIGNsaWVudC5idWNrZXQoXCJkZWZhdWx0XCIpXG4gKiAgICAuY29sbGVjdGlvbihcIm15LWJsb2dcIilcbiAqICAgIC5jcmVhdGVSZWNvcmQoe3RpdGxlOiBcIkZpcnN0IGFydGljbGVcIn0pXG4gKiAgIC50aGVuKGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSkpXG4gKiAgIC5jYXRjaChjb25zb2xlLmVycm9yLmJpbmQoY29uc29sZSkpO1xuICovXG5cbmV4cG9ydHMuU1VQUE9SVEVEX1BST1RPQ09MX1ZFUlNJT04gPSBTVVBQT1JURURfUFJPVE9DT0xfVkVSU0lPTjtcbnZhciBLaW50b0NsaWVudEJhc2UgPSAoX2RlYyA9ICgwLCBfdXRpbHMubm9iYXRjaCkoXCJUaGlzIG9wZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHdpdGhpbiBhIGJhdGNoIG9wZXJhdGlvbi5cIiksIF9kZWMyID0gKDAsIF91dGlscy5ub2JhdGNoKShcIlRoaXMgb3BlcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgd2l0aGluIGEgYmF0Y2ggb3BlcmF0aW9uLlwiKSwgX2RlYzMgPSAoMCwgX3V0aWxzLm5vYmF0Y2gpKFwiVGhpcyBvcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCB3aXRoaW4gYSBiYXRjaCBvcGVyYXRpb24uXCIpLCBfZGVjNCA9ICgwLCBfdXRpbHMubm9iYXRjaCkoXCJUaGlzIG9wZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHdpdGhpbiBhIGJhdGNoIG9wZXJhdGlvbi5cIiksIF9kZWM1ID0gKDAsIF91dGlscy5ub2JhdGNoKShcIkNhbid0IHVzZSBiYXRjaCB3aXRoaW4gYSBiYXRjaCFcIiksIF9kZWM2ID0gKDAsIF91dGlscy5jYXBhYmxlKShbXCJwZXJtaXNzaW9uc19lbmRwb2ludFwiXSksIF9kZWM3ID0gKDAsIF91dGlscy5zdXBwb3J0KShcIjEuNFwiLCBcIjIuMFwiKSwgKF9jbGFzcyA9XG4vKiNfX1BVUkVfXyovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rvci5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSAgICAgICByZW1vdGUgIFRoZSByZW1vdGUgVVJMLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgIFtvcHRpb25zPXt9XSAgICAgICAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgICBbb3B0aW9ucy5zYWZlPXRydWVdICAgICAgICAgICBBZGRzIGNvbmN1cnJlbmN5IGhlYWRlcnMgdG8gZXZlcnkgcmVxdWVzdHMuXG4gICAqIEBwYXJhbSAge0V2ZW50RW1pdHRlcn0gW29wdGlvbnMuZXZlbnRzPUV2ZW50RW1pdHRlcl0gVGhlIGV2ZW50cyBoYW5kbGVyIGluc3RhbmNlLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgIFtvcHRpb25zLmhlYWRlcnM9e31dICAgICAgICAgIFRoZSBrZXktdmFsdWUgaGVhZGVycyB0byBwYXNzIHRvIGVhY2ggcmVxdWVzdC5cbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB3aGVuIHJlcXVlc3QgZmFpbHMgKGRlZmF1bHQ6IDApXG4gICAqIEBwYXJhbSAge1N0cmluZ30gICAgICAgW29wdGlvbnMuYnVja2V0PVwiZGVmYXVsdFwiXSAgICBUaGUgZGVmYXVsdCBidWNrZXQgdG8gdXNlLlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgIFtvcHRpb25zLnJlcXVlc3RNb2RlPVwiY29yc1wiXSAgVGhlIEhUVFAgcmVxdWVzdCBtb2RlIChmcm9tIEVTNiBmZXRjaCBzcGVjKS5cbiAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICBbb3B0aW9ucy50aW1lb3V0PW51bGxdICAgICAgICBUaGUgcmVxdWVzdCB0aW1lb3V0IGluIG1zLCBpZiBhbnkuXG4gICAqL1xuICBmdW5jdGlvbiBLaW50b0NsaWVudEJhc2UocmVtb3RlKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIEtpbnRvQ2xpZW50QmFzZSk7XG5cbiAgICBpZiAodHlwZW9mIHJlbW90ZSAhPT0gXCJzdHJpbmdcIiB8fCAhcmVtb3RlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCByZW1vdGUgVVJMOiBcIiArIHJlbW90ZSk7XG4gICAgfVxuXG4gICAgaWYgKHJlbW90ZVtyZW1vdGUubGVuZ3RoIC0gMV0gPT09IFwiL1wiKSB7XG4gICAgICByZW1vdGUgPSByZW1vdGUuc2xpY2UoMCwgLTEpO1xuICAgIH1cblxuICAgIHRoaXMuX2JhY2tvZmZSZWxlYXNlVGltZSA9IG51bGw7XG4gICAgdGhpcy5fcmVxdWVzdHMgPSBbXTtcbiAgICB0aGlzLl9pc0JhdGNoID0gISFvcHRpb25zLmJhdGNoO1xuICAgIHRoaXMuX3JldHJ5ID0gb3B0aW9ucy5yZXRyeSB8fCAwO1xuICAgIHRoaXMuX3NhZmUgPSAhIW9wdGlvbnMuc2FmZTtcbiAgICB0aGlzLl9oZWFkZXJzID0gb3B0aW9ucy5oZWFkZXJzIHx8IHt9OyAvLyBwdWJsaWMgcHJvcGVydGllc1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlbW90ZSBzZXJ2ZXIgYmFzZSBVUkwuXG4gICAgICogQHR5cGUge1N0cmluZ31cbiAgICAgKi9cblxuICAgIHRoaXMucmVtb3RlID0gcmVtb3RlO1xuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgc2VydmVyIGluZm9ybWF0aW9uLlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBAdHlwZSB7T2JqZWN0fG51bGx9XG4gICAgICovXG5cbiAgICB0aGlzLnNlcnZlckluZm8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIFRoZSBldmVudCBlbWl0dGVyIGluc3RhbmNlLiBTaG91bGQgY29tcGx5IHdpdGggdGhlIGBFdmVudEVtaXR0ZXJgXG4gICAgICogaW50ZXJmYWNlLlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBAdHlwZSB7Q2xhc3N9XG4gICAgICovXG5cbiAgICB0aGlzLmV2ZW50cyA9IG9wdGlvbnMuZXZlbnRzO1xuICAgIHZhciByZXF1ZXN0TW9kZSA9IG9wdGlvbnMucmVxdWVzdE1vZGUsXG4gICAgICAgIHRpbWVvdXQgPSBvcHRpb25zLnRpbWVvdXQ7XG4gICAgLyoqXG4gICAgICogVGhlIEhUVFAgaW5zdGFuY2UuXG4gICAgICogQGlnbm9yZVxuICAgICAqIEB0eXBlIHtIVFRQfVxuICAgICAqL1xuXG4gICAgdGhpcy5odHRwID0gbmV3IF9odHRwLmRlZmF1bHQodGhpcy5ldmVudHMsIHtcbiAgICAgIHJlcXVlc3RNb2RlOiByZXF1ZXN0TW9kZSxcbiAgICAgIHRpbWVvdXQ6IHRpbWVvdXRcbiAgICB9KTtcblxuICAgIHRoaXMuX3JlZ2lzdGVySFRUUEV2ZW50cygpO1xuICB9XG4gIC8qKlxuICAgKiBUaGUgcmVtb3RlIGVuZHBvaW50IGJhc2UgVVJMLiBTZXR0aW5nIHRoZSB2YWx1ZSB3aWxsIGFsc28gZXh0cmFjdCBhbmRcbiAgICogdmFsaWRhdGUgdGhlIHZlcnNpb24uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqL1xuXG5cbiAgKDAsIF9jcmVhdGVDbGFzczIuZGVmYXVsdCkoS2ludG9DbGllbnRCYXNlLCBbe1xuICAgIGtleTogXCJfcmVnaXN0ZXJIVFRQRXZlbnRzXCIsXG5cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlcnMgSFRUUCBldmVudHMuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICB2YWx1ZTogZnVuY3Rpb24gX3JlZ2lzdGVySFRUUEV2ZW50cygpIHtcbiAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgIC8vIFByZXZlbnQgcmVnaXN0ZXJpbmcgZXZlbnQgZnJvbSBhIGJhdGNoIGNsaWVudCBpbnN0YW5jZVxuICAgICAgaWYgKCF0aGlzLl9pc0JhdGNoKSB7XG4gICAgICAgIHRoaXMuZXZlbnRzLm9uKFwiYmFja29mZlwiLCBmdW5jdGlvbiAoYmFja29mZk1zKSB7XG4gICAgICAgICAgX3RoaXMuX2JhY2tvZmZSZWxlYXNlVGltZSA9IGJhY2tvZmZNcztcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlIGEgYnVja2V0IG9iamVjdCB0byBwZXJmb3JtIG9wZXJhdGlvbnMgb24gaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICBuYW1lICAgICAgICAgICAgICBUaGUgYnVja2V0IG5hbWUuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgVGhlIHJlcXVlc3Qgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICBUaGUgcmVzdWx0aW5nIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5XSAgIFRoZSByZXN1bHRpbmcgcmV0cnkgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnNdIFRoZSBleHRlbmRlZCBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHJldHVybiB7QnVja2V0fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiYnVja2V0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGJ1Y2tldChuYW1lKSB7XG4gICAgICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG4gICAgICByZXR1cm4gbmV3IF9idWNrZXQuZGVmYXVsdCh0aGlzLCBuYW1lLCB7XG4gICAgICAgIGJhdGNoOiB0aGlzLl9pc0JhdGNoLFxuICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpLFxuICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgY2xpZW50IFwiaGVhZGVyc1wiIGZvciBldmVyeSByZXF1ZXN0LCB1cGRhdGluZyBwcmV2aW91cyBoZWFkZXJzIChpZiBhbnkpLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGhlYWRlcnMgVGhlIGhlYWRlcnMgdG8gbWVyZ2Ugd2l0aCBleGlzdGluZyBvbmVzLlxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwic2V0SGVhZGVyc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRIZWFkZXJzKGhlYWRlcnMpIHtcbiAgICAgIHRoaXMuX2hlYWRlcnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHRoaXMuX2hlYWRlcnMsIGhlYWRlcnMpO1xuICAgICAgdGhpcy5zZXJ2ZXJJbmZvID0gbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBvZiBcImhlYWRlcnNcIiBmb3IgYSBnaXZlbiByZXF1ZXN0LCBtZXJnaW5nIHRoZVxuICAgICAqIHBlci1yZXF1ZXN0IGhlYWRlcnMgd2l0aCBvdXIgb3duIFwiZGVmYXVsdFwiIGhlYWRlcnMuXG4gICAgICpcbiAgICAgKiBOb3RlIHRoYXQgdW5saWtlIG90aGVyIG9wdGlvbnMsIGhlYWRlcnMgYXJlbid0IG92ZXJyaWRkZW4sIGJ1dFxuICAgICAqIG1lcmdlZCBpbnN0ZWFkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBUaGUgb3B0aW9ucyBmb3IgYSByZXF1ZXN0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0SGVhZGVyc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZ2V0SGVhZGVycyhvcHRpb25zKSB7XG4gICAgICByZXR1cm4gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCB0aGlzLl9oZWFkZXJzLCBvcHRpb25zLmhlYWRlcnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIG9mIFwic2FmZVwiIGZvciBhIGdpdmVuIHJlcXVlc3QsIHVzaW5nIHRoZVxuICAgICAqIHBlci1yZXF1ZXN0IG9wdGlvbiBpZiBwcmVzZW50IG9yIGZhbGxpbmcgYmFjayB0byBvdXIgZGVmYXVsdFxuICAgICAqIG90aGVyd2lzZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgVGhlIG9wdGlvbnMgZm9yIGEgcmVxdWVzdC5cbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcIl9nZXRTYWZlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRTYWZlKG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe1xuICAgICAgICBzYWZlOiB0aGlzLl9zYWZlXG4gICAgICB9LCBvcHRpb25zKS5zYWZlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBcyBfZ2V0U2FmZSwgYnV0IGZvciBcInJldHJ5XCIuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2dldFJldHJ5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRSZXRyeShvcHRpb25zKSB7XG4gICAgICByZXR1cm4gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHtcbiAgICAgICAgcmV0cnk6IHRoaXMuX3JldHJ5XG4gICAgICB9LCBvcHRpb25zKS5yZXRyeTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBzZXJ2ZXIncyBcImhlbGxvXCIgZW5kcG9pbnQuIFRoaXMgZW5kcG9pbnQgcmV2ZWFsc1xuICAgICAqIHNlcnZlciBjYXBhYmlsaXRpZXMgYW5kIHNldHRpbmdzIGFzIHdlbGwgYXMgdGVsbGluZyB0aGUgY2xpZW50XG4gICAgICogXCJ3aG8gdGhleSBhcmVcIiBhY2NvcmRpbmcgdG8gdGhlaXIgZ2l2ZW4gYXV0aG9yaXphdGlvbiBoZWFkZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gVGhlIHJlcXVlc3Qgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzPXt9XSBIZWFkZXJzIHRvIHVzZSB3aGVuIG1ha2luZ1xuICAgICAqICAgICB0aGlzIHJlcXVlc3QuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2dldEhlbGxvXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZ2V0SGVsbG8yID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZSgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgX3JlZixcbiAgICAgICAgICAgIGpzb24sXG4gICAgICAgICAgICBfYXJncyA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlJChfY29udGV4dCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0LnByZXYgPSBfY29udGV4dC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MubGVuZ3RoID4gMCAmJiBfYXJnc1swXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3NbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXRoID0gdGhpcy5yZW1vdGUgKyAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwicm9vdFwiKTtcbiAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5odHRwLnJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBfcmVmID0gX2NvbnRleHQuc2VudDtcbiAgICAgICAgICAgICAgICBqc29uID0gX3JlZi5qc29uO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dC5hYnJ1cHQoXCJyZXR1cm5cIiwganNvbik7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gX2dldEhlbGxvKCkge1xuICAgICAgICByZXR1cm4gX2dldEhlbGxvMi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgc2VydmVyIGluZm9ybWF0aW9uIGFuZCBwZXJzaXN0IHRoZW0gbG9jYWxseS4gVGhpcyBvcGVyYXRpb24gaXNcbiAgICAgKiB1c3VhbGx5IHBlcmZvcm1lZCBhIHNpbmdsZSB0aW1lIGR1cmluZyB0aGUgaW5zdGFuY2UgbGlmZWN5Y2xlLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dIFRoZSByZXF1ZXN0IG9wdGlvbnMuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZmV0Y2hTZXJ2ZXJJbmZvXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZmV0Y2hTZXJ2ZXJJbmZvID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTIoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgX2FyZ3MyID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMiQoX2NvbnRleHQyKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQyLnByZXYgPSBfY29udGV4dDIubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMi5sZW5ndGggPiAwICYmIF9hcmdzMlswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MyWzBdIDoge307XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc2VydmVySW5mbykge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQyLm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5zZXJ2ZXJJbmZvKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQyLm5leHQgPSA1O1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRIZWxsbyh7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgdGhpcy5zZXJ2ZXJJbmZvID0gX2NvbnRleHQyLnNlbnQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5zZXJ2ZXJJbmZvKTtcblxuICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUyLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGZldGNoU2VydmVySW5mbygpIHtcbiAgICAgICAgcmV0dXJuIF9mZXRjaFNlcnZlckluZm8uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIEtpbnRvIHNlcnZlciBzZXR0aW5ncy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSBUaGUgcmVxdWVzdCBvcHRpb25zLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImZldGNoU2VydmVyU2V0dGluZ3NcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9mZXRjaFNlcnZlclNldHRpbmdzID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTMob3B0aW9ucykge1xuICAgICAgICB2YXIgX3JlZjIsIHNldHRpbmdzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUzJChfY29udGV4dDMpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDMucHJldiA9IF9jb250ZXh0My5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBfY29udGV4dDMubmV4dCA9IDI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmV0Y2hTZXJ2ZXJJbmZvKG9wdGlvbnMpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICBfcmVmMiA9IF9jb250ZXh0My5zZW50O1xuICAgICAgICAgICAgICAgIHNldHRpbmdzID0gX3JlZjIuc2V0dGluZ3M7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0My5hYnJ1cHQoXCJyZXR1cm5cIiwgc2V0dGluZ3MpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDMuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTMsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZmV0Y2hTZXJ2ZXJTZXR0aW5ncyhfeCkge1xuICAgICAgICByZXR1cm4gX2ZldGNoU2VydmVyU2V0dGluZ3MuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmV0cmlldmUgc2VydmVyIGNhcGFiaWxpdGllcyBpbmZvcm1hdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSBUaGUgcmVxdWVzdCBvcHRpb25zLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImZldGNoU2VydmVyQ2FwYWJpbGl0aWVzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZmV0Y2hTZXJ2ZXJDYXBhYmlsaXRpZXMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlNCgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBfcmVmMyxcbiAgICAgICAgICAgIGNhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIF9hcmdzNCA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlNCQoX2NvbnRleHQ0KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ0LnByZXYgPSBfY29udGV4dDQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzNC5sZW5ndGggPiAwICYmIF9hcmdzNFswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M0WzBdIDoge307XG4gICAgICAgICAgICAgICAgX2NvbnRleHQ0Lm5leHQgPSAzO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZldGNoU2VydmVySW5mbyhvcHRpb25zKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgX3JlZjMgPSBfY29udGV4dDQuc2VudDtcbiAgICAgICAgICAgICAgICBjYXBhYmlsaXRpZXMgPSBfcmVmMy5jYXBhYmlsaXRpZXM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NC5hYnJ1cHQoXCJyZXR1cm5cIiwgY2FwYWJpbGl0aWVzKTtcblxuICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU0LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGZldGNoU2VydmVyQ2FwYWJpbGl0aWVzKCkge1xuICAgICAgICByZXR1cm4gX2ZldGNoU2VydmVyQ2FwYWJpbGl0aWVzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlIGF1dGhlbnRpY2F0ZWQgdXNlciBpbmZvcm1hdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSBUaGUgcmVxdWVzdCBvcHRpb25zLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnM9e31dIEhlYWRlcnMgdG8gdXNlIHdoZW4gbWFraW5nXG4gICAgICogICAgIHRoaXMgcmVxdWVzdC5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJmZXRjaFVzZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9mZXRjaFVzZXIgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlNSgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBfcmVmNCxcbiAgICAgICAgICAgIHVzZXIsXG4gICAgICAgICAgICBfYXJnczUgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTUkKF9jb250ZXh0NSkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0NS5wcmV2ID0gX2NvbnRleHQ1Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczUubGVuZ3RoID4gMCAmJiBfYXJnczVbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzNVswXSA6IHt9O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0NS5uZXh0ID0gMztcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0SGVsbG8ob3B0aW9ucyk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIF9yZWY0ID0gX2NvbnRleHQ1LnNlbnQ7XG4gICAgICAgICAgICAgICAgdXNlciA9IF9yZWY0LnVzZXI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NS5hYnJ1cHQoXCJyZXR1cm5cIiwgdXNlcik7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBmZXRjaFVzZXIoKSB7XG4gICAgICAgIHJldHVybiBfZmV0Y2hVc2VyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlIGF1dGhlbnRpY2F0ZWQgdXNlciBpbmZvcm1hdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSBUaGUgcmVxdWVzdCBvcHRpb25zLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImZldGNoSFRUUEFwaVZlcnNpb25cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9mZXRjaEhUVFBBcGlWZXJzaW9uID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTYoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgX3JlZjUsXG4gICAgICAgICAgICBodHRwX2FwaV92ZXJzaW9uLFxuICAgICAgICAgICAgX2FyZ3M2ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU2JChfY29udGV4dDYpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDYucHJldiA9IF9jb250ZXh0Ni5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M2Lmxlbmd0aCA+IDAgJiYgX2FyZ3M2WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczZbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDYubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmV0Y2hTZXJ2ZXJJbmZvKG9wdGlvbnMpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBfcmVmNSA9IF9jb250ZXh0Ni5zZW50O1xuICAgICAgICAgICAgICAgIGh0dHBfYXBpX3ZlcnNpb24gPSBfcmVmNS5odHRwX2FwaV92ZXJzaW9uO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDYuYWJydXB0KFwicmV0dXJuXCIsIGh0dHBfYXBpX3ZlcnNpb24pO1xuXG4gICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDYuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTYsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZmV0Y2hIVFRQQXBpVmVyc2lvbigpIHtcbiAgICAgICAgcmV0dXJuIF9mZXRjaEhUVFBBcGlWZXJzaW9uLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFByb2Nlc3MgYmF0Y2ggcmVxdWVzdHMsIGNodW5raW5nIHRoZW0gYWNjb3JkaW5nIHRvIHRoZSBiYXRjaF9tYXhfcmVxdWVzdHNcbiAgICAgKiBzZXJ2ZXIgc2V0dGluZyB3aGVuIG5lZWRlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge0FycmF5fSAgcmVxdWVzdHMgICAgIFRoZSBsaXN0IG9mIGJhdGNoIHN1YnJlcXVlc3RzIHRvIHBlcmZvcm0uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJfYmF0Y2hSZXF1ZXN0c1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2JhdGNoUmVxdWVzdHMyID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTcocmVxdWVzdHMpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgICAgc2VydmVyU2V0dGluZ3MsXG4gICAgICAgICAgICBtYXhSZXF1ZXN0cyxcbiAgICAgICAgICAgIGNodW5rcyxcbiAgICAgICAgICAgIF9yZWY2LFxuICAgICAgICAgICAgcmVzcG9uc2VzLFxuICAgICAgICAgICAgX2FyZ3M3ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU3JChfY29udGV4dDcpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDcucHJldiA9IF9jb250ZXh0Ny5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M3Lmxlbmd0aCA+IDEgJiYgX2FyZ3M3WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczdbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICBoZWFkZXJzID0gdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKTtcblxuICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Ny5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDcuYWJydXB0KFwicmV0dXJuXCIsIFtdKTtcblxuICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQ3Lm5leHQgPSA2O1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZldGNoU2VydmVyU2V0dGluZ3Moe1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgIHNlcnZlclNldHRpbmdzID0gX2NvbnRleHQ3LnNlbnQ7XG4gICAgICAgICAgICAgICAgbWF4UmVxdWVzdHMgPSBzZXJ2ZXJTZXR0aW5nc1tcImJhdGNoX21heF9yZXF1ZXN0c1wiXTtcblxuICAgICAgICAgICAgICAgIGlmICghKG1heFJlcXVlc3RzICYmIHJlcXVlc3RzLmxlbmd0aCA+IG1heFJlcXVlc3RzKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQ3Lm5leHQgPSAxMTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNodW5rcyA9ICgwLCBfdXRpbHMucGFydGl0aW9uKShyZXF1ZXN0cywgbWF4UmVxdWVzdHMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDcuYWJydXB0KFwicmV0dXJuXCIsICgwLCBfdXRpbHMucE1hcCkoY2h1bmtzLCBmdW5jdGlvbiAoY2h1bmspIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIuX2JhdGNoUmVxdWVzdHMoY2h1bmssIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDExOlxuICAgICAgICAgICAgICAgIF9jb250ZXh0Ny5uZXh0ID0gMTM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSh7XG4gICAgICAgICAgICAgICAgICAvLyBGSVhNRTogaXMgdGhpcyByZWFsbHkgbmVjZXNzYXJ5LCBzaW5jZSBpdCdzIGFsc28gcHJlc2VudCBpblxuICAgICAgICAgICAgICAgICAgLy8gdGhlIFwiZGVmYXVsdHNcIj9cbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IGhlYWRlcnMsXG4gICAgICAgICAgICAgICAgICBwYXRoOiAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYmF0Y2hcIiksXG4gICAgICAgICAgICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICAgICAgICAgICAgYm9keToge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0czoge1xuICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IGhlYWRlcnNcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHM6IHJlcXVlc3RzXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMzpcbiAgICAgICAgICAgICAgICBfcmVmNiA9IF9jb250ZXh0Ny5zZW50O1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlcyA9IF9yZWY2LnJlc3BvbnNlcztcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ3LmFicnVwdChcInJldHVyblwiLCByZXNwb25zZXMpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTY6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ3LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU3LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIF9iYXRjaFJlcXVlc3RzKF94Mikge1xuICAgICAgICByZXR1cm4gX2JhdGNoUmVxdWVzdHMyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFNlbmRzIGJhdGNoIHJlcXVlc3RzIHRvIHRoZSByZW1vdGUgc2VydmVyLlxuICAgICAqXG4gICAgICogTm90ZTogUmVzZXJ2ZWQgZm9yIGludGVybmFsIHVzZSBvbmx5LlxuICAgICAqXG4gICAgICogQGlnbm9yZVxuICAgICAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmbiAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBmdW5jdGlvbiB0byB1c2UgZm9yIGRlc2NyaWJpbmcgYmF0Y2ggb3BzLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucz17fV0gICAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgW29wdGlvbnMuc2FmZV0gICAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgIFtvcHRpb25zLnJldHJ5XSAgICAgICAgICAgVGhlIHJldHJ5IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgW29wdGlvbnMuYnVja2V0XSAgICAgICAgICBUaGUgYnVja2V0IG5hbWUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gICBbb3B0aW9ucy5jb2xsZWN0aW9uXSAgICAgIFRoZSBjb2xsZWN0aW9uIG5hbWUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gIFtvcHRpb25zLmFnZ3JlZ2F0ZT1mYWxzZV0gUHJvZHVjZXMgYW4gYWdncmVnYXRlZCByZXN1bHQgb2JqZWN0LlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJiYXRjaFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2JhdGNoID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTgoZm4pIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICByb290QmF0Y2gsXG4gICAgICAgICAgICBidWNrZXRCYXRjaCxcbiAgICAgICAgICAgIGNvbGxCYXRjaCxcbiAgICAgICAgICAgIGJhdGNoQ2xpZW50LFxuICAgICAgICAgICAgcmVzcG9uc2VzLFxuICAgICAgICAgICAgX2FyZ3M4ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlOCQoX2NvbnRleHQ4KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ4LnByZXYgPSBfY29udGV4dDgubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzOC5sZW5ndGggPiAxICYmIF9hcmdzOFsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M4WzFdIDoge307XG4gICAgICAgICAgICAgICAgcm9vdEJhdGNoID0gbmV3IEtpbnRvQ2xpZW50QmFzZSh0aGlzLnJlbW90ZSwge1xuICAgICAgICAgICAgICAgICAgZXZlbnRzOiB0aGlzLmV2ZW50cyxcbiAgICAgICAgICAgICAgICAgIGJhdGNoOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuYnVja2V0KSB7XG4gICAgICAgICAgICAgICAgICBidWNrZXRCYXRjaCA9IHJvb3RCYXRjaC5idWNrZXQob3B0aW9ucy5idWNrZXQpO1xuXG4gICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5jb2xsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbGxCYXRjaCA9IGJ1Y2tldEJhdGNoLmNvbGxlY3Rpb24ob3B0aW9ucy5jb2xsZWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBiYXRjaENsaWVudCA9IGNvbGxCYXRjaCB8fCBidWNrZXRCYXRjaCB8fCByb290QmF0Y2g7XG4gICAgICAgICAgICAgICAgZm4oYmF0Y2hDbGllbnQpO1xuICAgICAgICAgICAgICAgIF9jb250ZXh0OC5uZXh0ID0gNztcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYmF0Y2hSZXF1ZXN0cyhyb290QmF0Y2guX3JlcXVlc3RzLCBvcHRpb25zKTtcblxuICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgICAgcmVzcG9uc2VzID0gX2NvbnRleHQ4LnNlbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbnMuYWdncmVnYXRlKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDgubmV4dCA9IDEyO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OC5hYnJ1cHQoXCJyZXR1cm5cIiwgKDAsIF9iYXRjaDIuYWdncmVnYXRlKShyZXNwb25zZXMsIHJvb3RCYXRjaC5fcmVxdWVzdHMpKTtcblxuICAgICAgICAgICAgICBjYXNlIDEyOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDguYWJydXB0KFwicmV0dXJuXCIsIHJlc3BvbnNlcyk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDguc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTgsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gYmF0Y2goX3gzKSB7XG4gICAgICAgIHJldHVybiBfYmF0Y2guYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogRXhlY3V0ZXMgYW4gYXRvbWljIEhUVFAgcmVxdWVzdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgcmVxdWVzdCAgICAgICAgICAgICBUaGUgcmVxdWVzdCBvYmplY3QuXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgcmVxdWVzdC5wYXRoICAgICAgICBUaGUgcGF0aCB0byBmZXRjaCwgcmVsYXRpdmVcbiAgICAgKiAgICAgdG8gdGhlIEtpbnRvIHNlcnZlciByb290LlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gIFtyZXF1ZXN0Lm1ldGhvZD1cIkdFVFwiXSBUaGUgbWV0aG9kIHRvIHVzZSBpbiB0aGVcbiAgICAgKiAgICAgcmVxdWVzdC5cbiAgICAgKiBAcGFyYW0gIHtCb2R5fSAgICBbcmVxdWVzdC5ib2R5XSAgICAgIFRoZSByZXF1ZXN0IGJvZHkuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW3JlcXVlc3QuaGVhZGVycz17fV0gVGhlIHJlcXVlc3QgaGVhZGVycy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5yYXc9ZmFsc2VdIElmIHRydWUsIHJlc29sdmUgd2l0aCBmdWxsIHJlc3BvbnNlXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc3RyaW5naWZ5PXRydWVdIElmIHRydWUsIHNlcmlhbGl6ZSBib2R5IGRhdGEgdG9cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgIFRoZSBudW1iZXIgb2YgdGltZXMgdG9cbiAgICAgKiAgICAgcmV0cnkgYSByZXF1ZXN0IGlmIHRoZSBzZXJ2ZXIgcmVzcG9uZHMgd2l0aCBSZXRyeS1BZnRlci5cbiAgICAgKiBKU09OLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJleGVjdXRlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZXhlY3V0ZSA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU5KHJlcXVlc3QpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBfb3B0aW9ucyRyYXcsXG4gICAgICAgICAgICByYXcsXG4gICAgICAgICAgICBfb3B0aW9ucyRzdHJpbmdpZnksXG4gICAgICAgICAgICBzdHJpbmdpZnksXG4gICAgICAgICAgICBtc2csXG4gICAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgICBfYXJnczkgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTkkKF9jb250ZXh0OSkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0OS5wcmV2ID0gX2NvbnRleHQ5Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczkubGVuZ3RoID4gMSAmJiBfYXJnczlbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzOVsxXSA6IHt9O1xuICAgICAgICAgICAgICAgIF9vcHRpb25zJHJhdyA9IG9wdGlvbnMucmF3LCByYXcgPSBfb3B0aW9ucyRyYXcgPT09IHZvaWQgMCA/IGZhbHNlIDogX29wdGlvbnMkcmF3LCBfb3B0aW9ucyRzdHJpbmdpZnkgPSBvcHRpb25zLnN0cmluZ2lmeSwgc3RyaW5naWZ5ID0gX29wdGlvbnMkc3RyaW5naWZ5ID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkc3RyaW5naWZ5OyAvLyBJZiB3ZSdyZSB3aXRoaW4gYSBiYXRjaCwgYWRkIHRoZSByZXF1ZXN0IHRvIHRoZSBzdGFjayB0byBzZW5kIGF0IG9uY2UuXG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2lzQmF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0OS5uZXh0ID0gNjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuX3JlcXVlc3RzLnB1c2gocmVxdWVzdCk7IC8vIFJlc29sdmUgd2l0aCBhIG1lc3NhZ2UgaW4gY2FzZSBwZW9wbGUgYXR0ZW1wdCBhdCBjb25zdW1pbmcgdGhlIHJlc3VsdFxuICAgICAgICAgICAgICAgIC8vIGZyb20gd2l0aGluIGEgYmF0Y2ggb3BlcmF0aW9uLlxuXG5cbiAgICAgICAgICAgICAgICBtc2cgPSBcIlRoaXMgcmVzdWx0IGlzIGdlbmVyYXRlZCBmcm9tIHdpdGhpbiBhIGJhdGNoIFwiICsgXCJvcGVyYXRpb24gYW5kIHNob3VsZCBub3QgYmUgY29uc3VtZWQuXCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OS5hYnJ1cHQoXCJyZXR1cm5cIiwgcmF3ID8ge1xuICAgICAgICAgICAgICAgICAganNvbjogbXNnLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHt9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSA6IG1zZyk7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgIF9jb250ZXh0OS5uZXh0ID0gODtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5odHRwLnJlcXVlc3QodGhpcy5yZW1vdGUgKyByZXF1ZXN0LnBhdGgsICgwLCBfdXRpbHMuY2xlYW5VbmRlZmluZWRQcm9wZXJ0aWVzKSh7XG4gICAgICAgICAgICAgICAgICAvLyBMaW1pdCByZXF1ZXN0cyB0byBvbmx5IHRob3NlIHBhcnRzIHRoYXQgd291bGQgYmUgYWxsb3dlZCBpblxuICAgICAgICAgICAgICAgICAgLy8gYSBiYXRjaCByZXF1ZXN0IC0tIGRvbid0IHBhc3MgdGhyb3VnaCBvdGhlciBmYW5jeSBmZXRjaCgpXG4gICAgICAgICAgICAgICAgICAvLyBvcHRpb25zIGxpa2UgaW50ZWdyaXR5LCByZWRpcmVjdCwgbW9kZSBiZWNhdXNlIHRoZXkgd2lsbFxuICAgICAgICAgICAgICAgICAgLy8gYnJlYWsgb24gYSBiYXRjaCByZXF1ZXN0LiAgQSBiYXRjaCByZXF1ZXN0IG9ubHkgYWxsb3dzXG4gICAgICAgICAgICAgICAgICAvLyBoZWFkZXJzLCBtZXRob2QsIHBhdGggKGFib3ZlKSwgYW5kIGJvZHkuXG4gICAgICAgICAgICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICAgICAgICAgICAgYm9keTogc3RyaW5naWZ5ID8gSlNPTi5zdHJpbmdpZnkocmVxdWVzdC5ib2R5KSA6IHJlcXVlc3QuYm9keVxuICAgICAgICAgICAgICAgIH0pLCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gX2NvbnRleHQ5LnNlbnQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OS5hYnJ1cHQoXCJyZXR1cm5cIiwgcmF3ID8gcmVzdWx0IDogcmVzdWx0Lmpzb24pO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ5LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU5LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGV4ZWN1dGUoX3g0KSB7XG4gICAgICAgIHJldHVybiBfZXhlY3V0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBGZXRjaCBzb21lIHBhZ2VzIGZyb20gYSBwYWdpbmF0ZWQgbGlzdCwgZm9sbG93aW5nIHRoZSBgbmV4dC1wYWdlYFxuICAgICAqIGhlYWRlciBhdXRvbWF0aWNhbGx5IHVudGlsIHdlIGhhdmUgZmV0Y2hlZCB0aGUgcmVxdWVzdGVkIG51bWJlclxuICAgICAqIG9mIHBhZ2VzLiBSZXR1cm4gYSByZXNwb25zZSB3aXRoIGEgYC5uZXh0KClgIG1ldGhvZCB0aGF0IGNhbiBiZVxuICAgICAqIGNhbGxlZCB0byBmZXRjaCBtb3JlIHJlc3VsdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gIHBhdGhcbiAgICAgKiAgICAgVGhlIHBhdGggdG8gbWFrZSB0aGUgcmVxdWVzdCB0by5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBwYXJhbXNcbiAgICAgKiAgICAgVGhlIHBhcmFtZXRlcnMgdG8gdXNlIHdoZW4gbWFraW5nIHRoZSByZXF1ZXN0LlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gIFtwYXJhbXMuc29ydD1cIi1sYXN0X21vZGlmaWVkXCJdXG4gICAgICogICAgIFRoZSBzb3J0aW5nIG9yZGVyIHRvIHVzZSB3aGVuIGZldGNoaW5nLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtwYXJhbXMuZmlsdGVycz17fV1cbiAgICAgKiAgICAgVGhlIGZpbHRlcnMgdG8gc2VuZCBpbiB0aGUgcmVxdWVzdC5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbcGFyYW1zLmxpbWl0PXVuZGVmaW5lZF1cbiAgICAgKiAgICAgVGhlIGxpbWl0IHRvIHNlbmQgaW4gdGhlIHJlcXVlc3QuIFVuZGVmaW5lZCBtZWFucyBubyBsaW1pdC5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbcGFyYW1zLnBhZ2VzPXVuZGVmaW5lZF1cbiAgICAgKiAgICAgVGhlIG51bWJlciBvZiBwYWdlcyB0byBmZXRjaC4gVW5kZWZpbmVkIG1lYW5zIG9uZSBwYWdlLiBQYXNzXG4gICAgICogICAgIEluZmluaXR5IHRvIGZldGNoIGV2ZXJ5dGhpbmcuXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgW3BhcmFtcy5zaW5jZT11bmRlZmluZWRdXG4gICAgICogICAgIFRoZSBFVGFnIGZyb20gd2hpY2ggdG8gc3RhcnQgZmV0Y2hpbmcuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dXG4gICAgICogICAgIEFkZGl0aW9uYWwgcmVxdWVzdC1sZXZlbCBwYXJhbWV0ZXJzIHRvIHVzZSBpbiBhbGwgcmVxdWVzdHMuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVycz17fV1cbiAgICAgKiAgICAgSGVhZGVycyB0byB1c2UgZHVyaW5nIGFsbCByZXF1ZXN0cy5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXVxuICAgICAqICAgICBOdW1iZXIgb2YgdGltZXMgdG8gcmV0cnkgZWFjaCByZXF1ZXN0IGlmIHRoZSBzZXJ2ZXIgcmVzcG9uZHNcbiAgICAgKiAgICAgd2l0aCBSZXRyeS1BZnRlci5cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInBhZ2luYXRlZExpc3RcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9wYWdpbmF0ZWRMaXN0ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTEzKHBhdGgsIHBhcmFtcykge1xuICAgICAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIF9zb3J0JHBhcmFtcyxcbiAgICAgICAgICAgIHNvcnQsXG4gICAgICAgICAgICBmaWx0ZXJzLFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICBwYWdlcyxcbiAgICAgICAgICAgIHNpbmNlLFxuICAgICAgICAgICAgcXVlcnlzdHJpbmcsXG4gICAgICAgICAgICByZXN1bHRzLFxuICAgICAgICAgICAgY3VycmVudCxcbiAgICAgICAgICAgIG5leHQsXG4gICAgICAgICAgICBwcm9jZXNzTmV4dFBhZ2UsXG4gICAgICAgICAgICBwYWdlUmVzdWx0cyxcbiAgICAgICAgICAgIGhhbmRsZVJlc3BvbnNlLFxuICAgICAgICAgICAgX2FyZ3MxMyA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTMkKF9jb250ZXh0MTMpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDEzLnByZXYgPSBfY29udGV4dDEzLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczEzLmxlbmd0aCA+IDIgJiYgX2FyZ3MxM1syXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxM1syXSA6IHt9O1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FOiB0aGlzIGlzIGNhbGxlZCBldmVuIGluIGJhdGNoIHJlcXVlc3RzLCB3aGljaCBkb2Vzbid0XG4gICAgICAgICAgICAgICAgLy8gbWFrZSBhbnkgc2Vuc2UgKHNpbmNlIGFsbCBiYXRjaCByZXF1ZXN0cyBnZXQgYSBcImR1bW15XCJcbiAgICAgICAgICAgICAgICAvLyByZXNwb25zZTsgc2VlIGV4ZWN1dGUoKSBhYm92ZSkuXG4gICAgICAgICAgICAgICAgX3NvcnQkcGFyYW1zID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHtcbiAgICAgICAgICAgICAgICAgIHNvcnQ6IFwiLWxhc3RfbW9kaWZpZWRcIlxuICAgICAgICAgICAgICAgIH0sIHBhcmFtcyksIHNvcnQgPSBfc29ydCRwYXJhbXMuc29ydCwgZmlsdGVycyA9IF9zb3J0JHBhcmFtcy5maWx0ZXJzLCBsaW1pdCA9IF9zb3J0JHBhcmFtcy5saW1pdCwgcGFnZXMgPSBfc29ydCRwYXJhbXMucGFnZXMsIHNpbmNlID0gX3NvcnQkcGFyYW1zLnNpbmNlOyAvLyBTYWZldHkvQ29uc2lzdGVuY3kgY2hlY2sgb24gRVRhZyB2YWx1ZS5cblxuICAgICAgICAgICAgICAgIGlmICghKHNpbmNlICYmIHR5cGVvZiBzaW5jZSAhPT0gXCJzdHJpbmdcIikpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTMubmV4dCA9IDQ7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHZhbHVlIGZvciBzaW5jZSAoXCIuY29uY2F0KHNpbmNlLCBcIiksIHNob3VsZCBiZSBFVGFnIHZhbHVlLlwiKSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIHF1ZXJ5c3RyaW5nID0gKDAsIF91dGlscy5xc2lmeSkoKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBmaWx0ZXJzLCB7XG4gICAgICAgICAgICAgICAgICBfc29ydDogc29ydCxcbiAgICAgICAgICAgICAgICAgIF9saW1pdDogbGltaXQsXG4gICAgICAgICAgICAgICAgICBfc2luY2U6IHNpbmNlXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBbXSwgY3VycmVudCA9IDA7XG5cbiAgICAgICAgICAgICAgICBuZXh0ID1cbiAgICAgICAgICAgICAgICAvKiNfX1BVUkVfXyovXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgdmFyIF9yZWY3ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgICAgICAgICAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgICAgICAgICAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTEwKG5leHRQYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxMCQoX2NvbnRleHQxMCkge1xuICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTAucHJldiA9IF9jb250ZXh0MTAubmV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRQYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGV4dDEwLm5leHQgPSAyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUGFnaW5hdGlvbiBleGhhdXN0ZWQuXCIpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMC5hYnJ1cHQoXCJyZXR1cm5cIiwgcHJvY2Vzc05leHRQYWdlKG5leHRQYWdlKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTAuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSwgX2NhbGxlZTEwLCB0aGlzKTtcbiAgICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5leHQoX3g3KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmVmNy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KCk7XG5cbiAgICAgICAgICAgICAgICBwcm9jZXNzTmV4dFBhZ2UgPVxuICAgICAgICAgICAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgX3JlZjggPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgICAgICAgICAgICAgLyojX19QVVJFX18qL1xuICAgICAgICAgICAgICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTEobmV4dFBhZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhlYWRlcnM7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxMSQoX2NvbnRleHQxMSkge1xuICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTEucHJldiA9IF9jb250ZXh0MTEubmV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVycyA9IG9wdGlvbnMuaGVhZGVycztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGV4dDExLnQwID0gaGFuZGxlUmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRleHQxMS5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMzLmh0dHAucmVxdWVzdChuZXh0UGFnZSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogaGVhZGVyc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGV4dDExLnQxID0gX2NvbnRleHQxMS5zZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDExLmFicnVwdChcInJldHVyblwiLCAoMCwgX2NvbnRleHQxMS50MCkoX2NvbnRleHQxMS50MSkpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDExLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sIF9jYWxsZWUxMSwgdGhpcyk7XG4gICAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiBwcm9jZXNzTmV4dFBhZ2UoX3g4KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmVmOC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KCk7XG5cbiAgICAgICAgICAgICAgICBwYWdlUmVzdWx0cyA9IGZ1bmN0aW9uIHBhZ2VSZXN1bHRzKHJlc3VsdHMsIG5leHRQYWdlLCBldGFnLCB0b3RhbFJlY29yZHMpIHtcbiAgICAgICAgICAgICAgICAgIC8vIEVUYWcgc3RyaW5nIGlzIHN1cHBvc2VkIHRvIGJlIG9wYXF1ZSBhbmQgc3RvcmVkIMKrYXMtaXPCuy5cbiAgICAgICAgICAgICAgICAgIC8vIEVUYWcgaGVhZGVyIHZhbHVlcyBhcmUgcXVvdGVkIChiZWNhdXNlIG9mICogYW5kIFcvXCJmb29cIikuXG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBldGFnID8gZXRhZy5yZXBsYWNlKC9cIi9nLCBcIlwiKSA6IGV0YWcsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHJlc3VsdHMsXG4gICAgICAgICAgICAgICAgICAgIG5leHQ6IG5leHQuYmluZChudWxsLCBuZXh0UGFnZSksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRQYWdlOiAhIW5leHRQYWdlLFxuICAgICAgICAgICAgICAgICAgICB0b3RhbFJlY29yZHM6IHRvdGFsUmVjb3Jkc1xuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaGFuZGxlUmVzcG9uc2UgPVxuICAgICAgICAgICAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgX3JlZjkgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgICAgICAgICAgICAgLyojX19QVVJFX18qL1xuICAgICAgICAgICAgICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTIoX3JlZjEwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBoZWFkZXJzLCBqc29uLCBuZXh0UGFnZSwgZXRhZywgdG90YWxSZWNvcmRzO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTIkKF9jb250ZXh0MTIpIHtcbiAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDEyLnByZXYgPSBfY29udGV4dDEyLm5leHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnMgPSBfcmVmMTAuaGVhZGVycywganNvbiA9IF9yZWYxMC5qc29uO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRQYWdlID0gaGVhZGVycy5nZXQoXCJOZXh0LVBhZ2VcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXRhZyA9IGhlYWRlcnMuZ2V0KFwiRVRhZ1wiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbFJlY29yZHMgPSBwYXJzZUludChoZWFkZXJzLmdldChcIlRvdGFsLVJlY29yZHNcIiksIDEwKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYWdlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRleHQxMi5uZXh0ID0gNjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEyLmFicnVwdChcInJldHVyblwiLCBwYWdlUmVzdWx0cyhqc29uLmRhdGEsIG5leHRQYWdlLCBldGFnLCB0b3RhbFJlY29yZHMpKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWdncmVnYXRlIG5ldyByZXN1bHRzIHdpdGggcHJldmlvdXMgb25lc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSByZXN1bHRzLmNvbmNhdChqc29uLmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgKz0gMTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGN1cnJlbnQgPj0gcGFnZXMgfHwgIW5leHRQYWdlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRleHQxMi5uZXh0ID0gMTA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMi5hYnJ1cHQoXCJyZXR1cm5cIiwgcGFnZVJlc3VsdHMocmVzdWx0cywgbmV4dFBhZ2UsIGV0YWcsIHRvdGFsUmVjb3JkcykpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTIuYWJydXB0KFwicmV0dXJuXCIsIHByb2Nlc3NOZXh0UGFnZShuZXh0UGFnZSkpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTE6XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMi5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LCBfY2FsbGVlMTIsIHRoaXMpO1xuICAgICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gaGFuZGxlUmVzcG9uc2UoX3g5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmVmOS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KCk7XG5cbiAgICAgICAgICAgICAgICBfY29udGV4dDEzLnQwID0gaGFuZGxlUmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQxMy5uZXh0ID0gMTM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSggLy8gTi5CLjogVGhpcyBkb2Vzbid0IHVzZSBfZ2V0SGVhZGVycywgYmVjYXVzZSBhbGwgY2FsbHMgdG9cbiAgICAgICAgICAgICAgICAvLyBgcGFnaW5hdGVkTGlzdGAgYXJlIGFzc3VtZWQgdG8gY29tZSBmcm9tIGNhbGxzIHRoYXQgYWxyZWFkeVxuICAgICAgICAgICAgICAgIC8vIGhhdmUgaGVhZGVycyBtZXJnZWQgYXQgZS5nLiB0aGUgYnVja2V0IG9yIGNvbGxlY3Rpb24gbGV2ZWwuXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogb3B0aW9ucy5oZWFkZXJzLFxuICAgICAgICAgICAgICAgICAgcGF0aDogcGF0aCArIFwiP1wiICsgcXVlcnlzdHJpbmdcbiAgICAgICAgICAgICAgICB9LCAvLyBOLkIuIFRoaXMgZG9lc24ndCB1c2UgX2dldFJldHJ5LCBiZWNhdXNlIGFsbCBjYWxscyB0b1xuICAgICAgICAgICAgICAgIC8vIGBwYWdpbmF0ZWRMaXN0YCBhcmUgYXNzdW1lZCB0byBjb21lIGZyb20gY2FsbHMgdGhhdCBhbHJlYWR5XG4gICAgICAgICAgICAgICAgLy8gdXNlZCBgX2dldFJldHJ5YCBhdCBlLmcuIHRoZSBidWNrZXQgb3IgY29sbGVjdGlvbiBsZXZlbC5cbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICByYXc6IHRydWUsXG4gICAgICAgICAgICAgICAgICByZXRyeTogb3B0aW9ucy5yZXRyeSB8fCAwXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMzpcbiAgICAgICAgICAgICAgICBfY29udGV4dDEzLnQxID0gX2NvbnRleHQxMy5zZW50O1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEzLmFicnVwdChcInJldHVyblwiLCAoMCwgX2NvbnRleHQxMy50MCkoX2NvbnRleHQxMy50MSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTU6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMy5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTMsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gcGFnaW5hdGVkTGlzdChfeDUsIF94Nikge1xuICAgICAgICByZXR1cm4gX3BhZ2luYXRlZExpc3QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogTGlzdHMgYWxsIHBlcm1pc3Npb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzPXt9XSBIZWFkZXJzIHRvIHVzZSB3aGVuIG1ha2luZ1xuICAgICAqICAgICB0aGlzIHJlcXVlc3QuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0W10sIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImxpc3RQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2xpc3RQZXJtaXNzaW9ucyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNCgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcGFnaW5hdGlvbk9wdGlvbnMsXG4gICAgICAgICAgICBfYXJnczE0ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTQkKF9jb250ZXh0MTQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDE0LnByZXYgPSBfY29udGV4dDE0Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczE0Lmxlbmd0aCA+IDAgJiYgX2FyZ3MxNFswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxNFswXSA6IHt9O1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwicGVybWlzc2lvbnNcIik7IC8vIEVuc3VyZSB0aGUgZGVmYXVsdCBzb3J0IHBhcmFtZXRlciBpcyBzb21ldGhpbmcgdGhhdCBleGlzdHMgaW4gcGVybWlzc2lvbnNcbiAgICAgICAgICAgICAgICAvLyBlbnRyaWVzLCBhcyBgbGFzdF9tb2RpZmllZGAgZG9lc24ndDsgaGVyZSwgd2UgcGljayBcImlkXCIuXG5cbiAgICAgICAgICAgICAgICBwYWdpbmF0aW9uT3B0aW9ucyA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7XG4gICAgICAgICAgICAgICAgICBzb3J0OiBcImlkXCJcbiAgICAgICAgICAgICAgICB9LCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5wYWdpbmF0ZWRMaXN0KHBhdGgsIHBhZ2luYXRpb25PcHRpb25zLCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBsaXN0UGVybWlzc2lvbnMoKSB7XG4gICAgICAgIHJldHVybiBfbGlzdFBlcm1pc3Npb25zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgbGlzdCBvZiBidWNrZXRzLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzPXt9XSBIZWFkZXJzIHRvIHVzZSB3aGVuIG1ha2luZ1xuICAgICAqICAgICB0aGlzIHJlcXVlc3QuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0W10sIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImxpc3RCdWNrZXRzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfbGlzdEJ1Y2tldHMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTUoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIF9hcmdzMTUgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxNSQoX2NvbnRleHQxNSkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTUucHJldiA9IF9jb250ZXh0MTUubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTUubGVuZ3RoID4gMCAmJiBfYXJnczE1WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczE1WzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJidWNrZXRcIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTUuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMucGFnaW5hdGVkTGlzdChwYXRoLCBvcHRpb25zLCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE1LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBsaXN0QnVja2V0cygpIHtcbiAgICAgICAgcmV0dXJuIF9saXN0QnVja2V0cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGJ1Y2tldCBvbiB0aGUgc2VydmVyLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7U3RyaW5nfG51bGx9ICBpZCAgICAgICAgICAgICAgICBUaGUgYnVja2V0IG5hbWUgKG9wdGlvbmFsKS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgIFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgICAgIFtvcHRpb25zLmRhdGFdICAgIFRoZSBidWNrZXQgZGF0YSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgICBbb3B0aW9ucy5zYWZlXSAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICAgICAgW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiY3JlYXRlQnVja2V0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfY3JlYXRlQnVja2V0ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE2KGlkKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgX29wdGlvbnMkZGF0YSxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBfYXJnczE2ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxNiQoX2NvbnRleHQxNikge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTYucHJldiA9IF9jb250ZXh0MTYubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTYubGVuZ3RoID4gMSAmJiBfYXJnczE2WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczE2WzFdIDoge307XG4gICAgICAgICAgICAgICAgX29wdGlvbnMkZGF0YSA9IG9wdGlvbnMuZGF0YSwgZGF0YSA9IF9vcHRpb25zJGRhdGEgPT09IHZvaWQgMCA/IHt9IDogX29wdGlvbnMkZGF0YSwgcGVybWlzc2lvbnMgPSBvcHRpb25zLnBlcm1pc3Npb25zO1xuXG4gICAgICAgICAgICAgICAgaWYgKGlkICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgIGRhdGEuaWQgPSBpZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBwYXRoID0gZGF0YS5pZCA/ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJidWNrZXRcIiwgZGF0YS5pZCkgOiAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYnVja2V0XCIpO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE2LmFicnVwdChcInJldHVyblwiLCB0aGlzLmV4ZWN1dGUocmVxdWVzdHMuY3JlYXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE2LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNiwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBjcmVhdGVCdWNrZXQoX3gxMCkge1xuICAgICAgICByZXR1cm4gX2NyZWF0ZUJ1Y2tldC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBEZWxldGVzIGEgYnVja2V0IGZyb20gdGhlIHNlcnZlci5cbiAgICAgKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R8U3RyaW5nfSBidWNrZXQgICAgICAgICAgICAgICAgICBUaGUgYnVja2V0IHRvIGRlbGV0ZS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgICAgW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgICAgICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImRlbGV0ZUJ1Y2tldFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2RlbGV0ZUJ1Y2tldCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNyhidWNrZXQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBidWNrZXRPYmosXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgX2J1Y2tldE9iaiRvcHRpb25zLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIF9hcmdzMTcgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE3JChfY29udGV4dDE3KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxNy5wcmV2ID0gX2NvbnRleHQxNy5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxNy5sZW5ndGggPiAxICYmIF9hcmdzMTdbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTdbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICBidWNrZXRPYmogPSAoMCwgX3V0aWxzLnRvRGF0YUJvZHkpKGJ1Y2tldCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoYnVja2V0T2JqLmlkKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDE3Lm5leHQgPSA0O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBidWNrZXQgaWQgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJ1Y2tldFwiLCBidWNrZXRPYmouaWQpO1xuICAgICAgICAgICAgICAgIF9idWNrZXRPYmokb3B0aW9ucyA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgYnVja2V0T2JqLCBvcHRpb25zKSwgbGFzdF9tb2RpZmllZCA9IF9idWNrZXRPYmokb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE3LmFicnVwdChcInJldHVyblwiLCB0aGlzLmV4ZWN1dGUocmVxdWVzdHMuZGVsZXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE3LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNywgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBkZWxldGVCdWNrZXQoX3gxMSkge1xuICAgICAgICByZXR1cm4gX2RlbGV0ZUJ1Y2tldC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBEZWxldGVzIGFsbCBidWNrZXRzIG9uIHRoZSBzZXJ2ZXIuXG4gICAgICpcbiAgICAgKiBAaWdub3JlXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZGVsZXRlQnVja2V0c1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2RlbGV0ZUJ1Y2tldHMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTgoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIF9hcmdzMTggPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxOCQoX2NvbnRleHQxOCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTgucHJldiA9IF9jb250ZXh0MTgubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTgubGVuZ3RoID4gMCAmJiBfYXJnczE4WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczE4WzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJidWNrZXRcIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTguYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuZXhlY3V0ZShyZXF1ZXN0cy5kZWxldGVSZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IG9wdGlvbnMubGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSksIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxOC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTgsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZGVsZXRlQnVja2V0cygpIHtcbiAgICAgICAgcmV0dXJuIF9kZWxldGVCdWNrZXRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICB9LCB7XG4gICAga2V5OiBcInJlbW90ZVwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3JlbW90ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgICxcbiAgICBzZXQ6IGZ1bmN0aW9uIHNldCh1cmwpIHtcbiAgICAgIHZhciB2ZXJzaW9uO1xuXG4gICAgICB0cnkge1xuICAgICAgICB2ZXJzaW9uID0gdXJsLm1hdGNoKC9cXC8odlxcZCspXFwvPyQvKVsxXTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcmVtb3RlIFVSTCBtdXN0IGNvbnRhaW4gdGhlIHZlcnNpb246IFwiICsgdXJsKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHZlcnNpb24gIT09IFNVUFBPUlRFRF9QUk9UT0NPTF9WRVJTSU9OKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVuc3VwcG9ydGVkIHByb3RvY29sIHZlcnNpb246IFwiLmNvbmNhdCh2ZXJzaW9uKSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3JlbW90ZSA9IHVybDtcbiAgICAgIHRoaXMuX3ZlcnNpb24gPSB2ZXJzaW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudCBzZXJ2ZXIgcHJvdG9jb2wgdmVyc2lvbiwgZWcuIGB2MWAuXG4gICAgICogQHR5cGUge1N0cmluZ31cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInZlcnNpb25cIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLl92ZXJzaW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCYWNrb2ZmIHJlbWFpbmluZyB0aW1lLCBpbiBtaWxsaXNlY29uZHMuIERlZmF1bHRzIHRvIHplcm8gaWYgbm8gYmFja29mZiBpc1xuICAgICAqIG9uZ29pbmcuXG4gICAgICpcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiYmFja29mZlwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIGN1cnJlbnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgICAgIGlmICh0aGlzLl9iYWNrb2ZmUmVsZWFzZVRpbWUgJiYgY3VycmVudFRpbWUgPCB0aGlzLl9iYWNrb2ZmUmVsZWFzZVRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JhY2tvZmZSZWxlYXNlVGltZSAtIGN1cnJlbnRUaW1lO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gIH1dKTtcbiAgcmV0dXJuIEtpbnRvQ2xpZW50QmFzZTtcbn0oKSwgKCgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImZldGNoU2VydmVyU2V0dGluZ3NcIiwgW19kZWNdLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwiZmV0Y2hTZXJ2ZXJTZXR0aW5nc1wiKSwgX2NsYXNzLnByb3RvdHlwZSksICgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImZldGNoU2VydmVyQ2FwYWJpbGl0aWVzXCIsIFtfZGVjMl0sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgXCJmZXRjaFNlcnZlckNhcGFiaWxpdGllc1wiKSwgX2NsYXNzLnByb3RvdHlwZSksICgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImZldGNoVXNlclwiLCBbX2RlYzNdLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwiZmV0Y2hVc2VyXCIpLCBfY2xhc3MucHJvdG90eXBlKSwgKDAsIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyLmRlZmF1bHQpKF9jbGFzcy5wcm90b3R5cGUsIFwiZmV0Y2hIVFRQQXBpVmVyc2lvblwiLCBbX2RlYzRdLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwiZmV0Y2hIVFRQQXBpVmVyc2lvblwiKSwgX2NsYXNzLnByb3RvdHlwZSksICgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImJhdGNoXCIsIFtfZGVjNV0sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgXCJiYXRjaFwiKSwgX2NsYXNzLnByb3RvdHlwZSksICgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImxpc3RQZXJtaXNzaW9uc1wiLCBbX2RlYzZdLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwibGlzdFBlcm1pc3Npb25zXCIpLCBfY2xhc3MucHJvdG90eXBlKSwgKDAsIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyLmRlZmF1bHQpKF9jbGFzcy5wcm90b3R5cGUsIFwiZGVsZXRlQnVja2V0c1wiLCBbX2RlYzddLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwiZGVsZXRlQnVja2V0c1wiKSwgX2NsYXNzLnByb3RvdHlwZSkpLCBfY2xhc3MpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEtpbnRvQ2xpZW50QmFzZTsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuYWdncmVnYXRlID0gYWdncmVnYXRlO1xuXG4vKipcbiAqIEV4cG9ydHMgYmF0Y2ggcmVzcG9uc2VzIGFzIGEgcmVzdWx0IG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtICB7QXJyYXl9IHJlc3BvbnNlcyBUaGUgYmF0Y2ggc3VicmVxdWVzdCByZXNwb25zZXMuXG4gKiBAcGFyYW0gIHtBcnJheX0gcmVxdWVzdHMgIFRoZSBpbml0aWFsIGlzc3VlZCByZXF1ZXN0cy5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gYWdncmVnYXRlKCkge1xuICB2YXIgcmVzcG9uc2VzID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBbXTtcbiAgdmFyIHJlcXVlc3RzID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBbXTtcblxuICBpZiAocmVzcG9uc2VzLmxlbmd0aCAhPT0gcmVxdWVzdHMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiUmVzcG9uc2VzIGxlbmd0aCBzaG91bGQgbWF0Y2ggcmVxdWVzdHMgb25lLlwiKTtcbiAgfVxuXG4gIHZhciByZXN1bHRzID0ge1xuICAgIGVycm9yczogW10sXG4gICAgcHVibGlzaGVkOiBbXSxcbiAgICBjb25mbGljdHM6IFtdLFxuICAgIHNraXBwZWQ6IFtdXG4gIH07XG4gIHJldHVybiByZXNwb25zZXMucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHJlc3BvbnNlLCBpbmRleCkge1xuICAgIHZhciBzdGF0dXMgPSByZXNwb25zZS5zdGF0dXM7XG4gICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0c1tpbmRleF07XG5cbiAgICBpZiAoc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCA0MDApIHtcbiAgICAgIGFjYy5wdWJsaXNoZWQucHVzaChyZXNwb25zZS5ib2R5KTtcbiAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PT0gNDA0KSB7XG4gICAgICAvLyBFeHRyYWN0IHRoZSBpZCBtYW51YWxseSBmcm9tIHJlcXVlc3QgcGF0aCB3aGlsZSB3YWl0aW5nIGZvciBLaW50by9raW50byM4MThcbiAgICAgIHZhciByZWdleCA9IC8oYnVja2V0c3xncm91cHN8Y29sbGVjdGlvbnN8cmVjb3JkcylcXC8oW14vXSspJC87XG4gICAgICB2YXIgZXh0cmFjdHMgPSByZXF1ZXN0LnBhdGgubWF0Y2gocmVnZXgpO1xuICAgICAgdmFyIGlkID0gZXh0cmFjdHMubGVuZ3RoID09PSAzID8gZXh0cmFjdHNbMl0gOiB1bmRlZmluZWQ7XG4gICAgICBhY2Muc2tpcHBlZC5wdXNoKHtcbiAgICAgICAgaWQ6IGlkLFxuICAgICAgICBwYXRoOiByZXF1ZXN0LnBhdGgsXG4gICAgICAgIGVycm9yOiByZXNwb25zZS5ib2R5XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PT0gNDEyKSB7XG4gICAgICBhY2MuY29uZmxpY3RzLnB1c2goe1xuICAgICAgICAvLyBYWFg6IHNwZWNpZnlpbmcgdGhlIHR5cGUgaXMgcHJvYmFibHkgc3VwZXJmbHVvdXNcbiAgICAgICAgdHlwZTogXCJvdXRnb2luZ1wiLFxuICAgICAgICBsb2NhbDogcmVxdWVzdC5ib2R5LFxuICAgICAgICByZW1vdGU6IHJlc3BvbnNlLmJvZHkuZGV0YWlscyAmJiByZXNwb25zZS5ib2R5LmRldGFpbHMuZXhpc3RpbmcgfHwgbnVsbFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFjYy5lcnJvcnMucHVzaCh7XG4gICAgICAgIHBhdGg6IHJlcXVlc3QucGF0aCxcbiAgICAgICAgc2VudDogcmVxdWVzdCxcbiAgICAgICAgZXJyb3I6IHJlc3BvbnNlLmJvZHlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBhY2M7XG4gIH0sIHJlc3VsdHMpO1xufSIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlRGVmYXVsdFwiKTtcblxudmFyIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvaW50ZXJvcFJlcXVpcmVXaWxkY2FyZFwiKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF9yZWdlbmVyYXRvciA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL3JlZ2VuZXJhdG9yXCIpKTtcblxudmFyIF9hc3luY1RvR2VuZXJhdG9yMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYXN5bmNUb0dlbmVyYXRvclwiKSk7XG5cbnZhciBfb2JqZWN0U3ByZWFkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvb2JqZWN0U3ByZWFkXCIpKTtcblxudmFyIF9jbGFzc0NhbGxDaGVjazIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NsYXNzQ2FsbENoZWNrXCIpKTtcblxudmFyIF9jcmVhdGVDbGFzczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NyZWF0ZUNsYXNzXCIpKTtcblxudmFyIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hcHBseURlY29yYXRlZERlc2NyaXB0b3JcIikpO1xuXG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4vdXRpbHNcIik7XG5cbnZhciBfY29sbGVjdGlvbiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vY29sbGVjdGlvblwiKSk7XG5cbnZhciByZXF1ZXN0cyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL3JlcXVlc3RzXCIpKTtcblxudmFyIF9lbmRwb2ludCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vZW5kcG9pbnRcIikpO1xuXG52YXIgX2RlYywgX2NsYXNzO1xuXG4vKipcbiAqIEFic3RyYWN0IHJlcHJlc2VudGF0aW9uIG9mIGEgc2VsZWN0ZWQgYnVja2V0LlxuICpcbiAqL1xudmFyIEJ1Y2tldCA9IChfZGVjID0gKDAsIF91dGlscy5jYXBhYmxlKShbXCJoaXN0b3J5XCJdKSwgKF9jbGFzcyA9XG4vKiNfX1BVUkVfXyovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rvci5cbiAgICpcbiAgICogQHBhcmFtICB7S2ludG9DbGllbnR9IGNsaWVudCAgICAgICAgICAgIFRoZSBjbGllbnQgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSAge1N0cmluZ30gICAgICBuYW1lICAgICAgICAgICAgICBUaGUgYnVja2V0IG5hbWUuXG4gICAqIEBwYXJhbSAge09iamVjdH0gICAgICBbb3B0aW9ucz17fV0gICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgW29wdGlvbnMuaGVhZGVyc10gVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgIFtvcHRpb25zLnNhZmVdICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgIFtvcHRpb25zLnJldHJ5XSAgIFRoZSByZXRyeSBvcHRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBCdWNrZXQoY2xpZW50LCBuYW1lKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IHt9O1xuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIEJ1Y2tldCk7XG5cbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gICAgLyoqXG4gICAgICogVGhlIGJ1Y2tldCBuYW1lLlxuICAgICAqIEB0eXBlIHtTdHJpbmd9XG4gICAgICovXG5cbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cblxuICAgIHRoaXMuX2lzQmF0Y2ggPSAhIW9wdGlvbnMuYmF0Y2g7XG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuXG4gICAgdGhpcy5faGVhZGVycyA9IG9wdGlvbnMuaGVhZGVycyB8fCB7fTtcbiAgICB0aGlzLl9yZXRyeSA9IG9wdGlvbnMucmV0cnkgfHwgMDtcbiAgICB0aGlzLl9zYWZlID0gISFvcHRpb25zLnNhZmU7XG4gIH1cbiAgLyoqXG4gICAqIEdldCB0aGUgdmFsdWUgb2YgXCJoZWFkZXJzXCIgZm9yIGEgZ2l2ZW4gcmVxdWVzdCwgbWVyZ2luZyB0aGVcbiAgICogcGVyLXJlcXVlc3QgaGVhZGVycyB3aXRoIG91ciBvd24gXCJkZWZhdWx0XCIgaGVhZGVycy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICAoMCwgX2NyZWF0ZUNsYXNzMi5kZWZhdWx0KShCdWNrZXQsIFt7XG4gICAga2V5OiBcIl9nZXRIZWFkZXJzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRIZWFkZXJzKG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHRoaXMuX2hlYWRlcnMsIG9wdGlvbnMuaGVhZGVycyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgb2YgXCJzYWZlXCIgZm9yIGEgZ2l2ZW4gcmVxdWVzdCwgdXNpbmcgdGhlXG4gICAgICogcGVyLXJlcXVlc3Qgb3B0aW9uIGlmIHByZXNlbnQgb3IgZmFsbGluZyBiYWNrIHRvIG91ciBkZWZhdWx0XG4gICAgICogb3RoZXJ3aXNlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBUaGUgb3B0aW9ucyBmb3IgYSByZXF1ZXN0LlxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2dldFNhZmVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldFNhZmUob3B0aW9ucykge1xuICAgICAgcmV0dXJuICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7XG4gICAgICAgIHNhZmU6IHRoaXMuX3NhZmVcbiAgICAgIH0sIG9wdGlvbnMpLnNhZmU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFzIF9nZXRTYWZlLCBidXQgZm9yIFwicmV0cnlcIi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0UmV0cnlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldFJldHJ5KG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe1xuICAgICAgICByZXRyeTogdGhpcy5fcmV0cnlcbiAgICAgIH0sIG9wdGlvbnMpLnJldHJ5O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWxlY3RzIGEgY29sbGVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gIG5hbWUgICAgICAgICAgICAgIFRoZSBjb2xsZWN0aW9uIG5hbWUuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge0NvbGxlY3Rpb259XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJjb2xsZWN0aW9uXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbGxlY3Rpb24obmFtZSkge1xuICAgICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICAgICAgcmV0dXJuIG5ldyBfY29sbGVjdGlvbi5kZWZhdWx0KHRoaXMuY2xpZW50LCB0aGlzLCBuYW1lLCB7XG4gICAgICAgIGJhdGNoOiB0aGlzLl9pc0JhdGNoLFxuICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucyksXG4gICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgYnVja2V0IGRhdGEuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXREYXRhXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZ2V0RGF0YSA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9yZWYsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgX2FyZ3MgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZSQoX2NvbnRleHQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dC5wcmV2ID0gX2NvbnRleHQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzLmxlbmd0aCA+IDAgJiYgX2FyZ3NbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzWzBdIDoge307XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBwYXRoOiAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYnVja2V0XCIsIHRoaXMubmFtZSlcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSA0O1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBfcmVmID0gX2NvbnRleHQuc2VudDtcbiAgICAgICAgICAgICAgICBkYXRhID0gX3JlZi5kYXRhO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dC5hYnJ1cHQoXCJyZXR1cm5cIiwgZGF0YSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZ2V0RGF0YSgpIHtcbiAgICAgICAgcmV0dXJuIF9nZXREYXRhLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFNldCBidWNrZXQgZGF0YS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBkYXRhICAgICAgICAgICAgICAgICAgICBUaGUgYnVja2V0IGRhdGEgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzPXt9XSAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnBhdGNoXSAgICAgICAgIFRoZSBwYXRjaCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJzZXREYXRhXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfc2V0RGF0YSA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUyKGRhdGEpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBidWNrZXQsXG4gICAgICAgICAgICBidWNrZXRJZCxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBwYXRjaCxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgX2RhdGEkb3B0aW9ucyxcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3MyID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUyJChfY29udGV4dDIpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDIucHJldiA9IF9jb250ZXh0Mi5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MyLmxlbmd0aCA+IDEgJiYgX2FyZ3MyWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczJbMV0gOiB7fTtcblxuICAgICAgICAgICAgICAgIGlmICgoMCwgX3V0aWxzLmlzT2JqZWN0KShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQyLm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBidWNrZXQgb2JqZWN0IGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgYnVja2V0ID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBkYXRhLCB7XG4gICAgICAgICAgICAgICAgICBpZDogdGhpcy5uYW1lXG4gICAgICAgICAgICAgICAgfSk7IC8vIEZvciBkZWZhdWx0IGJ1Y2tldCwgd2UgbmVlZCB0byBkcm9wIHRoZSBpZCBmcm9tIHRoZSBkYXRhIG9iamVjdC5cbiAgICAgICAgICAgICAgICAvLyBCdWcgaW4gS2ludG8gPCAzLjEuMVxuXG4gICAgICAgICAgICAgICAgYnVja2V0SWQgPSBidWNrZXQuaWQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoYnVja2V0LmlkID09PSBcImRlZmF1bHRcIikge1xuICAgICAgICAgICAgICAgICAgZGVsZXRlIGJ1Y2tldC5pZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJ1Y2tldFwiLCBidWNrZXRJZCk7XG4gICAgICAgICAgICAgICAgcGF0Y2ggPSBvcHRpb25zLnBhdGNoLCBwZXJtaXNzaW9ucyA9IG9wdGlvbnMucGVybWlzc2lvbnM7XG4gICAgICAgICAgICAgICAgX2RhdGEkb3B0aW9ucyA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgZGF0YSwgb3B0aW9ucyksIGxhc3RfbW9kaWZpZWQgPSBfZGF0YSRvcHRpb25zLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLnVwZGF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogYnVja2V0LFxuICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIHBhdGNoOiBwYXRjaCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDIuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTIsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gc2V0RGF0YShfeCkge1xuICAgICAgICByZXR1cm4gX3NldERhdGEuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBsaXN0IG9mIGhpc3RvcnkgZW50cmllcyBpbiB0aGUgY3VycmVudCBidWNrZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8QXJyYXk8T2JqZWN0PiwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwibGlzdEhpc3RvcnlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9saXN0SGlzdG9yeSA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUzKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBfYXJnczMgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUzJChfY29udGV4dDMpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDMucHJldiA9IF9jb250ZXh0My5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MzLmxlbmd0aCA+IDAgJiYgX2FyZ3MzWzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczNbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImhpc3RvcnlcIiwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQzLmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5wYWdpbmF0ZWRMaXN0KHBhdGgsIG9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0My5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMywgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBsaXN0SGlzdG9yeSgpIHtcbiAgICAgICAgcmV0dXJuIF9saXN0SGlzdG9yeS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIGxpc3Qgb2YgY29sbGVjdGlvbnMgaW4gdGhlIGN1cnJlbnQgYnVja2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PE9iamVjdD4sIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImxpc3RDb2xsZWN0aW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2xpc3RDb2xsZWN0aW9ucyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU0KCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBfYXJnczQgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU0JChfY29udGV4dDQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDQucHJldiA9IF9jb250ZXh0NC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M0Lmxlbmd0aCA+IDAgJiYgX2FyZ3M0WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczRbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImNvbGxlY3Rpb25cIiwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ0LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5wYWdpbmF0ZWRMaXN0KHBhdGgsIG9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBsaXN0Q29sbGVjdGlvbnMoKSB7XG4gICAgICAgIHJldHVybiBfbGlzdENvbGxlY3Rpb25zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgY29sbGVjdGlvbiBpbiBjdXJyZW50IGJ1Y2tldC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ3x1bmRlZmluZWR9ICBpZCAgICAgICAgICBUaGUgY29sbGVjdGlvbiBpZC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMucGVybWlzc2lvbnNdIFRoZSBwZXJtaXNzaW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuZGF0YV0gICAgICAgIFRoZSBkYXRhIG9iamVjdC5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiY3JlYXRlQ29sbGVjdGlvblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2NyZWF0ZUNvbGxlY3Rpb24gPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlNShpZCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgX29wdGlvbnMkZGF0YSxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzNSA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlNSQoX2NvbnRleHQ1KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ1LnByZXYgPSBfY29udGV4dDUubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzNS5sZW5ndGggPiAxICYmIF9hcmdzNVsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M1WzFdIDoge307XG4gICAgICAgICAgICAgICAgcGVybWlzc2lvbnMgPSBvcHRpb25zLnBlcm1pc3Npb25zLCBfb3B0aW9ucyRkYXRhID0gb3B0aW9ucy5kYXRhLCBkYXRhID0gX29wdGlvbnMkZGF0YSA9PT0gdm9pZCAwID8ge30gOiBfb3B0aW9ucyRkYXRhO1xuICAgICAgICAgICAgICAgIGRhdGEuaWQgPSBpZDtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImNvbGxlY3Rpb25cIiwgdGhpcy5uYW1lLCBpZCk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLmNyZWF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NS5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBjcmVhdGVDb2xsZWN0aW9uKF94Mikge1xuICAgICAgICByZXR1cm4gX2NyZWF0ZUNvbGxlY3Rpb24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogRGVsZXRlcyBhIGNvbGxlY3Rpb24gZnJvbSB0aGUgY3VycmVudCBidWNrZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R8U3RyaW5nfSBjb2xsZWN0aW9uICAgICAgICAgICAgICBUaGUgY29sbGVjdGlvbiB0byBkZWxldGUuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgICAgICBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJkZWxldGVDb2xsZWN0aW9uXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZGVsZXRlQ29sbGVjdGlvbiA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU2KGNvbGxlY3Rpb24pIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBjb2xsZWN0aW9uT2JqLFxuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBfY29sbGVjdGlvbk9iaiRvcHRpb24sXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczYgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTYkKF9jb250ZXh0Nikge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0Ni5wcmV2ID0gX2NvbnRleHQ2Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczYubGVuZ3RoID4gMSAmJiBfYXJnczZbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzNlsxXSA6IHt9O1xuICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25PYmogPSAoMCwgX3V0aWxzLnRvRGF0YUJvZHkpKGNvbGxlY3Rpb24pO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNvbGxlY3Rpb25PYmouaWQpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Ni5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgY29sbGVjdGlvbiBpZCBpcyByZXF1aXJlZC5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIGlkID0gY29sbGVjdGlvbk9iai5pZDtcbiAgICAgICAgICAgICAgICBfY29sbGVjdGlvbk9iaiRvcHRpb24gPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGNvbGxlY3Rpb25PYmosIG9wdGlvbnMpLCBsYXN0X21vZGlmaWVkID0gX2NvbGxlY3Rpb25PYmokb3B0aW9uLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMubmFtZSwgaWQpO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy5kZWxldGVSZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDYuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgOTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDYuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTYsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZGVsZXRlQ29sbGVjdGlvbihfeDMpIHtcbiAgICAgICAgcmV0dXJuIF9kZWxldGVDb2xsZWN0aW9uLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgbGlzdCBvZiBncm91cHMgaW4gdGhlIGN1cnJlbnQgYnVja2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PE9iamVjdD4sIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImxpc3RHcm91cHNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9saXN0R3JvdXBzID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTcoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIF9hcmdzNyA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTckKF9jb250ZXh0Nykge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0Ny5wcmV2ID0gX2NvbnRleHQ3Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczcubGVuZ3RoID4gMCAmJiBfYXJnczdbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzN1swXSA6IHt9O1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiZ3JvdXBcIiwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ3LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5wYWdpbmF0ZWRMaXN0KHBhdGgsIG9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Ny5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNywgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBsaXN0R3JvdXBzKCkge1xuICAgICAgICByZXR1cm4gX2xpc3RHcm91cHMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBncm91cCBpbiBjdXJyZW50IGJ1Y2tldC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gaWQgICAgICAgICAgICAgICAgVGhlIGdyb3VwIGlkLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnM9e31dICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMuaGVhZGVyc10gVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IFtvcHRpb25zLnJldHJ5PTBdIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImdldEdyb3VwXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZ2V0R3JvdXAgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlOChpZCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczggPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU4JChfY29udGV4dDgpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDgucHJldiA9IF9jb250ZXh0OC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M4Lmxlbmd0aCA+IDEgJiYgX2FyZ3M4WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczhbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0ge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHBhdGg6ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJncm91cFwiLCB0aGlzLm5hbWUsIGlkKVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlOCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBnZXRHcm91cChfeDQpIHtcbiAgICAgICAgcmV0dXJuIF9nZXRHcm91cC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGdyb3VwIGluIGN1cnJlbnQgYnVja2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7U3RyaW5nfHVuZGVmaW5lZH0gIGlkICAgICAgICAgICAgICAgICAgICBUaGUgZ3JvdXAgaWQuXG4gICAgICogQHBhcmFtICB7QXJyYXk8U3RyaW5nPn0gICAgIFttZW1iZXJzPVtdXSAgICAgICAgICBUaGUgbGlzdCBvZiBwcmluY2lwYWxzLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgICAgICBbb3B0aW9ucz17fV0gICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgICAgICBbb3B0aW9ucy5kYXRhXSAgICAgICAgVGhlIGRhdGEgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgICAgICBbb3B0aW9ucy5wZXJtaXNzaW9uc10gVGhlIHBlcm1pc3Npb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgICAgICAgICAgW29wdGlvbnMuc2FmZV0gICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICAgICAgW29wdGlvbnMuaGVhZGVyc10gICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICAgICAgIFtvcHRpb25zLnJldHJ5PTBdICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJjcmVhdGVHcm91cFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2NyZWF0ZUdyb3VwID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTkoaWQpIHtcbiAgICAgICAgdmFyIG1lbWJlcnMsXG4gICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczkgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU5JChfY29udGV4dDkpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDkucHJldiA9IF9jb250ZXh0OS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBtZW1iZXJzID0gX2FyZ3M5Lmxlbmd0aCA+IDEgJiYgX2FyZ3M5WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczlbMV0gOiBbXTtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M5Lmxlbmd0aCA+IDIgJiYgX2FyZ3M5WzJdICE9PSB1bmRlZmluZWQgPyBfYXJnczlbMl0gOiB7fTtcbiAgICAgICAgICAgICAgICBkYXRhID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBvcHRpb25zLmRhdGEsIHtcbiAgICAgICAgICAgICAgICAgIGlkOiBpZCxcbiAgICAgICAgICAgICAgICAgIG1lbWJlcnM6IG1lbWJlcnNcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImdyb3VwXCIsIHRoaXMubmFtZSwgaWQpO1xuICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zID0gb3B0aW9ucy5wZXJtaXNzaW9ucztcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuY3JlYXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ5LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ5LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU5LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGNyZWF0ZUdyb3VwKF94NSkge1xuICAgICAgICByZXR1cm4gX2NyZWF0ZUdyb3VwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgYW4gZXhpc3RpbmcgZ3JvdXAgaW4gY3VycmVudCBidWNrZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBncm91cCAgICAgICAgICAgICAgICAgICBUaGUgZ3JvdXAgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5kYXRhXSAgICAgICAgICBUaGUgZGF0YSBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMucGVybWlzc2lvbnNdICAgVGhlIHBlcm1pc3Npb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwidXBkYXRlR3JvdXBcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF91cGRhdGVHcm91cCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxMChncm91cCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcGF0Y2gsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIF9kYXRhJG9wdGlvbnMyLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczEwID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxMCQoX2NvbnRleHQxMCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTAucHJldiA9IF9jb250ZXh0MTAubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTAubGVuZ3RoID4gMSAmJiBfYXJnczEwWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczEwWzFdIDoge307XG5cbiAgICAgICAgICAgICAgICBpZiAoKDAsIF91dGlscy5pc09iamVjdCkoZ3JvdXApKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDEwLm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBncm91cCBvYmplY3QgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBpZiAoZ3JvdXAuaWQpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTAubmV4dCA9IDU7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIGdyb3VwIGlkIGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgZGF0YSA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgb3B0aW9ucy5kYXRhLCBncm91cCk7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJncm91cFwiLCB0aGlzLm5hbWUsIGdyb3VwLmlkKTtcbiAgICAgICAgICAgICAgICBwYXRjaCA9IG9wdGlvbnMucGF0Y2gsIHBlcm1pc3Npb25zID0gb3B0aW9ucy5wZXJtaXNzaW9ucztcbiAgICAgICAgICAgICAgICBfZGF0YSRvcHRpb25zMiA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgZGF0YSwgb3B0aW9ucyksIGxhc3RfbW9kaWZpZWQgPSBfZGF0YSRvcHRpb25zMi5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy51cGRhdGVSZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgICAgICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgcGF0Y2g6IHBhdGNoLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEwLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxMCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiB1cGRhdGVHcm91cChfeDYpIHtcbiAgICAgICAgcmV0dXJuIF91cGRhdGVHcm91cC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBEZWxldGVzIGEgZ3JvdXAgZnJvbSB0aGUgY3VycmVudCBidWNrZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R8U3RyaW5nfSBncm91cCAgICAgICAgICAgICAgICAgICBUaGUgZ3JvdXAgdG8gZGVsZXRlLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICAgICAgIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgICAgW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICAgICAgIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZGVsZXRlR3JvdXBcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9kZWxldGVHcm91cCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxMShncm91cCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIGdyb3VwT2JqLFxuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBfZ3JvdXBPYmokb3B0aW9ucyxcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMTEgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTExJChfY29udGV4dDExKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxMS5wcmV2ID0gX2NvbnRleHQxMS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxMS5sZW5ndGggPiAxICYmIF9hcmdzMTFbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTFbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICBncm91cE9iaiA9ICgwLCBfdXRpbHMudG9EYXRhQm9keSkoZ3JvdXApO1xuICAgICAgICAgICAgICAgIGlkID0gZ3JvdXBPYmouaWQ7XG4gICAgICAgICAgICAgICAgX2dyb3VwT2JqJG9wdGlvbnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGdyb3VwT2JqLCBvcHRpb25zKSwgbGFzdF9tb2RpZmllZCA9IF9ncm91cE9iaiRvcHRpb25zLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJncm91cFwiLCB0aGlzLm5hbWUsIGlkKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuZGVsZXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMS5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTEuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTExLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGRlbGV0ZUdyb3VwKF94Nykge1xuICAgICAgICByZXR1cm4gX2RlbGV0ZUdyb3VwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgbGlzdCBvZiBwZXJtaXNzaW9ucyBmb3IgdGhpcyBidWNrZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2dldFBlcm1pc3Npb25zID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTEyKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfcmVmMixcbiAgICAgICAgICAgIHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgX2FyZ3MxMiA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTIkKF9jb250ZXh0MTIpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDEyLnByZXYgPSBfY29udGV4dDEyLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczEyLmxlbmd0aCA+IDAgJiYgX2FyZ3MxMlswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxMlswXSA6IHt9O1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcGF0aDogKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJ1Y2tldFwiLCB0aGlzLm5hbWUpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDEyLm5leHQgPSA0O1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBfcmVmMiA9IF9jb250ZXh0MTIuc2VudDtcbiAgICAgICAgICAgICAgICBwZXJtaXNzaW9ucyA9IF9yZWYyLnBlcm1pc3Npb25zO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEyLmFicnVwdChcInJldHVyblwiLCBwZXJtaXNzaW9ucyk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTIuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTEyLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGdldFBlcm1pc3Npb25zKCkge1xuICAgICAgICByZXR1cm4gX2dldFBlcm1pc3Npb25zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJlcGxhY2VzIGFsbCBleGlzdGluZyBidWNrZXQgcGVybWlzc2lvbnMgd2l0aCB0aGUgb25lcyBwcm92aWRlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIHBlcm1pc3Npb25zICAgICAgICAgICAgIFRoZSBwZXJtaXNzaW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0XG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnM9e31dICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInNldFBlcm1pc3Npb25zXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfc2V0UGVybWlzc2lvbnMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTMocGVybWlzc2lvbnMpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3MxMyA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTEzJChfY29udGV4dDEzKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxMy5wcmV2ID0gX2NvbnRleHQxMy5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxMy5sZW5ndGggPiAxICYmIF9hcmdzMTNbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTNbMV0gOiB7fTtcblxuICAgICAgICAgICAgICAgIGlmICgoMCwgX3V0aWxzLmlzT2JqZWN0KShwZXJtaXNzaW9ucykpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTMubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHBlcm1pc3Npb25zIG9iamVjdCBpcyByZXF1aXJlZC5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYnVja2V0XCIsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZCA9IG9wdGlvbnMubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICBkYXRhID0ge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLnVwZGF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTMuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEzLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxMywgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBzZXRQZXJtaXNzaW9ucyhfeDgpIHtcbiAgICAgICAgcmV0dXJuIF9zZXRQZXJtaXNzaW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBBcHBlbmQgcHJpbmNpcGFscyB0byB0aGUgYnVja2V0IHBlcm1pc3Npb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgcGVybWlzc2lvbnMgICAgICAgICAgICAgVGhlIHBlcm1pc3Npb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3RcbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiYWRkUGVybWlzc2lvbnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9hZGRQZXJtaXNzaW9ucyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNChwZXJtaXNzaW9ucykge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMTQgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxNCQoX2NvbnRleHQxNCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTQucHJldiA9IF9jb250ZXh0MTQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTQubGVuZ3RoID4gMSAmJiBfYXJnczE0WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczE0WzFdIDoge307XG5cbiAgICAgICAgICAgICAgICBpZiAoKDAsIF91dGlscy5pc09iamVjdCkocGVybWlzc2lvbnMpKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDE0Lm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBwZXJtaXNzaW9ucyBvYmplY3QgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJ1Y2tldFwiLCB0aGlzLm5hbWUpO1xuICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQgPSBvcHRpb25zLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLmpzb25QYXRjaFBlcm1pc3Npb25zUmVxdWVzdChwYXRoLCBwZXJtaXNzaW9ucywgXCJhZGRcIiwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTQuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBhZGRQZXJtaXNzaW9ucyhfeDkpIHtcbiAgICAgICAgcmV0dXJuIF9hZGRQZXJtaXNzaW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZW1vdmUgcHJpbmNpcGFscyBmcm9tIHRoZSBidWNrZXQgcGVybWlzc2lvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBwZXJtaXNzaW9ucyAgICAgICAgICAgICBUaGUgcGVybWlzc2lvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdFxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJyZW1vdmVQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3JlbW92ZVBlcm1pc3Npb25zID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE1KHBlcm1pc3Npb25zKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3MxNSA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE1JChfY29udGV4dDE1KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxNS5wcmV2ID0gX2NvbnRleHQxNS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxNS5sZW5ndGggPiAxICYmIF9hcmdzMTVbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTVbMV0gOiB7fTtcblxuICAgICAgICAgICAgICAgIGlmICgoMCwgX3V0aWxzLmlzT2JqZWN0KShwZXJtaXNzaW9ucykpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTUubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHBlcm1pc3Npb25zIG9iamVjdCBpcyByZXF1aXJlZC5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYnVja2V0XCIsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZCA9IG9wdGlvbnMubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuanNvblBhdGNoUGVybWlzc2lvbnNSZXF1ZXN0KHBhdGgsIHBlcm1pc3Npb25zLCBcInJlbW92ZVwiLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNS5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTUuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTE1LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHJlbW92ZVBlcm1pc3Npb25zKF94MTApIHtcbiAgICAgICAgcmV0dXJuIF9yZW1vdmVQZXJtaXNzaW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBiYXRjaCBvcGVyYXRpb25zIGF0IHRoZSBjdXJyZW50IGJ1Y2tldCBsZXZlbC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmbiAgICAgICAgICAgICAgICAgICBUaGUgYmF0Y2ggb3BlcmF0aW9uIGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucz17fV0gICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgIFtvcHRpb25zLmhlYWRlcnNdICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gIFtvcHRpb25zLnNhZmVdICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgW29wdGlvbnMucmV0cnk9MF0gICAgVGhlIHJldHJ5IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgW29wdGlvbnMuYWdncmVnYXRlXSAgUHJvZHVjZXMgYSBncm91cGVkIHJlc3VsdCBvYmplY3QuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImJhdGNoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfYmF0Y2ggPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTYoZm4pIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBfYXJnczE2ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTYkKF9jb250ZXh0MTYpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDE2LnByZXYgPSBfY29udGV4dDE2Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczE2Lmxlbmd0aCA+IDEgJiYgX2FyZ3MxNlsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxNlsxXSA6IHt9O1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE2LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5iYXRjaChmbiwge1xuICAgICAgICAgICAgICAgICAgYnVja2V0OiB0aGlzLm5hbWUsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIGFnZ3JlZ2F0ZTogISFvcHRpb25zLmFnZ3JlZ2F0ZVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNi5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTYsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gYmF0Y2goX3gxMSkge1xuICAgICAgICByZXR1cm4gX2JhdGNoLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICB9XSk7XG4gIHJldHVybiBCdWNrZXQ7XG59KCksICgoMCwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIuZGVmYXVsdCkoX2NsYXNzLnByb3RvdHlwZSwgXCJsaXN0SGlzdG9yeVwiLCBbX2RlY10sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgXCJsaXN0SGlzdG9yeVwiKSwgX2NsYXNzLnByb3RvdHlwZSkpLCBfY2xhc3MpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEJ1Y2tldDsiLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbnRlcm9wUmVxdWlyZURlZmF1bHRcIik7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlV2lsZGNhcmRcIik7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfc2xpY2VkVG9BcnJheTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL3NsaWNlZFRvQXJyYXlcIikpO1xuXG52YXIgX3JlZ2VuZXJhdG9yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvcmVnZW5lcmF0b3JcIikpO1xuXG52YXIgX2FzeW5jVG9HZW5lcmF0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yXCIpKTtcblxudmFyIF9vYmplY3RTcHJlYWQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9vYmplY3RTcHJlYWRcIikpO1xuXG52YXIgX2NsYXNzQ2FsbENoZWNrMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2tcIikpO1xuXG52YXIgX2NyZWF0ZUNsYXNzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY3JlYXRlQ2xhc3NcIikpO1xuXG52YXIgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvclwiKSk7XG5cbnZhciBfdXVpZCA9IHJlcXVpcmUoXCJ1dWlkXCIpO1xuXG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4vdXRpbHNcIik7XG5cbnZhciByZXF1ZXN0cyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL3JlcXVlc3RzXCIpKTtcblxudmFyIF9lbmRwb2ludCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vZW5kcG9pbnRcIikpO1xuXG52YXIgX2RlYywgX2RlYzIsIF9kZWMzLCBfY2xhc3M7XG5cbi8qKlxuICogQWJzdHJhY3QgcmVwcmVzZW50YXRpb24gb2YgYSBzZWxlY3RlZCBjb2xsZWN0aW9uLlxuICpcbiAqL1xudmFyIENvbGxlY3Rpb24gPSAoX2RlYyA9ICgwLCBfdXRpbHMuY2FwYWJsZSkoW1wiYXR0YWNobWVudHNcIl0pLCBfZGVjMiA9ICgwLCBfdXRpbHMuY2FwYWJsZSkoW1wiYXR0YWNobWVudHNcIl0pLCBfZGVjMyA9ICgwLCBfdXRpbHMuY2FwYWJsZSkoW1wiaGlzdG9yeVwiXSksIChfY2xhc3MgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQ29uc3RydWN0b3IuXG4gICAqXG4gICAqIEBwYXJhbSAge0tpbnRvQ2xpZW50fSAgY2xpZW50ICAgICAgICAgICAgVGhlIGNsaWVudCBpbnN0YW5jZS5cbiAgICogQHBhcmFtICB7QnVja2V0fSAgICAgICBidWNrZXQgICAgICAgICAgICBUaGUgYnVja2V0IGluc3RhbmNlLlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgIG5hbWUgICAgICAgICAgICAgIFRoZSBjb2xsZWN0aW9uIG5hbWUuXG4gICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgW29wdGlvbnM9e31dICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgIFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAqIEBwYXJhbSAge0Jvb2xlYW59ICAgICAgW29wdGlvbnMuc2FmZV0gICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgICAgIFtvcHRpb25zLnJldHJ5XSAgIFRoZSByZXRyeSBvcHRpb24uXG4gICAqIEBwYXJhbSAge0Jvb2xlYW59ICAgICAgW29wdGlvbnMuYmF0Y2hdICAgKFByaXZhdGUpIFdoZXRoZXIgdGhpc1xuICAgKiAgICAgQ29sbGVjdGlvbiBpcyBvcGVyYXRpbmcgYXMgcGFydCBvZiBhIGJhdGNoLlxuICAgKi9cbiAgZnVuY3Rpb24gQ29sbGVjdGlvbihjbGllbnQsIGJ1Y2tldCwgbmFtZSkge1xuICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiB7fTtcbiAgICAoMCwgX2NsYXNzQ2FsbENoZWNrMi5kZWZhdWx0KSh0aGlzLCBDb2xsZWN0aW9uKTtcblxuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICB0aGlzLmNsaWVudCA9IGNsaWVudDtcbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG5cbiAgICB0aGlzLmJ1Y2tldCA9IGJ1Y2tldDtcbiAgICAvKipcbiAgICAgKiBUaGUgY29sbGVjdGlvbiBuYW1lLlxuICAgICAqIEB0eXBlIHtTdHJpbmd9XG4gICAgICovXG5cbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cblxuICAgIHRoaXMuX2lzQmF0Y2ggPSAhIW9wdGlvbnMuYmF0Y2g7XG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuXG4gICAgdGhpcy5fcmV0cnkgPSBvcHRpb25zLnJldHJ5IHx8IDA7XG4gICAgdGhpcy5fc2FmZSA9ICEhb3B0aW9ucy5zYWZlOyAvLyBGSVhNRTogVGhpcyBpcyBraW5kIG9mIHVnbHk7IHNob3VsZG4ndCB0aGUgYnVja2V0IGJlIHJlc3BvbnNpYmxlXG4gICAgLy8gZm9yIGRvaW5nIHRoZSBtZXJnZT9cblxuICAgIHRoaXMuX2hlYWRlcnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHRoaXMuYnVja2V0Ll9oZWFkZXJzLCBvcHRpb25zLmhlYWRlcnMpO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdGhlIHZhbHVlIG9mIFwiaGVhZGVyc1wiIGZvciBhIGdpdmVuIHJlcXVlc3QsIG1lcmdpbmcgdGhlXG4gICAqIHBlci1yZXF1ZXN0IGhlYWRlcnMgd2l0aCBvdXIgb3duIFwiZGVmYXVsdFwiIGhlYWRlcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgKDAsIF9jcmVhdGVDbGFzczIuZGVmYXVsdCkoQ29sbGVjdGlvbiwgW3tcbiAgICBrZXk6IFwiX2dldEhlYWRlcnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldEhlYWRlcnMob3B0aW9ucykge1xuICAgICAgcmV0dXJuICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgdGhpcy5faGVhZGVycywgb3B0aW9ucy5oZWFkZXJzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBvZiBcInNhZmVcIiBmb3IgYSBnaXZlbiByZXF1ZXN0LCB1c2luZyB0aGVcbiAgICAgKiBwZXItcmVxdWVzdCBvcHRpb24gaWYgcHJlc2VudCBvciBmYWxsaW5nIGJhY2sgdG8gb3VyIGRlZmF1bHRcbiAgICAgKiBvdGhlcndpc2UuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFRoZSBvcHRpb25zIGZvciBhIHJlcXVlc3QuXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0U2FmZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZ2V0U2FmZShvcHRpb25zKSB7XG4gICAgICByZXR1cm4gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHtcbiAgICAgICAgc2FmZTogdGhpcy5fc2FmZVxuICAgICAgfSwgb3B0aW9ucykuc2FmZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXMgX2dldFNhZmUsIGJ1dCBmb3IgXCJyZXRyeVwiLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcIl9nZXRSZXRyeVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZ2V0UmV0cnkob3B0aW9ucykge1xuICAgICAgcmV0dXJuICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7XG4gICAgICAgIHJldHJ5OiB0aGlzLl9yZXRyeVxuICAgICAgfSwgb3B0aW9ucykucmV0cnk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgdG90YWwgbnVtYmVyIG9mIHJlY29yZHMgaW4gdGhpcyBjb2xsZWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE51bWJlciwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0VG90YWxSZWNvcmRzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZ2V0VG90YWxSZWNvcmRzID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZSgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9yZWYsXG4gICAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgICAgX2FyZ3MgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZSQoX2NvbnRleHQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dC5wcmV2ID0gX2NvbnRleHQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzLmxlbmd0aCA+IDAgJiYgX2FyZ3NbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzWzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJyZWNvcmRcIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0ge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgICAgICBtZXRob2Q6IFwiSEVBRFwiXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gNTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByYXc6IHRydWUsXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgX3JlZiA9IF9jb250ZXh0LnNlbnQ7XG4gICAgICAgICAgICAgICAgaGVhZGVycyA9IF9yZWYuaGVhZGVycztcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuYWJydXB0KFwicmV0dXJuXCIsIHBhcnNlSW50KGhlYWRlcnMuZ2V0KFwiVG90YWwtUmVjb3Jkc1wiKSwgMTApKTtcblxuICAgICAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBnZXRUb3RhbFJlY29yZHMoKSB7XG4gICAgICAgIHJldHVybiBfZ2V0VG90YWxSZWNvcmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBjb2xsZWN0aW9uIGRhdGEuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5xdWVyeV0gICBRdWVyeSBwYXJhbWV0ZXJzIHRvIHBhc3MgaW5cbiAgICAgKiAgICAgdGhlIHJlcXVlc3QuIFRoaXMgbWlnaHQgYmUgdXNlZnVsIGZvciBmZWF0dXJlcyB0aGF0IGFyZW4ndFxuICAgICAqICAgICB5ZXQgc3VwcG9ydGVkIGJ5IHRoaXMgbGlicmFyeS5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IFtvcHRpb25zLnJldHJ5PTBdIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImdldERhdGFcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9nZXREYXRhID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTIoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHF1ZXJ5c3RyaW5nLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9yZWYyLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIF9hcmdzMiA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMiQoX2NvbnRleHQyKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQyLnByZXYgPSBfY29udGV4dDIubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMi5sZW5ndGggPiAwICYmIF9hcmdzMlswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MyWzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSk7XG5cbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5xdWVyeSkge1xuICAgICAgICAgICAgICAgICAgcXVlcnlzdHJpbmcgPSAoMCwgX3V0aWxzLnFzaWZ5KShvcHRpb25zLnF1ZXJ5KTtcbiAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXRoICsgXCI/XCIgKyBxdWVyeXN0cmluZztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0ge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGhcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0Mi5uZXh0ID0gNjtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgICAgX3JlZjIgPSBfY29udGV4dDIuc2VudDtcbiAgICAgICAgICAgICAgICBkYXRhID0gX3JlZjIuZGF0YTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLmFicnVwdChcInJldHVyblwiLCBkYXRhKTtcblxuICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUyLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGdldERhdGEoKSB7XG4gICAgICAgIHJldHVybiBfZ2V0RGF0YS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBTZXQgY29sbGVjdGlvbiBkYXRhLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBkYXRhICAgICAgICAgICAgICAgICAgICBUaGUgY29sbGVjdGlvbiBkYXRhIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gIFtvcHRpb25zLnBhdGNoXSAgICAgICAgIFRoZSBwYXRjaCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwic2V0RGF0YVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3NldERhdGEgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMyhkYXRhKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0Y2gsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIF9kYXRhJG9wdGlvbnMsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczMgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTMkKF9jb250ZXh0Mykge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0My5wcmV2ID0gX2NvbnRleHQzLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczMubGVuZ3RoID4gMSAmJiBfYXJnczNbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzM1sxXSA6IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKCgwLCBfdXRpbHMuaXNPYmplY3QpKGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDMubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIGNvbGxlY3Rpb24gb2JqZWN0IGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgcGF0Y2ggPSBvcHRpb25zLnBhdGNoLCBwZXJtaXNzaW9ucyA9IG9wdGlvbnMucGVybWlzc2lvbnM7XG4gICAgICAgICAgICAgICAgX2RhdGEkb3B0aW9ucyA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgZGF0YSwgb3B0aW9ucyksIGxhc3RfbW9kaWZpZWQgPSBfZGF0YSRvcHRpb25zLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLnVwZGF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgICBwYXRjaDogcGF0Y2gsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDMuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDMuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTMsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gc2V0RGF0YShfeCkge1xuICAgICAgICByZXR1cm4gX3NldERhdGEuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBsaXN0IG9mIHBlcm1pc3Npb25zIGZvciB0aGlzIGNvbGxlY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2dldFBlcm1pc3Npb25zID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTQoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfcmVmMyxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgX2FyZ3M0ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU0JChfY29udGV4dDQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDQucHJldiA9IF9jb250ZXh0NC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M0Lmxlbmd0aCA+IDAgJiYgX2FyZ3M0WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczRbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImNvbGxlY3Rpb25cIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0ge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGhcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0NC5uZXh0ID0gNTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgX3JlZjMgPSBfY29udGV4dDQuc2VudDtcbiAgICAgICAgICAgICAgICBwZXJtaXNzaW9ucyA9IF9yZWYzLnBlcm1pc3Npb25zO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDQuYWJydXB0KFwicmV0dXJuXCIsIHBlcm1pc3Npb25zKTtcblxuICAgICAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU0LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGdldFBlcm1pc3Npb25zKCkge1xuICAgICAgICByZXR1cm4gX2dldFBlcm1pc3Npb25zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJlcGxhY2VzIGFsbCBleGlzdGluZyBjb2xsZWN0aW9uIHBlcm1pc3Npb25zIHdpdGggdGhlIG9uZXMgcHJvdmlkZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgcGVybWlzc2lvbnMgICAgICAgICAgICAgVGhlIHBlcm1pc3Npb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0XG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gIFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJzZXRQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3NldFBlcm1pc3Npb25zID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTUocGVybWlzc2lvbnMpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczUgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU1JChfY29udGV4dDUpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDUucHJldiA9IF9jb250ZXh0NS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M1Lmxlbmd0aCA+IDEgJiYgX2FyZ3M1WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczVbMV0gOiB7fTtcblxuICAgICAgICAgICAgICAgIGlmICgoMCwgX3V0aWxzLmlzT2JqZWN0KShwZXJtaXNzaW9ucykpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0NS5uZXh0ID0gMztcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgcGVybWlzc2lvbnMgb2JqZWN0IGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IG9wdGlvbnMubGFzdF9tb2RpZmllZFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLnVwZGF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NS5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBzZXRQZXJtaXNzaW9ucyhfeDIpIHtcbiAgICAgICAgcmV0dXJuIF9zZXRQZXJtaXNzaW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBBcHBlbmQgcHJpbmNpcGFscyB0byB0aGUgY29sbGVjdGlvbiBwZXJtaXNzaW9ucy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIHBlcm1pc3Npb25zICAgICAgICAgICAgIFRoZSBwZXJtaXNzaW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0XG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImFkZFBlcm1pc3Npb25zXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfYWRkUGVybWlzc2lvbnMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlNihwZXJtaXNzaW9ucykge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzNiA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTYkKF9jb250ZXh0Nikge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0Ni5wcmV2ID0gX2NvbnRleHQ2Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczYubGVuZ3RoID4gMSAmJiBfYXJnczZbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzNlsxXSA6IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKCgwLCBfdXRpbHMuaXNPYmplY3QpKHBlcm1pc3Npb25zKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQ2Lm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBwZXJtaXNzaW9ucyBvYmplY3QgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImNvbGxlY3Rpb25cIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkID0gb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy5qc29uUGF0Y2hQZXJtaXNzaW9uc1JlcXVlc3QocGF0aCwgcGVybWlzc2lvbnMsIFwiYWRkXCIsIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDYuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDYuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTYsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gYWRkUGVybWlzc2lvbnMoX3gzKSB7XG4gICAgICAgIHJldHVybiBfYWRkUGVybWlzc2lvbnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHByaW5jaXBhbHMgZnJvbSB0aGUgY29sbGVjdGlvbiBwZXJtaXNzaW9ucy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIHBlcm1pc3Npb25zICAgICAgICAgICAgIFRoZSBwZXJtaXNzaW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0XG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInJlbW92ZVBlcm1pc3Npb25zXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfcmVtb3ZlUGVybWlzc2lvbnMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlNyhwZXJtaXNzaW9ucykge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzNyA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTckKF9jb250ZXh0Nykge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0Ny5wcmV2ID0gX2NvbnRleHQ3Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczcubGVuZ3RoID4gMSAmJiBfYXJnczdbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzN1sxXSA6IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKCgwLCBfdXRpbHMuaXNPYmplY3QpKHBlcm1pc3Npb25zKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQ3Lm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBwZXJtaXNzaW9ucyBvYmplY3QgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImNvbGxlY3Rpb25cIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkID0gb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy5qc29uUGF0Y2hQZXJtaXNzaW9uc1JlcXVlc3QocGF0aCwgcGVybWlzc2lvbnMsIFwicmVtb3ZlXCIsIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDcuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDcuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTcsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gcmVtb3ZlUGVybWlzc2lvbnMoX3g0KSB7XG4gICAgICAgIHJldHVybiBfcmVtb3ZlUGVybWlzc2lvbnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHJlY29yZCBpbiBjdXJyZW50IGNvbGxlY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICByZWNvcmQgICAgICAgICAgICAgICAgVGhlIHJlY29yZCB0byBjcmVhdGUuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLnBlcm1pc3Npb25zXSBUaGUgcGVybWlzc2lvbnMgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJjcmVhdGVSZWNvcmRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9jcmVhdGVSZWNvcmQgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlOChyZWNvcmQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3M4ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlOCQoX2NvbnRleHQ4KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ4LnByZXYgPSBfY29udGV4dDgubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzOC5sZW5ndGggPiAxICYmIF9hcmdzOFsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M4WzFdIDoge307XG4gICAgICAgICAgICAgICAgcGVybWlzc2lvbnMgPSBvcHRpb25zLnBlcm1pc3Npb25zO1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwicmVjb3JkXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSwgcmVjb3JkLmlkKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuY3JlYXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBkYXRhOiByZWNvcmQsXG4gICAgICAgICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgICAgICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDguYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDguc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTgsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gY3JlYXRlUmVjb3JkKF94NSkge1xuICAgICAgICByZXR1cm4gX2NyZWF0ZVJlY29yZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBBZGRzIGFuIGF0dGFjaG1lbnQgdG8gYSByZWNvcmQsIGNyZWF0aW5nIHRoZSByZWNvcmQgd2hlbiBpdCBkb2Vzbid0IGV4aXN0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgZGF0YVVSTCAgICAgICAgICAgICAgICAgVGhlIGRhdGEgdXJsLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtyZWNvcmQ9e31dICAgICAgICAgICAgIFRoZSByZWNvcmQgZGF0YS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMucGVybWlzc2lvbnNdICAgVGhlIHBlcm1pc3Npb25zIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICBbb3B0aW9ucy5maWxlbmFtZV0gICAgICBGb3JjZSB0aGUgYXR0YWNobWVudCBmaWxlbmFtZS5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICBbb3B0aW9ucy5nemlwcGVkXSAgICAgICBGb3JjZSB0aGUgYXR0YWNobWVudCB0byBiZSBnemlwcGVkIG9yIG5vdC5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiYWRkQXR0YWNobWVudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2FkZEF0dGFjaG1lbnQgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlOShkYXRhVVJJKSB7XG4gICAgICAgIHZhciByZWNvcmQsXG4gICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICAgcGVybWlzc2lvbnMsXG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBfcmVjb3JkJG9wdGlvbnMsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgYWRkQXR0YWNobWVudFJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczkgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTkkKF9jb250ZXh0OSkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0OS5wcmV2ID0gX2NvbnRleHQ5Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIHJlY29yZCA9IF9hcmdzOS5sZW5ndGggPiAxICYmIF9hcmdzOVsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M5WzFdIDoge307XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzOS5sZW5ndGggPiAyICYmIF9hcmdzOVsyXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M5WzJdIDoge307XG4gICAgICAgICAgICAgICAgcGVybWlzc2lvbnMgPSBvcHRpb25zLnBlcm1pc3Npb25zO1xuICAgICAgICAgICAgICAgIGlkID0gcmVjb3JkLmlkIHx8IF91dWlkLnY0LnY0KCk7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJhdHRhY2htZW50XCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSwgaWQpO1xuICAgICAgICAgICAgICAgIF9yZWNvcmQkb3B0aW9ucyA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgcmVjb3JkLCBvcHRpb25zKSwgbGFzdF9tb2RpZmllZCA9IF9yZWNvcmQkb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIGFkZEF0dGFjaG1lbnRSZXF1ZXN0ID0gcmVxdWVzdHMuYWRkQXR0YWNobWVudFJlcXVlc3QocGF0aCwgZGF0YVVSSSwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogcmVjb3JkLFxuICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBvcHRpb25zLmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgZ3ppcHBlZDogb3B0aW9ucy5nemlwcGVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDkubmV4dCA9IDk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50LmV4ZWN1dGUoYWRkQXR0YWNobWVudFJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHN0cmluZ2lmeTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OS5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5nZXRSZWNvcmQoaWQpKTtcblxuICAgICAgICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlOSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBhZGRBdHRhY2htZW50KF94Nikge1xuICAgICAgICByZXR1cm4gX2FkZEF0dGFjaG1lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbiBhdHRhY2htZW50IGZyb20gYSBnaXZlbiByZWNvcmQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICByZWNvcmRJZCAgICAgICAgICAgICAgICBUaGUgcmVjb3JkIGlkLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInJlbW92ZUF0dGFjaG1lbnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9yZW1vdmVBdHRhY2htZW50ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTEwKHJlY29yZElkKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3MxMCA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTEwJChfY29udGV4dDEwKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxMC5wcmV2ID0gX2NvbnRleHQxMC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxMC5sZW5ndGggPiAxICYmIF9hcmdzMTBbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTBbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkID0gb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYXR0YWNobWVudFwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUsIHJlY29yZElkKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuZGVsZXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTAuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTEwLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHJlbW92ZUF0dGFjaG1lbnQoX3g3KSB7XG4gICAgICAgIHJldHVybiBfcmVtb3ZlQXR0YWNobWVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIGEgcmVjb3JkIGluIGN1cnJlbnQgY29sbGVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIHJlY29yZCAgICAgICAgICAgICAgICAgIFRoZSByZWNvcmQgdG8gdXBkYXRlLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5wZXJtaXNzaW9uc10gICBUaGUgcGVybWlzc2lvbnMgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJ1cGRhdGVSZWNvcmRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF91cGRhdGVSZWNvcmQgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTEocmVjb3JkKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGVybWlzc2lvbnMsXG4gICAgICAgICAgICBfcmVjb3JkJG9wdGlvbnMyLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3MxMSA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTEkKF9jb250ZXh0MTEpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDExLnByZXYgPSBfY29udGV4dDExLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczExLmxlbmd0aCA+IDEgJiYgX2FyZ3MxMVsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxMVsxXSA6IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKCgwLCBfdXRpbHMuaXNPYmplY3QpKHJlY29yZCkpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTEubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHJlY29yZCBvYmplY3QgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBpZiAocmVjb3JkLmlkKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDExLm5leHQgPSA1O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSByZWNvcmQgaWQgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgICBwZXJtaXNzaW9ucyA9IG9wdGlvbnMucGVybWlzc2lvbnM7XG4gICAgICAgICAgICAgICAgX3JlY29yZCRvcHRpb25zMiA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgcmVjb3JkLCBvcHRpb25zKSwgbGFzdF9tb2RpZmllZCA9IF9yZWNvcmQkb3B0aW9uczIubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcInJlY29yZFwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUsIHJlY29yZC5pZCk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLnVwZGF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogcmVjb3JkLFxuICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgcGF0Y2g6ICEhb3B0aW9ucy5wYXRjaFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDExLmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTEuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTExLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHVwZGF0ZVJlY29yZChfeDgpIHtcbiAgICAgICAgcmV0dXJuIF91cGRhdGVSZWNvcmQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogRGVsZXRlcyBhIHJlY29yZCBmcm9tIHRoZSBjdXJyZW50IGNvbGxlY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R8U3RyaW5nfSByZWNvcmQgICAgICAgICAgICAgICAgICBUaGUgcmVjb3JkIHRvIGRlbGV0ZS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgICAgICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICAgICAgIFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgICAgICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImRlbGV0ZVJlY29yZFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2RlbGV0ZVJlY29yZCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxMihyZWNvcmQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICByZWNvcmRPYmosXG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIF9yZWNvcmRPYmokb3B0aW9ucyxcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMTIgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTEyJChfY29udGV4dDEyKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxMi5wcmV2ID0gX2NvbnRleHQxMi5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxMi5sZW5ndGggPiAxICYmIF9hcmdzMTJbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTJbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICByZWNvcmRPYmogPSAoMCwgX3V0aWxzLnRvRGF0YUJvZHkpKHJlY29yZCk7XG5cbiAgICAgICAgICAgICAgICBpZiAocmVjb3JkT2JqLmlkKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDEyLm5leHQgPSA0O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSByZWNvcmQgaWQgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBpZCA9IHJlY29yZE9iai5pZDtcbiAgICAgICAgICAgICAgICBfcmVjb3JkT2JqJG9wdGlvbnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHJlY29yZE9iaiwgb3B0aW9ucyksIGxhc3RfbW9kaWZpZWQgPSBfcmVjb3JkT2JqJG9wdGlvbnMubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcInJlY29yZFwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUsIGlkKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuZGVsZXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMi5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA5OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTIuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTEyLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGRlbGV0ZVJlY29yZChfeDkpIHtcbiAgICAgICAgcmV0dXJuIF9kZWxldGVSZWNvcmQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGEgcmVjb3JkIGZyb20gdGhlIGN1cnJlbnQgY29sbGVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gaWQgICAgICAgICAgICAgICAgVGhlIHJlY29yZCBpZCB0byByZXRyaWV2ZS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRSZWNvcmRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9nZXRSZWNvcmQgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTMoaWQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMTMgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxMyQoX2NvbnRleHQxMykge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTMucHJldiA9IF9jb250ZXh0MTMubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTMubGVuZ3RoID4gMSAmJiBfYXJnczEzWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczEzWzFdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJyZWNvcmRcIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lLCBpZCk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBwYXRoOiBwYXRoXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMy5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTMuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTEzLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGdldFJlY29yZChfeDEwKSB7XG4gICAgICAgIHJldHVybiBfZ2V0UmVjb3JkLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIExpc3RzIHJlY29yZHMgZnJvbSB0aGUgY3VycmVudCBjb2xsZWN0aW9uLlxuICAgICAqXG4gICAgICogU29ydGluZyBpcyBkb25lIGJ5IHBhc3NpbmcgYSBgc29ydGAgc3RyaW5nIG9wdGlvbjpcbiAgICAgKlxuICAgICAqIC0gVGhlIGZpZWxkIHRvIG9yZGVyIHRoZSByZXN1bHRzIGJ5LCBwcmVmaXhlZCB3aXRoIGAtYCBmb3IgZGVzY2VuZGluZy5cbiAgICAgKiBEZWZhdWx0OiBgLWxhc3RfbW9kaWZpZWRgLlxuICAgICAqXG4gICAgICogQHNlZSBodHRwOi8va2ludG8ucmVhZHRoZWRvY3MuaW8vZW4vc3RhYmxlL2FwaS8xLngvc29ydGluZy5odG1sXG4gICAgICpcbiAgICAgKiBGaWx0ZXJpbmcgaXMgZG9uZSBieSBwYXNzaW5nIGEgYGZpbHRlcnNgIG9wdGlvbiBvYmplY3Q6XG4gICAgICpcbiAgICAgKiAtIGB7ZmllbGRuYW1lOiBcInZhbHVlXCJ9YFxuICAgICAqIC0gYHttaW5fZmllbGRuYW1lOiA0MDAwfWBcbiAgICAgKiAtIGB7aW5fZmllbGRuYW1lOiBcIjEsMiwzXCJ9YFxuICAgICAqIC0gYHtub3RfZmllbGRuYW1lOiAwfWBcbiAgICAgKiAtIGB7ZXhjbHVkZV9maWVsZG5hbWU6IFwiMCwxXCJ9YFxuICAgICAqXG4gICAgICogQHNlZSBodHRwOi8va2ludG8ucmVhZHRoZWRvY3MuaW8vZW4vc3RhYmxlL2FwaS8xLngvZmlsdGVyaW5nLmh0bWxcbiAgICAgKlxuICAgICAqIFBhZ2luYXRpbmcgaXMgZG9uZSBieSBwYXNzaW5nIGEgYGxpbWl0YCBvcHRpb24sIHRoZW4gY2FsbGluZyB0aGUgYG5leHQoKWBcbiAgICAgKiBtZXRob2QgZnJvbSB0aGUgcmVzb2x2ZWQgcmVzdWx0IG9iamVjdCB0byBmZXRjaCB0aGUgbmV4dCBwYWdlLCBpZiBhbnkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnM9e31dICAgICAgICAgICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgIFtvcHRpb25zLmhlYWRlcnNdICAgICAgICAgICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgICAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucy5maWx0ZXJzPVtdXSAgICAgICAgICAgIFRoZSBmaWx0ZXJzIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgW29wdGlvbnMuc29ydD1cIi1sYXN0X21vZGlmaWVkXCJdIFRoZSBzb3J0IGZpZWxkLlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gICBbb3B0aW9ucy5hdF0gICAgICAgICAgICAgICAgICAgIFRoZSB0aW1lc3RhbXAgdG8gZ2V0IGEgc25hcHNob3QgYXQuXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgIFtvcHRpb25zLmxpbWl0PW51bGxdICAgICAgICAgICAgVGhlIGxpbWl0IGZpZWxkLlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gICBbb3B0aW9ucy5wYWdlcz0xXSAgICAgICAgICAgICAgIFRoZSBudW1iZXIgb2YgcmVzdWx0IHBhZ2VzIHRvIGFnZ3JlZ2F0ZS5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgW29wdGlvbnMuc2luY2U9bnVsbF0gICAgICAgICAgICBPbmx5IHJldHJpZXZlIHJlY29yZHMgbW9kaWZpZWQgc2luY2UgdGhlIHByb3ZpZGVkIHRpbWVzdGFtcC5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwibGlzdFJlY29yZHNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9saXN0UmVjb3JkcyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNCgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgX2FyZ3MxNCA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE0JChfY29udGV4dDE0KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxNC5wcmV2ID0gX2NvbnRleHQxNC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxNC5sZW5ndGggPiAwICYmIF9hcmdzMTRbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTRbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcInJlY29yZFwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KFwiYXRcIikpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTQubmV4dCA9IDY7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5nZXRTbmFwc2hvdChvcHRpb25zLmF0KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE0LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5wYWdpbmF0ZWRMaXN0KHBhdGgsIG9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTQuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTE0LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGxpc3RSZWNvcmRzKCkge1xuICAgICAgICByZXR1cm4gX2xpc3RSZWNvcmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJpc0hpc3RvcnlDb21wbGV0ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2lzSGlzdG9yeUNvbXBsZXRlID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE1KCkge1xuICAgICAgICB2YXIgX3JlZjQsIF9yZWY0JGRhdGEsIG9sZGVzdEhpc3RvcnlFbnRyeTtcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTUkKF9jb250ZXh0MTUpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDE1LnByZXYgPSBfY29udGV4dDE1Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIF9jb250ZXh0MTUubmV4dCA9IDI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYnVja2V0Lmxpc3RIaXN0b3J5KHtcbiAgICAgICAgICAgICAgICAgIGxpbWl0OiAxLFxuICAgICAgICAgICAgICAgICAgZmlsdGVyczoge1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb246IFwiY3JlYXRlXCIsXG4gICAgICAgICAgICAgICAgICAgIHJlc291cmNlX25hbWU6IFwiY29sbGVjdGlvblwiLFxuICAgICAgICAgICAgICAgICAgICBjb2xsZWN0aW9uX2lkOiB0aGlzLm5hbWVcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgX3JlZjQgPSBfY29udGV4dDE1LnNlbnQ7XG4gICAgICAgICAgICAgICAgX3JlZjQkZGF0YSA9ICgwLCBfc2xpY2VkVG9BcnJheTIuZGVmYXVsdCkoX3JlZjQuZGF0YSwgMSk7XG4gICAgICAgICAgICAgICAgb2xkZXN0SGlzdG9yeUVudHJ5ID0gX3JlZjQkZGF0YVswXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNS5hYnJ1cHQoXCJyZXR1cm5cIiwgISFvbGRlc3RIaXN0b3J5RW50cnkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE1LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBpc0hpc3RvcnlDb21wbGV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIF9pc0hpc3RvcnlDb21wbGV0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwibGlzdENoYW5nZXNCYWNrVG9cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9saXN0Q2hhbmdlc0JhY2tUbyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNihhdCkge1xuICAgICAgICB2YXIgX3JlZjUsIGNoYW5nZXM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE2JChfY29udGV4dDE2KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxNi5wcmV2ID0gX2NvbnRleHQxNi5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBfY29udGV4dDE2Lm5leHQgPSAyO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmlzSGlzdG9yeUNvbXBsZXRlKCk7XG5cbiAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIGlmIChfY29udGV4dDE2LnNlbnQpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTYubmV4dCA9IDQ7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb21wdXRpbmcgYSBzbmFwc2hvdCBpcyBvbmx5IHBvc3NpYmxlIHdoZW4gdGhlIGZ1bGwgaGlzdG9yeSBmb3IgYSBcIiArIFwiY29sbGVjdGlvbiBpcyBhdmFpbGFibGUuIEhlcmUsIHRoZSBoaXN0b3J5IHBsdWdpbiBzZWVtcyB0byBoYXZlIFwiICsgXCJiZWVuIGVuYWJsZWQgYWZ0ZXIgdGhlIGNyZWF0aW9uIG9mIHRoZSBjb2xsZWN0aW9uLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQxNi5uZXh0ID0gNjtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5idWNrZXQubGlzdEhpc3Rvcnkoe1xuICAgICAgICAgICAgICAgICAgcGFnZXM6IEluZmluaXR5LFxuICAgICAgICAgICAgICAgICAgLy8gYWxsIHBhZ2VzIHVwIHRvIHRhcmdldCB0aW1lc3RhbXAgYXJlIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICBzb3J0OiBcIi10YXJnZXQuZGF0YS5sYXN0X21vZGlmaWVkXCIsXG4gICAgICAgICAgICAgICAgICBmaWx0ZXJzOiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc291cmNlX25hbWU6IFwicmVjb3JkXCIsXG4gICAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25faWQ6IHRoaXMubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgXCJtYXhfdGFyZ2V0LmRhdGEubGFzdF9tb2RpZmllZFwiOiBTdHJpbmcoYXQpIC8vIGVxLiB0byA8PVxuXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgIF9yZWY1ID0gX2NvbnRleHQxNi5zZW50O1xuICAgICAgICAgICAgICAgIGNoYW5nZXMgPSBfcmVmNS5kYXRhO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE2LmFicnVwdChcInJldHVyblwiLCBjaGFuZ2VzKTtcblxuICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNi5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTYsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gbGlzdENoYW5nZXNCYWNrVG8oX3gxMSkge1xuICAgICAgICByZXR1cm4gX2xpc3RDaGFuZ2VzQmFja1RvLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRTbmFwc2hvdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2dldFNuYXBzaG90ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE3KGF0KSB7XG4gICAgICAgIHZhciBjaGFuZ2VzLCBzZWVuSWRzLCBzbmFwc2hvdCwgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiwgX2RpZEl0ZXJhdG9yRXJyb3IsIF9pdGVyYXRvckVycm9yLCBfbG9vcCwgX2l0ZXJhdG9yLCBfc3RlcDtcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTckKF9jb250ZXh0MTcpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDE3LnByZXYgPSBfY29udGV4dDE3Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIGlmICghKCFOdW1iZXIuaXNJbnRlZ2VyKGF0KSB8fCBhdCA8PSAwKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQxNy5uZXh0ID0gMjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgYXJndW1lbnQsIGV4cGVjdGVkIGEgcG9zaXRpdmUgaW50ZWdlci5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIF9jb250ZXh0MTcubmV4dCA9IDQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGlzdENoYW5nZXNCYWNrVG8oYXQpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBjaGFuZ2VzID0gX2NvbnRleHQxNy5zZW50O1xuICAgICAgICAgICAgICAgIC8vIFJlcGxheSBjaGFuZ2VzIHRvIGNvbXB1dGUgdGhlIHJlcXVlc3RlZCBzbmFwc2hvdC5cbiAgICAgICAgICAgICAgICBzZWVuSWRzID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgICAgIHNuYXBzaG90ID0gW107XG4gICAgICAgICAgICAgICAgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWU7XG4gICAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBfY29udGV4dDE3LnByZXYgPSAxMDtcblxuICAgICAgICAgICAgICAgIF9sb29wID0gZnVuY3Rpb24gX2xvb3AoKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgX3JlZjYgPSBfc3RlcC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgIHZhciBhY3Rpb24gPSBfcmVmNi5hY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgICAgcmVjb3JkID0gX3JlZjYudGFyZ2V0LmRhdGE7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gPT0gXCJkZWxldGVcIikge1xuICAgICAgICAgICAgICAgICAgICBzZWVuSWRzLmFkZChyZWNvcmQuaWQpOyAvLyBlbnN1cmUgbm90IHJlcHJvY2Vzc2luZyBkZWxldGVkIGVudHJpZXNcblxuICAgICAgICAgICAgICAgICAgICBzbmFwc2hvdCA9IHNuYXBzaG90LmZpbHRlcihmdW5jdGlvbiAocikge1xuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByLmlkICE9PSByZWNvcmQuaWQ7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghc2Vlbklkcy5oYXMocmVjb3JkLmlkKSkge1xuICAgICAgICAgICAgICAgICAgICBzZWVuSWRzLmFkZChyZWNvcmQuaWQpO1xuICAgICAgICAgICAgICAgICAgICBzbmFwc2hvdC5wdXNoKHJlY29yZCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGZvciAoX2l0ZXJhdG9yID0gY2hhbmdlc1tTeW1ib2wuaXRlcmF0b3JdKCk7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IChfc3RlcCA9IF9pdGVyYXRvci5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgX2xvb3AoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBfY29udGV4dDE3Lm5leHQgPSAxOTtcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICBjYXNlIDE1OlxuICAgICAgICAgICAgICAgIF9jb250ZXh0MTcucHJldiA9IDE1O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0MTcudDAgPSBfY29udGV4dDE3W1wiY2F0Y2hcIl0oMTApO1xuICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvciA9IF9jb250ZXh0MTcudDA7XG5cbiAgICAgICAgICAgICAgY2FzZSAxOTpcbiAgICAgICAgICAgICAgICBfY29udGV4dDE3LnByZXYgPSAxOTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDE3LnByZXYgPSAyMDtcblxuICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiAmJiBfaXRlcmF0b3IucmV0dXJuICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgIF9pdGVyYXRvci5yZXR1cm4oKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY2FzZSAyMjpcbiAgICAgICAgICAgICAgICBfY29udGV4dDE3LnByZXYgPSAyMjtcblxuICAgICAgICAgICAgICAgIGlmICghX2RpZEl0ZXJhdG9yRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTcubmV4dCA9IDI1O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3I7XG5cbiAgICAgICAgICAgICAgY2FzZSAyNTpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNy5maW5pc2goMjIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjY6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTcuZmluaXNoKDE5KTtcblxuICAgICAgICAgICAgICBjYXNlIDI3OlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE3LmFicnVwdChcInJldHVyblwiLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBTdHJpbmcoYXQpLFxuICAgICAgICAgICAgICAgICAgZGF0YTogc25hcHNob3Quc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYi5sYXN0X21vZGlmaWVkIC0gYS5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICBuZXh0OiBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTbmFwc2hvdHMgZG9uJ3Qgc3VwcG9ydCBwYWdpbmF0aW9uXCIpO1xuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGhhc05leHRQYWdlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIHRvdGFsUmVjb3Jkczogc25hcHNob3QubGVuZ3RoXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAyODpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE3LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNywgdGhpcywgW1sxMCwgMTUsIDE5LCAyN10sIFsyMCwsIDIyLCAyNl1dKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGdldFNuYXBzaG90KF94MTIpIHtcbiAgICAgICAgcmV0dXJuIF9nZXRTbmFwc2hvdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBiYXRjaCBvcGVyYXRpb25zIGF0IHRoZSBjdXJyZW50IGNvbGxlY3Rpb24gbGV2ZWwuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtGdW5jdGlvbn0gZm4gICAgICAgICAgICAgICAgICAgVGhlIGJhdGNoIG9wZXJhdGlvbiBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnM9e31dICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucy5oZWFkZXJzXSAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICBbb3B0aW9ucy5zYWZlXSAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgIFtvcHRpb25zLnJldHJ5XSAgICAgIFRoZSByZXRyeSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gIFtvcHRpb25zLmFnZ3JlZ2F0ZV0gIFByb2R1Y2VzIGEgZ3JvdXBlZCByZXN1bHQgb2JqZWN0LlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJiYXRjaFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2JhdGNoID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE4KGZuKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgX2FyZ3MxOCA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE4JChfY29udGV4dDE4KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxOC5wcmV2ID0gX2NvbnRleHQxOC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxOC5sZW5ndGggPiAxICYmIF9hcmdzMThbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMThbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxOC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuYmF0Y2goZm4sIHtcbiAgICAgICAgICAgICAgICAgIGJ1Y2tldDogdGhpcy5idWNrZXQubmFtZSxcbiAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb246IHRoaXMubmFtZSxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgYWdncmVnYXRlOiAhIW9wdGlvbnMuYWdncmVnYXRlXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE4LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxOCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBiYXRjaChfeDEzKSB7XG4gICAgICAgIHJldHVybiBfYmF0Y2guYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gIH1dKTtcbiAgcmV0dXJuIENvbGxlY3Rpb247XG59KCksICgoMCwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIuZGVmYXVsdCkoX2NsYXNzLnByb3RvdHlwZSwgXCJhZGRBdHRhY2htZW50XCIsIFtfZGVjXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCBcImFkZEF0dGFjaG1lbnRcIiksIF9jbGFzcy5wcm90b3R5cGUpLCAoMCwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIuZGVmYXVsdCkoX2NsYXNzLnByb3RvdHlwZSwgXCJyZW1vdmVBdHRhY2htZW50XCIsIFtfZGVjMl0sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgXCJyZW1vdmVBdHRhY2htZW50XCIpLCBfY2xhc3MucHJvdG90eXBlKSwgKDAsIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyLmRlZmF1bHQpKF9jbGFzcy5wcm90b3R5cGUsIFwiZ2V0U25hcHNob3RcIiwgW19kZWMzXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCBcImdldFNuYXBzaG90XCIpLCBfY2xhc3MucHJvdG90eXBlKSksIF9jbGFzcykpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ29sbGVjdGlvbjsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGVuZHBvaW50O1xuXG4vKipcbiAqIEVuZHBvaW50cyB0ZW1wbGF0ZXMuXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG52YXIgRU5EUE9JTlRTID0ge1xuICByb290OiBmdW5jdGlvbiByb290KCkge1xuICAgIHJldHVybiBcIi9cIjtcbiAgfSxcbiAgYmF0Y2g6IGZ1bmN0aW9uIGJhdGNoKCkge1xuICAgIHJldHVybiBcIi9iYXRjaFwiO1xuICB9LFxuICBwZXJtaXNzaW9uczogZnVuY3Rpb24gcGVybWlzc2lvbnMoKSB7XG4gICAgcmV0dXJuIFwiL3Blcm1pc3Npb25zXCI7XG4gIH0sXG4gIGJ1Y2tldDogZnVuY3Rpb24gYnVja2V0KF9idWNrZXQpIHtcbiAgICByZXR1cm4gXCIvYnVja2V0c1wiICsgKF9idWNrZXQgPyBcIi9cIi5jb25jYXQoX2J1Y2tldCkgOiBcIlwiKTtcbiAgfSxcbiAgaGlzdG9yeTogZnVuY3Rpb24gaGlzdG9yeShidWNrZXQpIHtcbiAgICByZXR1cm4gXCJcIi5jb25jYXQoRU5EUE9JTlRTLmJ1Y2tldChidWNrZXQpLCBcIi9oaXN0b3J5XCIpO1xuICB9LFxuICBjb2xsZWN0aW9uOiBmdW5jdGlvbiBjb2xsZWN0aW9uKGJ1Y2tldCwgY29sbCkge1xuICAgIHJldHVybiBcIlwiLmNvbmNhdChFTkRQT0lOVFMuYnVja2V0KGJ1Y2tldCksIFwiL2NvbGxlY3Rpb25zXCIpICsgKGNvbGwgPyBcIi9cIi5jb25jYXQoY29sbCkgOiBcIlwiKTtcbiAgfSxcbiAgZ3JvdXA6IGZ1bmN0aW9uIGdyb3VwKGJ1Y2tldCwgX2dyb3VwKSB7XG4gICAgcmV0dXJuIFwiXCIuY29uY2F0KEVORFBPSU5UUy5idWNrZXQoYnVja2V0KSwgXCIvZ3JvdXBzXCIpICsgKF9ncm91cCA/IFwiL1wiLmNvbmNhdChfZ3JvdXApIDogXCJcIik7XG4gIH0sXG4gIHJlY29yZDogZnVuY3Rpb24gcmVjb3JkKGJ1Y2tldCwgY29sbCwgaWQpIHtcbiAgICByZXR1cm4gXCJcIi5jb25jYXQoRU5EUE9JTlRTLmNvbGxlY3Rpb24oYnVja2V0LCBjb2xsKSwgXCIvcmVjb3Jkc1wiKSArIChpZCA/IFwiL1wiLmNvbmNhdChpZCkgOiBcIlwiKTtcbiAgfSxcbiAgYXR0YWNobWVudDogZnVuY3Rpb24gYXR0YWNobWVudChidWNrZXQsIGNvbGwsIGlkKSB7XG4gICAgcmV0dXJuIFwiXCIuY29uY2F0KEVORFBPSU5UUy5yZWNvcmQoYnVja2V0LCBjb2xsLCBpZCksIFwiL2F0dGFjaG1lbnRcIik7XG4gIH1cbn07XG4vKipcbiAqIFJldHJpZXZlcyBhIHNlcnZlciBlbnBvaW50IGJ5IGl0cyBuYW1lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gIHtTdHJpbmd9ICAgIG5hbWUgVGhlIGVuZHBvaW50IG5hbWUuXG4gKiBAcGFyYW0gIHsuLi5zdHJpbmd9IGFyZ3MgVGhlIGVuZHBvaW50IHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cblxuZnVuY3Rpb24gZW5kcG9pbnQobmFtZSkge1xuICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgYXJnc1tfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07XG4gIH1cblxuICByZXR1cm4gRU5EUE9JTlRTW25hbWVdLmFwcGx5KEVORFBPSU5UUywgYXJncyk7XG59IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvaW50ZXJvcFJlcXVpcmVEZWZhdWx0XCIpO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5VbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3IgPSBleHBvcnRzLlNlcnZlclJlc3BvbnNlID0gZXhwb3J0cy5OZXR3b3JrVGltZW91dEVycm9yID0gZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX2NsYXNzQ2FsbENoZWNrMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2tcIikpO1xuXG52YXIgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuXCIpKTtcblxudmFyIF9nZXRQcm90b3R5cGVPZjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2dldFByb3RvdHlwZU9mXCIpKTtcblxudmFyIF9pbmhlcml0czIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2luaGVyaXRzXCIpKTtcblxudmFyIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRcIikpO1xuXG5mdW5jdGlvbiBfZXh0ZW5kYWJsZUJ1aWx0aW41KGNscykge1xuICBmdW5jdGlvbiBFeHRlbmRhYmxlQnVpbHRpbigpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBSZWZsZWN0LmNvbnN0cnVjdChjbHMsIEFycmF5LmZyb20oYXJndW1lbnRzKSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGluc3RhbmNlLCBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykpO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfVxuXG4gIEV4dGVuZGFibGVCdWlsdGluLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoY2xzLnByb3RvdHlwZSwge1xuICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICB2YWx1ZTogY2xzLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH1cbiAgfSk7XG5cbiAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikge1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZihFeHRlbmRhYmxlQnVpbHRpbiwgY2xzKTtcbiAgfSBlbHNlIHtcbiAgICBFeHRlbmRhYmxlQnVpbHRpbi5fX3Byb3RvX18gPSBjbHM7XG4gIH1cblxuICByZXR1cm4gRXh0ZW5kYWJsZUJ1aWx0aW47XG59XG5cbmZ1bmN0aW9uIF9leHRlbmRhYmxlQnVpbHRpbjMoY2xzKSB7XG4gIGZ1bmN0aW9uIEV4dGVuZGFibGVCdWlsdGluKCkge1xuICAgIHZhciBpbnN0YW5jZSA9IFJlZmxlY3QuY29uc3RydWN0KGNscywgQXJyYXkuZnJvbShhcmd1bWVudHMpKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoaW5zdGFuY2UsIE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKSk7XG4gICAgcmV0dXJuIGluc3RhbmNlO1xuICB9XG5cbiAgRXh0ZW5kYWJsZUJ1aWx0aW4ucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShjbHMucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IHtcbiAgICAgIHZhbHVlOiBjbHMsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfVxuICB9KTtcblxuICBpZiAoT2JqZWN0LnNldFByb3RvdHlwZU9mKSB7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKEV4dGVuZGFibGVCdWlsdGluLCBjbHMpO1xuICB9IGVsc2Uge1xuICAgIEV4dGVuZGFibGVCdWlsdGluLl9fcHJvdG9fXyA9IGNscztcbiAgfVxuXG4gIHJldHVybiBFeHRlbmRhYmxlQnVpbHRpbjtcbn1cblxuZnVuY3Rpb24gX2V4dGVuZGFibGVCdWlsdGluKGNscykge1xuICBmdW5jdGlvbiBFeHRlbmRhYmxlQnVpbHRpbigpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBSZWZsZWN0LmNvbnN0cnVjdChjbHMsIEFycmF5LmZyb20oYXJndW1lbnRzKSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGluc3RhbmNlLCBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykpO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfVxuXG4gIEV4dGVuZGFibGVCdWlsdGluLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoY2xzLnByb3RvdHlwZSwge1xuICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICB2YWx1ZTogY2xzLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH1cbiAgfSk7XG5cbiAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikge1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZihFeHRlbmRhYmxlQnVpbHRpbiwgY2xzKTtcbiAgfSBlbHNlIHtcbiAgICBFeHRlbmRhYmxlQnVpbHRpbi5fX3Byb3RvX18gPSBjbHM7XG4gIH1cblxuICByZXR1cm4gRXh0ZW5kYWJsZUJ1aWx0aW47XG59XG5cbi8qKlxuICogS2ludG8gc2VydmVyIGVycm9yIGNvZGUgZGVzY3JpcHRvcnMuXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG52YXIgRVJST1JfQ09ERVMgPSB7XG4gIDEwNDogXCJNaXNzaW5nIEF1dGhvcml6YXRpb24gVG9rZW5cIixcbiAgMTA1OiBcIkludmFsaWQgQXV0aG9yaXphdGlvbiBUb2tlblwiLFxuICAxMDY6IFwiUmVxdWVzdCBib2R5IHdhcyBub3QgdmFsaWQgSlNPTlwiLFxuICAxMDc6IFwiSW52YWxpZCByZXF1ZXN0IHBhcmFtZXRlclwiLFxuICAxMDg6IFwiTWlzc2luZyByZXF1ZXN0IHBhcmFtZXRlclwiLFxuICAxMDk6IFwiSW52YWxpZCBwb3N0ZWQgZGF0YVwiLFxuICAxMTA6IFwiSW52YWxpZCBUb2tlbiAvIGlkXCIsXG4gIDExMTogXCJNaXNzaW5nIFRva2VuIC8gaWRcIixcbiAgMTEyOiBcIkNvbnRlbnQtTGVuZ3RoIGhlYWRlciB3YXMgbm90IHByb3ZpZGVkXCIsXG4gIDExMzogXCJSZXF1ZXN0IGJvZHkgdG9vIGxhcmdlXCIsXG4gIDExNDogXCJSZXNvdXJjZSB3YXMgY3JlYXRlZCwgdXBkYXRlZCBvciBkZWxldGVkIG1lYW53aGlsZVwiLFxuICAxMTU6IFwiTWV0aG9kIG5vdCBhbGxvd2VkIG9uIHRoaXMgZW5kIHBvaW50IChoaW50OiBzZXJ2ZXIgbWF5IGJlIHJlYWRvbmx5KVwiLFxuICAxMTY6IFwiUmVxdWVzdGVkIHZlcnNpb24gbm90IGF2YWlsYWJsZSBvbiB0aGlzIHNlcnZlclwiLFxuICAxMTc6IFwiQ2xpZW50IGhhcyBzZW50IHRvbyBtYW55IHJlcXVlc3RzXCIsXG4gIDEyMTogXCJSZXNvdXJjZSBhY2Nlc3MgaXMgZm9yYmlkZGVuIGZvciB0aGlzIHVzZXJcIixcbiAgMTIyOiBcIkFub3RoZXIgcmVzb3VyY2UgdmlvbGF0ZXMgY29uc3RyYWludFwiLFxuICAyMDE6IFwiU2VydmljZSBUZW1wb3JhcnkgdW5hdmFpbGFibGUgZHVlIHRvIGhpZ2ggbG9hZFwiLFxuICAyMDI6IFwiU2VydmljZSBkZXByZWNhdGVkXCIsXG4gIDk5OTogXCJJbnRlcm5hbCBTZXJ2ZXIgRXJyb3JcIlxufTtcbnZhciBfZGVmYXVsdCA9IEVSUk9SX0NPREVTO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7XG5cbnZhciBOZXR3b3JrVGltZW91dEVycm9yID1cbi8qI19fUFVSRV9fKi9cbmZ1bmN0aW9uIChfZXh0ZW5kYWJsZUJ1aWx0aW4yKSB7XG4gICgwLCBfaW5oZXJpdHMyLmRlZmF1bHQpKE5ldHdvcmtUaW1lb3V0RXJyb3IsIF9leHRlbmRhYmxlQnVpbHRpbjIpO1xuXG4gIGZ1bmN0aW9uIE5ldHdvcmtUaW1lb3V0RXJyb3IodXJsLCBvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgKDAsIF9jbGFzc0NhbGxDaGVjazIuZGVmYXVsdCkodGhpcywgTmV0d29ya1RpbWVvdXRFcnJvcik7XG4gICAgX3RoaXMgPSAoMCwgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yLmRlZmF1bHQpKHRoaXMsICgwLCBfZ2V0UHJvdG90eXBlT2YyLmRlZmF1bHQpKE5ldHdvcmtUaW1lb3V0RXJyb3IpLmNhbGwodGhpcywgXCJUaW1lb3V0IHdoaWxlIHRyeWluZyB0byBhY2Nlc3MgXCIuY29uY2F0KHVybCwgXCIgd2l0aCBcIikuY29uY2F0KEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpKSkpO1xuXG4gICAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSgoMCwgX2Fzc2VydFRoaXNJbml0aWFsaXplZDIuZGVmYXVsdCkoKDAsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyLmRlZmF1bHQpKF90aGlzKSksIE5ldHdvcmtUaW1lb3V0RXJyb3IpO1xuICAgIH1cblxuICAgIF90aGlzLnVybCA9IHVybDtcbiAgICBfdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICByZXR1cm4gTmV0d29ya1RpbWVvdXRFcnJvcjtcbn0oX2V4dGVuZGFibGVCdWlsdGluKEVycm9yKSk7XG5cbmV4cG9ydHMuTmV0d29ya1RpbWVvdXRFcnJvciA9IE5ldHdvcmtUaW1lb3V0RXJyb3I7XG5cbnZhciBVbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3IgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKF9leHRlbmRhYmxlQnVpbHRpbjQpIHtcbiAgKDAsIF9pbmhlcml0czIuZGVmYXVsdCkoVW5wYXJzZWFibGVSZXNwb25zZUVycm9yLCBfZXh0ZW5kYWJsZUJ1aWx0aW40KTtcblxuICBmdW5jdGlvbiBVbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3IocmVzcG9uc2UsIGJvZHksIGVycm9yKSB7XG4gICAgdmFyIF90aGlzMjtcblxuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIFVucGFyc2VhYmxlUmVzcG9uc2VFcnJvcik7XG4gICAgdmFyIHN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cztcbiAgICBfdGhpczIgPSAoMCwgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yLmRlZmF1bHQpKHRoaXMsICgwLCBfZ2V0UHJvdG90eXBlT2YyLmRlZmF1bHQpKFVucGFyc2VhYmxlUmVzcG9uc2VFcnJvcikuY2FsbCh0aGlzLCBcIlJlc3BvbnNlIGZyb20gc2VydmVyIHVucGFyc2VhYmxlIChIVFRQIFwiLmNvbmNhdChzdGF0dXMgfHwgMCwgXCI7IFwiKS5jb25jYXQoZXJyb3IsIFwiKTogXCIpLmNvbmNhdChib2R5KSkpO1xuXG4gICAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSgoMCwgX2Fzc2VydFRoaXNJbml0aWFsaXplZDIuZGVmYXVsdCkoKDAsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyLmRlZmF1bHQpKF90aGlzMikpLCBVbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3IpO1xuICAgIH1cblxuICAgIF90aGlzMi5zdGF0dXMgPSBzdGF0dXM7XG4gICAgX3RoaXMyLnJlc3BvbnNlID0gcmVzcG9uc2U7XG4gICAgX3RoaXMyLnN0YWNrID0gZXJyb3Iuc3RhY2s7XG4gICAgX3RoaXMyLmVycm9yID0gZXJyb3I7XG4gICAgcmV0dXJuIF90aGlzMjtcbiAgfVxuXG4gIHJldHVybiBVbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3I7XG59KF9leHRlbmRhYmxlQnVpbHRpbjMoRXJyb3IpKTtcbi8qKlxuICogXCJFcnJvclwiIHN1YmNsYXNzIHJlcHJlc2VudGluZyBhID49NDAwIHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlci5cbiAqXG4gKiBXaGV0aGVyIG9yIG5vdCB0aGlzIGlzIGFuIGVycm9yIGRlcGVuZHMgb24geW91ciBhcHBsaWNhdGlvbi5cbiAqXG4gKiBUaGUgYGpzb25gIGZpZWxkIGNhbiBiZSB1bmRlZmluZWQgaWYgdGhlIHNlcnZlciByZXNwb25kZWQgd2l0aCBhblxuICogZW1wdHkgcmVzcG9uc2UgYm9keS4gVGhpcyBzaG91bGRuJ3QgZ2VuZXJhbGx5IGhhcHBlbi4gTW9zdCBcImJhZFwiXG4gKiByZXNwb25zZXMgY29tZSB3aXRoIGEgSlNPTiBlcnJvciBkZXNjcmlwdGlvbiwgb3IgKGlmIHRoZXkncmVcbiAqIGZyb250ZWQgYnkgYSBDRE4gb3Igbmdpbnggb3Igc29tZXRoaW5nKSBvY2Nhc2lvbmFsbHkgbm9uLUpTT05cbiAqIHJlc3BvbnNlcyAod2hpY2ggYmVjb21lIFVucGFyc2VhYmxlUmVzcG9uc2VFcnJvcnMsIGFib3ZlKS5cbiAqL1xuXG5cbmV4cG9ydHMuVW5wYXJzZWFibGVSZXNwb25zZUVycm9yID0gVW5wYXJzZWFibGVSZXNwb25zZUVycm9yO1xuXG52YXIgU2VydmVyUmVzcG9uc2UgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKF9leHRlbmRhYmxlQnVpbHRpbjYpIHtcbiAgKDAsIF9pbmhlcml0czIuZGVmYXVsdCkoU2VydmVyUmVzcG9uc2UsIF9leHRlbmRhYmxlQnVpbHRpbjYpO1xuXG4gIGZ1bmN0aW9uIFNlcnZlclJlc3BvbnNlKHJlc3BvbnNlLCBqc29uKSB7XG4gICAgdmFyIF90aGlzMztcblxuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIFNlcnZlclJlc3BvbnNlKTtcbiAgICB2YXIgc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzO1xuICAgIHZhciBzdGF0dXNUZXh0ID0gcmVzcG9uc2Uuc3RhdHVzVGV4dDtcbiAgICB2YXIgZXJybm9Nc2c7XG5cbiAgICBpZiAoanNvbikge1xuICAgICAgLy8gVHJ5IHRvIGZpbGwgaW4gaW5mb3JtYXRpb24gZnJvbSB0aGUgSlNPTiBlcnJvci5cbiAgICAgIHN0YXR1c1RleHQgPSBqc29uLmVycm9yIHx8IHN0YXR1c1RleHQ7IC8vIFRha2UgZXJybm9Nc2cgZnJvbSBlaXRoZXIgRVJST1JfQ09ERVMgb3IganNvbi5tZXNzYWdlLlxuXG4gICAgICBpZiAoanNvbi5lcnJubyAmJiBqc29uLmVycm5vIGluIEVSUk9SX0NPREVTKSB7XG4gICAgICAgIGVycm5vTXNnID0gRVJST1JfQ09ERVNbanNvbi5lcnJub107XG4gICAgICB9IGVsc2UgaWYgKGpzb24ubWVzc2FnZSkge1xuICAgICAgICBlcnJub01zZyA9IGpzb24ubWVzc2FnZTtcbiAgICAgIH0gLy8gSWYgd2UgaGFkIGJvdGggRVJST1JfQ09ERVMgYW5kIGpzb24ubWVzc2FnZSwgYW5kIHRoZXkgZGlmZmVyLFxuICAgICAgLy8gY29tYmluZSB0aGVtLlxuXG5cbiAgICAgIGlmIChlcnJub01zZyAmJiBqc29uLm1lc3NhZ2UgJiYganNvbi5tZXNzYWdlICE9PSBlcnJub01zZykge1xuICAgICAgICBlcnJub01zZyArPSBcIiAoXCIuY29uY2F0KGpzb24ubWVzc2FnZSwgXCIpXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBtZXNzYWdlID0gXCJIVFRQIFwiLmNvbmNhdChzdGF0dXMsIFwiIFwiKS5jb25jYXQoc3RhdHVzVGV4dCk7XG5cbiAgICBpZiAoZXJybm9Nc2cpIHtcbiAgICAgIG1lc3NhZ2UgKz0gXCI6IFwiLmNvbmNhdChlcnJub01zZyk7XG4gICAgfVxuXG4gICAgX3RoaXMzID0gKDAsIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuMi5kZWZhdWx0KSh0aGlzLCAoMCwgX2dldFByb3RvdHlwZU9mMi5kZWZhdWx0KShTZXJ2ZXJSZXNwb25zZSkuY2FsbCh0aGlzLCBtZXNzYWdlLnRyaW0oKSkpO1xuXG4gICAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSgoMCwgX2Fzc2VydFRoaXNJbml0aWFsaXplZDIuZGVmYXVsdCkoKDAsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyLmRlZmF1bHQpKF90aGlzMykpLCBTZXJ2ZXJSZXNwb25zZSk7XG4gICAgfVxuXG4gICAgX3RoaXMzLnJlc3BvbnNlID0gcmVzcG9uc2U7XG4gICAgX3RoaXMzLmRhdGEgPSBqc29uO1xuICAgIHJldHVybiBfdGhpczM7XG4gIH1cblxuICByZXR1cm4gU2VydmVyUmVzcG9uc2U7XG59KF9leHRlbmRhYmxlQnVpbHRpbjUoRXJyb3IpKTtcblxuZXhwb3J0cy5TZXJ2ZXJSZXNwb25zZSA9IFNlcnZlclJlc3BvbnNlOyIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlRGVmYXVsdFwiKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF9vYmplY3RTcHJlYWQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9vYmplY3RTcHJlYWRcIikpO1xuXG52YXIgX3JlZ2VuZXJhdG9yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvcmVnZW5lcmF0b3JcIikpO1xuXG52YXIgX2FzeW5jVG9HZW5lcmF0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yXCIpKTtcblxudmFyIF9jbGFzc0NhbGxDaGVjazIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NsYXNzQ2FsbENoZWNrXCIpKTtcblxudmFyIF9jcmVhdGVDbGFzczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NyZWF0ZUNsYXNzXCIpKTtcblxudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpO1xuXG52YXIgX2Vycm9ycyA9IHJlcXVpcmUoXCIuL2Vycm9yc1wiKTtcblxuLyoqXG4gKiBFbmhhbmNlZCBIVFRQIGNsaWVudCBmb3IgdGhlIEtpbnRvIHByb3RvY29sLlxuICogQHByaXZhdGVcbiAqL1xudmFyIEhUVFAgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKCkge1xuICAoMCwgX2NyZWF0ZUNsYXNzMi5kZWZhdWx0KShIVFRQLCBudWxsLCBbe1xuICAgIGtleTogXCJERUZBVUxUX1JFUVVFU1RfSEVBREVSU1wiLFxuXG4gICAgLyoqXG4gICAgICogRGVmYXVsdCBIVFRQIHJlcXVlc3QgaGVhZGVycyBhcHBsaWVkIHRvIGVhY2ggb3V0Z29pbmcgcmVxdWVzdC5cbiAgICAgKlxuICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICovXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBBY2NlcHQ6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIlxuICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVmYXVsdCBvcHRpb25zLlxuICAgICAqXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImRlZmF1bHRPcHRpb25zXCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0aW1lb3V0OiBudWxsLFxuICAgICAgICByZXF1ZXN0TW9kZTogXCJjb3JzXCJcbiAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdG9yLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtFdmVudEVtaXR0ZXJ9IGV2ZW50cyAgICAgICAgICAgICAgICAgICAgICAgVGhlIGV2ZW50IGhhbmRsZXIuXG4gICAgICogQHBhcmFtIHtPYmplY3R9ICAgICAgIFtvcHRpb25zPXt9fSAgICAgICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSAgICAgICBbb3B0aW9ucy50aW1lb3V0PW51bGxdICAgICAgIFRoZSByZXF1ZXN0IHRpbWVvdXQgaW4gbXMsIGlmIGFueSAoZGVmYXVsdDogYG51bGxgKS5cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gICAgICAgW29wdGlvbnMucmVxdWVzdE1vZGU9XCJjb3JzXCJdIFRoZSBIVFRQIHJlcXVlc3QgbW9kZSAoZGVmYXVsdDogYFwiY29yc1wiYCkuXG4gICAgICovXG5cbiAgfV0pO1xuXG4gIGZ1bmN0aW9uIEhUVFAoZXZlbnRzKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIEhUVFApO1xuXG4gICAgLy8gcHVibGljIHByb3BlcnRpZXNcblxuICAgIC8qKlxuICAgICAqIFRoZSBldmVudCBlbWl0dGVyIGluc3RhbmNlLlxuICAgICAqIEB0eXBlIHtFdmVudEVtaXR0ZXJ9XG4gICAgICovXG4gICAgaWYgKCFldmVudHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGV2ZW50cyBoYW5kbGVyIHByb3ZpZGVkXCIpO1xuICAgIH1cblxuICAgIHRoaXMuZXZlbnRzID0gZXZlbnRzO1xuICAgIC8qKlxuICAgICAqIFRoZSByZXF1ZXN0IG1vZGUuXG4gICAgICogQHNlZSAgaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI3JlcXVlc3Rtb2RlXG4gICAgICogQHR5cGUge1N0cmluZ31cbiAgICAgKi9cblxuICAgIHRoaXMucmVxdWVzdE1vZGUgPSBvcHRpb25zLnJlcXVlc3RNb2RlIHx8IEhUVFAuZGVmYXVsdE9wdGlvbnMucmVxdWVzdE1vZGU7XG4gICAgLyoqXG4gICAgICogVGhlIHJlcXVlc3QgdGltZW91dC5cbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy50aW1lb3V0ID0gb3B0aW9ucy50aW1lb3V0IHx8IEhUVFAuZGVmYXVsdE9wdGlvbnMudGltZW91dDtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICAoMCwgX2NyZWF0ZUNsYXNzMi5kZWZhdWx0KShIVFRQLCBbe1xuICAgIGtleTogXCJ0aW1lZEZldGNoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHRpbWVkRmV0Y2godXJsLCBvcHRpb25zKSB7XG4gICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICB2YXIgaGFzVGltZWRvdXQgPSBmYWxzZTtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIC8vIERldGVjdCBpZiBhIHJlcXVlc3QgaGFzIHRpbWVkIG91dC5cbiAgICAgICAgdmFyIF90aW1lb3V0SWQ7XG5cbiAgICAgICAgaWYgKF90aGlzLnRpbWVvdXQpIHtcbiAgICAgICAgICBfdGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBoYXNUaW1lZG91dCA9IHRydWU7XG4gICAgICAgICAgICByZWplY3QobmV3IF9lcnJvcnMuTmV0d29ya1RpbWVvdXRFcnJvcih1cmwsIG9wdGlvbnMpKTtcbiAgICAgICAgICB9LCBfdGhpcy50aW1lb3V0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHByb2NlZWRXaXRoSGFuZGxlcihmbikge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoYXJnKSB7XG4gICAgICAgICAgICBpZiAoIWhhc1RpbWVkb3V0KSB7XG4gICAgICAgICAgICAgIGlmIChfdGltZW91dElkKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF90aW1lb3V0SWQpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgZm4oYXJnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgZmV0Y2godXJsLCBvcHRpb25zKS50aGVuKHByb2NlZWRXaXRoSGFuZGxlcihyZXNvbHZlKSkuY2F0Y2gocHJvY2VlZFdpdGhIYW5kbGVyKHJlamVjdCkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJwcm9jZXNzUmVzcG9uc2VcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9wcm9jZXNzUmVzcG9uc2UgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlKHJlc3BvbnNlKSB7XG4gICAgICAgIHZhciBzdGF0dXMsIGhlYWRlcnMsIHRleHQsIGpzb247XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUkKF9jb250ZXh0KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQucHJldiA9IF9jb250ZXh0Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIHN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cywgaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnM7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnRleHQoKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgdGV4dCA9IF9jb250ZXh0LnNlbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoISh0ZXh0Lmxlbmd0aCAhPT0gMCkpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSAxMjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIF9jb250ZXh0LnByZXYgPSA1O1xuICAgICAgICAgICAgICAgIGpzb24gPSBKU09OLnBhcnNlKHRleHQpO1xuICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSAxMjtcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQucHJldiA9IDk7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQudDAgPSBfY29udGV4dFtcImNhdGNoXCJdKDUpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBfZXJyb3JzLlVucGFyc2VhYmxlUmVzcG9uc2VFcnJvcihyZXNwb25zZSwgdGV4dCwgX2NvbnRleHQudDApO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTI6XG4gICAgICAgICAgICAgICAgaWYgKCEoc3RhdHVzID49IDQwMCkpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSAxNDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBfZXJyb3JzLlNlcnZlclJlc3BvbnNlKHJlc3BvbnNlLCBqc29uKTtcblxuICAgICAgICAgICAgICBjYXNlIDE0OlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dC5hYnJ1cHQoXCJyZXR1cm5cIiwge1xuICAgICAgICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMsXG4gICAgICAgICAgICAgICAgICBqc29uOiBqc29uLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogaGVhZGVyc1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTU6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZSwgdGhpcywgW1s1LCA5XV0pO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gcHJvY2Vzc1Jlc3BvbnNlKF94KSB7XG4gICAgICAgIHJldHVybiBfcHJvY2Vzc1Jlc3BvbnNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJyZXRyeVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3JldHJ5ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTIodXJsLCByZXRyeUFmdGVyLCByZXF1ZXN0LCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUyJChfY29udGV4dDIpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDIucHJldiA9IF9jb250ZXh0Mi5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBfY29udGV4dDIubmV4dCA9IDI7XG4gICAgICAgICAgICAgICAgcmV0dXJuICgwLCBfdXRpbHMuZGVsYXkpKHJldHJ5QWZ0ZXIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLmFicnVwdChcInJldHVyblwiLCB0aGlzLnJlcXVlc3QodXJsLCByZXF1ZXN0LCAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIG9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiBvcHRpb25zLnJldHJ5IC0gMVxuICAgICAgICAgICAgICAgIH0pKSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMiwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiByZXRyeShfeDIsIF94MywgX3g0LCBfeDUpIHtcbiAgICAgICAgcmV0dXJuIF9yZXRyeS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBhbiBIVFRQIHJlcXVlc3QgdG8gdGhlIEtpbnRvIHNlcnZlci5cbiAgICAgKlxuICAgICAqIFJlc29sdmVzIHdpdGggYW4gb2JqZXQgY29udGFpbmluZyB0aGUgZm9sbG93aW5nIEhUVFAgcmVzcG9uc2UgcHJvcGVydGllczpcbiAgICAgKiAtIGB7TnVtYmVyfSAgc3RhdHVzYCAgVGhlIEhUVFAgc3RhdHVzIGNvZGUuXG4gICAgICogLSBge09iamVjdH0gIGpzb25gICAgIFRoZSBKU09OIHJlc3BvbnNlIGJvZHkuXG4gICAgICogLSBge0hlYWRlcnN9IGhlYWRlcnNgIFRoZSByZXNwb25zZSBoZWFkZXJzIG9iamVjdDsgc2VlIHRoZSBFUzYgZmV0Y2goKSBzcGVjLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSB1cmwgICAgICAgICAgICAgICBUaGUgVVJMLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW3JlcXVlc3Q9e31dICAgICAgVGhlIHJlcXVlc3Qgb2JqZWN0LCBwYXNzZWQgdG9cbiAgICAgKiAgICAgZmV0Y2goKSBhcyBpdHMgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbcmVxdWVzdC5oZWFkZXJzXSBUaGUgcmVxdWVzdCBoZWFkZXJzIG9iamVjdCAoZGVmYXVsdDoge30pXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBPcHRpb25zIGZvciBtYWtpbmcgdGhlXG4gICAgICogICAgIHJlcXVlc3RcbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IFtvcHRpb25zLnJldHJ5XSAgIE51bWJlciBvZiByZXRyaWVzIChkZWZhdWx0OiAwKVxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJyZXF1ZXN0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfcmVxdWVzdDIgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMyh1cmwpIHtcbiAgICAgICAgdmFyIF9yZXF1ZXN0LFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgIHJlc3BvbnNlLFxuICAgICAgICAgICAgc3RhdHVzLFxuICAgICAgICAgICAgaGVhZGVycyxcbiAgICAgICAgICAgIHJldHJ5QWZ0ZXIsXG4gICAgICAgICAgICBfYXJnczMgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTMkKF9jb250ZXh0Mykge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0My5wcmV2ID0gX2NvbnRleHQzLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIF9yZXF1ZXN0ID0gX2FyZ3MzLmxlbmd0aCA+IDEgJiYgX2FyZ3MzWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczNbMV0gOiB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB7fVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMy5sZW5ndGggPiAyICYmIF9hcmdzM1syXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MzWzJdIDoge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IDBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIC8vIEVuc3VyZSBkZWZhdWx0IHJlcXVlc3QgaGVhZGVycyBhcmUgYWx3YXlzIHNldFxuICAgICAgICAgICAgICAgIF9yZXF1ZXN0LmhlYWRlcnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIEhUVFAuREVGQVVMVF9SRVFVRVNUX0hFQURFUlMsIF9yZXF1ZXN0LmhlYWRlcnMpOyAvLyBJZiBhIG11bHRpcGFydCBib2R5IGlzIHByb3ZpZGVkLCByZW1vdmUgYW55IGN1c3RvbSBDb250ZW50LVR5cGUgaGVhZGVyIGFzXG4gICAgICAgICAgICAgICAgLy8gdGhlIGZldGNoKCkgaW1wbGVtZW50YXRpb24gd2lsbCBhZGQgdGhlIGNvcnJlY3Qgb25lIGZvciB1cy5cblxuICAgICAgICAgICAgICAgIGlmIChfcmVxdWVzdC5ib2R5ICYmIHR5cGVvZiBfcmVxdWVzdC5ib2R5LmFwcGVuZCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgICBkZWxldGUgX3JlcXVlc3QuaGVhZGVyc1tcIkNvbnRlbnQtVHlwZVwiXTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBfcmVxdWVzdC5tb2RlID0gdGhpcy5yZXF1ZXN0TW9kZTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDMubmV4dCA9IDc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudGltZWRGZXRjaCh1cmwsIF9yZXF1ZXN0KTtcblxuICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBfY29udGV4dDMuc2VudDtcbiAgICAgICAgICAgICAgICBzdGF0dXMgPSByZXNwb25zZS5zdGF0dXMsIGhlYWRlcnMgPSByZXNwb25zZS5oZWFkZXJzO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tGb3JEZXByZWNhdGlvbkhlYWRlcihoZWFkZXJzKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuX2NoZWNrRm9yQmFja29mZkhlYWRlcihzdGF0dXMsIGhlYWRlcnMpOyAvLyBDaGVjayBpZiB0aGUgc2VydmVyIHN1bW1vbnMgdGhlIGNsaWVudCB0byByZXRyeSBhZnRlciBhIHdoaWxlLlxuXG5cbiAgICAgICAgICAgICAgICByZXRyeUFmdGVyID0gdGhpcy5fY2hlY2tGb3JSZXRyeUFmdGVySGVhZGVyKHN0YXR1cywgaGVhZGVycyk7IC8vIElmIG51bWJlciBvZiBhbGxvd2VkIG9mIHJldHJpZXMgaXMgbm90IGV4aGF1c3RlZCwgcmV0cnkgdGhlIHNhbWUgcmVxdWVzdC5cblxuICAgICAgICAgICAgICAgIGlmICghKHJldHJ5QWZ0ZXIgJiYgb3B0aW9ucy5yZXRyeSA+IDApKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDMubmV4dCA9IDE2O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0My5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5yZXRyeSh1cmwsIHJldHJ5QWZ0ZXIsIF9yZXF1ZXN0LCBvcHRpb25zKSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxNjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQzLmFicnVwdChcInJldHVyblwiLCB0aGlzLnByb2Nlc3NSZXNwb25zZShyZXNwb25zZSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTc6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQzLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUzLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHJlcXVlc3QoX3g2KSB7XG4gICAgICAgIHJldHVybiBfcmVxdWVzdDIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gIH0sIHtcbiAgICBrZXk6IFwiX2NoZWNrRm9yRGVwcmVjYXRpb25IZWFkZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2NoZWNrRm9yRGVwcmVjYXRpb25IZWFkZXIoaGVhZGVycykge1xuICAgICAgdmFyIGFsZXJ0SGVhZGVyID0gaGVhZGVycy5nZXQoXCJBbGVydFwiKTtcblxuICAgICAgaWYgKCFhbGVydEhlYWRlcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBhbGVydDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYWxlcnQgPSBKU09OLnBhcnNlKGFsZXJ0SGVhZGVyKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLndhcm4oXCJVbmFibGUgdG8gcGFyc2UgQWxlcnQgaGVhZGVyIG1lc3NhZ2VcIiwgYWxlcnRIZWFkZXIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnNvbGUud2FybihhbGVydC5tZXNzYWdlLCBhbGVydC51cmwpO1xuICAgICAgdGhpcy5ldmVudHMuZW1pdChcImRlcHJlY2F0ZWRcIiwgYWxlcnQpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJfY2hlY2tGb3JCYWNrb2ZmSGVhZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9jaGVja0ZvckJhY2tvZmZIZWFkZXIoc3RhdHVzLCBoZWFkZXJzKSB7XG4gICAgICB2YXIgYmFja29mZk1zO1xuICAgICAgdmFyIGJhY2tvZmZTZWNvbmRzID0gcGFyc2VJbnQoaGVhZGVycy5nZXQoXCJCYWNrb2ZmXCIpLCAxMCk7XG5cbiAgICAgIGlmIChiYWNrb2ZmU2Vjb25kcyA+IDApIHtcbiAgICAgICAgYmFja29mZk1zID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgKyBiYWNrb2ZmU2Vjb25kcyAqIDEwMDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBiYWNrb2ZmTXMgPSAwO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmV2ZW50cy5lbWl0KFwiYmFja29mZlwiLCBiYWNrb2ZmTXMpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJfY2hlY2tGb3JSZXRyeUFmdGVySGVhZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9jaGVja0ZvclJldHJ5QWZ0ZXJIZWFkZXIoc3RhdHVzLCBoZWFkZXJzKSB7XG4gICAgICB2YXIgcmV0cnlBZnRlciA9IGhlYWRlcnMuZ2V0KFwiUmV0cnktQWZ0ZXJcIik7XG5cbiAgICAgIGlmICghcmV0cnlBZnRlcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBkZWxheSA9IHBhcnNlSW50KHJldHJ5QWZ0ZXIsIDEwKSAqIDEwMDA7XG4gICAgICByZXRyeUFmdGVyID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgKyBkZWxheTtcbiAgICAgIHRoaXMuZXZlbnRzLmVtaXQoXCJyZXRyeS1hZnRlclwiLCByZXRyeUFmdGVyKTtcbiAgICAgIHJldHVybiBkZWxheTtcbiAgICB9XG4gIH1dKTtcbiAgcmV0dXJuIEhUVFA7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IEhUVFA7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvaW50ZXJvcFJlcXVpcmVEZWZhdWx0XCIpO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3R5cGVvZjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL3R5cGVvZlwiKSk7XG5cbnZhciBfY2xhc3NDYWxsQ2hlY2syID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jbGFzc0NhbGxDaGVja1wiKSk7XG5cbnZhciBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5cIikpO1xuXG52YXIgX2dldFByb3RvdHlwZU9mMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZ2V0UHJvdG90eXBlT2ZcIikpO1xuXG52YXIgX2luaGVyaXRzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvaW5oZXJpdHNcIikpO1xuXG52YXIgX2V2ZW50cyA9IHJlcXVpcmUoXCJldmVudHNcIik7XG5cbnZhciBfYmFzZSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vYmFzZVwiKSk7XG5cbnZhciBLaW50b0NsaWVudCA9XG4vKiNfX1BVUkVfXyovXG5mdW5jdGlvbiAoX0tpbnRvQ2xpZW50QmFzZSkge1xuICAoMCwgX2luaGVyaXRzMi5kZWZhdWx0KShLaW50b0NsaWVudCwgX0tpbnRvQ2xpZW50QmFzZSk7XG5cbiAgZnVuY3Rpb24gS2ludG9DbGllbnQocmVtb3RlKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIEtpbnRvQ2xpZW50KTtcbiAgICB2YXIgZXZlbnRzID0gb3B0aW9ucy5ldmVudHMgfHwgbmV3IF9ldmVudHMuRXZlbnRFbWl0dGVyKCk7XG4gICAgcmV0dXJuICgwLCBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjIuZGVmYXVsdCkodGhpcywgKDAsIF9nZXRQcm90b3R5cGVPZjIuZGVmYXVsdCkoS2ludG9DbGllbnQpLmNhbGwodGhpcywgcmVtb3RlLCBPYmplY3QuYXNzaWduKHtcbiAgICAgIGV2ZW50czogZXZlbnRzXG4gICAgfSwgb3B0aW9ucykpKTtcbiAgfVxuXG4gIHJldHVybiBLaW50b0NsaWVudDtcbn0oX2Jhc2UuZGVmYXVsdCk7IC8vIFRoaXMgaXMgYSBoYWNrIHRvIGF2b2lkIEJyb3dzZXJpZnkgdG8gZXhwb3NlIHRoZSBhYm92ZSBjbGFzc1xuLy8gYXQgYG5ldyBLaW50b0NsaWVudCgpYCBpbnN0ZWFkIG9mIGBuZXcgS2ludG9DbGllbnQuZGVmYXVsdCgpYC5cbi8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vS2ludG8va2ludG8taHR0cC5qcy9pc3N1ZXMvNzdcblxuXG5leHBvcnRzLmRlZmF1bHQgPSBLaW50b0NsaWVudDtcblxuaWYgKCh0eXBlb2YgbW9kdWxlID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6ICgwLCBfdHlwZW9mMi5kZWZhdWx0KShtb2R1bGUpKSA9PT0gXCJvYmplY3RcIikge1xuICBtb2R1bGUuZXhwb3J0cyA9IEtpbnRvQ2xpZW50O1xufSIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlRGVmYXVsdFwiKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuY3JlYXRlUmVxdWVzdCA9IGNyZWF0ZVJlcXVlc3Q7XG5leHBvcnRzLnVwZGF0ZVJlcXVlc3QgPSB1cGRhdGVSZXF1ZXN0O1xuZXhwb3J0cy5qc29uUGF0Y2hQZXJtaXNzaW9uc1JlcXVlc3QgPSBqc29uUGF0Y2hQZXJtaXNzaW9uc1JlcXVlc3Q7XG5leHBvcnRzLmRlbGV0ZVJlcXVlc3QgPSBkZWxldGVSZXF1ZXN0O1xuZXhwb3J0cy5hZGRBdHRhY2htZW50UmVxdWVzdCA9IGFkZEF0dGFjaG1lbnRSZXF1ZXN0O1xuXG52YXIgX3NsaWNlZFRvQXJyYXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zbGljZWRUb0FycmF5XCIpKTtcblxudmFyIF9vYmplY3RTcHJlYWQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9vYmplY3RTcHJlYWRcIikpO1xuXG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4vdXRpbHNcIik7XG5cbnZhciByZXF1ZXN0RGVmYXVsdHMgPSB7XG4gIHNhZmU6IGZhbHNlLFxuICAvLyBjaGVjayBpZiB3ZSBzaG91bGQgc2V0IGRlZmF1bHQgY29udGVudCB0eXBlIGhlcmVcbiAgaGVhZGVyczoge30sXG4gIHBlcm1pc3Npb25zOiB1bmRlZmluZWQsXG4gIGRhdGE6IHVuZGVmaW5lZCxcbiAgcGF0Y2g6IGZhbHNlXG59O1xuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHNhZmVIZWFkZXIoc2FmZSwgbGFzdF9tb2RpZmllZCkge1xuICBpZiAoIXNhZmUpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBpZiAobGFzdF9tb2RpZmllZCkge1xuICAgIHJldHVybiB7XG4gICAgICBcIklmLU1hdGNoXCI6IFwiXFxcIlwiLmNvbmNhdChsYXN0X21vZGlmaWVkLCBcIlxcXCJcIilcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBcIklmLU5vbmUtTWF0Y2hcIjogXCIqXCJcbiAgfTtcbn1cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuXG5cbmZ1bmN0aW9uIGNyZWF0ZVJlcXVlc3QocGF0aCwgX3JlZikge1xuICB2YXIgZGF0YSA9IF9yZWYuZGF0YSxcbiAgICAgIHBlcm1pc3Npb25zID0gX3JlZi5wZXJtaXNzaW9ucztcbiAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IHt9O1xuXG4gIHZhciBfcmVxdWVzdERlZmF1bHRzJG9wdGkgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHJlcXVlc3REZWZhdWx0cywgb3B0aW9ucyksXG4gICAgICBoZWFkZXJzID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpLmhlYWRlcnMsXG4gICAgICBzYWZlID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpLnNhZmU7XG5cbiAgcmV0dXJuIHtcbiAgICBtZXRob2Q6IGRhdGEgJiYgZGF0YS5pZCA/IFwiUFVUXCIgOiBcIlBPU1RcIixcbiAgICBwYXRoOiBwYXRoLFxuICAgIGhlYWRlcnM6ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgaGVhZGVycywgc2FmZUhlYWRlcihzYWZlKSksXG4gICAgYm9keToge1xuICAgICAgZGF0YTogZGF0YSxcbiAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgIH1cbiAgfTtcbn1cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuXG5cbmZ1bmN0aW9uIHVwZGF0ZVJlcXVlc3QocGF0aCwgX3JlZjIpIHtcbiAgdmFyIGRhdGEgPSBfcmVmMi5kYXRhLFxuICAgICAgcGVybWlzc2lvbnMgPSBfcmVmMi5wZXJtaXNzaW9ucztcbiAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IHt9O1xuXG4gIHZhciBfcmVxdWVzdERlZmF1bHRzJG9wdGkyID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCByZXF1ZXN0RGVmYXVsdHMsIG9wdGlvbnMpLFxuICAgICAgaGVhZGVycyA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTIuaGVhZGVycyxcbiAgICAgIHNhZmUgPSBfcmVxdWVzdERlZmF1bHRzJG9wdGkyLnNhZmUsXG4gICAgICBwYXRjaCA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTIucGF0Y2g7XG5cbiAgdmFyIF9kYXRhJG9wdGlvbnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGRhdGEsIG9wdGlvbnMpLFxuICAgICAgbGFzdF9tb2RpZmllZCA9IF9kYXRhJG9wdGlvbnMubGFzdF9tb2RpZmllZDtcblxuICBpZiAoT2JqZWN0LmtleXMoKDAsIF91dGlscy5vbWl0KShkYXRhLCBcImlkXCIsIFwibGFzdF9tb2RpZmllZFwiKSkubGVuZ3RoID09PSAwKSB7XG4gICAgZGF0YSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbWV0aG9kOiBwYXRjaCA/IFwiUEFUQ0hcIiA6IFwiUFVUXCIsXG4gICAgcGF0aDogcGF0aCxcbiAgICBoZWFkZXJzOiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGhlYWRlcnMsIHNhZmVIZWFkZXIoc2FmZSwgbGFzdF9tb2RpZmllZCkpLFxuICAgIGJvZHk6IHtcbiAgICAgIGRhdGE6IGRhdGEsXG4gICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgICB9XG4gIH07XG59XG4vKipcbiAqIEBwcml2YXRlXG4gKi9cblxuXG5mdW5jdGlvbiBqc29uUGF0Y2hQZXJtaXNzaW9uc1JlcXVlc3QocGF0aCwgcGVybWlzc2lvbnMsIG9wVHlwZSkge1xuICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDoge307XG5cbiAgdmFyIF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHJlcXVlc3REZWZhdWx0cywgb3B0aW9ucyksXG4gICAgICBoZWFkZXJzID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpMy5oZWFkZXJzLFxuICAgICAgc2FmZSA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTMuc2FmZSxcbiAgICAgIGxhc3RfbW9kaWZpZWQgPSBfcmVxdWVzdERlZmF1bHRzJG9wdGkzLmxhc3RfbW9kaWZpZWQ7XG5cbiAgdmFyIG9wcyA9IFtdO1xuXG4gIHZhciBfYXJyID0gT2JqZWN0LmVudHJpZXMocGVybWlzc2lvbnMpO1xuXG4gIGZvciAodmFyIF9pID0gMDsgX2kgPCBfYXJyLmxlbmd0aDsgX2krKykge1xuICAgIHZhciBfYXJyJF9pID0gKDAsIF9zbGljZWRUb0FycmF5Mi5kZWZhdWx0KShfYXJyW19pXSwgMiksXG4gICAgICAgIHR5cGUgPSBfYXJyJF9pWzBdLFxuICAgICAgICBwcmluY2lwYWxzID0gX2FyciRfaVsxXTtcblxuICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZTtcbiAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IgPSBmYWxzZTtcbiAgICB2YXIgX2l0ZXJhdG9yRXJyb3IgPSB1bmRlZmluZWQ7XG5cbiAgICB0cnkge1xuICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gcHJpbmNpcGFsc1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSAoX3N0ZXAgPSBfaXRlcmF0b3IubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWUpIHtcbiAgICAgICAgdmFyIHByaW5jaXBhbCA9IF9zdGVwLnZhbHVlO1xuICAgICAgICBvcHMucHVzaCh7XG4gICAgICAgICAgb3A6IG9wVHlwZSxcbiAgICAgICAgICBwYXRoOiBcIi9wZXJtaXNzaW9ucy9cIi5jb25jYXQodHlwZSwgXCIvXCIpLmNvbmNhdChwcmluY2lwYWwpXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IgPSB0cnVlO1xuICAgICAgX2l0ZXJhdG9yRXJyb3IgPSBlcnI7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiAmJiBfaXRlcmF0b3IucmV0dXJuICE9IG51bGwpIHtcbiAgICAgICAgICBfaXRlcmF0b3IucmV0dXJuKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcikge1xuICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBtZXRob2Q6IFwiUEFUQ0hcIixcbiAgICBwYXRoOiBwYXRoLFxuICAgIGhlYWRlcnM6ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgaGVhZGVycywgc2FmZUhlYWRlcihzYWZlLCBsYXN0X21vZGlmaWVkKSwge1xuICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uLXBhdGNoK2pzb25cIlxuICAgIH0pLFxuICAgIGJvZHk6IG9wc1xuICB9O1xufVxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5cblxuZnVuY3Rpb24gZGVsZXRlUmVxdWVzdChwYXRoKSB7XG4gIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICB2YXIgX3JlcXVlc3REZWZhdWx0cyRvcHRpNCA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgcmVxdWVzdERlZmF1bHRzLCBvcHRpb25zKSxcbiAgICAgIGhlYWRlcnMgPSBfcmVxdWVzdERlZmF1bHRzJG9wdGk0LmhlYWRlcnMsXG4gICAgICBzYWZlID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpNC5zYWZlLFxuICAgICAgbGFzdF9tb2RpZmllZCA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTQubGFzdF9tb2RpZmllZDtcblxuICBpZiAoc2FmZSAmJiAhbGFzdF9tb2RpZmllZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlNhZmUgY29uY3VycmVuY3kgY2hlY2sgcmVxdWlyZXMgYSBsYXN0X21vZGlmaWVkIHZhbHVlLlwiKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbWV0aG9kOiBcIkRFTEVURVwiLFxuICAgIHBhdGg6IHBhdGgsXG4gICAgaGVhZGVyczogKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBoZWFkZXJzLCBzYWZlSGVhZGVyKHNhZmUsIGxhc3RfbW9kaWZpZWQpKVxuICB9O1xufVxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5cblxuZnVuY3Rpb24gYWRkQXR0YWNobWVudFJlcXVlc3QocGF0aCwgZGF0YVVSSSkge1xuICB2YXIgX3JlZjMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IHt9LFxuICAgICAgZGF0YSA9IF9yZWYzLmRhdGEsXG4gICAgICBwZXJtaXNzaW9ucyA9IF9yZWYzLnBlcm1pc3Npb25zO1xuXG4gIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiB7fTtcblxuICB2YXIgX3JlcXVlc3REZWZhdWx0cyRvcHRpNSA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgcmVxdWVzdERlZmF1bHRzLCBvcHRpb25zKSxcbiAgICAgIGhlYWRlcnMgPSBfcmVxdWVzdERlZmF1bHRzJG9wdGk1LmhlYWRlcnMsXG4gICAgICBzYWZlID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpNS5zYWZlLFxuICAgICAgZ3ppcHBlZCA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTUuZ3ppcHBlZDtcblxuICB2YXIgX2RhdGEkb3B0aW9uczIgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGRhdGEsIG9wdGlvbnMpLFxuICAgICAgbGFzdF9tb2RpZmllZCA9IF9kYXRhJG9wdGlvbnMyLmxhc3RfbW9kaWZpZWQ7XG5cbiAgdmFyIGJvZHkgPSB7XG4gICAgZGF0YTogZGF0YSxcbiAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgfTtcbiAgdmFyIGZvcm1EYXRhID0gKDAsIF91dGlscy5jcmVhdGVGb3JtRGF0YSkoZGF0YVVSSSwgYm9keSwgb3B0aW9ucyk7XG4gIHZhciBjdXN0b21QYXRoID0gZ3ppcHBlZCAhPSBudWxsID8gY3VzdG9tUGF0aCA9IHBhdGggKyBcIj9nemlwcGVkPVwiICsgKGd6aXBwZWQgPyBcInRydWVcIiA6IFwiZmFsc2VcIikgOiBwYXRoO1xuICByZXR1cm4ge1xuICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgcGF0aDogY3VzdG9tUGF0aCxcbiAgICBoZWFkZXJzOiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGhlYWRlcnMsIHNhZmVIZWFkZXIoc2FmZSwgbGFzdF9tb2RpZmllZCkpLFxuICAgIGJvZHk6IGZvcm1EYXRhXG4gIH07XG59IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvaW50ZXJvcFJlcXVpcmVEZWZhdWx0XCIpO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5wYXJ0aXRpb24gPSBwYXJ0aXRpb247XG5leHBvcnRzLmRlbGF5ID0gZGVsYXk7XG5leHBvcnRzLnBNYXAgPSBwTWFwO1xuZXhwb3J0cy5vbWl0ID0gb21pdDtcbmV4cG9ydHMudG9EYXRhQm9keSA9IHRvRGF0YUJvZHk7XG5leHBvcnRzLnFzaWZ5ID0gcXNpZnk7XG5leHBvcnRzLmNoZWNrVmVyc2lvbiA9IGNoZWNrVmVyc2lvbjtcbmV4cG9ydHMuc3VwcG9ydCA9IHN1cHBvcnQ7XG5leHBvcnRzLmNhcGFibGUgPSBjYXBhYmxlO1xuZXhwb3J0cy5ub2JhdGNoID0gbm9iYXRjaDtcbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcbmV4cG9ydHMucGFyc2VEYXRhVVJMID0gcGFyc2VEYXRhVVJMO1xuZXhwb3J0cy5leHRyYWN0RmlsZUluZm8gPSBleHRyYWN0RmlsZUluZm87XG5leHBvcnRzLmNyZWF0ZUZvcm1EYXRhID0gY3JlYXRlRm9ybURhdGE7XG5leHBvcnRzLmNsZWFuVW5kZWZpbmVkUHJvcGVydGllcyA9IGNsZWFuVW5kZWZpbmVkUHJvcGVydGllcztcblxudmFyIF9yZWdlbmVyYXRvciA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL3JlZ2VuZXJhdG9yXCIpKTtcblxudmFyIF9kZWZpbmVQcm9wZXJ0eTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2RlZmluZVByb3BlcnR5XCIpKTtcblxudmFyIF9vYmplY3RTcHJlYWQzID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9vYmplY3RTcHJlYWRcIikpO1xuXG52YXIgX3RvQXJyYXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy90b0FycmF5XCIpKTtcblxudmFyIF90eXBlb2YyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy90eXBlb2ZcIikpO1xuXG52YXIgX3NsaWNlZFRvQXJyYXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zbGljZWRUb0FycmF5XCIpKTtcblxudmFyIF9hc3luY1RvR2VuZXJhdG9yMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYXN5bmNUb0dlbmVyYXRvclwiKSk7XG5cbi8qKlxuICogQ2h1bmtzIGFuIGFycmF5IGludG8gbiBwaWVjZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSAge0FycmF5fSAgYXJyYXlcbiAqIEBwYXJhbSAge051bWJlcn0gblxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmZ1bmN0aW9uIHBhcnRpdGlvbihhcnJheSwgbikge1xuICBpZiAobiA8PSAwKSB7XG4gICAgcmV0dXJuIGFycmF5O1xuICB9XG5cbiAgcmV0dXJuIGFycmF5LnJlZHVjZShmdW5jdGlvbiAoYWNjLCB4LCBpKSB7XG4gICAgaWYgKGkgPT09IDAgfHwgaSAlIG4gPT09IDApIHtcbiAgICAgIGFjYy5wdXNoKFt4XSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFjY1thY2MubGVuZ3RoIC0gMV0ucHVzaCh4KTtcbiAgICB9XG5cbiAgICByZXR1cm4gYWNjO1xuICB9LCBbXSk7XG59XG4vKipcbiAqIFJldHVybnMgYSBQcm9taXNlIGFsd2F5cyByZXNvbHZpbmcgYWZ0ZXIgdGhlIHNwZWNpZmllZCBhbW91bnQgaW4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIEByZXR1cm4gUHJvbWlzZTx2b2lkPlxuICovXG5cblxuZnVuY3Rpb24gZGVsYXkobXMpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgcmV0dXJuIHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpO1xuICB9KTtcbn1cbi8qKlxuICogTWFwcyBhIGxpc3QgdG8gcHJvbWlzZXMgdXNpbmcgdGhlIHByb3ZpZGVkIG1hcHBpbmcgZnVuY3Rpb24sIGV4ZWN1dGVzIHRoZW1cbiAqIHNlcXVlbnRpYWxseSB0aGVuIHJldHVybnMgYSBQcm9taXNlIHJlc29sdmluZyB3aXRoIG9yZGVyZWQgcmVzdWx0cyBvYnRhaW5lZC5cbiAqIFRoaW5rIG9mIHRoaXMgYXMgYSBzZXF1ZW50aWFsIFByb21pc2UuYWxsLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gIHtBcnJheX0gICAgbGlzdCBUaGUgbGlzdCB0byBtYXAuXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gZm4gICBUaGUgbWFwcGluZyBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKi9cblxuXG5mdW5jdGlvbiBwTWFwKF94LCBfeDIpIHtcbiAgcmV0dXJuIF9wTWFwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG4vKipcbiAqIFRha2VzIGFuIG9iamVjdCBhbmQgcmV0dXJucyBhIGNvcHkgb2YgaXQgd2l0aCB0aGUgcHJvdmlkZWQga2V5cyBvbWl0dGVkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gIHtPYmplY3R9ICAgIG9iaiAgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcGFyYW0gIHsuLi5TdHJpbmd9IGtleXMgVGhlIGtleXMgdG8gb21pdC5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuXG5cbmZ1bmN0aW9uIF9wTWFwKCkge1xuICBfcE1hcCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gIC8qI19fUFVSRV9fKi9cbiAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMihsaXN0LCBmbikge1xuICAgIHZhciByZXN1bHRzO1xuICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUyJChfY29udGV4dDIpIHtcbiAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgIHN3aXRjaCAoX2NvbnRleHQyLnByZXYgPSBfY29udGV4dDIubmV4dCkge1xuICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIF9jb250ZXh0Mi5uZXh0ID0gMztcbiAgICAgICAgICAgIHJldHVybiBsaXN0LnJlZHVjZShcbiAgICAgICAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgdmFyIF9yZWYgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgICAgICAgICAvKiNfX1BVUkVfXyovXG4gICAgICAgICAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZShwcm9taXNlLCBlbnRyeSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUkKF9jb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0LnByZXYgPSBfY29udGV4dC5uZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRleHQubmV4dCA9IDI7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcblxuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZXh0LnQwID0gcmVzdWx0cztcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSA1O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZuKGVudHJ5KTtcblxuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZXh0LnQxID0gX2NvbnRleHQuc2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBfY29udGV4dC50MC5jb25jYXQuY2FsbChfY29udGV4dC50MCwgX2NvbnRleHQudDEpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LCBfY2FsbGVlLCB0aGlzKTtcbiAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoX3gzLCBfeDQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gX3JlZi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSgpLCBQcm9taXNlLnJlc29sdmUoKSk7XG5cbiAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLmFicnVwdChcInJldHVyblwiLCByZXN1bHRzKTtcblxuICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLnN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sIF9jYWxsZWUyLCB0aGlzKTtcbiAgfSkpO1xuICByZXR1cm4gX3BNYXAuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuZnVuY3Rpb24gb21pdChvYmopIHtcbiAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGtleXMgPSBuZXcgQXJyYXkoX2xlbiA+IDEgPyBfbGVuIC0gMSA6IDApLCBfa2V5ID0gMTsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgIGtleXNbX2tleSAtIDFdID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgcmV0dXJuIE9iamVjdC5rZXlzKG9iaikucmVkdWNlKGZ1bmN0aW9uIChhY2MsIGtleSkge1xuICAgIGlmICgha2V5cy5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICBhY2Nba2V5XSA9IG9ialtrZXldO1xuICAgIH1cblxuICAgIHJldHVybiBhY2M7XG4gIH0sIHt9KTtcbn1cbi8qKlxuICogQWx3YXlzIHJldHVybnMgYSByZXNvdXJjZSBkYXRhIG9iamVjdCBmcm9tIHRoZSBwcm92aWRlZCBhcmd1bWVudC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtICB7T2JqZWN0fFN0cmluZ30gcmVzb3VyY2VcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuXG5cbmZ1bmN0aW9uIHRvRGF0YUJvZHkocmVzb3VyY2UpIHtcbiAgaWYgKGlzT2JqZWN0KHJlc291cmNlKSkge1xuICAgIHJldHVybiByZXNvdXJjZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcmVzb3VyY2UgPT09IFwic3RyaW5nXCIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHJlc291cmNlXG4gICAgfTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgYXJndW1lbnQuXCIpO1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIGFuIG9iamVjdCBpbnRvIGFuIFVSTCBxdWVyeSBzdHJpbmcsIHN0cmlwcGluZyBvdXQgYW55IHVuZGVmaW5lZFxuICogdmFsdWVzLlxuICpcbiAqIEBwYXJhbSAge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cblxuXG5mdW5jdGlvbiBxc2lmeShvYmopIHtcbiAgdmFyIGVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZSh2KSB7XG4gICAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudCh0eXBlb2YgdiA9PT0gXCJib29sZWFuXCIgPyBTdHJpbmcodikgOiB2KTtcbiAgfTtcblxuICB2YXIgc3RyaXBVbmRlZmluZWQgPSBmdW5jdGlvbiBzdHJpcFVuZGVmaW5lZChvKSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkobykpO1xuICB9O1xuXG4gIHZhciBzdHJpcHBlZCA9IHN0cmlwVW5kZWZpbmVkKG9iaik7XG4gIHJldHVybiBPYmplY3Qua2V5cyhzdHJpcHBlZCkubWFwKGZ1bmN0aW9uIChrKSB7XG4gICAgdmFyIGtzID0gZW5jb2RlKGspICsgXCI9XCI7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShzdHJpcHBlZFtrXSkpIHtcbiAgICAgIHJldHVybiBrcyArIHN0cmlwcGVkW2tdLm1hcChmdW5jdGlvbiAodikge1xuICAgICAgICByZXR1cm4gZW5jb2RlKHYpO1xuICAgICAgfSkuam9pbihcIixcIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBrcyArIGVuY29kZShzdHJpcHBlZFtrXSk7XG4gICAgfVxuICB9KS5qb2luKFwiJlwiKTtcbn1cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmVyc2lvbiBpcyB3aXRoaW4gdGhlIHByb3ZpZGVkIHJhbmdlLlxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gdmVyc2lvbiAgICBUaGUgdmVyc2lvbiB0byBjaGVjay5cbiAqIEBwYXJhbSAge1N0cmluZ30gbWluVmVyc2lvbiBUaGUgbWluaW11bSBzdXBwb3J0ZWQgdmVyc2lvbiAoaW5jbHVzaXZlKS5cbiAqIEBwYXJhbSAge1N0cmluZ30gbWF4VmVyc2lvbiBUaGUgbWluaW11bSBzdXBwb3J0ZWQgdmVyc2lvbiAoZXhjbHVzaXZlKS5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgdmVyc2lvbiBpcyBvdXRzaWRlIG9mIHRoZSBwcm92aWRlZCByYW5nZS5cbiAqL1xuXG5cbmZ1bmN0aW9uIGNoZWNrVmVyc2lvbih2ZXJzaW9uLCBtaW5WZXJzaW9uLCBtYXhWZXJzaW9uKSB7XG4gIHZhciBleHRyYWN0ID0gZnVuY3Rpb24gZXh0cmFjdChzdHIpIHtcbiAgICByZXR1cm4gc3RyLnNwbGl0KFwiLlwiKS5tYXAoZnVuY3Rpb24gKHgpIHtcbiAgICAgIHJldHVybiBwYXJzZUludCh4LCAxMCk7XG4gICAgfSk7XG4gIH07XG5cbiAgdmFyIF9leHRyYWN0ID0gZXh0cmFjdCh2ZXJzaW9uKSxcbiAgICAgIF9leHRyYWN0MiA9ICgwLCBfc2xpY2VkVG9BcnJheTIuZGVmYXVsdCkoX2V4dHJhY3QsIDIpLFxuICAgICAgdmVyTWFqb3IgPSBfZXh0cmFjdDJbMF0sXG4gICAgICB2ZXJNaW5vciA9IF9leHRyYWN0MlsxXTtcblxuICB2YXIgX2V4dHJhY3QzID0gZXh0cmFjdChtaW5WZXJzaW9uKSxcbiAgICAgIF9leHRyYWN0NCA9ICgwLCBfc2xpY2VkVG9BcnJheTIuZGVmYXVsdCkoX2V4dHJhY3QzLCAyKSxcbiAgICAgIG1pbk1ham9yID0gX2V4dHJhY3Q0WzBdLFxuICAgICAgbWluTWlub3IgPSBfZXh0cmFjdDRbMV07XG5cbiAgdmFyIF9leHRyYWN0NSA9IGV4dHJhY3QobWF4VmVyc2lvbiksXG4gICAgICBfZXh0cmFjdDYgPSAoMCwgX3NsaWNlZFRvQXJyYXkyLmRlZmF1bHQpKF9leHRyYWN0NSwgMiksXG4gICAgICBtYXhNYWpvciA9IF9leHRyYWN0NlswXSxcbiAgICAgIG1heE1pbm9yID0gX2V4dHJhY3Q2WzFdO1xuXG4gIHZhciBjaGVja3MgPSBbdmVyTWFqb3IgPCBtaW5NYWpvciwgdmVyTWFqb3IgPT09IG1pbk1ham9yICYmIHZlck1pbm9yIDwgbWluTWlub3IsIHZlck1ham9yID4gbWF4TWFqb3IsIHZlck1ham9yID09PSBtYXhNYWpvciAmJiB2ZXJNaW5vciA+PSBtYXhNaW5vcl07XG5cbiAgaWYgKGNoZWNrcy5zb21lKGZ1bmN0aW9uICh4KSB7XG4gICAgcmV0dXJuIHg7XG4gIH0pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVmVyc2lvbiBcIi5jb25jYXQodmVyc2lvbiwgXCIgZG9lc24ndCBzYXRpc2Z5IFwiKS5jb25jYXQobWluVmVyc2lvbiwgXCIgPD0geCA8IFwiKS5jb25jYXQobWF4VmVyc2lvbikpO1xuICB9XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIGRlY29yYXRvciBmdW5jdGlvbiBlbnN1cmluZyBhIHZlcnNpb24gY2hlY2sgaXMgcGVyZm9ybWVkIGFnYWluc3RcbiAqIHRoZSBwcm92aWRlZCByZXF1aXJlbWVudHMgYmVmb3JlIGV4ZWN1dGluZyBpdC5cbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG1pbiBUaGUgcmVxdWlyZWQgbWluIHZlcnNpb24gKGluY2x1c2l2ZSkuXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG1heCBUaGUgcmVxdWlyZWQgbWF4IHZlcnNpb24gKGluY2x1c2l2ZSkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5cbmZ1bmN0aW9uIHN1cHBvcnQobWluLCBtYXgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcikge1xuICAgIHZhciBmbiA9IGRlc2NyaXB0b3IudmFsdWU7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciB3cmFwcGVkTWV0aG9kID0gZnVuY3Rpb24gd3JhcHBlZE1ldGhvZCgpIHtcbiAgICAgICAgICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjIpLCBfa2V5MiA9IDA7IF9rZXkyIDwgX2xlbjI7IF9rZXkyKyspIHtcbiAgICAgICAgICAgIGFyZ3NbX2tleTJdID0gYXJndW1lbnRzW19rZXkyXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBcInRoaXNcIiBpcyB0aGUgY3VycmVudCBpbnN0YW5jZSB3aGljaCBpdHMgbWV0aG9kIGlzIGRlY29yYXRlZC5cbiAgICAgICAgICB2YXIgY2xpZW50ID0gXCJjbGllbnRcIiBpbiBfdGhpcyA/IF90aGlzLmNsaWVudCA6IF90aGlzO1xuICAgICAgICAgIHJldHVybiBjbGllbnQuZmV0Y2hIVFRQQXBpVmVyc2lvbigpLnRoZW4oZnVuY3Rpb24gKHZlcnNpb24pIHtcbiAgICAgICAgICAgIHJldHVybiBjaGVja1ZlcnNpb24odmVyc2lvbiwgbWluLCBtYXgpO1xuICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGZuLmFwcGx5KF90aGlzLCBhcmdzKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCB7XG4gICAgICAgICAgdmFsdWU6IHdyYXBwZWRNZXRob2QsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gd3JhcHBlZE1ldGhvZDtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xufVxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBkZWNvcmF0b3IgZnVuY3Rpb24gZW5zdXJpbmcgdGhhdCB0aGUgc3BlY2lmaWVkIGNhcGFiaWxpdGllcyBhcmVcbiAqIGF2YWlsYWJsZSBvbiB0aGUgc2VydmVyIGJlZm9yZSBleGVjdXRpbmcgaXQuXG4gKlxuICogQHBhcmFtICB7QXJyYXk8U3RyaW5nPn0gY2FwYWJpbGl0aWVzIFRoZSByZXF1aXJlZCBjYXBhYmlsaXRpZXMuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5cbmZ1bmN0aW9uIGNhcGFibGUoY2FwYWJpbGl0aWVzKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpIHtcbiAgICB2YXIgZm4gPSBkZXNjcmlwdG9yLnZhbHVlO1xuICAgIHJldHVybiB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHdyYXBwZWRNZXRob2QgPSBmdW5jdGlvbiB3cmFwcGVkTWV0aG9kKCkge1xuICAgICAgICAgIGZvciAodmFyIF9sZW4zID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMyksIF9rZXkzID0gMDsgX2tleTMgPCBfbGVuMzsgX2tleTMrKykge1xuICAgICAgICAgICAgYXJnc1tfa2V5M10gPSBhcmd1bWVudHNbX2tleTNdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFwidGhpc1wiIGlzIHRoZSBjdXJyZW50IGluc3RhbmNlIHdoaWNoIGl0cyBtZXRob2QgaXMgZGVjb3JhdGVkLlxuICAgICAgICAgIHZhciBjbGllbnQgPSBcImNsaWVudFwiIGluIF90aGlzMiA/IF90aGlzMi5jbGllbnQgOiBfdGhpczI7XG4gICAgICAgICAgcmV0dXJuIGNsaWVudC5mZXRjaFNlcnZlckNhcGFiaWxpdGllcygpLnRoZW4oZnVuY3Rpb24gKGF2YWlsYWJsZSkge1xuICAgICAgICAgICAgdmFyIG1pc3NpbmcgPSBjYXBhYmlsaXRpZXMuZmlsdGVyKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgICAgIHJldHVybiAhKGMgaW4gYXZhaWxhYmxlKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAobWlzc2luZy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIHZhciBtaXNzaW5nU3RyID0gbWlzc2luZy5qb2luKFwiLCBcIik7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlcXVpcmVkIGNhcGFiaWxpdGllcyBcIi5jb25jYXQobWlzc2luZ1N0ciwgXCIgbm90IHByZXNlbnQgb24gc2VydmVyXCIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseShfdGhpczIsIGFyZ3MpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBrZXksIHtcbiAgICAgICAgICB2YWx1ZTogd3JhcHBlZE1ldGhvZCxcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB3cmFwcGVkTWV0aG9kO1xuICAgICAgfVxuICAgIH07XG4gIH07XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIGRlY29yYXRvciBmdW5jdGlvbiBlbnN1cmluZyBhbiBvcGVyYXRpb24gaXMgbm90IHBlcmZvcm1lZCBmcm9tXG4gKiB3aXRoaW4gYSBiYXRjaCByZXF1ZXN0LlxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZSB0byB0aHJvdy5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5cblxuZnVuY3Rpb24gbm9iYXRjaChtZXNzYWdlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpIHtcbiAgICB2YXIgZm4gPSBkZXNjcmlwdG9yLnZhbHVlO1xuICAgIHJldHVybiB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgICAgdmFyIF90aGlzMyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHdyYXBwZWRNZXRob2QgPSBmdW5jdGlvbiB3cmFwcGVkTWV0aG9kKCkge1xuICAgICAgICAgIC8vIFwidGhpc1wiIGlzIHRoZSBjdXJyZW50IGluc3RhbmNlIHdoaWNoIGl0cyBtZXRob2QgaXMgZGVjb3JhdGVkLlxuICAgICAgICAgIGlmIChfdGhpczMuX2lzQmF0Y2gpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IgKHZhciBfbGVuNCA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjQpLCBfa2V5NCA9IDA7IF9rZXk0IDwgX2xlbjQ7IF9rZXk0KyspIHtcbiAgICAgICAgICAgIGFyZ3NbX2tleTRdID0gYXJndW1lbnRzW19rZXk0XTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZm4uYXBwbHkoX3RoaXMzLCBhcmdzKTtcbiAgICAgICAgfTtcblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCB7XG4gICAgICAgICAgdmFsdWU6IHdyYXBwZWRNZXRob2QsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gd3JhcHBlZE1ldGhvZDtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xufVxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhbiBvYmplY3QgKGkuZS4gbm90IGFuIGFycmF5IG5vciBudWxsKS5cbiAqIEBwYXJhbSAge09iamVjdH0gdGhpbmcgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gKiBAcmV0dXJuIHtib29sfVxuICovXG5cblxuZnVuY3Rpb24gaXNPYmplY3QodGhpbmcpIHtcbiAgcmV0dXJuICgwLCBfdHlwZW9mMi5kZWZhdWx0KSh0aGluZykgPT09IFwib2JqZWN0XCIgJiYgdGhpbmcgIT09IG51bGwgJiYgIUFycmF5LmlzQXJyYXkodGhpbmcpO1xufVxuLyoqXG4gKiBQYXJzZXMgYSBkYXRhIHVybC5cbiAqIEBwYXJhbSAge1N0cmluZ30gZGF0YVVSTCBUaGUgZGF0YSB1cmwuXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cblxuXG5mdW5jdGlvbiBwYXJzZURhdGFVUkwoZGF0YVVSTCkge1xuICB2YXIgcmVnZXggPSAvXmRhdGE6KC4qKTtiYXNlNjQsKC4qKS87XG4gIHZhciBtYXRjaCA9IGRhdGFVUkwubWF0Y2gocmVnZXgpO1xuXG4gIGlmICghbWF0Y2gpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGRhdGEtdXJsOiBcIi5jb25jYXQoU3RyaW5nKGRhdGFVUkwpLnN1YnN0cigwLCAzMiksIFwiLi4uXCIpKTtcbiAgfVxuXG4gIHZhciBwcm9wcyA9IG1hdGNoWzFdO1xuICB2YXIgYmFzZTY0ID0gbWF0Y2hbMl07XG5cbiAgdmFyIF9wcm9wcyRzcGxpdCA9IHByb3BzLnNwbGl0KFwiO1wiKSxcbiAgICAgIF9wcm9wcyRzcGxpdDIgPSAoMCwgX3RvQXJyYXkyLmRlZmF1bHQpKF9wcm9wcyRzcGxpdCksXG4gICAgICB0eXBlID0gX3Byb3BzJHNwbGl0MlswXSxcbiAgICAgIHJhd1BhcmFtcyA9IF9wcm9wcyRzcGxpdDIuc2xpY2UoMSk7XG5cbiAgdmFyIHBhcmFtcyA9IHJhd1BhcmFtcy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgcGFyYW0pIHtcbiAgICB2YXIgX3BhcmFtJHNwbGl0ID0gcGFyYW0uc3BsaXQoXCI9XCIpLFxuICAgICAgICBfcGFyYW0kc3BsaXQyID0gKDAsIF9zbGljZWRUb0FycmF5Mi5kZWZhdWx0KShfcGFyYW0kc3BsaXQsIDIpLFxuICAgICAgICBrZXkgPSBfcGFyYW0kc3BsaXQyWzBdLFxuICAgICAgICB2YWx1ZSA9IF9wYXJhbSRzcGxpdDJbMV07XG5cbiAgICByZXR1cm4gKDAsIF9vYmplY3RTcHJlYWQzLmRlZmF1bHQpKHt9LCBhY2MsICgwLCBfZGVmaW5lUHJvcGVydHkyLmRlZmF1bHQpKHt9LCBrZXksIHZhbHVlKSk7XG4gIH0sIHt9KTtcbiAgcmV0dXJuICgwLCBfb2JqZWN0U3ByZWFkMy5kZWZhdWx0KSh7fSwgcGFyYW1zLCB7XG4gICAgdHlwZTogdHlwZSxcbiAgICBiYXNlNjQ6IGJhc2U2NFxuICB9KTtcbn1cbi8qKlxuICogRXh0cmFjdHMgZmlsZSBpbmZvcm1hdGlvbiBmcm9tIGEgZGF0YSB1cmwuXG4gKiBAcGFyYW0gIHtTdHJpbmd9IGRhdGFVUkwgVGhlIGRhdGEgdXJsLlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5cblxuZnVuY3Rpb24gZXh0cmFjdEZpbGVJbmZvKGRhdGFVUkwpIHtcbiAgdmFyIF9wYXJzZURhdGFVUkwgPSBwYXJzZURhdGFVUkwoZGF0YVVSTCksXG4gICAgICBuYW1lID0gX3BhcnNlRGF0YVVSTC5uYW1lLFxuICAgICAgdHlwZSA9IF9wYXJzZURhdGFVUkwudHlwZSxcbiAgICAgIGJhc2U2NCA9IF9wYXJzZURhdGFVUkwuYmFzZTY0O1xuXG4gIHZhciBiaW5hcnkgPSBhdG9iKGJhc2U2NCk7XG4gIHZhciBhcnJheSA9IFtdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYmluYXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgYXJyYXkucHVzaChiaW5hcnkuY2hhckNvZGVBdChpKSk7XG4gIH1cblxuICB2YXIgYmxvYiA9IG5ldyBCbG9iKFtuZXcgVWludDhBcnJheShhcnJheSldLCB7XG4gICAgdHlwZTogdHlwZVxuICB9KTtcbiAgcmV0dXJuIHtcbiAgICBibG9iOiBibG9iLFxuICAgIG5hbWU6IG5hbWVcbiAgfTtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIEZvcm1EYXRhIGluc3RhbmNlIGZyb20gYSBkYXRhIHVybCBhbmQgYW4gZXhpc3RpbmcgSlNPTiByZXNwb25zZVxuICogYm9keS5cbiAqIEBwYXJhbSAge1N0cmluZ30gZGF0YVVSTCAgICAgICAgICAgIFRoZSBkYXRhIHVybC5cbiAqIEBwYXJhbSAge09iamVjdH0gYm9keSAgICAgICAgICAgICAgIFRoZSByZXNwb25zZSBib2R5LlxuICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5maWxlbmFtZV0gRm9yY2UgYXR0YWNobWVudCBmaWxlIG5hbWUuXG4gKiBAcmV0dXJuIHtGb3JtRGF0YX1cbiAqL1xuXG5cbmZ1bmN0aW9uIGNyZWF0ZUZvcm1EYXRhKGRhdGFVUkwsIGJvZHkpIHtcbiAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IHt9O1xuICB2YXIgX29wdGlvbnMkZmlsZW5hbWUgPSBvcHRpb25zLmZpbGVuYW1lLFxuICAgICAgZmlsZW5hbWUgPSBfb3B0aW9ucyRmaWxlbmFtZSA9PT0gdm9pZCAwID8gXCJ1bnRpdGxlZFwiIDogX29wdGlvbnMkZmlsZW5hbWU7XG5cbiAgdmFyIF9leHRyYWN0RmlsZUluZm8gPSBleHRyYWN0RmlsZUluZm8oZGF0YVVSTCksXG4gICAgICBibG9iID0gX2V4dHJhY3RGaWxlSW5mby5ibG9iLFxuICAgICAgbmFtZSA9IF9leHRyYWN0RmlsZUluZm8ubmFtZTtcblxuICB2YXIgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcbiAgZm9ybURhdGEuYXBwZW5kKFwiYXR0YWNobWVudFwiLCBibG9iLCBuYW1lIHx8IGZpbGVuYW1lKTtcblxuICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBib2R5KSB7XG4gICAgaWYgKHR5cGVvZiBib2R5W3Byb3BlcnR5XSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgZm9ybURhdGEuYXBwZW5kKHByb3BlcnR5LCBKU09OLnN0cmluZ2lmeShib2R5W3Byb3BlcnR5XSkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmb3JtRGF0YTtcbn1cbi8qKlxuICogQ2xvbmVzIGFuIG9iamVjdCB3aXRoIGFsbCBpdHMgdW5kZWZpbmVkIGtleXMgcmVtb3ZlZC5cbiAqIEBwcml2YXRlXG4gKi9cblxuXG5mdW5jdGlvbiBjbGVhblVuZGVmaW5lZFByb3BlcnRpZXMob2JqKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcblxuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKHR5cGVvZiBvYmpba2V5XSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgcmVzdWx0W2tleV0gPSBvYmpba2V5XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufSIsInZhciB2MSA9IHJlcXVpcmUoJy4vdjEnKTtcbnZhciB2NCA9IHJlcXVpcmUoJy4vdjQnKTtcblxudmFyIHV1aWQgPSB2NDtcbnV1aWQudjEgPSB2MTtcbnV1aWQudjQgPSB2NDtcblxubW9kdWxlLmV4cG9ydHMgPSB1dWlkO1xuIiwiLyoqXG4gKiBDb252ZXJ0IGFycmF5IG9mIDE2IGJ5dGUgdmFsdWVzIHRvIFVVSUQgc3RyaW5nIGZvcm1hdCBvZiB0aGUgZm9ybTpcbiAqIFhYWFhYWFhYLVhYWFgtWFhYWC1YWFhYLVhYWFhYWFhYWFhYWFxuICovXG52YXIgYnl0ZVRvSGV4ID0gW107XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKSB7XG4gIGJ5dGVUb0hleFtpXSA9IChpICsgMHgxMDApLnRvU3RyaW5nKDE2KS5zdWJzdHIoMSk7XG59XG5cbmZ1bmN0aW9uIGJ5dGVzVG9VdWlkKGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gb2Zmc2V0IHx8IDA7XG4gIHZhciBidGggPSBieXRlVG9IZXg7XG4gIC8vIGpvaW4gdXNlZCB0byBmaXggbWVtb3J5IGlzc3VlIGNhdXNlZCBieSBjb25jYXRlbmF0aW9uOiBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMTc1I2M0XG4gIHJldHVybiAoW2J0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sIFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV1dKS5qb2luKCcnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBieXRlc1RvVXVpZDtcbiIsIi8vIFVuaXF1ZSBJRCBjcmVhdGlvbiByZXF1aXJlcyBhIGhpZ2ggcXVhbGl0eSByYW5kb20gIyBnZW5lcmF0b3IuICBJbiB0aGVcbi8vIGJyb3dzZXIgdGhpcyBpcyBhIGxpdHRsZSBjb21wbGljYXRlZCBkdWUgdG8gdW5rbm93biBxdWFsaXR5IG9mIE1hdGgucmFuZG9tKClcbi8vIGFuZCBpbmNvbnNpc3RlbnQgc3VwcG9ydCBmb3IgdGhlIGBjcnlwdG9gIEFQSS4gIFdlIGRvIHRoZSBiZXN0IHdlIGNhbiB2aWFcbi8vIGZlYXR1cmUtZGV0ZWN0aW9uXG5cbi8vIGdldFJhbmRvbVZhbHVlcyBuZWVkcyB0byBiZSBpbnZva2VkIGluIGEgY29udGV4dCB3aGVyZSBcInRoaXNcIiBpcyBhIENyeXB0b1xuLy8gaW1wbGVtZW50YXRpb24uIEFsc28sIGZpbmQgdGhlIGNvbXBsZXRlIGltcGxlbWVudGF0aW9uIG9mIGNyeXB0byBvbiBJRTExLlxudmFyIGdldFJhbmRvbVZhbHVlcyA9ICh0eXBlb2YoY3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzICYmIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMuYmluZChjcnlwdG8pKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICh0eXBlb2YobXNDcnlwdG8pICE9ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3cubXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzID09ICdmdW5jdGlvbicgJiYgbXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQobXNDcnlwdG8pKTtcblxuaWYgKGdldFJhbmRvbVZhbHVlcykge1xuICAvLyBXSEFUV0cgY3J5cHRvIFJORyAtIGh0dHA6Ly93aWtpLndoYXR3Zy5vcmcvd2lraS9DcnlwdG9cbiAgdmFyIHJuZHM4ID0gbmV3IFVpbnQ4QXJyYXkoMTYpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB3aGF0d2dSTkcoKSB7XG4gICAgZ2V0UmFuZG9tVmFsdWVzKHJuZHM4KTtcbiAgICByZXR1cm4gcm5kczg7XG4gIH07XG59IGVsc2Uge1xuICAvLyBNYXRoLnJhbmRvbSgpLWJhc2VkIChSTkcpXG4gIC8vXG4gIC8vIElmIGFsbCBlbHNlIGZhaWxzLCB1c2UgTWF0aC5yYW5kb20oKS4gIEl0J3MgZmFzdCwgYnV0IGlzIG9mIHVuc3BlY2lmaWVkXG4gIC8vIHF1YWxpdHkuXG4gIHZhciBybmRzID0gbmV3IEFycmF5KDE2KTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG1hdGhSTkcoKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIHI7IGkgPCAxNjsgaSsrKSB7XG4gICAgICBpZiAoKGkgJiAweDAzKSA9PT0gMCkgciA9IE1hdGgucmFuZG9tKCkgKiAweDEwMDAwMDAwMDtcbiAgICAgIHJuZHNbaV0gPSByID4+PiAoKGkgJiAweDAzKSA8PCAzKSAmIDB4ZmY7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJuZHM7XG4gIH07XG59XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG4vLyAqKmB2MSgpYCAtIEdlbmVyYXRlIHRpbWUtYmFzZWQgVVVJRCoqXG4vL1xuLy8gSW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL0xpb3NLL1VVSUQuanNcbi8vIGFuZCBodHRwOi8vZG9jcy5weXRob24ub3JnL2xpYnJhcnkvdXVpZC5odG1sXG5cbnZhciBfbm9kZUlkO1xudmFyIF9jbG9ja3NlcTtcblxuLy8gUHJldmlvdXMgdXVpZCBjcmVhdGlvbiB0aW1lXG52YXIgX2xhc3RNU2VjcyA9IDA7XG52YXIgX2xhc3ROU2VjcyA9IDA7XG5cbi8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYnJvb2ZhL25vZGUtdXVpZCBmb3IgQVBJIGRldGFpbHNcbmZ1bmN0aW9uIHYxKG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuICB2YXIgYiA9IGJ1ZiB8fCBbXTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgdmFyIG5vZGUgPSBvcHRpb25zLm5vZGUgfHwgX25vZGVJZDtcbiAgdmFyIGNsb2Nrc2VxID0gb3B0aW9ucy5jbG9ja3NlcSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jbG9ja3NlcSA6IF9jbG9ja3NlcTtcblxuICAvLyBub2RlIGFuZCBjbG9ja3NlcSBuZWVkIHRvIGJlIGluaXRpYWxpemVkIHRvIHJhbmRvbSB2YWx1ZXMgaWYgdGhleSdyZSBub3RcbiAgLy8gc3BlY2lmaWVkLiAgV2UgZG8gdGhpcyBsYXppbHkgdG8gbWluaW1pemUgaXNzdWVzIHJlbGF0ZWQgdG8gaW5zdWZmaWNpZW50XG4gIC8vIHN5c3RlbSBlbnRyb3B5LiAgU2VlICMxODlcbiAgaWYgKG5vZGUgPT0gbnVsbCB8fCBjbG9ja3NlcSA9PSBudWxsKSB7XG4gICAgdmFyIHNlZWRCeXRlcyA9IHJuZygpO1xuICAgIGlmIChub2RlID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjUsIGNyZWF0ZSBhbmQgNDgtYml0IG5vZGUgaWQsICg0NyByYW5kb20gYml0cyArIG11bHRpY2FzdCBiaXQgPSAxKVxuICAgICAgbm9kZSA9IF9ub2RlSWQgPSBbXG4gICAgICAgIHNlZWRCeXRlc1swXSB8IDB4MDEsXG4gICAgICAgIHNlZWRCeXRlc1sxXSwgc2VlZEJ5dGVzWzJdLCBzZWVkQnl0ZXNbM10sIHNlZWRCeXRlc1s0XSwgc2VlZEJ5dGVzWzVdXG4gICAgICBdO1xuICAgIH1cbiAgICBpZiAoY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgICAgLy8gUGVyIDQuMi4yLCByYW5kb21pemUgKDE0IGJpdCkgY2xvY2tzZXFcbiAgICAgIGNsb2Nrc2VxID0gX2Nsb2Nrc2VxID0gKHNlZWRCeXRlc1s2XSA8PCA4IHwgc2VlZEJ5dGVzWzddKSAmIDB4M2ZmZjtcbiAgICB9XG4gIH1cblxuICAvLyBVVUlEIHRpbWVzdGFtcHMgYXJlIDEwMCBuYW5vLXNlY29uZCB1bml0cyBzaW5jZSB0aGUgR3JlZ29yaWFuIGVwb2NoLFxuICAvLyAoMTU4Mi0xMC0xNSAwMDowMCkuICBKU051bWJlcnMgYXJlbid0IHByZWNpc2UgZW5vdWdoIGZvciB0aGlzLCBzb1xuICAvLyB0aW1lIGlzIGhhbmRsZWQgaW50ZXJuYWxseSBhcyAnbXNlY3MnIChpbnRlZ2VyIG1pbGxpc2Vjb25kcykgYW5kICduc2VjcydcbiAgLy8gKDEwMC1uYW5vc2Vjb25kcyBvZmZzZXQgZnJvbSBtc2Vjcykgc2luY2UgdW5peCBlcG9jaCwgMTk3MC0wMS0wMSAwMDowMC5cbiAgdmFyIG1zZWNzID0gb3B0aW9ucy5tc2VjcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5tc2VjcyA6IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gIC8vIFBlciA0LjIuMS4yLCB1c2UgY291bnQgb2YgdXVpZCdzIGdlbmVyYXRlZCBkdXJpbmcgdGhlIGN1cnJlbnQgY2xvY2tcbiAgLy8gY3ljbGUgdG8gc2ltdWxhdGUgaGlnaGVyIHJlc29sdXRpb24gY2xvY2tcbiAgdmFyIG5zZWNzID0gb3B0aW9ucy5uc2VjcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5uc2VjcyA6IF9sYXN0TlNlY3MgKyAxO1xuXG4gIC8vIFRpbWUgc2luY2UgbGFzdCB1dWlkIGNyZWF0aW9uIChpbiBtc2VjcylcbiAgdmFyIGR0ID0gKG1zZWNzIC0gX2xhc3RNU2VjcykgKyAobnNlY3MgLSBfbGFzdE5TZWNzKS8xMDAwMDtcblxuICAvLyBQZXIgNC4yLjEuMiwgQnVtcCBjbG9ja3NlcSBvbiBjbG9jayByZWdyZXNzaW9uXG4gIGlmIChkdCA8IDAgJiYgb3B0aW9ucy5jbG9ja3NlcSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY2xvY2tzZXEgPSBjbG9ja3NlcSArIDEgJiAweDNmZmY7XG4gIH1cblxuICAvLyBSZXNldCBuc2VjcyBpZiBjbG9jayByZWdyZXNzZXMgKG5ldyBjbG9ja3NlcSkgb3Igd2UndmUgbW92ZWQgb250byBhIG5ld1xuICAvLyB0aW1lIGludGVydmFsXG4gIGlmICgoZHQgPCAwIHx8IG1zZWNzID4gX2xhc3RNU2VjcykgJiYgb3B0aW9ucy5uc2VjcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbnNlY3MgPSAwO1xuICB9XG5cbiAgLy8gUGVyIDQuMi4xLjIgVGhyb3cgZXJyb3IgaWYgdG9vIG1hbnkgdXVpZHMgYXJlIHJlcXVlc3RlZFxuICBpZiAobnNlY3MgPj0gMTAwMDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3V1aWQudjEoKTogQ2FuXFwndCBjcmVhdGUgbW9yZSB0aGFuIDEwTSB1dWlkcy9zZWMnKTtcbiAgfVxuXG4gIF9sYXN0TVNlY3MgPSBtc2VjcztcbiAgX2xhc3ROU2VjcyA9IG5zZWNzO1xuICBfY2xvY2tzZXEgPSBjbG9ja3NlcTtcblxuICAvLyBQZXIgNC4xLjQgLSBDb252ZXJ0IGZyb20gdW5peCBlcG9jaCB0byBHcmVnb3JpYW4gZXBvY2hcbiAgbXNlY3MgKz0gMTIyMTkyOTI4MDAwMDA7XG5cbiAgLy8gYHRpbWVfbG93YFxuICB2YXIgdGwgPSAoKG1zZWNzICYgMHhmZmZmZmZmKSAqIDEwMDAwICsgbnNlY3MpICUgMHgxMDAwMDAwMDA7XG4gIGJbaSsrXSA9IHRsID4+PiAyNCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsID4+PiAxNiAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdGwgJiAweGZmO1xuXG4gIC8vIGB0aW1lX21pZGBcbiAgdmFyIHRtaCA9IChtc2VjcyAvIDB4MTAwMDAwMDAwICogMTAwMDApICYgMHhmZmZmZmZmO1xuICBiW2krK10gPSB0bWggPj4+IDggJiAweGZmO1xuICBiW2krK10gPSB0bWggJiAweGZmO1xuXG4gIC8vIGB0aW1lX2hpZ2hfYW5kX3ZlcnNpb25gXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMjQgJiAweGYgfCAweDEwOyAvLyBpbmNsdWRlIHZlcnNpb25cbiAgYltpKytdID0gdG1oID4+PiAxNiAmIDB4ZmY7XG5cbiAgLy8gYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgIChQZXIgNC4yLjIgLSBpbmNsdWRlIHZhcmlhbnQpXG4gIGJbaSsrXSA9IGNsb2Nrc2VxID4+PiA4IHwgMHg4MDtcblxuICAvLyBgY2xvY2tfc2VxX2xvd2BcbiAgYltpKytdID0gY2xvY2tzZXEgJiAweGZmO1xuXG4gIC8vIGBub2RlYFxuICBmb3IgKHZhciBuID0gMDsgbiA8IDY7ICsrbikge1xuICAgIGJbaSArIG5dID0gbm9kZVtuXTtcbiAgfVxuXG4gIHJldHVybiBidWYgPyBidWYgOiBieXRlc1RvVXVpZChiKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB2MTtcbiIsInZhciBybmcgPSByZXF1aXJlKCcuL2xpYi9ybmcnKTtcbnZhciBieXRlc1RvVXVpZCA9IHJlcXVpcmUoJy4vbGliL2J5dGVzVG9VdWlkJyk7XG5cbmZ1bmN0aW9uIHY0KG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuXG4gIGlmICh0eXBlb2Yob3B0aW9ucykgPT0gJ3N0cmluZycpIHtcbiAgICBidWYgPSBvcHRpb25zID09PSAnYmluYXJ5JyA/IG5ldyBBcnJheSgxNikgOiBudWxsO1xuICAgIG9wdGlvbnMgPSBudWxsO1xuICB9XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHZhciBybmRzID0gb3B0aW9ucy5yYW5kb20gfHwgKG9wdGlvbnMucm5nIHx8IHJuZykoKTtcblxuICAvLyBQZXIgNC40LCBzZXQgYml0cyBmb3IgdmVyc2lvbiBhbmQgYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgXG4gIHJuZHNbNl0gPSAocm5kc1s2XSAmIDB4MGYpIHwgMHg0MDtcbiAgcm5kc1s4XSA9IChybmRzWzhdICYgMHgzZikgfCAweDgwO1xuXG4gIC8vIENvcHkgYnl0ZXMgdG8gYnVmZmVyLCBpZiBwcm92aWRlZFxuICBpZiAoYnVmKSB7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IDE2OyArK2lpKSB7XG4gICAgICBidWZbaSArIGlpXSA9IHJuZHNbaWldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWYgfHwgYnl0ZXNUb1V1aWQocm5kcyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjQ7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IENvbGxlY3Rpb24gZnJvbSBcIi4vY29sbGVjdGlvblwiO1xuaW1wb3J0IEJhc2VBZGFwdGVyIGZyb20gXCIuL2FkYXB0ZXJzL2Jhc2VcIjtcblxuY29uc3QgREVGQVVMVF9CVUNLRVRfTkFNRSA9IFwiZGVmYXVsdFwiO1xuY29uc3QgREVGQVVMVF9SRU1PVEUgPSBcImh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC92MVwiO1xuY29uc3QgREVGQVVMVF9SRVRSWSA9IDE7XG5cbi8qKlxuICogS2ludG9CYXNlIGNsYXNzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBLaW50b0Jhc2Uge1xuICAvKipcbiAgICogUHJvdmlkZXMgYSBwdWJsaWMgYWNjZXNzIHRvIHRoZSBiYXNlIGFkYXB0ZXIgY2xhc3MuIFVzZXJzIGNhbiBjcmVhdGUgYVxuICAgKiBjdXN0b20gREIgYWRhcHRlciBieSBleHRlbmRpbmcge0BsaW5rIEJhc2VBZGFwdGVyfS5cbiAgICpcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgYWRhcHRlcnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIEJhc2VBZGFwdGVyOiBCYXNlQWRhcHRlcixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFN5bmNocm9uaXphdGlvbiBzdHJhdGVnaWVzLiBBdmFpbGFibGUgc3RyYXRlZ2llcyBhcmU6XG4gICAqXG4gICAqIC0gYE1BTlVBTGA6IENvbmZsaWN0cyB3aWxsIGJlIHJlcG9ydGVkIGluIGEgZGVkaWNhdGVkIGFycmF5LlxuICAgKiAtIGBTRVJWRVJfV0lOU2A6IENvbmZsaWN0cyBhcmUgcmVzb2x2ZWQgdXNpbmcgcmVtb3RlIGRhdGEuXG4gICAqIC0gYENMSUVOVF9XSU5TYDogQ29uZmxpY3RzIGFyZSByZXNvbHZlZCB1c2luZyBsb2NhbCBkYXRhLlxuICAgKlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgc3RhdGljIGdldCBzeW5jU3RyYXRlZ3koKSB7XG4gICAgcmV0dXJuIENvbGxlY3Rpb24uc3RyYXRlZ3k7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0b3IuXG4gICAqXG4gICAqIE9wdGlvbnM6XG4gICAqIC0gYHtTdHJpbmd9YCAgICAgICBgcmVtb3RlYCAgICAgICAgIFRoZSBzZXJ2ZXIgVVJMIHRvIHVzZS5cbiAgICogLSBge1N0cmluZ31gICAgICAgIGBidWNrZXRgICAgICAgICAgVGhlIGNvbGxlY3Rpb24gYnVja2V0IG5hbWUuXG4gICAqIC0gYHtFdmVudEVtaXR0ZXJ9YCBgZXZlbnRzYCAgICAgICAgIEV2ZW50cyBoYW5kbGVyLlxuICAgKiAtIGB7QmFzZUFkYXB0ZXJ9YCAgYGFkYXB0ZXJgICAgICAgICBUaGUgYmFzZSBEQiBhZGFwdGVyIGNsYXNzLlxuICAgKiAtIGB7T2JqZWN0fWAgICAgICAgYGFkYXB0ZXJPcHRpb25zYCBPcHRpb25zIGdpdmVuIHRvIHRoZSBhZGFwdGVyLlxuICAgKiAtIGB7T2JqZWN0fWAgICAgICAgYGhlYWRlcnNgICAgICAgICBUaGUgSFRUUCBoZWFkZXJzIHRvIHVzZS5cbiAgICogLSBge09iamVjdH1gICAgICAgIGByZXRyeWAgICAgICAgICAgTnVtYmVyIG9mIHJldHJpZXMgd2hlbiB0aGUgc2VydmVyIGZhaWxzIHRvIHByb2Nlc3MgdGhlIHJlcXVlc3QgKGRlZmF1bHQ6IGAxYClcbiAgICogLSBge1N0cmluZ31gICAgICAgIGByZXF1ZXN0TW9kZWAgICAgVGhlIEhUVFAgQ09SUyBtb2RlIHRvIHVzZS5cbiAgICogLSBge051bWJlcn1gICAgICAgIGB0aW1lb3V0YCAgICAgICAgVGhlIHJlcXVlc3RzIHRpbWVvdXQgaW4gbXMgKGRlZmF1bHQ6IGA1MDAwYCkuXG4gICAqXG4gICAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9ucyBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBkZWZhdWx0cyA9IHtcbiAgICAgIGJ1Y2tldDogREVGQVVMVF9CVUNLRVRfTkFNRSxcbiAgICAgIHJlbW90ZTogREVGQVVMVF9SRU1PVEUsXG4gICAgICByZXRyeTogREVGQVVMVF9SRVRSWSxcbiAgICB9O1xuICAgIHRoaXMuX29wdGlvbnMgPSB7IC4uLmRlZmF1bHRzLCAuLi5vcHRpb25zIH07XG4gICAgaWYgKCF0aGlzLl9vcHRpb25zLmFkYXB0ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGFkYXB0ZXIgcHJvdmlkZWRcIik7XG4gICAgfVxuXG4gICAgY29uc3Qge1xuICAgICAgQXBpQ2xhc3MsXG4gICAgICBldmVudHMsXG4gICAgICBoZWFkZXJzLFxuICAgICAgcmVtb3RlLFxuICAgICAgcmVxdWVzdE1vZGUsXG4gICAgICByZXRyeSxcbiAgICAgIHRpbWVvdXQsXG4gICAgfSA9IHRoaXMuX29wdGlvbnM7XG5cbiAgICAvLyBwdWJsaWMgcHJvcGVydGllc1xuXG4gICAgLyoqXG4gICAgICogVGhlIGtpbnRvIEhUVFAgY2xpZW50IGluc3RhbmNlLlxuICAgICAqIEB0eXBlIHtLaW50b0NsaWVudH1cbiAgICAgKi9cbiAgICB0aGlzLmFwaSA9IG5ldyBBcGlDbGFzcyhyZW1vdGUsIHtcbiAgICAgIGV2ZW50cyxcbiAgICAgIGhlYWRlcnMsXG4gICAgICByZXF1ZXN0TW9kZSxcbiAgICAgIHJldHJ5LFxuICAgICAgdGltZW91dCxcbiAgICB9KTtcbiAgICAvKipcbiAgICAgKiBUaGUgZXZlbnQgZW1pdHRlciBpbnN0YW5jZS5cbiAgICAgKiBAdHlwZSB7RXZlbnRFbWl0dGVyfVxuICAgICAqL1xuICAgIHRoaXMuZXZlbnRzID0gdGhpcy5fb3B0aW9ucy5ldmVudHM7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHtAbGluayBDb2xsZWN0aW9ufSBpbnN0YW5jZS4gVGhlIHNlY29uZCAob3B0aW9uYWwpIHBhcmFtZXRlclxuICAgKiB3aWxsIHNldCBjb2xsZWN0aW9uLWxldmVsIG9wdGlvbnMgbGlrZSBlLmcuIGByZW1vdGVUcmFuc2Zvcm1lcnNgLlxuICAgKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGNvbGxOYW1lIFRoZSBjb2xsZWN0aW9uIG5hbWUuXG4gICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnM9e31dICAgICAgICAgICAgICAgICBFeHRyYSBvcHRpb25zIG9yIG92ZXJyaWRlIGNsaWVudCdzIG9wdGlvbnMuXG4gICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMuaWRTY2hlbWFdICAgICAgICAgICBJZFNjaGVtYSBpbnN0YW5jZSAoZGVmYXVsdDogVVVJRClcbiAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5yZW1vdGVUcmFuc2Zvcm1lcnNdIEFycmF5PFJlbW90ZVRyYW5zZm9ybWVyPiAoZGVmYXVsdDogYFtdYF0pXG4gICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMuaG9va3NdICAgICAgICAgICAgICBBcnJheTxIb29rPiAoZGVmYXVsdDogYFtdYF0pXG4gICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMubG9jYWxGaWVsZHNdICAgICAgICBBcnJheTxGaWVsZD4gKGRlZmF1bHQ6IGBbXWBdKVxuICAgKiBAcmV0dXJuIHtDb2xsZWN0aW9ufVxuICAgKi9cbiAgY29sbGVjdGlvbihjb2xsTmFtZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCFjb2xsTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwibWlzc2luZyBjb2xsZWN0aW9uIG5hbWVcIik7XG4gICAgfVxuICAgIGNvbnN0IHsgYnVja2V0LCBldmVudHMsIGFkYXB0ZXIsIGFkYXB0ZXJPcHRpb25zIH0gPSB7XG4gICAgICAuLi50aGlzLl9vcHRpb25zLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9O1xuICAgIGNvbnN0IHsgaWRTY2hlbWEsIHJlbW90ZVRyYW5zZm9ybWVycywgaG9va3MsIGxvY2FsRmllbGRzIH0gPSBvcHRpb25zO1xuXG4gICAgcmV0dXJuIG5ldyBDb2xsZWN0aW9uKGJ1Y2tldCwgY29sbE5hbWUsIHRoaXMuYXBpLCB7XG4gICAgICBldmVudHMsXG4gICAgICBhZGFwdGVyLFxuICAgICAgYWRhcHRlck9wdGlvbnMsXG4gICAgICBpZFNjaGVtYSxcbiAgICAgIHJlbW90ZVRyYW5zZm9ybWVycyxcbiAgICAgIGhvb2tzLFxuICAgICAgbG9jYWxGaWVsZHMsXG4gICAgfSk7XG4gIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgQmFzZUFkYXB0ZXIgZnJvbSBcIi4vYmFzZS5qc1wiO1xuaW1wb3J0IHtcbiAgZmlsdGVyT2JqZWN0LFxuICBvbWl0S2V5cyxcbiAgc29ydE9iamVjdHMsXG4gIGFycmF5RXF1YWwsXG4gIHRyYW5zZm9ybVN1Yk9iamVjdEZpbHRlcnMsXG59IGZyb20gXCIuLi91dGlsc1wiO1xuXG5jb25zdCBJTkRFWEVEX0ZJRUxEUyA9IFtcImlkXCIsIFwiX3N0YXR1c1wiLCBcImxhc3RfbW9kaWZpZWRcIl07XG5cbi8qKlxuICogU21hbGwgaGVscGVyIHRoYXQgd3JhcHMgdGhlIG9wZW5pbmcgb2YgYW4gSW5kZXhlZERCIGludG8gYSBQcm9taXNlLlxuICpcbiAqIEBwYXJhbSBkYm5hbWUgICAgICAgICAge1N0cmluZ30gICBUaGUgZGF0YWJhc2UgbmFtZS5cbiAqIEBwYXJhbSB2ZXJzaW9uICAgICAgICAge0ludGVnZXJ9ICBTY2hlbWEgdmVyc2lvblxuICogQHBhcmFtIG9udXBncmFkZW5lZWRlZCB7RnVuY3Rpb259IFRoZSBjYWxsYmFjayB0byBleGVjdXRlIGlmIHNjaGVtYSBpc1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pc3Npbmcgb3IgZGlmZmVyZW50LlxuICogQHJldHVybiB7UHJvbWlzZTxJREJEYXRhYmFzZT59XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcGVuKGRibmFtZSwgeyB2ZXJzaW9uLCBvbnVwZ3JhZGVuZWVkZWQgfSkge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBpbmRleGVkREIub3BlbihkYm5hbWUsIHZlcnNpb24pO1xuICAgIHJlcXVlc3Qub251cGdyYWRlbmVlZGVkID0gZXZlbnQgPT4ge1xuICAgICAgY29uc3QgZGIgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgZGIub25lcnJvciA9IGV2ZW50ID0+IHJlamVjdChldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgcmV0dXJuIG9udXBncmFkZW5lZWRlZChldmVudCk7XG4gICAgfTtcbiAgICByZXF1ZXN0Lm9uZXJyb3IgPSBldmVudCA9PiB7XG4gICAgICByZWplY3QoZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICB9O1xuICAgIHJlcXVlc3Qub25zdWNjZXNzID0gZXZlbnQgPT4ge1xuICAgICAgY29uc3QgZGIgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgcmVzb2x2ZShkYik7XG4gICAgfTtcbiAgfSk7XG59XG5cbi8qKlxuICogSGVscGVyIHRvIHJ1biB0aGUgc3BlY2lmaWVkIGNhbGxiYWNrIGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uIG9uIHRoZVxuICogc3BlY2lmaWVkIHN0b3JlLlxuICogVGhlIGhlbHBlciBmb2N1c2VzIG9uIHRyYW5zYWN0aW9uIHdyYXBwaW5nIGludG8gYSBwcm9taXNlLlxuICpcbiAqIEBwYXJhbSBkYiAgICAgICAgICAge0lEQkRhdGFiYXNlfSBUaGUgZGF0YWJhc2UgaW5zdGFuY2UuXG4gKiBAcGFyYW0gbmFtZSAgICAgICAgIHtTdHJpbmd9ICAgICAgVGhlIHN0b3JlIG5hbWUuXG4gKiBAcGFyYW0gY2FsbGJhY2sgICAgIHtGdW5jdGlvbn0gICAgVGhlIHBpZWNlIG9mIGNvZGUgdG8gZXhlY3V0ZSBpbiB0aGUgdHJhbnNhY3Rpb24uXG4gKiBAcGFyYW0gb3B0aW9ucyAgICAgIHtPYmplY3R9ICAgICAgT3B0aW9ucy5cbiAqIEBwYXJhbSBvcHRpb25zLm1vZGUge1N0cmluZ30gICAgICBUcmFuc2FjdGlvbiBtb2RlIChkZWZhdWx0OiByZWFkKS5cbiAqIEByZXR1cm4ge1Byb21pc2V9IGFueSB2YWx1ZSByZXR1cm5lZCBieSB0aGUgY2FsbGJhY2suXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleGVjdXRlKGRiLCBuYW1lLCBjYWxsYmFjaywgb3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IHsgbW9kZSB9ID0gb3B0aW9ucztcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAvLyBPbiBTYWZhcmksIGNhbGxpbmcgSURCRGF0YWJhc2UudHJhbnNhY3Rpb24gd2l0aCBtb2RlID09IHVuZGVmaW5lZCByYWlzZXNcbiAgICAvLyBhIFR5cGVFcnJvci5cbiAgICBjb25zdCB0cmFuc2FjdGlvbiA9IG1vZGVcbiAgICAgID8gZGIudHJhbnNhY3Rpb24oW25hbWVdLCBtb2RlKVxuICAgICAgOiBkYi50cmFuc2FjdGlvbihbbmFtZV0pO1xuICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUobmFtZSk7XG5cbiAgICAvLyBMZXQgdGhlIGNhbGxiYWNrIGFib3J0IHRoaXMgdHJhbnNhY3Rpb24uXG4gICAgY29uc3QgYWJvcnQgPSBlID0+IHtcbiAgICAgIHRyYW5zYWN0aW9uLmFib3J0KCk7XG4gICAgICByZWplY3QoZSk7XG4gICAgfTtcbiAgICAvLyBFeGVjdXRlIHRoZSBzcGVjaWZpZWQgY2FsbGJhY2sgKipzeW5jaHJvbm91c2x5KiouXG4gICAgbGV0IHJlc3VsdDtcbiAgICB0cnkge1xuICAgICAgcmVzdWx0ID0gY2FsbGJhY2soc3RvcmUsIGFib3J0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBhYm9ydChlKTtcbiAgICB9XG4gICAgdHJhbnNhY3Rpb24ub25lcnJvciA9IGV2ZW50ID0+IHJlamVjdChldmVudC50YXJnZXQuZXJyb3IpO1xuICAgIHRyYW5zYWN0aW9uLm9uY29tcGxldGUgPSBldmVudCA9PiByZXNvbHZlKHJlc3VsdCk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEhlbHBlciB0byB3cmFwIHRoZSBkZWxldGlvbiBvZiBhbiBJbmRleGVkREIgZGF0YWJhc2UgaW50byBhIHByb21pc2UuXG4gKlxuICogQHBhcmFtIGRiTmFtZSB7U3RyaW5nfSB0aGUgZGF0YWJhc2UgdG8gZGVsZXRlXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICovXG5hc3luYyBmdW5jdGlvbiBkZWxldGVEYXRhYmFzZShkYk5hbWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXhlZERCLmRlbGV0ZURhdGFiYXNlKGRiTmFtZSk7XG4gICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSBldmVudCA9PiByZXNvbHZlKGV2ZW50LnRhcmdldCk7XG4gICAgcmVxdWVzdC5vbmVycm9yID0gZXZlbnQgPT4gcmVqZWN0KGV2ZW50LnRhcmdldC5lcnJvcik7XG4gIH0pO1xufVxuXG4vKipcbiAqIElEQiBjdXJzb3IgaGFuZGxlcnMuXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG5jb25zdCBjdXJzb3JIYW5kbGVycyA9IHtcbiAgYWxsKGZpbHRlcnMsIGRvbmUpIHtcbiAgICBjb25zdCByZXN1bHRzID0gW107XG4gICAgcmV0dXJuIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGN1cnNvciA9IGV2ZW50LnRhcmdldC5yZXN1bHQ7XG4gICAgICBpZiAoY3Vyc29yKSB7XG4gICAgICAgIGNvbnN0IHsgdmFsdWUgfSA9IGN1cnNvcjtcbiAgICAgICAgaWYgKGZpbHRlck9iamVjdChmaWx0ZXJzLCB2YWx1ZSkpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGN1cnNvci5jb250aW51ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZG9uZShyZXN1bHRzKTtcbiAgICAgIH1cbiAgICB9O1xuICB9LFxuXG4gIGluKHZhbHVlcywgZmlsdGVycywgZG9uZSkge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICBsZXQgaSA9IDA7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICBjb25zdCBjdXJzb3IgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgaWYgKCFjdXJzb3IpIHtcbiAgICAgICAgZG9uZShyZXN1bHRzKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBrZXksIHZhbHVlIH0gPSBjdXJzb3I7XG4gICAgICAvLyBga2V5YCBjYW4gYmUgYW4gYXJyYXkgb2YgdHdvIHZhbHVlcyAoc2VlIGBrZXlQYXRoYCBpbiBpbmRpY2VzIGRlZmluaXRpb25zKS5cbiAgICAgIC8vIGB2YWx1ZXNgIGNhbiBiZSBhbiBhcnJheSBvZiBhcnJheXMgaWYgd2UgZmlsdGVyIHVzaW5nIGFuIGluZGV4IHdob3NlIGtleSBwYXRoXG4gICAgICAvLyBpcyBhbiBhcnJheSAoZWcuIGBjdXJzb3JIYW5kbGVycy5pbihbW1wiYmlkL2NpZFwiLCA0Ml0sIFtcImJpZC9jaWRcIiwgNDNdXSwgLi4uKWApXG4gICAgICB3aGlsZSAoa2V5ID4gdmFsdWVzW2ldKSB7XG4gICAgICAgIC8vIFRoZSBjdXJzb3IgaGFzIHBhc3NlZCBiZXlvbmQgdGhpcyBrZXkuIENoZWNrIG5leHQuXG4gICAgICAgICsraTtcbiAgICAgICAgaWYgKGkgPT09IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgICBkb25lKHJlc3VsdHMpOyAvLyBUaGVyZSBpcyBubyBuZXh0LiBTdG9wIHNlYXJjaGluZy5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IGlzRXF1YWwgPSBBcnJheS5pc0FycmF5KGtleSlcbiAgICAgICAgPyBhcnJheUVxdWFsKGtleSwgdmFsdWVzW2ldKVxuICAgICAgICA6IGtleSA9PT0gdmFsdWVzW2ldO1xuICAgICAgaWYgKGlzRXF1YWwpIHtcbiAgICAgICAgaWYgKGZpbHRlck9iamVjdChmaWx0ZXJzLCB2YWx1ZSkpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGN1cnNvci5jb250aW51ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3Vyc29yLmNvbnRpbnVlKHZhbHVlc1tpXSk7XG4gICAgICB9XG4gICAgfTtcbiAgfSxcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBJREIgcmVxdWVzdCBhbmQgYXR0YWNoIGl0IHRoZSBhcHByb3ByaWF0ZSBjdXJzb3IgZXZlbnQgaGFuZGxlciB0b1xuICogcGVyZm9ybSBhIGxpc3QgcXVlcnkuXG4gKlxuICogTXVsdGlwbGUgbWF0Y2hpbmcgdmFsdWVzIGFyZSBoYW5kbGVkIGJ5IHBhc3NpbmcgYW4gYXJyYXkuXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSAgICAgICAgICAgY2lkICAgICAgICBUaGUgY29sbGVjdGlvbiBpZCAoaWUuIGB7YmlkfS97Y2lkfWApXG4gKiBAcGFyYW0gIHtJREJTdG9yZX0gICAgICAgICBzdG9yZSAgICAgIFRoZSBJREIgc3RvcmUuXG4gKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICAgICBmaWx0ZXJzICAgIEZpbHRlciB0aGUgcmVjb3JkcyBieSBmaWVsZC5cbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSAgICAgICAgIGRvbmUgICAgICAgVGhlIG9wZXJhdGlvbiBjb21wbGV0aW9uIGhhbmRsZXIuXG4gKiBAcmV0dXJuIHtJREJSZXF1ZXN0fVxuICovXG5mdW5jdGlvbiBjcmVhdGVMaXN0UmVxdWVzdChjaWQsIHN0b3JlLCBmaWx0ZXJzLCBkb25lKSB7XG4gIGNvbnN0IGZpbHRlckZpZWxkcyA9IE9iamVjdC5rZXlzKGZpbHRlcnMpO1xuXG4gIC8vIElmIG5vIGZpbHRlcnMsIGdldCBhbGwgcmVzdWx0cyBpbiBvbmUgYnVsay5cbiAgaWYgKGZpbHRlckZpZWxkcy5sZW5ndGggPT0gMCkge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5pbmRleChcImNpZFwiKS5nZXRBbGwoSURCS2V5UmFuZ2Uub25seShjaWQpKTtcbiAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGV2ZW50ID0+IGRvbmUoZXZlbnQudGFyZ2V0LnJlc3VsdCk7XG4gICAgcmV0dXJuIHJlcXVlc3Q7XG4gIH1cblxuICAvLyBJbnRyb3NwZWN0IGZpbHRlcnMgYW5kIGNoZWNrIGlmIHRoZXkgbGV2ZXJhZ2UgYW4gaW5kZXhlZCBmaWVsZC5cbiAgY29uc3QgaW5kZXhGaWVsZCA9IGZpbHRlckZpZWxkcy5maW5kKGZpZWxkID0+IHtcbiAgICByZXR1cm4gSU5ERVhFRF9GSUVMRFMuaW5jbHVkZXMoZmllbGQpO1xuICB9KTtcblxuICBpZiAoIWluZGV4RmllbGQpIHtcbiAgICAvLyBJdGVyYXRlIG9uIGFsbCByZWNvcmRzIGZvciB0aGlzIGNvbGxlY3Rpb24gKGllLiBjaWQpXG4gICAgY29uc3QgaXNTdWJRdWVyeSA9IE9iamVjdC5rZXlzKGZpbHRlcnMpLnNvbWUoa2V5ID0+IGtleS5pbmNsdWRlcyhcIi5cIikpOyAvLyAoaWUuIGZpbHRlcnM6IHtcImFydGljbGUudGl0bGVcIjogXCJoZWxsb1wifSlcbiAgICBpZiAoaXNTdWJRdWVyeSkge1xuICAgICAgY29uc3QgbmV3RmlsdGVyID0gdHJhbnNmb3JtU3ViT2JqZWN0RmlsdGVycyhmaWx0ZXJzKTtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5pbmRleChcImNpZFwiKS5vcGVuQ3Vyc29yKElEQktleVJhbmdlLm9ubHkoY2lkKSk7XG4gICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGN1cnNvckhhbmRsZXJzLmFsbChuZXdGaWx0ZXIsIGRvbmUpO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfVxuXG4gICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLmluZGV4KFwiY2lkXCIpLm9wZW5DdXJzb3IoSURCS2V5UmFuZ2Uub25seShjaWQpKTtcbiAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGN1cnNvckhhbmRsZXJzLmFsbChmaWx0ZXJzLCBkb25lKTtcbiAgICByZXR1cm4gcmVxdWVzdDtcbiAgfVxuICAvLyBJZiBgaW5kZXhGaWVsZGAgd2FzIHVzZWQgYWxyZWFkeSwgZG9uJ3QgZmlsdGVyIGFnYWluLlxuICBjb25zdCByZW1haW5pbmdGaWx0ZXJzID0gb21pdEtleXMoZmlsdGVycywgW2luZGV4RmllbGRdKTtcblxuICAvLyB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGZpbHRlciAoZWcuIGBmaWx0ZXJzOiB7IF9zdGF0dXM6IFtcImNyZWF0ZWRcIiwgXCJ1cGRhdGVkXCJdIH1gKVxuICBjb25zdCB2YWx1ZSA9IGZpbHRlcnNbaW5kZXhGaWVsZF07XG4gIC8vIEZvciB0aGUgXCJpZFwiIGZpZWxkLCB1c2UgdGhlIHByaW1hcnkga2V5LlxuICBjb25zdCBpbmRleFN0b3JlID0gaW5kZXhGaWVsZCA9PSBcImlkXCIgPyBzdG9yZSA6IHN0b3JlLmluZGV4KGluZGV4RmllbGQpO1xuXG4gIC8vIFdIRVJFIElOIGVxdWl2YWxlbnQgY2xhdXNlXG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBkb25lKFtdKTtcbiAgICB9XG4gICAgY29uc3QgdmFsdWVzID0gdmFsdWUubWFwKGkgPT4gW2NpZCwgaV0pLnNvcnQoKTtcbiAgICBjb25zdCByYW5nZSA9IElEQktleVJhbmdlLmJvdW5kKHZhbHVlc1swXSwgdmFsdWVzW3ZhbHVlcy5sZW5ndGggLSAxXSk7XG4gICAgY29uc3QgcmVxdWVzdCA9IGluZGV4U3RvcmUub3BlbkN1cnNvcihyYW5nZSk7XG4gICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSBjdXJzb3JIYW5kbGVycy5pbih2YWx1ZXMsIHJlbWFpbmluZ0ZpbHRlcnMsIGRvbmUpO1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG5cbiAgLy8gSWYgbm8gZmlsdGVycyBvbiBjdXN0b20gYXR0cmlidXRlLCBnZXQgYWxsIHJlc3VsdHMgaW4gb25lIGJ1bGsuXG4gIGlmIChyZW1haW5pbmdGaWx0ZXJzLmxlbmd0aCA9PSAwKSB7XG4gICAgY29uc3QgcmVxdWVzdCA9IGluZGV4U3RvcmUuZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoW2NpZCwgdmFsdWVdKSk7XG4gICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSBldmVudCA9PiBkb25lKGV2ZW50LnRhcmdldC5yZXN1bHQpO1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG5cbiAgLy8gV0hFUkUgZmllbGQgPSB2YWx1ZSBjbGF1c2VcbiAgY29uc3QgcmVxdWVzdCA9IGluZGV4U3RvcmUub3BlbkN1cnNvcihJREJLZXlSYW5nZS5vbmx5KFtjaWQsIHZhbHVlXSkpO1xuICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGN1cnNvckhhbmRsZXJzLmFsbChyZW1haW5pbmdGaWx0ZXJzLCBkb25lKTtcbiAgcmV0dXJuIHJlcXVlc3Q7XG59XG5cbi8qKlxuICogSW5kZXhlZERCIGFkYXB0ZXIuXG4gKlxuICogVGhpcyBhZGFwdGVyIGRvZXNuJ3Qgc3VwcG9ydCBhbnkgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSURCIGV4dGVuZHMgQmFzZUFkYXB0ZXIge1xuICAvKipcbiAgICogQ29uc3RydWN0b3IuXG4gICAqXG4gICAqIEBwYXJhbSAge1N0cmluZ30gY2lkICBUaGUga2V5IGJhc2UgZm9yIHRoaXMgY29sbGVjdGlvbiAoZWcuIGBiaWQvY2lkYClcbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEBwYXJhbSAge1N0cmluZ30gb3B0aW9ucy5kYk5hbWUgICAgICAgICBUaGUgSW5kZXhlZERCIG5hbWUgKGRlZmF1bHQ6IGBcIktpbnRvREJcImApXG4gICAqIEBwYXJhbSAge1N0cmluZ30gb3B0aW9ucy5taWdyYXRlT2xkRGF0YSBXaGV0aGVyIG9sZCBkYXRhYmFzZSBkYXRhIHNob3VsZCBiZSBtaWdyYXRlZCAoZGVmYXVsdDogYGZhbHNlYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKGNpZCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuY2lkID0gY2lkO1xuICAgIHRoaXMuZGJOYW1lID0gb3B0aW9ucy5kYk5hbWUgfHwgXCJLaW50b0RCXCI7XG5cbiAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLl9kYiA9IG51bGw7XG4gIH1cblxuICBfaGFuZGxlRXJyb3IobWV0aG9kLCBlcnIpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcihgSW5kZXhlZERCICR7bWV0aG9kfSgpICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgZXJyb3Iuc3RhY2sgPSBlcnIuc3RhY2s7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlcyBhIGNvbm5lY3Rpb24gdG8gdGhlIEluZGV4ZWREQiBkYXRhYmFzZSBoYXMgYmVlbiBvcGVuZWQuXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgb3BlbigpIHtcbiAgICBpZiAodGhpcy5fZGIpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEluIHByZXZpb3VzIHZlcnNpb25zLCB3ZSB1c2VkIHRvIGhhdmUgYSBkYXRhYmFzZSB3aXRoIG5hbWUgYCR7YmlkfS8ke2NpZH1gLlxuICAgIC8vIENoZWNrIGlmIGl0IGV4aXN0cywgYW5kIG1pZ3JhdGUgZGF0YSBvbmNlIG5ldyBzY2hlbWEgaXMgaW4gcGxhY2UuXG4gICAgLy8gTm90ZTogdGhlIGJ1aWx0LWluIG1pZ3JhdGlvbnMgZnJvbSBJbmRleGVkREIgY2FuIG9ubHkgYmUgdXNlZCBpZiB0aGVcbiAgICAvLyBkYXRhYmFzZSBuYW1lIGRvZXMgbm90IGNoYW5nZS5cbiAgICBjb25zdCBkYXRhVG9NaWdyYXRlID0gdGhpcy5fb3B0aW9ucy5taWdyYXRlT2xkRGF0YVxuICAgICAgPyBhd2FpdCBtaWdyYXRpb25SZXF1aXJlZCh0aGlzLmNpZClcbiAgICAgIDogbnVsbDtcblxuICAgIHRoaXMuX2RiID0gYXdhaXQgb3Blbih0aGlzLmRiTmFtZSwge1xuICAgICAgdmVyc2lvbjogMixcbiAgICAgIG9udXBncmFkZW5lZWRlZDogZXZlbnQgPT4ge1xuICAgICAgICBjb25zdCBkYiA9IGV2ZW50LnRhcmdldC5yZXN1bHQ7XG5cbiAgICAgICAgaWYgKGV2ZW50Lm9sZFZlcnNpb24gPCAxKSB7XG4gICAgICAgICAgLy8gUmVjb3JkcyBzdG9yZVxuICAgICAgICAgIGNvbnN0IHJlY29yZHNTdG9yZSA9IGRiLmNyZWF0ZU9iamVjdFN0b3JlKFwicmVjb3Jkc1wiLCB7XG4gICAgICAgICAgICBrZXlQYXRoOiBbXCJfY2lkXCIsIFwiaWRcIl0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgLy8gQW4gaW5kZXggdG8gb2J0YWluIGFsbCB0aGUgcmVjb3JkcyBpbiBhIGNvbGxlY3Rpb24uXG4gICAgICAgICAgcmVjb3Jkc1N0b3JlLmNyZWF0ZUluZGV4KFwiY2lkXCIsIFwiX2NpZFwiKTtcbiAgICAgICAgICAvLyBIZXJlIHdlIGNyZWF0ZSBpbmRpY2VzIGZvciBldmVyeSBrbm93biBmaWVsZCBpbiByZWNvcmRzIGJ5IGNvbGxlY3Rpb24uXG4gICAgICAgICAgLy8gTG9jYWwgcmVjb3JkIHN0YXR1cyAoXCJzeW5jZWRcIiwgXCJjcmVhdGVkXCIsIFwidXBkYXRlZFwiLCBcImRlbGV0ZWRcIilcbiAgICAgICAgICByZWNvcmRzU3RvcmUuY3JlYXRlSW5kZXgoXCJfc3RhdHVzXCIsIFtcIl9jaWRcIiwgXCJfc3RhdHVzXCJdKTtcbiAgICAgICAgICAvLyBMYXN0IG1vZGlmaWVkIGZpZWxkXG4gICAgICAgICAgcmVjb3Jkc1N0b3JlLmNyZWF0ZUluZGV4KFwibGFzdF9tb2RpZmllZFwiLCBbXCJfY2lkXCIsIFwibGFzdF9tb2RpZmllZFwiXSk7XG4gICAgICAgICAgLy8gVGltZXN0YW1wcyBzdG9yZVxuICAgICAgICAgIGRiLmNyZWF0ZU9iamVjdFN0b3JlKFwidGltZXN0YW1wc1wiLCB7XG4gICAgICAgICAgICBrZXlQYXRoOiBcImNpZFwiLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2ZW50Lm9sZFZlcnNpb24gPCAyKSB7XG4gICAgICAgICAgLy8gQ29sbGVjdGlvbnMgc3RvcmVcbiAgICAgICAgICBkYi5jcmVhdGVPYmplY3RTdG9yZShcImNvbGxlY3Rpb25zXCIsIHtcbiAgICAgICAgICAgIGtleVBhdGg6IFwiY2lkXCIsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoZGF0YVRvTWlncmF0ZSkge1xuICAgICAgY29uc3QgeyByZWNvcmRzLCB0aW1lc3RhbXAgfSA9IGRhdGFUb01pZ3JhdGU7XG4gICAgICBhd2FpdCB0aGlzLmltcG9ydEJ1bGsocmVjb3Jkcyk7XG4gICAgICBhd2FpdCB0aGlzLnNhdmVMYXN0TW9kaWZpZWQodGltZXN0YW1wKTtcbiAgICAgIGNvbnNvbGUubG9nKGAke3RoaXMuY2lkfTogZGF0YSB3YXMgbWlncmF0ZWQgc3VjY2Vzc2Z1bGx5LmApO1xuICAgICAgLy8gRGVsZXRlIHRoZSBvbGQgZGF0YWJhc2UuXG4gICAgICBhd2FpdCBkZWxldGVEYXRhYmFzZSh0aGlzLmNpZCk7XG4gICAgICBjb25zb2xlLndhcm4oYCR7dGhpcy5jaWR9OiBvbGQgZGF0YWJhc2Ugd2FzIGRlbGV0ZWQuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIGN1cnJlbnQgY29ubmVjdGlvbiB0byB0aGUgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgY2xvc2UoKSB7XG4gICAgaWYgKHRoaXMuX2RiKSB7XG4gICAgICB0aGlzLl9kYi5jbG9zZSgpOyAvLyBpbmRleGVkREIuY2xvc2UgaXMgc3luY2hyb25vdXNcbiAgICAgIHRoaXMuX2RiID0gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB0cmFuc2FjdGlvbiBhbmQgYW4gb2JqZWN0IHN0b3JlIGZvciBhIHN0b3JlIG5hbWUuXG4gICAqXG4gICAqIFRvIGRldGVybWluZSBpZiBhIHRyYW5zYWN0aW9uIGhhcyBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5LCB3ZSBzaG91bGQgcmF0aGVyXG4gICAqIGxpc3RlbiB0byB0aGUgdHJhbnNhY3Rpb27igJlzIGNvbXBsZXRlIGV2ZW50IHJhdGhlciB0aGFuIHRoZSBJREJPYmplY3RTdG9yZVxuICAgKiByZXF1ZXN04oCZcyBzdWNjZXNzIGV2ZW50LCBiZWNhdXNlIHRoZSB0cmFuc2FjdGlvbiBtYXkgc3RpbGwgZmFpbCBhZnRlciB0aGVcbiAgICogc3VjY2VzcyBldmVudCBmaXJlcy5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSAgICAgIG5hbWUgIFN0b3JlIG5hbWVcbiAgICogQHBhcmFtICB7RnVuY3Rpb259ICAgIGNhbGxiYWNrIHRvIGV4ZWN1dGVcbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgIG9wdGlvbnMgT3B0aW9uc1xuICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgb3B0aW9ucy5tb2RlICBUcmFuc2FjdGlvbiBtb2RlIChcInJlYWR3cml0ZVwiIG9yIHVuZGVmaW5lZClcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgYXN5bmMgcHJlcGFyZShuYW1lLCBjYWxsYmFjaywgb3B0aW9ucykge1xuICAgIGF3YWl0IHRoaXMub3BlbigpO1xuICAgIGF3YWl0IGV4ZWN1dGUodGhpcy5fZGIsIG5hbWUsIGNhbGxiYWNrLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGV2ZXJ5IHJlY29yZHMgaW4gdGhlIGN1cnJlbnQgY29sbGVjdGlvbi5cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBjbGVhcigpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlKFxuICAgICAgICBcInJlY29yZHNcIixcbiAgICAgICAgc3RvcmUgPT4ge1xuICAgICAgICAgIGNvbnN0IHJhbmdlID0gSURCS2V5UmFuZ2Uub25seSh0aGlzLmNpZCk7XG4gICAgICAgICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLmluZGV4KFwiY2lkXCIpLm9wZW5LZXlDdXJzb3IocmFuZ2UpO1xuICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gZXZlbnQgPT4ge1xuICAgICAgICAgICAgY29uc3QgY3Vyc29yID0gZXZlbnQudGFyZ2V0LnJlc3VsdDtcbiAgICAgICAgICAgIGlmIChjdXJzb3IpIHtcbiAgICAgICAgICAgICAgc3RvcmUuZGVsZXRlKGN1cnNvci5wcmltYXJ5S2V5KTtcbiAgICAgICAgICAgICAgY3Vyc29yLmNvbnRpbnVlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICAgICAgfSxcbiAgICAgICAgeyBtb2RlOiBcInJlYWR3cml0ZVwiIH1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5faGFuZGxlRXJyb3IoXCJjbGVhclwiLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZXMgdGhlIHNldCBvZiBzeW5jaHJvbm91cyBDUlVEIG9wZXJhdGlvbnMgZGVzY3JpYmVkIGluIHRoZSBwcm92aWRlZFxuICAgKiBjYWxsYmFjayB3aXRoaW4gYW4gSW5kZXhlZERCIHRyYW5zYWN0aW9uLCBmb3IgY3VycmVudCBkYiBzdG9yZS5cbiAgICpcbiAgICogVGhlIGNhbGxiYWNrIHdpbGwgYmUgcHJvdmlkZWQgYW4gb2JqZWN0IGV4cG9zaW5nIHRoZSBmb2xsb3dpbmcgc3luY2hyb25vdXNcbiAgICogQ1JVRCBvcGVyYXRpb24gbWV0aG9kczogZ2V0LCBjcmVhdGUsIHVwZGF0ZSwgZGVsZXRlLlxuICAgKlxuICAgKiBJbXBvcnRhbnQgbm90ZTogYmVjYXVzZSBsaW1pdGF0aW9ucyBpbiBJbmRleGVkREIgaW1wbGVtZW50YXRpb25zLCBub1xuICAgKiBhc3luY2hyb25vdXMgY29kZSBzaG91bGQgYmUgcGVyZm9ybWVkIHdpdGhpbiB0aGUgcHJvdmlkZWQgY2FsbGJhY2s7IHRoZVxuICAgKiBwcm9taXNlIHdpbGwgdGhlcmVmb3JlIGJlIHJlamVjdGVkIGlmIHRoZSBjYWxsYmFjayByZXR1cm5zIGEgUHJvbWlzZS5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7QXJyYXl9IHByZWxvYWQ6IFRoZSBsaXN0IG9mIHJlY29yZCBJRHMgdG8gZmV0Y2ggYW5kIG1ha2UgYXZhaWxhYmxlIHRvXG4gICAqICAgdGhlIHRyYW5zYWN0aW9uIG9iamVjdCBnZXQoKSBtZXRob2QgKGRlZmF1bHQ6IFtdKVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zdCBkYiA9IG5ldyBJREIoXCJleGFtcGxlXCIpO1xuICAgKiBjb25zdCByZXN1bHQgPSBhd2FpdCBkYi5leGVjdXRlKHRyYW5zYWN0aW9uID0+IHtcbiAgICogICB0cmFuc2FjdGlvbi5jcmVhdGUoe2lkOiAxLCB0aXRsZTogXCJmb29cIn0pO1xuICAgKiAgIHRyYW5zYWN0aW9uLnVwZGF0ZSh7aWQ6IDIsIHRpdGxlOiBcImJhclwifSk7XG4gICAqICAgdHJhbnNhY3Rpb24uZGVsZXRlKDMpO1xuICAgKiAgIHJldHVybiBcImZvb1wiO1xuICAgKiB9KTtcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEBwYXJhbSAge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgb3BlcmF0aW9uIGRlc2NyaXB0aW9uIGNhbGxiYWNrLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgb3B0aW9ucyAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZShjYWxsYmFjaywgb3B0aW9ucyA9IHsgcHJlbG9hZDogW10gfSkge1xuICAgIC8vIFRyYW5zYWN0aW9ucyBpbiBJbmRleGVkREIgYXJlIGF1dG9jb21taXRlZCB3aGVuIGEgY2FsbGJhY2sgZG9lcyBub3RcbiAgICAvLyBwZXJmb3JtIGFueSBhZGRpdGlvbmFsIG9wZXJhdGlvbi5cbiAgICAvLyBUaGUgd2F5IFByb21pc2VzIGFyZSBpbXBsZW1lbnRlZCBpbiBGaXJlZm94IChzZWUgaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTE5MzM5NClcbiAgICAvLyBwcmV2ZW50cyB1c2luZyB3aXRoaW4gYW4gb3BlbmVkIHRyYW5zYWN0aW9uLlxuICAgIC8vIFRvIGF2b2lkIG1hbmFnaW5nIGFzeW5jaHJvbm9jaXR5IGluIHRoZSBzcGVjaWZpZWQgYGNhbGxiYWNrYCwgd2UgcHJlbG9hZFxuICAgIC8vIGEgbGlzdCBvZiByZWNvcmQgaW4gb3JkZXIgdG8gZXhlY3V0ZSB0aGUgYGNhbGxiYWNrYCBzeW5jaHJvbm91c2x5LlxuICAgIC8vIFNlZSBhbHNvOlxuICAgIC8vIC0gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjgzODg4MDUvMzMwOTExXG4gICAgLy8gLSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xMDQwNTE5NlxuICAgIC8vIC0gaHR0cHM6Ly9qYWtlYXJjaGliYWxkLmNvbS8yMDE1L3Rhc2tzLW1pY3JvdGFza3MtcXVldWVzLWFuZC1zY2hlZHVsZXMvXG4gICAgbGV0IHJlc3VsdDtcbiAgICBhd2FpdCB0aGlzLnByZXBhcmUoXG4gICAgICBcInJlY29yZHNcIixcbiAgICAgIChzdG9yZSwgYWJvcnQpID0+IHtcbiAgICAgICAgY29uc3QgcnVuQ2FsbGJhY2sgPSAocHJlbG9hZGVkID0gW10pID0+IHtcbiAgICAgICAgICAvLyBFeHBvc2UgYSBjb25zaXN0ZW50IEFQSSBmb3IgZXZlcnkgYWRhcHRlciBpbnN0ZWFkIG9mIHJhdyBzdG9yZSBtZXRob2RzLlxuICAgICAgICAgIGNvbnN0IHByb3h5ID0gdHJhbnNhY3Rpb25Qcm94eSh0aGlzLCBzdG9yZSwgcHJlbG9hZGVkKTtcbiAgICAgICAgICAvLyBUaGUgY2FsbGJhY2sgaXMgZXhlY3V0ZWQgc3luY2hyb25vdXNseSB3aXRoaW4gdGhlIHNhbWUgdHJhbnNhY3Rpb24uXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJldHVybmVkID0gY2FsbGJhY2socHJveHkpO1xuICAgICAgICAgICAgaWYgKHJldHVybmVkIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAvLyBYWFg6IGludmVzdGlnYXRlIGhvdyB0byBwcm92aWRlIGRvY3VtZW50YXRpb24gZGV0YWlscyBpbiBlcnJvci5cbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiZXhlY3V0ZSgpIGNhbGxiYWNrIHNob3VsZCBub3QgcmV0dXJuIGEgUHJvbWlzZS5cIlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnJpbmcgdG8gc2NvcGUgdGhhdCB3aWxsIGJlIHJldHVybmVkIChvbmNlIHByb21pc2UgYXdhaXRlZCkuXG4gICAgICAgICAgICByZXN1bHQgPSByZXR1cm5lZDtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBUaGUgY2FsbGJhY2sgaGFzIHRocm93biBhbiBlcnJvciBleHBsaWNpdGx5LiBBYm9ydCB0cmFuc2FjdGlvbiBjbGVhbmx5LlxuICAgICAgICAgICAgYWJvcnQoZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIE5vIG9wdGlvbiB0byBwcmVsb2FkIHJlY29yZHMsIGdvIHN0cmFpZ2h0IHRvIGBjYWxsYmFja2AuXG4gICAgICAgIGlmICghb3B0aW9ucy5wcmVsb2FkLmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybiBydW5DYWxsYmFjaygpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJlbG9hZCBzcGVjaWZpZWQgcmVjb3JkcyB1c2luZyBhIGxpc3QgcmVxdWVzdC5cbiAgICAgICAgY29uc3QgZmlsdGVycyA9IHsgaWQ6IG9wdGlvbnMucHJlbG9hZCB9O1xuICAgICAgICBjcmVhdGVMaXN0UmVxdWVzdCh0aGlzLmNpZCwgc3RvcmUsIGZpbHRlcnMsIHJlY29yZHMgPT4ge1xuICAgICAgICAgIC8vIFN0b3JlIG9idGFpbmVkIHJlY29yZHMgYnkgaWQuXG4gICAgICAgICAgY29uc3QgcHJlbG9hZGVkID0ge307XG4gICAgICAgICAgZm9yIChjb25zdCByZWNvcmQgb2YgcmVjb3Jkcykge1xuICAgICAgICAgICAgZGVsZXRlIHJlY29yZFtcIl9jaWRcIl07XG4gICAgICAgICAgICBwcmVsb2FkZWRbcmVjb3JkLmlkXSA9IHJlY29yZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcnVuQ2FsbGJhY2socHJlbG9hZGVkKTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgeyBtb2RlOiBcInJlYWR3cml0ZVwiIH1cbiAgICApO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgYSByZWNvcmQgYnkgaXRzIHByaW1hcnkga2V5IGZyb20gdGhlIEluZGV4ZWREQiBkYXRhYmFzZS5cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEBwYXJhbSAge1N0cmluZ30gaWQgVGhlIHJlY29yZCBpZC5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIGdldChpZCkge1xuICAgIHRyeSB7XG4gICAgICBsZXQgcmVjb3JkO1xuICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlKFwicmVjb3Jkc1wiLCBzdG9yZSA9PiB7XG4gICAgICAgIHN0b3JlLmdldChbdGhpcy5jaWQsIGlkXSkub25zdWNjZXNzID0gZSA9PiAocmVjb3JkID0gZS50YXJnZXQucmVzdWx0KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlY29yZDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLl9oYW5kbGVFcnJvcihcImdldFwiLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTGlzdHMgYWxsIHJlY29yZHMgZnJvbSB0aGUgSW5kZXhlZERCIGRhdGFiYXNlLlxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHBhcmFtICB7T2JqZWN0fSBwYXJhbXMgIFRoZSBmaWx0ZXJzIGFuZCBvcmRlciB0byBhcHBseSB0byB0aGUgcmVzdWx0cy5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIGxpc3QocGFyYW1zID0geyBmaWx0ZXJzOiB7fSB9KSB7XG4gICAgY29uc3QgeyBmaWx0ZXJzIH0gPSBwYXJhbXM7XG4gICAgdHJ5IHtcbiAgICAgIGxldCByZXN1bHRzID0gW107XG4gICAgICBhd2FpdCB0aGlzLnByZXBhcmUoXCJyZWNvcmRzXCIsIHN0b3JlID0+IHtcbiAgICAgICAgY3JlYXRlTGlzdFJlcXVlc3QodGhpcy5jaWQsIHN0b3JlLCBmaWx0ZXJzLCBfcmVzdWx0cyA9PiB7XG4gICAgICAgICAgLy8gd2UgaGF2ZSByZWNlaXZlZCBhbGwgcmVxdWVzdGVkIHJlY29yZHMgdGhhdCBtYXRjaCB0aGUgZmlsdGVycyxcbiAgICAgICAgICAvLyB3ZSBub3cgcGFyayB0aGVtIHdpdGhpbiBjdXJyZW50IHNjb3BlIGFuZCBoaWRlIHRoZSBgX2NpZGAgYXR0cmlidXRlLlxuICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIF9yZXN1bHRzKSB7XG4gICAgICAgICAgICBkZWxldGUgcmVzdWx0W1wiX2NpZFwiXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0cyA9IF9yZXN1bHRzO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgLy8gVGhlIHJlc3VsdGluZyBsaXN0IG9mIHJlY29yZHMgaXMgc29ydGVkLlxuICAgICAgLy8gWFhYOiB3aXRoIHNvbWUgZWZmb3J0cywgdGhpcyBjb3VsZCBiZSBmdWxseSBpbXBsZW1lbnRlZCB1c2luZyBJREIgQVBJLlxuICAgICAgcmV0dXJuIHBhcmFtcy5vcmRlciA/IHNvcnRPYmplY3RzKHBhcmFtcy5vcmRlciwgcmVzdWx0cykgOiByZXN1bHRzO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9yKFwibGlzdFwiLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3RvcmUgdGhlIGxhc3RNb2RpZmllZCB2YWx1ZSBpbnRvIG1ldGFkYXRhIHN0b3JlLlxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHBhcmFtICB7TnVtYmVyfSAgbGFzdE1vZGlmaWVkXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBzYXZlTGFzdE1vZGlmaWVkKGxhc3RNb2RpZmllZCkge1xuICAgIGNvbnN0IHZhbHVlID0gcGFyc2VJbnQobGFzdE1vZGlmaWVkLCAxMCkgfHwgbnVsbDtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlKFxuICAgICAgICBcInRpbWVzdGFtcHNcIixcbiAgICAgICAgc3RvcmUgPT4gc3RvcmUucHV0KHsgY2lkOiB0aGlzLmNpZCwgdmFsdWUgfSksXG4gICAgICAgIHsgbW9kZTogXCJyZWFkd3JpdGVcIiB9XG4gICAgICApO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9yKFwic2F2ZUxhc3RNb2RpZmllZFwiLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgc2F2ZWQgbGFzdE1vZGlmaWVkIHZhbHVlLlxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIGdldExhc3RNb2RpZmllZCgpIHtcbiAgICB0cnkge1xuICAgICAgbGV0IGVudHJ5ID0gbnVsbDtcbiAgICAgIGF3YWl0IHRoaXMucHJlcGFyZShcInRpbWVzdGFtcHNcIiwgc3RvcmUgPT4ge1xuICAgICAgICBzdG9yZS5nZXQodGhpcy5jaWQpLm9uc3VjY2VzcyA9IGUgPT4gKGVudHJ5ID0gZS50YXJnZXQucmVzdWx0KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGVudHJ5ID8gZW50cnkudmFsdWUgOiBudWxsO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9yKFwiZ2V0TGFzdE1vZGlmaWVkXCIsIGUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGEgZHVtcCBvZiByZWNvcmRzIGV4cG9ydGVkIGZyb20gYSBzZXJ2ZXIuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgaW1wb3J0QnVsa30gaW5zdGVhZC5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSAge0FycmF5fSByZWNvcmRzIFRoZSByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBsb2FkRHVtcChyZWNvcmRzKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1wb3J0QnVsayhyZWNvcmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIHJlY29yZHMgaW4gYnVsayB0aGF0IHdlcmUgZXhwb3J0ZWQgZnJvbSBhIHNlcnZlci5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSAge0FycmF5fSByZWNvcmRzIFRoZSByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBpbXBvcnRCdWxrKHJlY29yZHMpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5leGVjdXRlKHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgLy8gU2luY2UgdGhlIHB1dCBvcGVyYXRpb25zIGFyZSBhc3luY2hyb25vdXMsIHdlIGNoYWluXG4gICAgICAgIC8vIHRoZW0gdG9nZXRoZXIuIFRoZSBsYXN0IG9uZSB3aWxsIGJlIHdhaXRlZCBmb3IgdGhlXG4gICAgICAgIC8vIGB0cmFuc2FjdGlvbi5vbmNvbXBsZXRlYCBjYWxsYmFjay4gKHNlZSAjZXhlY3V0ZSgpKVxuICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgIHB1dE5leHQoKTtcblxuICAgICAgICBmdW5jdGlvbiBwdXROZXh0KCkge1xuICAgICAgICAgIGlmIChpID09IHJlY29yZHMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIE9uIGVycm9yLCBgdHJhbnNhY3Rpb24ub25lcnJvcmAgaXMgY2FsbGVkLlxuICAgICAgICAgIHRyYW5zYWN0aW9uLnVwZGF0ZShyZWNvcmRzW2ldKS5vbnN1Y2Nlc3MgPSBwdXROZXh0O1xuICAgICAgICAgICsraTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBwcmV2aW91c0xhc3RNb2RpZmllZCA9IGF3YWl0IHRoaXMuZ2V0TGFzdE1vZGlmaWVkKCk7XG4gICAgICBjb25zdCBsYXN0TW9kaWZpZWQgPSBNYXRoLm1heChcbiAgICAgICAgLi4ucmVjb3Jkcy5tYXAocmVjb3JkID0+IHJlY29yZC5sYXN0X21vZGlmaWVkKVxuICAgICAgKTtcbiAgICAgIGlmIChsYXN0TW9kaWZpZWQgPiBwcmV2aW91c0xhc3RNb2RpZmllZCkge1xuICAgICAgICBhd2FpdCB0aGlzLnNhdmVMYXN0TW9kaWZpZWQobGFzdE1vZGlmaWVkKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZWNvcmRzO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9yKFwiaW1wb3J0QnVsa1wiLCBlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzYXZlTWV0YWRhdGEobWV0YWRhdGEpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlKFxuICAgICAgICBcImNvbGxlY3Rpb25zXCIsXG4gICAgICAgIHN0b3JlID0+IHN0b3JlLnB1dCh7IGNpZDogdGhpcy5jaWQsIG1ldGFkYXRhIH0pLFxuICAgICAgICB7IG1vZGU6IFwicmVhZHdyaXRlXCIgfVxuICAgICAgKTtcbiAgICAgIHJldHVybiBtZXRhZGF0YTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLl9oYW5kbGVFcnJvcihcInNhdmVNZXRhZGF0YVwiLCBlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBnZXRNZXRhZGF0YSgpIHtcbiAgICB0cnkge1xuICAgICAgbGV0IGVudHJ5ID0gbnVsbDtcbiAgICAgIGF3YWl0IHRoaXMucHJlcGFyZShcImNvbGxlY3Rpb25zXCIsIHN0b3JlID0+IHtcbiAgICAgICAgc3RvcmUuZ2V0KHRoaXMuY2lkKS5vbnN1Y2Nlc3MgPSBlID0+IChlbnRyeSA9IGUudGFyZ2V0LnJlc3VsdCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBlbnRyeSA/IGVudHJ5Lm1ldGFkYXRhIDogbnVsbDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLl9oYW5kbGVFcnJvcihcImdldE1ldGFkYXRhXCIsIGUpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIElEQiB0cmFuc2FjdGlvbiBwcm94eS5cbiAqXG4gKiBAcGFyYW0gIHtJREJ9IGFkYXB0ZXIgICAgICAgIFRoZSBjYWxsIElEQiBhZGFwdGVyXG4gKiBAcGFyYW0gIHtJREJTdG9yZX0gc3RvcmUgICAgIFRoZSBJbmRleGVkREIgZGF0YWJhc2Ugc3RvcmUuXG4gKiBAcGFyYW0gIHtBcnJheX0gICAgcHJlbG9hZGVkIFRoZSBsaXN0IG9mIHJlY29yZHMgdG8gbWFrZSBhdmFpbGFibGUgdG9cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0KCkgKGRlZmF1bHQ6IFtdKS5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gdHJhbnNhY3Rpb25Qcm94eShhZGFwdGVyLCBzdG9yZSwgcHJlbG9hZGVkID0gW10pIHtcbiAgY29uc3QgX2NpZCA9IGFkYXB0ZXIuY2lkO1xuICByZXR1cm4ge1xuICAgIGNyZWF0ZShyZWNvcmQpIHtcbiAgICAgIHN0b3JlLmFkZCh7IC4uLnJlY29yZCwgX2NpZCB9KTtcbiAgICB9LFxuXG4gICAgdXBkYXRlKHJlY29yZCkge1xuICAgICAgcmV0dXJuIHN0b3JlLnB1dCh7IC4uLnJlY29yZCwgX2NpZCB9KTtcbiAgICB9LFxuXG4gICAgZGVsZXRlKGlkKSB7XG4gICAgICBzdG9yZS5kZWxldGUoW19jaWQsIGlkXSk7XG4gICAgfSxcblxuICAgIGdldChpZCkge1xuICAgICAgcmV0dXJuIHByZWxvYWRlZFtpZF07XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBVcCB0byB2ZXJzaW9uIDEwLlggb2Yga2ludG8uanMsIGVhY2ggY29sbGVjdGlvbiBoYWQgaXRzIG93biBjb2xsZWN0aW9uLlxuICogVGhlIGRhdGFiYXNlIG5hbWUgd2FzIGAke2JpZH0vJHtjaWR9YCAoZWcuIGBcImJsb2NrbGlzdHMvY2VydGlmaWNhdGVzXCJgKVxuICogYW5kIGNvbnRhaW5lZCBvbmx5IG9uZSBzdG9yZSB3aXRoIHRoZSBzYW1lIG5hbWUuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIG1pZ3JhdGlvblJlcXVpcmVkKGRiTmFtZSkge1xuICBsZXQgZXhpc3RzID0gdHJ1ZTtcbiAgY29uc3QgZGIgPSBhd2FpdCBvcGVuKGRiTmFtZSwge1xuICAgIHZlcnNpb246IDEsXG4gICAgb251cGdyYWRlbmVlZGVkOiBldmVudCA9PiB7XG4gICAgICBleGlzdHMgPSBmYWxzZTtcbiAgICB9LFxuICB9KTtcblxuICAvLyBDaGVjayB0aGF0IHRoZSBEQiB3ZSdyZSBsb29raW5nIGF0IGlzIHJlYWxseSBhIGxlZ2FjeSBvbmUsXG4gIC8vIGFuZCBub3Qgc29tZSByZW1haW5kZXIgb2YgdGhlIG9wZW4oKSBvcGVyYXRpb24gYWJvdmUuXG4gIGV4aXN0cyAmPVxuICAgIGRiLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoXCJfX21ldGFfX1wiKSAmJlxuICAgIGRiLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoZGJOYW1lKTtcblxuICBpZiAoIWV4aXN0cykge1xuICAgIGRiLmNsb3NlKCk7XG4gICAgLy8gVGVzdGluZyB0aGUgZXhpc3RlbmNlIGNyZWF0ZXMgaXQsIHNvIGRlbGV0ZSBpdCA6KVxuICAgIGF3YWl0IGRlbGV0ZURhdGFiYXNlKGRiTmFtZSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zb2xlLndhcm4oYCR7ZGJOYW1lfTogb2xkIEluZGV4ZWREQiBkYXRhYmFzZSBmb3VuZC5gKTtcbiAgdHJ5IHtcbiAgICAvLyBTY2FuIGFsbCByZWNvcmRzLlxuICAgIGxldCByZWNvcmRzO1xuICAgIGF3YWl0IGV4ZWN1dGUoZGIsIGRiTmFtZSwgc3RvcmUgPT4ge1xuICAgICAgc3RvcmUub3BlbkN1cnNvcigpLm9uc3VjY2VzcyA9IGN1cnNvckhhbmRsZXJzLmFsbChcbiAgICAgICAge30sXG4gICAgICAgIHJlcyA9PiAocmVjb3JkcyA9IHJlcylcbiAgICAgICk7XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coYCR7ZGJOYW1lfTogZm91bmQgJHtyZWNvcmRzLmxlbmd0aH0gcmVjb3Jkcy5gKTtcblxuICAgIC8vIENoZWNrIGlmIHRoZXJlJ3MgYSBlbnRyeSBmb3IgdGhpcy5cbiAgICBsZXQgdGltZXN0YW1wID0gbnVsbDtcbiAgICBhd2FpdCBleGVjdXRlKGRiLCBcIl9fbWV0YV9fXCIsIHN0b3JlID0+IHtcbiAgICAgIHN0b3JlLmdldChgJHtkYk5hbWV9LWxhc3RNb2RpZmllZGApLm9uc3VjY2VzcyA9IGUgPT4ge1xuICAgICAgICB0aW1lc3RhbXAgPSBlLnRhcmdldC5yZXN1bHQgPyBlLnRhcmdldC5yZXN1bHQudmFsdWUgOiBudWxsO1xuICAgICAgfTtcbiAgICB9KTtcbiAgICAvLyBTb21lIHByZXZpb3VzIHZlcnNpb25zLCBhbHNvIHVzZWQgdG8gc3RvcmUgdGhlIHRpbWVzdGFtcHMgd2l0aG91dCBwcmVmaXguXG4gICAgaWYgKCF0aW1lc3RhbXApIHtcbiAgICAgIGF3YWl0IGV4ZWN1dGUoZGIsIFwiX19tZXRhX19cIiwgc3RvcmUgPT4ge1xuICAgICAgICBzdG9yZS5nZXQoXCJsYXN0TW9kaWZpZWRcIikub25zdWNjZXNzID0gZSA9PiB7XG4gICAgICAgICAgdGltZXN0YW1wID0gZS50YXJnZXQucmVzdWx0ID8gZS50YXJnZXQucmVzdWx0LnZhbHVlIDogbnVsbDtcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZyhgJHtkYk5hbWV9OiAke3RpbWVzdGFtcCA/IFwiZm91bmRcIiA6IFwibm9cIn0gdGltZXN0YW1wLmApO1xuXG4gICAgLy8gVGhvc2Ugd2lsbCBiZSBpbnNlcnRlZCBpbiB0aGUgbmV3IGRhdGFiYXNlL3NjaGVtYS5cbiAgICByZXR1cm4geyByZWNvcmRzLCB0aW1lc3RhbXAgfTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBvY2N1cmVkIGR1cmluZyBtaWdyYXRpb25cIiwgZSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH0gZmluYWxseSB7XG4gICAgZGIuY2xvc2UoKTtcbiAgfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qKlxuICogQmFzZSBkYiBhZGFwdGVyLlxuICpcbiAqIEBhYnN0cmFjdFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCYXNlQWRhcHRlciB7XG4gIC8qKlxuICAgKiBEZWxldGVzIGV2ZXJ5IHJlY29yZHMgcHJlc2VudCBpbiB0aGUgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgY2xlYXIoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IEltcGxlbWVudGVkLlwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlcyBhIGJhdGNoIG9mIG9wZXJhdGlvbnMgd2l0aGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtICB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBvcGVyYXRpb24gY2FsbGJhY2suXG4gICAqIEBwYXJhbSAge09iamVjdH0gICBvcHRpb25zICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBleGVjdXRlKGNhbGxiYWNrLCBvcHRpb25zID0geyBwcmVsb2FkOiBbXSB9KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IEltcGxlbWVudGVkLlwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBhIHJlY29yZCBieSBpdHMgcHJpbWFyeSBrZXkgZnJvbSB0aGUgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkIFRoZSByZWNvcmQgaWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBnZXQoaWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgSW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3RzIGFsbCByZWNvcmRzIGZyb20gdGhlIGRhdGFiYXNlLlxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtICB7T2JqZWN0fSBwYXJhbXMgIFRoZSBmaWx0ZXJzIGFuZCBvcmRlciB0byBhcHBseSB0byB0aGUgcmVzdWx0cy5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGxpc3QocGFyYW1zID0geyBmaWx0ZXJzOiB7fSwgb3JkZXI6IFwiXCIgfSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIk5vdCBJbXBsZW1lbnRlZC5cIik7XG4gIH1cblxuICAvKipcbiAgICogU3RvcmUgdGhlIGxhc3RNb2RpZmllZCB2YWx1ZS5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSAge051bWJlcn0gIGxhc3RNb2RpZmllZFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgc2F2ZUxhc3RNb2RpZmllZChsYXN0TW9kaWZpZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgSW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHNhdmVkIGxhc3RNb2RpZmllZCB2YWx1ZS5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBnZXRMYXN0TW9kaWZpZWQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IEltcGxlbWVudGVkLlwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIHJlY29yZHMgaW4gYnVsayB0aGF0IHdlcmUgZXhwb3J0ZWQgZnJvbSBhIHNlcnZlci5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSAge0FycmF5fSByZWNvcmRzIFRoZSByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBpbXBvcnRCdWxrKHJlY29yZHMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgSW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgYSBkdW1wIG9mIHJlY29yZHMgZXhwb3J0ZWQgZnJvbSBhIHNlcnZlci5cbiAgICpcbiAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayBpbXBvcnRCdWxrfSBpbnN0ZWFkLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtICB7QXJyYXl9IHJlY29yZHMgVGhlIHJlY29yZHMgdG8gbG9hZC5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGxvYWREdW1wKHJlY29yZHMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgSW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgc2F2ZU1ldGFkYXRhKG1ldGFkYXRhKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IEltcGxlbWVudGVkLlwiKTtcbiAgfVxuXG4gIGdldE1ldGFkYXRhKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIk5vdCBJbXBsZW1lbnRlZC5cIik7XG4gIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgQmFzZUFkYXB0ZXIgZnJvbSBcIi4vYWRhcHRlcnMvYmFzZVwiO1xuaW1wb3J0IElEQiBmcm9tIFwiLi9hZGFwdGVycy9JREJcIjtcbmltcG9ydCB7IHdhdGVyZmFsbCwgZGVlcEVxdWFsIH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IHY0IGFzIHV1aWQ0IH0gZnJvbSBcInV1aWRcIjtcbmltcG9ydCB7IG9taXRLZXlzLCBSRV9SRUNPUkRfSUQgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5jb25zdCBSRUNPUkRfRklFTERTX1RPX0NMRUFOID0gW1wiX3N0YXR1c1wiXTtcbmNvbnN0IEFWQUlMQUJMRV9IT09LUyA9IFtcImluY29taW5nLWNoYW5nZXNcIl07XG5jb25zdCBJTVBPUlRfQ0hVTktfU0laRSA9IDIwMDtcblxuLyoqXG4gKiBDb21wYXJlIHR3byByZWNvcmRzIG9taXR0aW5nIGxvY2FsIGZpZWxkcyBhbmQgc3luY2hyb25pemF0aW9uXG4gKiBhdHRyaWJ1dGVzIChsaWtlIF9zdGF0dXMgYW5kIGxhc3RfbW9kaWZpZWQpXG4gKiBAcGFyYW0ge09iamVjdH0gYSAgICBBIHJlY29yZCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IGIgICAgQSByZWNvcmQgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7QXJyYXl9IGxvY2FsRmllbGRzIEFkZGl0aW9uYWwgZmllbGRzIHRvIGlnbm9yZSBkdXJpbmcgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRzRXF1YWwoYSwgYiwgbG9jYWxGaWVsZHMgPSBbXSkge1xuICBjb25zdCBmaWVsZHNUb0NsZWFuID0gUkVDT1JEX0ZJRUxEU19UT19DTEVBTi5jb25jYXQoW1wibGFzdF9tb2RpZmllZFwiXSkuY29uY2F0KFxuICAgIGxvY2FsRmllbGRzXG4gICk7XG4gIGNvbnN0IGNsZWFuTG9jYWwgPSByID0+IG9taXRLZXlzKHIsIGZpZWxkc1RvQ2xlYW4pO1xuICByZXR1cm4gZGVlcEVxdWFsKGNsZWFuTG9jYWwoYSksIGNsZWFuTG9jYWwoYikpO1xufVxuXG4vKipcbiAqIFN5bmNocm9uaXphdGlvbiByZXN1bHQgb2JqZWN0LlxuICovXG5leHBvcnQgY2xhc3MgU3luY1Jlc3VsdE9iamVjdCB7XG4gIC8qKlxuICAgKiBQdWJsaWMgY29uc3RydWN0b3IuXG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvKipcbiAgICAgKiBDdXJyZW50IHN5bmNocm9uaXphdGlvbiByZXN1bHQgc3RhdHVzOyBiZWNvbWVzIGBmYWxzZWAgd2hlbiBjb25mbGljdHMgb3JcbiAgICAgKiBlcnJvcnMgYXJlIHJlZ2lzdGVyZWQuXG4gICAgICogQHR5cGUge0Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5sYXN0TW9kaWZpZWQgPSBudWxsO1xuICAgIHRoaXMuX2xpc3RzID0ge307XG4gICAgW1xuICAgICAgXCJlcnJvcnNcIixcbiAgICAgIFwiY3JlYXRlZFwiLFxuICAgICAgXCJ1cGRhdGVkXCIsXG4gICAgICBcImRlbGV0ZWRcIixcbiAgICAgIFwicHVibGlzaGVkXCIsXG4gICAgICBcImNvbmZsaWN0c1wiLFxuICAgICAgXCJza2lwcGVkXCIsXG4gICAgICBcInJlc29sdmVkXCIsXG4gICAgICBcInZvaWRcIixcbiAgICBdLmZvckVhY2gobCA9PiAodGhpcy5fbGlzdHNbbF0gPSBbXSkpO1xuICAgIHRoaXMuX2NhY2hlZCA9IHt9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgZW50cmllcyBmb3IgYSBnaXZlbiByZXN1bHQgdHlwZS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgICAgVGhlIHJlc3VsdCB0eXBlLlxuICAgKiBAcGFyYW0ge0FycmF5fSAgZW50cmllcyBUaGUgcmVzdWx0IGVudHJpZXMuXG4gICAqIEByZXR1cm4ge1N5bmNSZXN1bHRPYmplY3R9XG4gICAqL1xuICBhZGQodHlwZSwgZW50cmllcykge1xuICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLl9saXN0c1t0eXBlXSkpIHtcbiAgICAgIGNvbnNvbGUud2FybihgVW5rbm93biB0eXBlIFwiJHt0eXBlfVwiYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghQXJyYXkuaXNBcnJheShlbnRyaWVzKSkge1xuICAgICAgZW50cmllcyA9IFtlbnRyaWVzXTtcbiAgICB9XG4gICAgdGhpcy5fbGlzdHNbdHlwZV0gPSB0aGlzLl9saXN0c1t0eXBlXS5jb25jYXQoZW50cmllcyk7XG4gICAgZGVsZXRlIHRoaXMuX2NhY2hlZFt0eXBlXTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGdldCBvaygpIHtcbiAgICByZXR1cm4gdGhpcy5lcnJvcnMubGVuZ3RoICsgdGhpcy5jb25mbGljdHMubGVuZ3RoID09PSAwO1xuICB9XG5cbiAgZ2V0IGVycm9ycygpIHtcbiAgICByZXR1cm4gdGhpcy5fbGlzdHNbXCJlcnJvcnNcIl07XG4gIH1cblxuICBnZXQgY29uZmxpY3RzKCkge1xuICAgIHJldHVybiB0aGlzLl9saXN0c1tcImNvbmZsaWN0c1wiXTtcbiAgfVxuXG4gIGdldCBza2lwcGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9kZWR1cGxpY2F0ZShcInNraXBwZWRcIik7XG4gIH1cblxuICBnZXQgcmVzb2x2ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RlZHVwbGljYXRlKFwicmVzb2x2ZWRcIik7XG4gIH1cblxuICBnZXQgY3JlYXRlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZGVkdXBsaWNhdGUoXCJjcmVhdGVkXCIpO1xuICB9XG5cbiAgZ2V0IHVwZGF0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RlZHVwbGljYXRlKFwidXBkYXRlZFwiKTtcbiAgfVxuXG4gIGdldCBkZWxldGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9kZWR1cGxpY2F0ZShcImRlbGV0ZWRcIik7XG4gIH1cblxuICBnZXQgcHVibGlzaGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9kZWR1cGxpY2F0ZShcInB1Ymxpc2hlZFwiKTtcbiAgfVxuXG4gIF9kZWR1cGxpY2F0ZShsaXN0KSB7XG4gICAgaWYgKCEobGlzdCBpbiB0aGlzLl9jYWNoZWQpKSB7XG4gICAgICAvLyBEZWR1cGxpY2F0ZSBlbnRyaWVzIGJ5IGlkLiBJZiB0aGUgdmFsdWVzIGRvbid0IGhhdmUgYGlkYCBhdHRyaWJ1dGUsIGp1c3RcbiAgICAgIC8vIGtlZXAgYWxsLlxuICAgICAgY29uc3QgcmVjb3Jkc1dpdGhvdXRJZCA9IG5ldyBTZXQoKTtcbiAgICAgIGNvbnN0IHJlY29yZHNCeUlkID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy5fbGlzdHNbbGlzdF0uZm9yRWFjaChyZWNvcmQgPT4ge1xuICAgICAgICBpZiAoIXJlY29yZC5pZCkge1xuICAgICAgICAgIHJlY29yZHNXaXRob3V0SWQuYWRkKHJlY29yZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVjb3Jkc0J5SWQuc2V0KHJlY29yZC5pZCwgcmVjb3JkKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLl9jYWNoZWRbbGlzdF0gPSBBcnJheS5mcm9tKHJlY29yZHNCeUlkLnZhbHVlcygpKS5jb25jYXQoXG4gICAgICAgIEFycmF5LmZyb20ocmVjb3Jkc1dpdGhvdXRJZClcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jYWNoZWRbbGlzdF07XG4gIH1cblxuICAvKipcbiAgICogUmVpbml0aWFsaXplcyByZXN1bHQgZW50cmllcyBmb3IgYSBnaXZlbiByZXN1bHQgdHlwZS5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSB0eXBlIFRoZSByZXN1bHQgdHlwZS5cbiAgICogQHJldHVybiB7U3luY1Jlc3VsdE9iamVjdH1cbiAgICovXG4gIHJlc2V0KHR5cGUpIHtcbiAgICB0aGlzLl9saXN0c1t0eXBlXSA9IFtdO1xuICAgIGRlbGV0ZSB0aGlzLl9jYWNoZWRbdHlwZV07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB0b09iamVjdCgpIHtcbiAgICAvLyBPbmx5IHVzZWQgaW4gdGVzdHMuXG4gICAgcmV0dXJuIHtcbiAgICAgIG9rOiB0aGlzLm9rLFxuICAgICAgbGFzdE1vZGlmaWVkOiB0aGlzLmxhc3RNb2RpZmllZCxcbiAgICAgIGVycm9yczogdGhpcy5lcnJvcnMsXG4gICAgICBjcmVhdGVkOiB0aGlzLmNyZWF0ZWQsXG4gICAgICB1cGRhdGVkOiB0aGlzLnVwZGF0ZWQsXG4gICAgICBkZWxldGVkOiB0aGlzLmRlbGV0ZWQsXG4gICAgICBza2lwcGVkOiB0aGlzLnNraXBwZWQsXG4gICAgICBwdWJsaXNoZWQ6IHRoaXMucHVibGlzaGVkLFxuICAgICAgY29uZmxpY3RzOiB0aGlzLmNvbmZsaWN0cyxcbiAgICAgIHJlc29sdmVkOiB0aGlzLnJlc29sdmVkLFxuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNlcnZlcldhc0ZsdXNoZWRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IoY2xpZW50VGltZXN0YW1wLCBzZXJ2ZXJUaW1lc3RhbXAsIG1lc3NhZ2UpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcblxuICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgU2VydmVyV2FzRmx1c2hlZEVycm9yKTtcbiAgICB9XG5cbiAgICB0aGlzLmNsaWVudFRpbWVzdGFtcCA9IGNsaWVudFRpbWVzdGFtcDtcbiAgICB0aGlzLnNlcnZlclRpbWVzdGFtcCA9IHNlcnZlclRpbWVzdGFtcDtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVVVUlEU2NoZW1hKCkge1xuICByZXR1cm4ge1xuICAgIGdlbmVyYXRlKCkge1xuICAgICAgcmV0dXJuIHV1aWQ0KCk7XG4gICAgfSxcblxuICAgIHZhbGlkYXRlKGlkKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIGlkID09IFwic3RyaW5nXCIgJiYgUkVfUkVDT1JEX0lELnRlc3QoaWQpO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogSURTY2hlbWEgZm9yIHdoZW4gdXNpbmcga2ludG8uanMgYXMgYSBrZXktdmFsdWUgc3RvcmUuXG4gKiBVc2luZyB0aGlzIElEU2NoZW1hIHJlcXVpcmVzIHlvdSB0byBzZXQgYSBwcm9wZXJ0eSBhcyB0aGUgaWQuXG4gKiBUaGlzIHdpbGwgYmUgdGhlIHByb3BlcnR5IHVzZWQgdG8gcmV0cmlldmUgdGhpcyByZWNvcmQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGV4YW1wbGVDb2xsZWN0aW9uID0gZGIuY29sbGVjdGlvbihcImV4YW1wbGVcIiwgeyBpZFNjaGVtYTogY3JlYXRlS2V5VmFsdWVTdG9yZUlkU2NoZW1hKCkgfSlcbiAqIGF3YWl0IGV4YW1wbGVDb2xsZWN0aW9uLmNyZWF0ZSh7IHRpdGxlOiBcIkhvdyB0byB0aWUgYSB0aWVcIiwgZmF2b3JpdGVDb2xvcjogXCJibHVlXCIsIGlkOiBcInVzZXIxMjNcIiB9LCB7IHVzZVJlY29yZElkOiB0cnVlIH0pXG4gKiBhd2FpdCBleGFtcGxlQ29sbGVjdGlvbi5nZXRBbnkoXCJ1c2VyMTIzXCIpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVLZXlWYWx1ZVN0b3JlSWRTY2hlbWEoKSB7XG4gIHJldHVybiB7XG4gICAgZ2VuZXJhdGUoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjcmVhdGVLZXlWYWx1ZVN0b3JlSWRTY2hlbWEoKSBkb2VzIG5vdCBnZW5lcmF0ZSBhbiBpZFwiKTtcbiAgICB9LFxuICAgIHZhbGlkYXRlKCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbWFya1N0YXR1cyhyZWNvcmQsIHN0YXR1cykge1xuICByZXR1cm4geyAuLi5yZWNvcmQsIF9zdGF0dXM6IHN0YXR1cyB9O1xufVxuXG5mdW5jdGlvbiBtYXJrRGVsZXRlZChyZWNvcmQpIHtcbiAgcmV0dXJuIG1hcmtTdGF0dXMocmVjb3JkLCBcImRlbGV0ZWRcIik7XG59XG5cbmZ1bmN0aW9uIG1hcmtTeW5jZWQocmVjb3JkKSB7XG4gIHJldHVybiBtYXJrU3RhdHVzKHJlY29yZCwgXCJzeW5jZWRcIik7XG59XG5cbi8qKlxuICogSW1wb3J0IGEgcmVtb3RlIGNoYW5nZSBpbnRvIHRoZSBsb2NhbCBkYXRhYmFzZS5cbiAqXG4gKiBAcGFyYW0gIHtJREJUcmFuc2FjdGlvblByb3h5fSB0cmFuc2FjdGlvbiBUaGUgdHJhbnNhY3Rpb24gaGFuZGxlci5cbiAqIEBwYXJhbSAge09iamVjdH0gICAgICAgICAgICAgIHJlbW90ZSAgICAgIFRoZSByZW1vdGUgY2hhbmdlIG9iamVjdCB0byBpbXBvcnQuXG4gKiBAcGFyYW0gIHtBcnJheTxTdHJpbmc+fSAgICAgICBsb2NhbEZpZWxkcyBUaGUgbGlzdCBvZiBmaWVsZHMgdGhhdCByZW1haW4gbG9jYWwuXG4gKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgICAgICAgICBzdHJhdGVneSAgICBUaGUge0BsaW5rIENvbGxlY3Rpb24uc3RyYXRlZ3l9LlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBpbXBvcnRDaGFuZ2UodHJhbnNhY3Rpb24sIHJlbW90ZSwgbG9jYWxGaWVsZHMsIHN0cmF0ZWd5KSB7XG4gIGNvbnN0IGxvY2FsID0gdHJhbnNhY3Rpb24uZ2V0KHJlbW90ZS5pZCk7XG4gIGlmICghbG9jYWwpIHtcbiAgICAvLyBOb3QgZm91bmQgbG9jYWxseSBidXQgcmVtb3RlIGNoYW5nZSBpcyBtYXJrZWQgYXMgZGVsZXRlZDsgc2tpcCB0b1xuICAgIC8vIGF2b2lkIHJlY3JlYXRpb24uXG4gICAgaWYgKHJlbW90ZS5kZWxldGVkKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcInNraXBwZWRcIiwgZGF0YTogcmVtb3RlIH07XG4gICAgfVxuICAgIGNvbnN0IHN5bmNlZCA9IG1hcmtTeW5jZWQocmVtb3RlKTtcbiAgICB0cmFuc2FjdGlvbi5jcmVhdGUoc3luY2VkKTtcbiAgICByZXR1cm4geyB0eXBlOiBcImNyZWF0ZWRcIiwgZGF0YTogc3luY2VkIH07XG4gIH1cbiAgLy8gQXBwbHkgcmVtb3RlIGNoYW5nZXMgb24gbG9jYWwgcmVjb3JkLlxuICBjb25zdCBzeW5jZWQgPSB7IC4uLmxvY2FsLCAuLi5tYXJrU3luY2VkKHJlbW90ZSkgfTtcblxuICAvLyBXaXRoIHB1bGwgb25seSwgd2UgZG9uJ3QgbmVlZCB0byBjb21wYXJlIHJlY29yZHMgc2luY2Ugd2Ugb3ZlcnJpZGUgdGhlbS5cbiAgaWYgKHN0cmF0ZWd5ID09PSBDb2xsZWN0aW9uLnN0cmF0ZWd5LlBVTExfT05MWSkge1xuICAgIGlmIChyZW1vdGUuZGVsZXRlZCkge1xuICAgICAgdHJhbnNhY3Rpb24uZGVsZXRlKHJlbW90ZS5pZCk7XG4gICAgICByZXR1cm4geyB0eXBlOiBcImRlbGV0ZWRcIiwgZGF0YTogbG9jYWwgfTtcbiAgICB9XG4gICAgdHJhbnNhY3Rpb24udXBkYXRlKHN5bmNlZCk7XG4gICAgcmV0dXJuIHsgdHlwZTogXCJ1cGRhdGVkXCIsIGRhdGE6IHsgb2xkOiBsb2NhbCwgbmV3OiBzeW5jZWQgfSB9O1xuICB9XG5cbiAgLy8gV2l0aCBvdGhlciBzeW5jIHN0cmF0ZWdpZXMsIHdlIGRldGVjdCBjb25mbGljdHMsXG4gIC8vIGJ5IGNvbXBhcmluZyBsb2NhbCBhbmQgcmVtb3RlLCBpZ25vcmluZyBsb2NhbCBmaWVsZHMuXG4gIGNvbnN0IGlzSWRlbnRpY2FsID0gcmVjb3Jkc0VxdWFsKGxvY2FsLCByZW1vdGUsIGxvY2FsRmllbGRzKTtcbiAgLy8gRGV0ZWN0IG9yIGlnbm9yZSBjb25mbGljdHMgaWYgcmVjb3JkIGhhcyBhbHNvIGJlZW4gbW9kaWZpZWQgbG9jYWxseS5cbiAgaWYgKGxvY2FsLl9zdGF0dXMgIT09IFwic3luY2VkXCIpIHtcbiAgICAvLyBMb2NhbGx5IGRlbGV0ZWQsIHVuc3luY2VkOiBzY2hlZHVsZWQgZm9yIHJlbW90ZSBkZWxldGlvbi5cbiAgICBpZiAobG9jYWwuX3N0YXR1cyA9PT0gXCJkZWxldGVkXCIpIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IFwic2tpcHBlZFwiLCBkYXRhOiBsb2NhbCB9O1xuICAgIH1cbiAgICBpZiAoaXNJZGVudGljYWwpIHtcbiAgICAgIC8vIElmIHJlY29yZHMgYXJlIGlkZW50aWNhbCwgaW1wb3J0IGFueXdheSwgc28gd2UgYnVtcCB0aGVcbiAgICAgIC8vIGxvY2FsIGxhc3RfbW9kaWZpZWQgdmFsdWUgZnJvbSB0aGUgc2VydmVyIGFuZCBzZXQgcmVjb3JkXG4gICAgICAvLyBzdGF0dXMgdG8gXCJzeW5jZWRcIi5cbiAgICAgIHRyYW5zYWN0aW9uLnVwZGF0ZShzeW5jZWQpO1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJ1cGRhdGVkXCIsIGRhdGE6IHsgb2xkOiBsb2NhbCwgbmV3OiBzeW5jZWQgfSB9O1xuICAgIH1cbiAgICBpZiAoXG4gICAgICBsb2NhbC5sYXN0X21vZGlmaWVkICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIGxvY2FsLmxhc3RfbW9kaWZpZWQgPT09IHJlbW90ZS5sYXN0X21vZGlmaWVkXG4gICAgKSB7XG4gICAgICAvLyBJZiBvdXIgbG9jYWwgdmVyc2lvbiBoYXMgdGhlIHNhbWUgbGFzdF9tb2RpZmllZCBhcyB0aGUgcmVtb3RlXG4gICAgICAvLyBvbmUsIHRoaXMgcmVwcmVzZW50cyBhbiBvYmplY3QgdGhhdCBjb3JyZXNwb25kcyB0byBhIHJlc29sdmVkXG4gICAgICAvLyBjb25mbGljdC4gT3VyIGxvY2FsIHZlcnNpb24gcmVwcmVzZW50cyB0aGUgZmluYWwgb3V0cHV0LCBzb1xuICAgICAgLy8gd2Uga2VlcCB0aGF0IG9uZS4gKE5vIHRyYW5zYWN0aW9uIG9wZXJhdGlvbiB0byBkby4pXG4gICAgICAvLyBCdXQgaWYgb3VyIGxhc3RfbW9kaWZpZWQgaXMgdW5kZWZpbmVkLFxuICAgICAgLy8gdGhhdCBtZWFucyB3ZSd2ZSBjcmVhdGVkIHRoZSBzYW1lIG9iamVjdCBsb2NhbGx5IGFzIG9uZSBvblxuICAgICAgLy8gdGhlIHNlcnZlciwgd2hpY2ggKm11c3QqIGJlIGEgY29uZmxpY3QuXG4gICAgICByZXR1cm4geyB0eXBlOiBcInZvaWRcIiB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogXCJjb25mbGljdHNcIixcbiAgICAgIGRhdGE6IHsgdHlwZTogXCJpbmNvbWluZ1wiLCBsb2NhbDogbG9jYWwsIHJlbW90ZTogcmVtb3RlIH0sXG4gICAgfTtcbiAgfVxuICAvLyBMb2NhbCByZWNvcmQgd2FzIHN5bmNlZC5cbiAgaWYgKHJlbW90ZS5kZWxldGVkKSB7XG4gICAgdHJhbnNhY3Rpb24uZGVsZXRlKHJlbW90ZS5pZCk7XG4gICAgcmV0dXJuIHsgdHlwZTogXCJkZWxldGVkXCIsIGRhdGE6IGxvY2FsIH07XG4gIH1cbiAgLy8gSW1wb3J0IGxvY2FsbHkuXG4gIHRyYW5zYWN0aW9uLnVwZGF0ZShzeW5jZWQpO1xuICAvLyBpZiBpZGVudGljYWwsIHNpbXBseSBleGNsdWRlIGl0IGZyb20gYWxsIFN5bmNSZXN1bHRPYmplY3QgbGlzdHNcbiAgY29uc3QgdHlwZSA9IGlzSWRlbnRpY2FsID8gXCJ2b2lkXCIgOiBcInVwZGF0ZWRcIjtcbiAgcmV0dXJuIHsgdHlwZSwgZGF0YTogeyBvbGQ6IGxvY2FsLCBuZXc6IHN5bmNlZCB9IH07XG59XG5cbi8qKlxuICogQWJzdHJhY3RzIGEgY29sbGVjdGlvbiBvZiByZWNvcmRzIHN0b3JlZCBpbiB0aGUgbG9jYWwgZGF0YWJhc2UsIHByb3ZpZGluZ1xuICogQ1JVRCBvcGVyYXRpb25zIGFuZCBzeW5jaHJvbml6YXRpb24gaGVscGVycy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29sbGVjdGlvbiB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rvci5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSBge0Jhc2VBZGFwdGVyfSBhZGFwdGVyYCBUaGUgREIgYWRhcHRlciAoZGVmYXVsdDogYElEQmApXG4gICAqXG4gICAqIEBwYXJhbSAge1N0cmluZ30gYnVja2V0ICBUaGUgYnVja2V0IGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSAge1N0cmluZ30gbmFtZSAgICBUaGUgY29sbGVjdGlvbiBuYW1lLlxuICAgKiBAcGFyYW0gIHtBcGl9ICAgIGFwaSAgICAgVGhlIEFwaSBpbnN0YW5jZS5cbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGJ1Y2tldCwgbmFtZSwgYXBpLCBvcHRpb25zID0ge30pIHtcbiAgICB0aGlzLl9idWNrZXQgPSBidWNrZXQ7XG4gICAgdGhpcy5fbmFtZSA9IG5hbWU7XG4gICAgdGhpcy5fbGFzdE1vZGlmaWVkID0gbnVsbDtcblxuICAgIGNvbnN0IERCQWRhcHRlciA9IG9wdGlvbnMuYWRhcHRlciB8fCBJREI7XG4gICAgaWYgKCFEQkFkYXB0ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGFkYXB0ZXIgcHJvdmlkZWRcIik7XG4gICAgfVxuICAgIGNvbnN0IGRiID0gbmV3IERCQWRhcHRlcihgJHtidWNrZXR9LyR7bmFtZX1gLCBvcHRpb25zLmFkYXB0ZXJPcHRpb25zKTtcbiAgICBpZiAoIShkYiBpbnN0YW5jZW9mIEJhc2VBZGFwdGVyKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgYWRhcHRlci5cIik7XG4gICAgfVxuICAgIC8vIHB1YmxpYyBwcm9wZXJ0aWVzXG4gICAgLyoqXG4gICAgICogVGhlIGRiIGFkYXB0ZXIgaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7QmFzZUFkYXB0ZXJ9XG4gICAgICovXG4gICAgdGhpcy5kYiA9IGRiO1xuICAgIC8qKlxuICAgICAqIFRoZSBBcGkgaW5zdGFuY2UuXG4gICAgICogQHR5cGUge0tpbnRvQ2xpZW50fVxuICAgICAqL1xuICAgIHRoaXMuYXBpID0gYXBpO1xuICAgIC8qKlxuICAgICAqIFRoZSBldmVudCBlbWl0dGVyIGluc3RhbmNlLlxuICAgICAqIEB0eXBlIHtFdmVudEVtaXR0ZXJ9XG4gICAgICovXG4gICAgdGhpcy5ldmVudHMgPSBvcHRpb25zLmV2ZW50cztcbiAgICAvKipcbiAgICAgKiBUaGUgSWRTY2hlbWEgaW5zdGFuY2UuXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKi9cbiAgICB0aGlzLmlkU2NoZW1hID0gdGhpcy5fdmFsaWRhdGVJZFNjaGVtYShvcHRpb25zLmlkU2NoZW1hKTtcbiAgICAvKipcbiAgICAgKiBUaGUgbGlzdCBvZiByZW1vdGUgdHJhbnNmb3JtZXJzLlxuICAgICAqIEB0eXBlIHtBcnJheX1cbiAgICAgKi9cbiAgICB0aGlzLnJlbW90ZVRyYW5zZm9ybWVycyA9IHRoaXMuX3ZhbGlkYXRlUmVtb3RlVHJhbnNmb3JtZXJzKFxuICAgICAgb3B0aW9ucy5yZW1vdGVUcmFuc2Zvcm1lcnNcbiAgICApO1xuICAgIC8qKlxuICAgICAqIFRoZSBsaXN0IG9mIGhvb2tzLlxuICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICovXG4gICAgdGhpcy5ob29rcyA9IHRoaXMuX3ZhbGlkYXRlSG9va3Mob3B0aW9ucy5ob29rcyk7XG4gICAgLyoqXG4gICAgICogVGhlIGxpc3Qgb2YgZmllbGRzIG5hbWVzIHRoYXQgd2lsbCByZW1haW4gbG9jYWwuXG4gICAgICogQHR5cGUge0FycmF5fVxuICAgICAqL1xuICAgIHRoaXMubG9jYWxGaWVsZHMgPSBvcHRpb25zLmxvY2FsRmllbGRzIHx8IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBjb2xsZWN0aW9uIG5hbWUuXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqL1xuICBnZXQgbmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fbmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYnVja2V0IG5hbWUuXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqL1xuICBnZXQgYnVja2V0KCkge1xuICAgIHJldHVybiB0aGlzLl9idWNrZXQ7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGxhc3QgbW9kaWZpZWQgdGltZXN0YW1wLlxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKi9cbiAgZ2V0IGxhc3RNb2RpZmllZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fbGFzdE1vZGlmaWVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFN5bmNocm9uaXphdGlvbiBzdHJhdGVnaWVzLiBBdmFpbGFibGUgc3RyYXRlZ2llcyBhcmU6XG4gICAqXG4gICAqIC0gYE1BTlVBTGA6IENvbmZsaWN0cyB3aWxsIGJlIHJlcG9ydGVkIGluIGEgZGVkaWNhdGVkIGFycmF5LlxuICAgKiAtIGBTRVJWRVJfV0lOU2A6IENvbmZsaWN0cyBhcmUgcmVzb2x2ZWQgdXNpbmcgcmVtb3RlIGRhdGEuXG4gICAqIC0gYENMSUVOVF9XSU5TYDogQ29uZmxpY3RzIGFyZSByZXNvbHZlZCB1c2luZyBsb2NhbCBkYXRhLlxuICAgKlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgc3RhdGljIGdldCBzdHJhdGVneSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgQ0xJRU5UX1dJTlM6IFwiY2xpZW50X3dpbnNcIixcbiAgICAgIFNFUlZFUl9XSU5TOiBcInNlcnZlcl93aW5zXCIsXG4gICAgICBQVUxMX09OTFk6IFwicHVsbF9vbmx5XCIsXG4gICAgICBNQU5VQUw6IFwibWFudWFsXCIsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYW4gaWRTY2hlbWEuXG4gICAqXG4gICAqIEBwYXJhbSAge09iamVjdHx1bmRlZmluZWR9IGlkU2NoZW1hXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIF92YWxpZGF0ZUlkU2NoZW1hKGlkU2NoZW1hKSB7XG4gICAgaWYgKHR5cGVvZiBpZFNjaGVtYSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgcmV0dXJuIGNyZWF0ZVVVSURTY2hlbWEoKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBpZFNjaGVtYSAhPT0gXCJvYmplY3RcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaWRTY2hlbWEgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGlkU2NoZW1hLmdlbmVyYXRlICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImlkU2NoZW1hIG11c3QgcHJvdmlkZSBhIGdlbmVyYXRlIGZ1bmN0aW9uLlwiKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBpZFNjaGVtYS52YWxpZGF0ZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpZFNjaGVtYSBtdXN0IHByb3ZpZGUgYSB2YWxpZGF0ZSBmdW5jdGlvbi5cIik7XG4gICAgfVxuICAgIHJldHVybiBpZFNjaGVtYTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYSBsaXN0IG9mIHJlbW90ZSB0cmFuc2Zvcm1lcnMuXG4gICAqXG4gICAqIEBwYXJhbSAge0FycmF5fHVuZGVmaW5lZH0gcmVtb3RlVHJhbnNmb3JtZXJzXG4gICAqIEByZXR1cm4ge0FycmF5fVxuICAgKi9cbiAgX3ZhbGlkYXRlUmVtb3RlVHJhbnNmb3JtZXJzKHJlbW90ZVRyYW5zZm9ybWVycykge1xuICAgIGlmICh0eXBlb2YgcmVtb3RlVHJhbnNmb3JtZXJzID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGlmICghQXJyYXkuaXNBcnJheShyZW1vdGVUcmFuc2Zvcm1lcnMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJyZW1vdGVUcmFuc2Zvcm1lcnMgc2hvdWxkIGJlIGFuIGFycmF5LlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlbW90ZVRyYW5zZm9ybWVycy5tYXAodHJhbnNmb3JtZXIgPT4ge1xuICAgICAgaWYgKHR5cGVvZiB0cmFuc2Zvcm1lciAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHRyYW5zZm9ybWVyIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRyYW5zZm9ybWVyLmVuY29kZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgdHJhbnNmb3JtZXIgbXVzdCBwcm92aWRlIGFuIGVuY29kZSBmdW5jdGlvbi5cIik7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0cmFuc2Zvcm1lci5kZWNvZGUgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHRyYW5zZm9ybWVyIG11c3QgcHJvdmlkZSBhIGRlY29kZSBmdW5jdGlvbi5cIik7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJhbnNmb3JtZXI7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhlIHBhc3NlZCBob29rIGlzIGNvcnJlY3QuXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXl8dW5kZWZpbmVkfSBob29rLlxuICAgKiBAcmV0dXJuIHtBcnJheX1cbiAgICoqL1xuICBfdmFsaWRhdGVIb29rKGhvb2spIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoaG9vaykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgaG9vayBkZWZpbml0aW9uIHNob3VsZCBiZSBhbiBhcnJheSBvZiBmdW5jdGlvbnMuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gaG9vay5tYXAoZm4gPT4ge1xuICAgICAgaWYgKHR5cGVvZiBmbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgaG9vayBkZWZpbml0aW9uIHNob3VsZCBiZSBhbiBhcnJheSBvZiBmdW5jdGlvbnMuXCIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZuO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBhIGxpc3Qgb2YgaG9va3MuXG4gICAqXG4gICAqIEBwYXJhbSAge09iamVjdHx1bmRlZmluZWR9IGhvb2tzXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIF92YWxpZGF0ZUhvb2tzKGhvb2tzKSB7XG4gICAgaWYgKHR5cGVvZiBob29rcyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheShob29rcykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImhvb2tzIHNob3VsZCBiZSBhbiBvYmplY3QsIG5vdCBhbiBhcnJheS5cIik7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgaG9va3MgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImhvb2tzIHNob3VsZCBiZSBhbiBvYmplY3QuXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbGlkYXRlZEhvb2tzID0ge307XG5cbiAgICBmb3IgKGNvbnN0IGhvb2sgaW4gaG9va3MpIHtcbiAgICAgIGlmICghQVZBSUxBQkxFX0hPT0tTLmluY2x1ZGVzKGhvb2spKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBcIlRoZSBob29rIHNob3VsZCBiZSBvbmUgb2YgXCIgKyBBVkFJTEFCTEVfSE9PS1Muam9pbihcIiwgXCIpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB2YWxpZGF0ZWRIb29rc1tob29rXSA9IHRoaXMuX3ZhbGlkYXRlSG9vayhob29rc1tob29rXSk7XG4gICAgfVxuICAgIHJldHVybiB2YWxpZGF0ZWRIb29rcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGV2ZXJ5IHJlY29yZHMgaW4gdGhlIGN1cnJlbnQgY29sbGVjdGlvbiBhbmQgbWFya3MgdGhlIGNvbGxlY3Rpb24gYXNcbiAgICogbmV2ZXIgc3luY2VkLlxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgY2xlYXIoKSB7XG4gICAgYXdhaXQgdGhpcy5kYi5jbGVhcigpO1xuICAgIGF3YWl0IHRoaXMuZGIuc2F2ZU1ldGFkYXRhKG51bGwpO1xuICAgIGF3YWl0IHRoaXMuZGIuc2F2ZUxhc3RNb2RpZmllZChudWxsKTtcbiAgICByZXR1cm4geyBkYXRhOiBbXSwgcGVybWlzc2lvbnM6IHt9IH07XG4gIH1cblxuICAvKipcbiAgICogRW5jb2RlcyBhIHJlY29yZC5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSB0eXBlICAgRWl0aGVyIFwicmVtb3RlXCIgb3IgXCJsb2NhbFwiLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHJlY29yZCBUaGUgcmVjb3JkIG9iamVjdCB0byBlbmNvZGUuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBfZW5jb2RlUmVjb3JkKHR5cGUsIHJlY29yZCkge1xuICAgIGlmICghdGhpc1tgJHt0eXBlfVRyYW5zZm9ybWVyc2BdLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZWNvcmQpO1xuICAgIH1cbiAgICByZXR1cm4gd2F0ZXJmYWxsKFxuICAgICAgdGhpc1tgJHt0eXBlfVRyYW5zZm9ybWVyc2BdLm1hcCh0cmFuc2Zvcm1lciA9PiB7XG4gICAgICAgIHJldHVybiByZWNvcmQgPT4gdHJhbnNmb3JtZXIuZW5jb2RlKHJlY29yZCk7XG4gICAgICB9KSxcbiAgICAgIHJlY29yZFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRGVjb2RlcyBhIHJlY29yZC5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSB0eXBlICAgRWl0aGVyIFwicmVtb3RlXCIgb3IgXCJsb2NhbFwiLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHJlY29yZCBUaGUgcmVjb3JkIG9iamVjdCB0byBkZWNvZGUuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBfZGVjb2RlUmVjb3JkKHR5cGUsIHJlY29yZCkge1xuICAgIGlmICghdGhpc1tgJHt0eXBlfVRyYW5zZm9ybWVyc2BdLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZWNvcmQpO1xuICAgIH1cbiAgICByZXR1cm4gd2F0ZXJmYWxsKFxuICAgICAgdGhpc1tgJHt0eXBlfVRyYW5zZm9ybWVyc2BdLnJldmVyc2UoKS5tYXAodHJhbnNmb3JtZXIgPT4ge1xuICAgICAgICByZXR1cm4gcmVjb3JkID0+IHRyYW5zZm9ybWVyLmRlY29kZShyZWNvcmQpO1xuICAgICAgfSksXG4gICAgICByZWNvcmRcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZWNvcmQgdG8gdGhlIGxvY2FsIGRhdGFiYXNlLCBhc3NlcnRpbmcgdGhhdCBub25lXG4gICAqIGFscmVhZHkgZXhpc3Qgd2l0aCB0aGlzIElELlxuICAgKlxuICAgKiBOb3RlOiBJZiBlaXRoZXIgdGhlIGB1c2VSZWNvcmRJZGAgb3IgYHN5bmNlZGAgb3B0aW9ucyBhcmUgdHJ1ZSwgdGhlbiB0aGVcbiAgICogcmVjb3JkIG9iamVjdCBtdXN0IGNvbnRhaW4gdGhlIGlkIGZpZWxkIHRvIGJlIHZhbGlkYXRlZC4gSWYgbm9uZSBvZiB0aGVzZVxuICAgKiBvcHRpb25zIGFyZSB0cnVlLCBhbiBpZCBpcyBnZW5lcmF0ZWQgdXNpbmcgdGhlIGN1cnJlbnQgSWRTY2hlbWE7IGluIHRoaXNcbiAgICogY2FzZSwgdGhlIHJlY29yZCBwYXNzZWQgbXVzdCBub3QgaGF2ZSBhbiBpZC5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7Qm9vbGVhbn0gc3luY2VkICAgICAgIFNldHMgcmVjb3JkIHN0YXR1cyB0byBcInN5bmNlZFwiIChkZWZhdWx0OiBgZmFsc2VgKS5cbiAgICogLSB7Qm9vbGVhbn0gdXNlUmVjb3JkSWQgIEZvcmNlcyB0aGUgYGlkYCBmaWVsZCBmcm9tIHRoZSByZWNvcmQgdG8gYmUgdXNlZCxcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RlYWQgb2Ygb25lIHRoYXQgaXMgZ2VuZXJhdGVkIGF1dG9tYXRpY2FsbHlcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgIChkZWZhdWx0OiBgZmFsc2VgKS5cbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSByZWNvcmRcbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBjcmVhdGUocmVjb3JkLCBvcHRpb25zID0geyB1c2VSZWNvcmRJZDogZmFsc2UsIHN5bmNlZDogZmFsc2UgfSkge1xuICAgIC8vIFZhbGlkYXRlIHRoZSByZWNvcmQgYW5kIGl0cyBJRCAoaWYgYW55KSwgZXZlbiB0aG91Z2ggdGhpc1xuICAgIC8vIHZhbGlkYXRpb24gaXMgYWxzbyBkb25lIGluIHRoZSBDb2xsZWN0aW9uVHJhbnNhY3Rpb24gbWV0aG9kLFxuICAgIC8vIGJlY2F1c2Ugd2UgbmVlZCB0byBwYXNzIHRoZSBJRCB0byBwcmVsb2FkSWRzLlxuICAgIGNvbnN0IHJlamVjdCA9IG1zZyA9PiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IobXNnKSk7XG4gICAgaWYgKHR5cGVvZiByZWNvcmQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHJldHVybiByZWplY3QoXCJSZWNvcmQgaXMgbm90IGFuIG9iamVjdC5cIik7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIChvcHRpb25zLnN5bmNlZCB8fCBvcHRpb25zLnVzZVJlY29yZElkKSAmJlxuICAgICAgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChyZWNvcmQsIFwiaWRcIilcbiAgICApIHtcbiAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgIFwiTWlzc2luZyByZXF1aXJlZCBJZDsgc3luY2VkIGFuZCB1c2VSZWNvcmRJZCBvcHRpb25zIHJlcXVpcmUgb25lXCJcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICFvcHRpb25zLnN5bmNlZCAmJlxuICAgICAgIW9wdGlvbnMudXNlUmVjb3JkSWQgJiZcbiAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChyZWNvcmQsIFwiaWRcIilcbiAgICApIHtcbiAgICAgIHJldHVybiByZWplY3QoXCJFeHRyYW5lb3VzIElkOyBjYW4ndCBjcmVhdGUgYSByZWNvcmQgaGF2aW5nIG9uZSBzZXQuXCIpO1xuICAgIH1cbiAgICBjb25zdCBuZXdSZWNvcmQgPSB7XG4gICAgICAuLi5yZWNvcmQsXG4gICAgICBpZDpcbiAgICAgICAgb3B0aW9ucy5zeW5jZWQgfHwgb3B0aW9ucy51c2VSZWNvcmRJZFxuICAgICAgICAgID8gcmVjb3JkLmlkXG4gICAgICAgICAgOiB0aGlzLmlkU2NoZW1hLmdlbmVyYXRlKHJlY29yZCksXG4gICAgICBfc3RhdHVzOiBvcHRpb25zLnN5bmNlZCA/IFwic3luY2VkXCIgOiBcImNyZWF0ZWRcIixcbiAgICB9O1xuICAgIGlmICghdGhpcy5pZFNjaGVtYS52YWxpZGF0ZShuZXdSZWNvcmQuaWQpKSB7XG4gICAgICByZXR1cm4gcmVqZWN0KGBJbnZhbGlkIElkOiAke25ld1JlY29yZC5pZH1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSh0eG4gPT4gdHhuLmNyZWF0ZShuZXdSZWNvcmQpLCB7XG4gICAgICBwcmVsb2FkSWRzOiBbbmV3UmVjb3JkLmlkXSxcbiAgICB9KS5jYXRjaChlcnIgPT4ge1xuICAgICAgaWYgKG9wdGlvbnMudXNlUmVjb3JkSWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiQ291bGRuJ3QgY3JlYXRlIHJlY29yZC4gSXQgbWF5IGhhdmUgYmVlbiB2aXJ0dWFsbHkgZGVsZXRlZC5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExpa2Uge0BsaW5rIENvbGxlY3Rpb25UcmFuc2FjdGlvbiN1cGRhdGV9LCBidXQgd3JhcHBlZCBpbiBpdHMgb3duIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtCb29sZWFufSBzeW5jZWQ6IFNldHMgcmVjb3JkIHN0YXR1cyB0byBcInN5bmNlZFwiIChkZWZhdWx0OiBmYWxzZSlcbiAgICogLSB7Qm9vbGVhbn0gcGF0Y2g6ICBFeHRlbmRzIHRoZSBleGlzdGluZyByZWNvcmQgaW5zdGVhZCBvZiBvdmVyd3JpdGluZyBpdFxuICAgKiAgIChkZWZhdWx0OiBmYWxzZSlcbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSByZWNvcmRcbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICB1cGRhdGUocmVjb3JkLCBvcHRpb25zID0geyBzeW5jZWQ6IGZhbHNlLCBwYXRjaDogZmFsc2UgfSkge1xuICAgIC8vIFZhbGlkYXRlIHRoZSByZWNvcmQgYW5kIGl0cyBJRCwgZXZlbiB0aG91Z2ggdGhpcyB2YWxpZGF0aW9uIGlzXG4gICAgLy8gYWxzbyBkb25lIGluIHRoZSBDb2xsZWN0aW9uVHJhbnNhY3Rpb24gbWV0aG9kLCBiZWNhdXNlIHdlIG5lZWRcbiAgICAvLyB0byBwYXNzIHRoZSBJRCB0byBwcmVsb2FkSWRzLlxuICAgIGlmICh0eXBlb2YgcmVjb3JkICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiUmVjb3JkIGlzIG5vdCBhbiBvYmplY3QuXCIpKTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVjb3JkLCBcImlkXCIpKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQ2Fubm90IHVwZGF0ZSBhIHJlY29yZCBtaXNzaW5nIGlkLlwiKSk7XG4gICAgfVxuICAgIGlmICghdGhpcy5pZFNjaGVtYS52YWxpZGF0ZShyZWNvcmQuaWQpKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKGBJbnZhbGlkIElkOiAke3JlY29yZC5pZH1gKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSh0eG4gPT4gdHhuLnVwZGF0ZShyZWNvcmQsIG9wdGlvbnMpLCB7XG4gICAgICBwcmVsb2FkSWRzOiBbcmVjb3JkLmlkXSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaWtlIHtAbGluayBDb2xsZWN0aW9uVHJhbnNhY3Rpb24jdXBzZXJ0fSwgYnV0IHdyYXBwZWQgaW4gaXRzIG93biB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSByZWNvcmRcbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIHVwc2VydChyZWNvcmQpIHtcbiAgICAvLyBWYWxpZGF0ZSB0aGUgcmVjb3JkIGFuZCBpdHMgSUQsIGV2ZW4gdGhvdWdoIHRoaXMgdmFsaWRhdGlvbiBpc1xuICAgIC8vIGFsc28gZG9uZSBpbiB0aGUgQ29sbGVjdGlvblRyYW5zYWN0aW9uIG1ldGhvZCwgYmVjYXVzZSB3ZSBuZWVkXG4gICAgLy8gdG8gcGFzcyB0aGUgSUQgdG8gcHJlbG9hZElkcy5cbiAgICBpZiAodHlwZW9mIHJlY29yZCAhPT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIlJlY29yZCBpcyBub3QgYW4gb2JqZWN0LlwiKSk7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlY29yZCwgXCJpZFwiKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkNhbm5vdCB1cGRhdGUgYSByZWNvcmQgbWlzc2luZyBpZC5cIikpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuaWRTY2hlbWEudmFsaWRhdGUocmVjb3JkLmlkKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihgSW52YWxpZCBJZDogJHtyZWNvcmQuaWR9YCkpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmV4ZWN1dGUodHhuID0+IHR4bi51cHNlcnQocmVjb3JkKSwgeyBwcmVsb2FkSWRzOiBbcmVjb3JkLmlkXSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaWtlIHtAbGluayBDb2xsZWN0aW9uVHJhbnNhY3Rpb24jZ2V0fSwgYnV0IHdyYXBwZWQgaW4gaXRzIG93biB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7Qm9vbGVhbn0gaW5jbHVkZURlbGV0ZWQ6IEluY2x1ZGUgdmlydHVhbGx5IGRlbGV0ZWQgcmVjb3Jkcy5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSBpZFxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGdldChpZCwgb3B0aW9ucyA9IHsgaW5jbHVkZURlbGV0ZWQ6IGZhbHNlIH0pIHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlKHR4biA9PiB0eG4uZ2V0KGlkLCBvcHRpb25zKSwgeyBwcmVsb2FkSWRzOiBbaWRdIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExpa2Uge0BsaW5rIENvbGxlY3Rpb25UcmFuc2FjdGlvbiNnZXRBbnl9LCBidXQgd3JhcHBlZCBpbiBpdHMgb3duIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBnZXRBbnkoaWQpIHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlKHR4biA9PiB0eG4uZ2V0QW55KGlkKSwgeyBwcmVsb2FkSWRzOiBbaWRdIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhbWUgYXMge0BsaW5rIENvbGxlY3Rpb24jZGVsZXRlfSwgYnV0IHdyYXBwZWQgaW4gaXRzIG93biB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7Qm9vbGVhbn0gdmlydHVhbDogV2hlbiBzZXQgdG8gYHRydWVgLCBkb2Vzbid0IGFjdHVhbGx5IGRlbGV0ZSB0aGUgcmVjb3JkLFxuICAgKiAgIHVwZGF0ZSBpdHMgYF9zdGF0dXNgIGF0dHJpYnV0ZSB0byBgZGVsZXRlZGAgaW5zdGVhZCAoZGVmYXVsdDogdHJ1ZSlcbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSBpZCAgICAgICBUaGUgcmVjb3JkJ3MgSWQuXG4gICAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9ucyAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgZGVsZXRlKGlkLCBvcHRpb25zID0geyB2aXJ0dWFsOiB0cnVlIH0pIHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlKFxuICAgICAgdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgICByZXR1cm4gdHJhbnNhY3Rpb24uZGVsZXRlKGlkLCBvcHRpb25zKTtcbiAgICAgIH0sXG4gICAgICB7IHByZWxvYWRJZHM6IFtpZF0gfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogU2FtZSBhcyB7QGxpbmsgQ29sbGVjdGlvbiNkZWxldGVBbGx9LCBidXQgd3JhcHBlZCBpbiBpdHMgb3duIHRyYW5zYWN0aW9uLCBleGVjdWxkaW5nIHRoZSBwYXJhbWV0ZXIuXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBkZWxldGVBbGwoKSB7XG4gICAgY29uc3QgeyBkYXRhIH0gPSBhd2FpdCB0aGlzLmxpc3Qoe30sIHsgaW5jbHVkZURlbGV0ZWQ6IGZhbHNlIH0pO1xuICAgIGNvbnN0IHJlY29yZElkcyA9IGRhdGEubWFwKHJlY29yZCA9PiByZWNvcmQuaWQpO1xuICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoXG4gICAgICB0cmFuc2FjdGlvbiA9PiB7XG4gICAgICAgIHJldHVybiB0cmFuc2FjdGlvbi5kZWxldGVBbGwocmVjb3JkSWRzKTtcbiAgICAgIH0sXG4gICAgICB7IHByZWxvYWRJZHM6IHJlY29yZElkcyB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgc2FtZSBhcyB7QGxpbmsgQ29sbGVjdGlvblRyYW5zYWN0aW9uI2RlbGV0ZUFueX0sIGJ1dCB3cmFwcGVkXG4gICAqIGluIGl0cyBvd24gdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSAge1N0cmluZ30gaWQgICAgICAgVGhlIHJlY29yZCdzIElkLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgZGVsZXRlQW55KGlkKSB7XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSh0eG4gPT4gdHhuLmRlbGV0ZUFueShpZCksIHsgcHJlbG9hZElkczogW2lkXSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0cyByZWNvcmRzIGZyb20gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBQYXJhbXM6XG4gICAqIC0ge09iamVjdH0gZmlsdGVycyBGaWx0ZXIgdGhlIHJlc3VsdHMgKGRlZmF1bHQ6IGB7fWApLlxuICAgKiAtIHtTdHJpbmd9IG9yZGVyICAgVGhlIG9yZGVyIHRvIGFwcGx5ICAgKGRlZmF1bHQ6IGAtbGFzdF9tb2RpZmllZGApLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtCb29sZWFufSBpbmNsdWRlRGVsZXRlZDogSW5jbHVkZSB2aXJ0dWFsbHkgZGVsZXRlZCByZWNvcmRzLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHBhcmFtcyAgVGhlIGZpbHRlcnMgYW5kIG9yZGVyIHRvIGFwcGx5IHRvIHRoZSByZXN1bHRzLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnMgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgbGlzdChwYXJhbXMgPSB7fSwgb3B0aW9ucyA9IHsgaW5jbHVkZURlbGV0ZWQ6IGZhbHNlIH0pIHtcbiAgICBwYXJhbXMgPSB7IG9yZGVyOiBcIi1sYXN0X21vZGlmaWVkXCIsIGZpbHRlcnM6IHt9LCAuLi5wYXJhbXMgfTtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5kYi5saXN0KHBhcmFtcyk7XG4gICAgbGV0IGRhdGEgPSByZXN1bHRzO1xuICAgIGlmICghb3B0aW9ucy5pbmNsdWRlRGVsZXRlZCkge1xuICAgICAgZGF0YSA9IHJlc3VsdHMuZmlsdGVyKHJlY29yZCA9PiByZWNvcmQuX3N0YXR1cyAhPT0gXCJkZWxldGVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4geyBkYXRhLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnRzIHJlbW90ZSBjaGFuZ2VzIGludG8gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKiBUaGlzIG1ldGhvZCBpcyBpbiBjaGFyZ2Ugb2YgZGV0ZWN0aW5nIHRoZSBjb25mbGljdHMsIGFuZCByZXNvbHZlIHRoZW1cbiAgICogYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgc3RyYXRlZ3kuXG4gICAqIEBwYXJhbSAge1N5bmNSZXN1bHRPYmplY3R9IHN5bmNSZXN1bHRPYmplY3QgVGhlIHN5bmMgcmVzdWx0IG9iamVjdC5cbiAgICogQHBhcmFtICB7QXJyYXl9ICAgICAgICAgICAgZGVjb2RlZENoYW5nZXMgICBUaGUgbGlzdCBvZiBjaGFuZ2VzIHRvIGltcG9ydCBpbiB0aGUgbG9jYWwgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSAge1N0cmluZ30gICAgICAgICAgIHN0cmF0ZWd5ICAgICAgICAgVGhlIHtAbGluayBDb2xsZWN0aW9uLnN0cmF0ZWd5fSAoZGVmYXVsdDogTUFOVUFMKVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgaW1wb3J0Q2hhbmdlcyhcbiAgICBzeW5jUmVzdWx0T2JqZWN0LFxuICAgIGRlY29kZWRDaGFuZ2VzLFxuICAgIHN0cmF0ZWd5ID0gQ29sbGVjdGlvbi5zdHJhdGVneS5NQU5VQUxcbiAgKSB7XG4gICAgLy8gUmV0cmlldmUgcmVjb3JkcyBtYXRjaGluZyBjaGFuZ2UgaWRzLlxuICAgIHRyeSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRlY29kZWRDaGFuZ2VzLmxlbmd0aDsgaSArPSBJTVBPUlRfQ0hVTktfU0laRSkge1xuICAgICAgICBjb25zdCBzbGljZSA9IGRlY29kZWRDaGFuZ2VzLnNsaWNlKGksIGkgKyBJTVBPUlRfQ0hVTktfU0laRSk7XG5cbiAgICAgICAgY29uc3QgeyBpbXBvcnRzLCByZXNvbHZlZCB9ID0gYXdhaXQgdGhpcy5kYi5leGVjdXRlKFxuICAgICAgICAgIHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGltcG9ydHMgPSBzbGljZS5tYXAocmVtb3RlID0+IHtcbiAgICAgICAgICAgICAgLy8gU3RvcmUgcmVtb3RlIGNoYW5nZSBpbnRvIGxvY2FsIGRhdGFiYXNlLlxuICAgICAgICAgICAgICByZXR1cm4gaW1wb3J0Q2hhbmdlKFxuICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgICAgICAgICAgIHJlbW90ZSxcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsRmllbGRzLFxuICAgICAgICAgICAgICAgIHN0cmF0ZWd5XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbmZsaWN0cyA9IGltcG9ydHNcbiAgICAgICAgICAgICAgLmZpbHRlcihpID0+IGkudHlwZSA9PT0gXCJjb25mbGljdHNcIilcbiAgICAgICAgICAgICAgLm1hcChpID0+IGkuZGF0YSk7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlZCA9IHRoaXMuX2hhbmRsZUNvbmZsaWN0cyhcbiAgICAgICAgICAgICAgdHJhbnNhY3Rpb24sXG4gICAgICAgICAgICAgIGNvbmZsaWN0cyxcbiAgICAgICAgICAgICAgc3RyYXRlZ3lcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4geyBpbXBvcnRzLCByZXNvbHZlZCB9O1xuICAgICAgICAgIH0sXG4gICAgICAgICAgeyBwcmVsb2FkOiBzbGljZS5tYXAocmVjb3JkID0+IHJlY29yZC5pZCkgfVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIExpc3RzIG9mIGNyZWF0ZWQvdXBkYXRlZC9kZWxldGVkIHJlY29yZHNcbiAgICAgICAgaW1wb3J0cy5mb3JFYWNoKCh7IHR5cGUsIGRhdGEgfSkgPT4gc3luY1Jlc3VsdE9iamVjdC5hZGQodHlwZSwgZGF0YSkpO1xuICAgICAgICAvLyBBdXRvbWF0aWNhbGx5IHJlc29sdmVkIGNvbmZsaWN0cyAoaWYgbm90IG1hbnVhbClcbiAgICAgICAgaWYgKHJlc29sdmVkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBzeW5jUmVzdWx0T2JqZWN0LnJlc2V0KFwiY29uZmxpY3RzXCIpLmFkZChcInJlc29sdmVkXCIsIHJlc29sdmVkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc3QgZGF0YSA9IHtcbiAgICAgICAgdHlwZTogXCJpbmNvbWluZ1wiLFxuICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgc3RhY2s6IGVyci5zdGFjayxcbiAgICAgIH07XG4gICAgICAvLyBYWFggb25lIGVycm9yIG9mIHRoZSB3aG9sZSB0cmFuc2FjdGlvbiBpbnN0ZWFkIG9mIHBlciBhdG9taWMgb3BcbiAgICAgIHN5bmNSZXN1bHRPYmplY3QuYWRkKFwiZXJyb3JzXCIsIGRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiBzeW5jUmVzdWx0T2JqZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIEltcG9ydHMgdGhlIHJlc3BvbnNlcyBvZiBwdXNoZWQgY2hhbmdlcyBpbnRvIHRoZSBsb2NhbCBkYXRhYmFzZS5cbiAgICogQmFzaWNhbGx5IGl0IHN0b3JlcyB0aGUgdGltZXN0YW1wIGFzc2lnbmVkIGJ5IHRoZSBzZXJ2ZXIgaW50byB0aGUgbG9jYWxcbiAgICogZGF0YWJhc2UuXG4gICAqIEBwYXJhbSAge1N5bmNSZXN1bHRPYmplY3R9IHN5bmNSZXN1bHRPYmplY3QgVGhlIHN5bmMgcmVzdWx0IG9iamVjdC5cbiAgICogQHBhcmFtICB7QXJyYXl9ICAgICAgICAgICAgdG9BcHBseUxvY2FsbHkgICBUaGUgbGlzdCBvZiBjaGFuZ2VzIHRvIGltcG9ydCBpbiB0aGUgbG9jYWwgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSAge0FycmF5fSAgICAgICAgICAgIGNvbmZsaWN0cyAgICAgICAgVGhlIGxpc3Qgb2YgY29uZmxpY3RzIHRoYXQgaGF2ZSB0byBiZSByZXNvbHZlZC5cbiAgICogQHBhcmFtICB7U3RyaW5nfSAgICAgICAgICAgc3RyYXRlZ3kgICAgICAgICBUaGUge0BsaW5rIENvbGxlY3Rpb24uc3RyYXRlZ3l9LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgX2FwcGx5UHVzaGVkUmVzdWx0cyhcbiAgICBzeW5jUmVzdWx0T2JqZWN0LFxuICAgIHRvQXBwbHlMb2NhbGx5LFxuICAgIGNvbmZsaWN0cyxcbiAgICBzdHJhdGVneSA9IENvbGxlY3Rpb24uc3RyYXRlZ3kuTUFOVUFMXG4gICkge1xuICAgIGNvbnN0IHRvRGVsZXRlTG9jYWxseSA9IHRvQXBwbHlMb2NhbGx5LmZpbHRlcihyID0+IHIuZGVsZXRlZCk7XG4gICAgY29uc3QgdG9VcGRhdGVMb2NhbGx5ID0gdG9BcHBseUxvY2FsbHkuZmlsdGVyKHIgPT4gIXIuZGVsZXRlZCk7XG5cbiAgICBjb25zdCB7IHB1Ymxpc2hlZCwgcmVzb2x2ZWQgfSA9IGF3YWl0IHRoaXMuZGIuZXhlY3V0ZSh0cmFuc2FjdGlvbiA9PiB7XG4gICAgICBjb25zdCB1cGRhdGVkID0gdG9VcGRhdGVMb2NhbGx5Lm1hcChyZWNvcmQgPT4ge1xuICAgICAgICBjb25zdCBzeW5jZWQgPSBtYXJrU3luY2VkKHJlY29yZCk7XG4gICAgICAgIHRyYW5zYWN0aW9uLnVwZGF0ZShzeW5jZWQpO1xuICAgICAgICByZXR1cm4gc3luY2VkO1xuICAgICAgfSk7XG4gICAgICBjb25zdCBkZWxldGVkID0gdG9EZWxldGVMb2NhbGx5Lm1hcChyZWNvcmQgPT4ge1xuICAgICAgICB0cmFuc2FjdGlvbi5kZWxldGUocmVjb3JkLmlkKTtcbiAgICAgICAgLy8gQW1lbmQgcmVzdWx0IGRhdGEgd2l0aCB0aGUgZGVsZXRlZCBhdHRyaWJ1dGUgc2V0XG4gICAgICAgIHJldHVybiB7IGlkOiByZWNvcmQuaWQsIGRlbGV0ZWQ6IHRydWUgfTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcHVibGlzaGVkID0gdXBkYXRlZC5jb25jYXQoZGVsZXRlZCk7XG4gICAgICAvLyBIYW5kbGUgY29uZmxpY3RzLCBpZiBhbnlcbiAgICAgIGNvbnN0IHJlc29sdmVkID0gdGhpcy5faGFuZGxlQ29uZmxpY3RzKHRyYW5zYWN0aW9uLCBjb25mbGljdHMsIHN0cmF0ZWd5KTtcbiAgICAgIHJldHVybiB7IHB1Ymxpc2hlZCwgcmVzb2x2ZWQgfTtcbiAgICB9KTtcblxuICAgIHN5bmNSZXN1bHRPYmplY3QuYWRkKFwicHVibGlzaGVkXCIsIHB1Ymxpc2hlZCk7XG5cbiAgICBpZiAocmVzb2x2ZWQubGVuZ3RoID4gMCkge1xuICAgICAgc3luY1Jlc3VsdE9iamVjdFxuICAgICAgICAucmVzZXQoXCJjb25mbGljdHNcIilcbiAgICAgICAgLnJlc2V0KFwicmVzb2x2ZWRcIilcbiAgICAgICAgLmFkZChcInJlc29sdmVkXCIsIHJlc29sdmVkKTtcbiAgICB9XG4gICAgcmV0dXJuIHN5bmNSZXN1bHRPYmplY3Q7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyBzeW5jaHJvbml6YXRpb24gY29uZmxpY3RzIGFjY29yZGluZyB0byBzcGVjaWZpZWQgc3RyYXRlZ3kuXG4gICAqXG4gICAqIEBwYXJhbSAge1N5bmNSZXN1bHRPYmplY3R9IHJlc3VsdCAgICBUaGUgc3luYyByZXN1bHQgb2JqZWN0LlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgICAgICBzdHJhdGVneSAgVGhlIHtAbGluayBDb2xsZWN0aW9uLnN0cmF0ZWd5fS5cbiAgICogQHJldHVybiB7UHJvbWlzZTxBcnJheTxPYmplY3Q+Pn0gVGhlIHJlc29sdmVkIGNvbmZsaWN0cywgYXMgYW5cbiAgICogICAgYXJyYXkgb2Yge2FjY2VwdGVkLCByZWplY3RlZH0gb2JqZWN0c1xuICAgKi9cbiAgX2hhbmRsZUNvbmZsaWN0cyh0cmFuc2FjdGlvbiwgY29uZmxpY3RzLCBzdHJhdGVneSkge1xuICAgIGlmIChzdHJhdGVneSA9PT0gQ29sbGVjdGlvbi5zdHJhdGVneS5NQU5VQUwpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbmZsaWN0cy5tYXAoY29uZmxpY3QgPT4ge1xuICAgICAgY29uc3QgcmVzb2x1dGlvbiA9XG4gICAgICAgIHN0cmF0ZWd5ID09PSBDb2xsZWN0aW9uLnN0cmF0ZWd5LkNMSUVOVF9XSU5TXG4gICAgICAgICAgPyBjb25mbGljdC5sb2NhbFxuICAgICAgICAgIDogY29uZmxpY3QucmVtb3RlO1xuICAgICAgY29uc3QgcmVqZWN0ZWQgPVxuICAgICAgICBzdHJhdGVneSA9PT0gQ29sbGVjdGlvbi5zdHJhdGVneS5DTElFTlRfV0lOU1xuICAgICAgICAgID8gY29uZmxpY3QucmVtb3RlXG4gICAgICAgICAgOiBjb25mbGljdC5sb2NhbDtcbiAgICAgIGxldCBhY2NlcHRlZCwgc3RhdHVzLCBpZDtcbiAgICAgIGlmIChyZXNvbHV0aW9uID09PSBudWxsKSB7XG4gICAgICAgIC8vIFdlIFwicmVzb2x2ZWRcIiB3aXRoIHRoZSBzZXJ2ZXItc2lkZSBkZWxldGlvbi4gRGVsZXRlIGxvY2FsbHkuXG4gICAgICAgIC8vIFRoaXMgb25seSBoYXBwZW5zIGR1cmluZyBTRVJWRVJfV0lOUyBiZWNhdXNlIHRoZSBsb2NhbFxuICAgICAgICAvLyB2ZXJzaW9uIG9mIGEgcmVjb3JkIGNhbiBuZXZlciBiZSBudWxsLlxuICAgICAgICAvLyBXZSBjYW4gZ2V0IFwibnVsbFwiIGZyb20gdGhlIHJlbW90ZSBzaWRlIGlmIHdlIGdvdCBhIGNvbmZsaWN0XG4gICAgICAgIC8vIGFuZCB0aGVyZSBpcyBubyByZW1vdGUgdmVyc2lvbiBhdmFpbGFibGU7IHNlZSBraW50by1odHRwLmpzXG4gICAgICAgIC8vIGJhdGNoLmpzOmFnZ3JlZ2F0ZS5cbiAgICAgICAgdHJhbnNhY3Rpb24uZGVsZXRlKGNvbmZsaWN0LmxvY2FsLmlkKTtcbiAgICAgICAgYWNjZXB0ZWQgPSBudWxsO1xuICAgICAgICAvLyBUaGUgcmVjb3JkIHdhcyBkZWxldGVkLCBidXQgdGhhdCBzdGF0dXMgaXMgXCJzeW5jZWRcIiB3aXRoXG4gICAgICAgIC8vIHRoZSBzZXJ2ZXIsIHNvIHdlIGRvbid0IG5lZWQgdG8gcHVzaCB0aGUgY2hhbmdlLlxuICAgICAgICBzdGF0dXMgPSBcInN5bmNlZFwiO1xuICAgICAgICBpZCA9IGNvbmZsaWN0LmxvY2FsLmlkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgdXBkYXRlZCA9IHRoaXMuX3Jlc29sdmVSYXcoY29uZmxpY3QsIHJlc29sdXRpb24pO1xuICAgICAgICB0cmFuc2FjdGlvbi51cGRhdGUodXBkYXRlZCk7XG4gICAgICAgIGFjY2VwdGVkID0gdXBkYXRlZDtcbiAgICAgICAgc3RhdHVzID0gdXBkYXRlZC5fc3RhdHVzO1xuICAgICAgICBpZCA9IHVwZGF0ZWQuaWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4geyByZWplY3RlZCwgYWNjZXB0ZWQsIGlkLCBfc3RhdHVzOiBzdGF0dXMgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIGEgYnVuY2ggb2Ygb3BlcmF0aW9ucyBpbiBhIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBUaGlzIHRyYW5zYWN0aW9uIHNob3VsZCBiZSBhdG9taWMgLS0gZWl0aGVyIGFsbCBvZiBpdHMgb3BlcmF0aW9uc1xuICAgKiB3aWxsIHN1Y2NlZWQsIG9yIG5vbmUgd2lsbC5cbiAgICpcbiAgICogVGhlIGFyZ3VtZW50IHRvIHRoaXMgZnVuY3Rpb24gaXMgaXRzZWxmIGEgZnVuY3Rpb24gd2hpY2ggd2lsbCBiZVxuICAgKiBjYWxsZWQgd2l0aCBhIHtAbGluayBDb2xsZWN0aW9uVHJhbnNhY3Rpb259LiBDb2xsZWN0aW9uIG1ldGhvZHNcbiAgICogYXJlIGF2YWlsYWJsZSBvbiB0aGlzIHRyYW5zYWN0aW9uLCBidXQgaW5zdGVhZCBvZiByZXR1cm5pbmdcbiAgICogcHJvbWlzZXMsIHRoZXkgYXJlIHN5bmNocm9ub3VzLiBleGVjdXRlKCkgcmV0dXJucyBhIFByb21pc2Ugd2hvc2VcbiAgICogdmFsdWUgd2lsbCBiZSB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBwcm92aWRlZCBmdW5jdGlvbi5cbiAgICpcbiAgICogTW9zdCBvcGVyYXRpb25zIHdpbGwgcmVxdWlyZSBhY2Nlc3MgdG8gdGhlIHJlY29yZCBpdHNlbGYsIHdoaWNoXG4gICAqIG11c3QgYmUgcHJlbG9hZGVkIGJ5IHBhc3NpbmcgaXRzIElEIGluIHRoZSBwcmVsb2FkSWRzIG9wdGlvbi5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7QXJyYXl9IHByZWxvYWRJZHM6IGxpc3Qgb2YgSURzIHRvIGZldGNoIGF0IHRoZSBiZWdpbm5pbmcgb2ZcbiAgICogICB0aGUgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZX0gUmVzb2x2ZXMgd2l0aCB0aGUgcmVzdWx0IG9mIHRoZSBnaXZlbiBmdW5jdGlvblxuICAgKiAgICB3aGVuIHRoZSB0cmFuc2FjdGlvbiBjb21taXRzLlxuICAgKi9cbiAgZXhlY3V0ZShkb09wZXJhdGlvbnMsIHsgcHJlbG9hZElkcyA9IFtdIH0gPSB7fSkge1xuICAgIGZvciAoY29uc3QgaWQgb2YgcHJlbG9hZElkcykge1xuICAgICAgaWYgKCF0aGlzLmlkU2NoZW1hLnZhbGlkYXRlKGlkKSkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoRXJyb3IoYEludmFsaWQgSWQ6ICR7aWR9YCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmRiLmV4ZWN1dGUoXG4gICAgICB0cmFuc2FjdGlvbiA9PiB7XG4gICAgICAgIGNvbnN0IHR4biA9IG5ldyBDb2xsZWN0aW9uVHJhbnNhY3Rpb24odGhpcywgdHJhbnNhY3Rpb24pO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBkb09wZXJhdGlvbnModHhuKTtcbiAgICAgICAgdHhuLmVtaXRFdmVudHMoKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgICB7IHByZWxvYWQ6IHByZWxvYWRJZHMgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXRzIHRoZSBsb2NhbCByZWNvcmRzIGFzIGlmIHRoZXkgd2VyZSBuZXZlciBzeW5jZWQ7IGV4aXN0aW5nIHJlY29yZHMgYXJlXG4gICAqIG1hcmtlZCBhcyBuZXdseSBjcmVhdGVkLCBkZWxldGVkIHJlY29yZHMgYXJlIGRyb3BwZWQuXG4gICAqXG4gICAqIEEgbmV4dCBjYWxsIHRvIHtAbGluayBDb2xsZWN0aW9uLnN5bmN9IHdpbGwgdGh1cyByZXB1Ymxpc2ggdGhlIHdob2xlXG4gICAqIGNvbnRlbnQgb2YgdGhlIGxvY2FsIGNvbGxlY3Rpb24gdG8gdGhlIHNlcnZlci5cbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZX0gUmVzb2x2ZXMgd2l0aCB0aGUgbnVtYmVyIG9mIHByb2Nlc3NlZCByZWNvcmRzLlxuICAgKi9cbiAgYXN5bmMgcmVzZXRTeW5jU3RhdHVzKCkge1xuICAgIGNvbnN0IHVuc3luY2VkID0gYXdhaXQgdGhpcy5saXN0KFxuICAgICAgeyBmaWx0ZXJzOiB7IF9zdGF0dXM6IFtcImRlbGV0ZWRcIiwgXCJzeW5jZWRcIl0gfSwgb3JkZXI6IFwiXCIgfSxcbiAgICAgIHsgaW5jbHVkZURlbGV0ZWQ6IHRydWUgfVxuICAgICk7XG4gICAgYXdhaXQgdGhpcy5kYi5leGVjdXRlKHRyYW5zYWN0aW9uID0+IHtcbiAgICAgIHVuc3luY2VkLmRhdGEuZm9yRWFjaChyZWNvcmQgPT4ge1xuICAgICAgICBpZiAocmVjb3JkLl9zdGF0dXMgPT09IFwiZGVsZXRlZFwiKSB7XG4gICAgICAgICAgLy8gR2FyYmFnZSBjb2xsZWN0IGRlbGV0ZWQgcmVjb3Jkcy5cbiAgICAgICAgICB0cmFuc2FjdGlvbi5kZWxldGUocmVjb3JkLmlkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBSZWNvcmRzIHRoYXQgd2VyZSBzeW5jZWQgYmVjb21lIMKrY3JlYXRlZMK7LlxuICAgICAgICAgIHRyYW5zYWN0aW9uLnVwZGF0ZSh7XG4gICAgICAgICAgICAuLi5yZWNvcmQsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBfc3RhdHVzOiBcImNyZWF0ZWRcIixcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgdGhpcy5fbGFzdE1vZGlmaWVkID0gbnVsbDtcbiAgICBhd2FpdCB0aGlzLmRiLnNhdmVMYXN0TW9kaWZpZWQobnVsbCk7XG4gICAgcmV0dXJuIHVuc3luY2VkLmRhdGEubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdHdvIGxpc3RzOlxuICAgKlxuICAgKiAtIGB0b0RlbGV0ZWA6IHVuc3luY2VkIGRlbGV0ZWQgcmVjb3JkcyB3ZSBjYW4gc2FmZWx5IGRlbGV0ZTtcbiAgICogLSBgdG9TeW5jYDogbG9jYWwgdXBkYXRlcyB0byBzZW5kIHRvIHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBnYXRoZXJMb2NhbENoYW5nZXMoKSB7XG4gICAgY29uc3QgdW5zeW5jZWQgPSBhd2FpdCB0aGlzLmxpc3Qoe1xuICAgICAgZmlsdGVyczogeyBfc3RhdHVzOiBbXCJjcmVhdGVkXCIsIFwidXBkYXRlZFwiXSB9LFxuICAgICAgb3JkZXI6IFwiXCIsXG4gICAgfSk7XG4gICAgY29uc3QgZGVsZXRlZCA9IGF3YWl0IHRoaXMubGlzdChcbiAgICAgIHsgZmlsdGVyczogeyBfc3RhdHVzOiBcImRlbGV0ZWRcIiB9LCBvcmRlcjogXCJcIiB9LFxuICAgICAgeyBpbmNsdWRlRGVsZXRlZDogdHJ1ZSB9XG4gICAgKTtcblxuICAgIHJldHVybiBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHVuc3luY2VkLmRhdGFcbiAgICAgICAgLmNvbmNhdChkZWxldGVkLmRhdGEpXG4gICAgICAgIC5tYXAodGhpcy5fZW5jb2RlUmVjb3JkLmJpbmQodGhpcywgXCJyZW1vdGVcIikpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaCByZW1vdGUgY2hhbmdlcywgaW1wb3J0IHRoZW0gdG8gdGhlIGxvY2FsIGRhdGFiYXNlLCBhbmQgaGFuZGxlXG4gICAqIGNvbmZsaWN0cyBhY2NvcmRpbmcgdG8gYG9wdGlvbnMuc3RyYXRlZ3lgLiBUaGVuLCB1cGRhdGVzIHRoZSBwYXNzZWRcbiAgICoge0BsaW5rIFN5bmNSZXN1bHRPYmplY3R9IHdpdGggaW1wb3J0IHJlc3VsdHMuXG4gICAqXG4gICAqIE9wdGlvbnM6XG4gICAqIC0ge1N0cmluZ30gc3RyYXRlZ3k6IFRoZSBzZWxlY3RlZCBzeW5jIHN0cmF0ZWd5LlxuICAgKiAtIHtTdHJpbmd9IGV4cGVjdGVkVGltZXN0YW1wOiBBIHRpbWVzdGFtcCB0byB1c2UgYXMgYSBcImNhY2hlIGJ1c3RpbmdcIiBxdWVyeSBwYXJhbWV0ZXIuXG4gICAqIC0ge0FycmF5PFN0cmluZz59IGV4Y2x1ZGU6IEEgbGlzdCBvZiByZWNvcmQgaWRzIHRvIGV4Y2x1ZGUgZnJvbSBwdWxsLlxuICAgKiAtIHtPYmplY3R9IGhlYWRlcnM6IFRoZSBIVFRQIGhlYWRlcnMgdG8gdXNlIGluIHRoZSByZXF1ZXN0LlxuICAgKiAtIHtpbnR9IHJldHJ5OiBUaGUgbnVtYmVyIG9mIHJldHJpZXMgdG8gZG8gaWYgdGhlIEhUVFAgcmVxdWVzdCBmYWlscy5cbiAgICogLSB7aW50fSBsYXN0TW9kaWZpZWQ6IFRoZSB0aW1lc3RhbXAgdG8gdXNlIGluIGA/X3NpbmNlYCBxdWVyeS5cbiAgICpcbiAgICogQHBhcmFtICB7S2ludG9DbGllbnQuQ29sbGVjdGlvbn0gY2xpZW50ICAgICAgICAgICBLaW50byBjbGllbnQgQ29sbGVjdGlvbiBpbnN0YW5jZS5cbiAgICogQHBhcmFtICB7U3luY1Jlc3VsdE9iamVjdH0gICAgICAgc3luY1Jlc3VsdE9iamVjdCBUaGUgc3luYyByZXN1bHQgb2JqZWN0LlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICAgICAgICAgICBvcHRpb25zICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIHB1bGxDaGFuZ2VzKGNsaWVudCwgc3luY1Jlc3VsdE9iamVjdCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCFzeW5jUmVzdWx0T2JqZWN0Lm9rKSB7XG4gICAgICByZXR1cm4gc3luY1Jlc3VsdE9iamVjdDtcbiAgICB9XG5cbiAgICBjb25zdCBzaW5jZSA9IHRoaXMubGFzdE1vZGlmaWVkXG4gICAgICA/IHRoaXMubGFzdE1vZGlmaWVkXG4gICAgICA6IGF3YWl0IHRoaXMuZGIuZ2V0TGFzdE1vZGlmaWVkKCk7XG5cbiAgICBvcHRpb25zID0ge1xuICAgICAgc3RyYXRlZ3k6IENvbGxlY3Rpb24uc3RyYXRlZ3kuTUFOVUFMLFxuICAgICAgbGFzdE1vZGlmaWVkOiBzaW5jZSxcbiAgICAgIGhlYWRlcnM6IHt9LFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9O1xuXG4gICAgLy8gT3B0aW9uYWxseSBpZ25vcmUgc29tZSByZWNvcmRzIHdoZW4gcHVsbGluZyBmb3IgY2hhbmdlcy5cbiAgICAvLyAoYXZvaWQgcmVkb3dubG9hZGluZyBvdXIgb3duIGNoYW5nZXMgb24gbGFzdCBzdGVwIG9mICNzeW5jKCkpXG4gICAgbGV0IGZpbHRlcnM7XG4gICAgaWYgKG9wdGlvbnMuZXhjbHVkZSkge1xuICAgICAgLy8gTGltaXQgdGhlIGxpc3Qgb2YgZXhjbHVkZWQgcmVjb3JkcyB0byB0aGUgZmlyc3QgNTAgcmVjb3JkcyBpbiBvcmRlclxuICAgICAgLy8gdG8gcmVtYWluIHVuZGVyIGRlLWZhY3RvIFVSTCBzaXplIGxpbWl0ICh+MjAwMCBjaGFycykuXG4gICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQxNzE0Mi93aGF0LWlzLXRoZS1tYXhpbXVtLWxlbmd0aC1vZi1hLXVybC1pbi1kaWZmZXJlbnQtYnJvd3NlcnMvNDE3MTg0IzQxNzE4NFxuICAgICAgY29uc3QgZXhjbHVkZV9pZCA9IG9wdGlvbnMuZXhjbHVkZVxuICAgICAgICAuc2xpY2UoMCwgNTApXG4gICAgICAgIC5tYXAociA9PiByLmlkKVxuICAgICAgICAuam9pbihcIixcIik7XG4gICAgICBmaWx0ZXJzID0geyBleGNsdWRlX2lkIH07XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmV4cGVjdGVkVGltZXN0YW1wKSB7XG4gICAgICBmaWx0ZXJzID0ge1xuICAgICAgICAuLi5maWx0ZXJzLFxuICAgICAgICBfZXhwZWN0ZWQ6IG9wdGlvbnMuZXhwZWN0ZWRUaW1lc3RhbXAsXG4gICAgICB9O1xuICAgIH1cbiAgICAvLyBGaXJzdCBmZXRjaCByZW1vdGUgY2hhbmdlcyBmcm9tIHRoZSBzZXJ2ZXJcbiAgICBjb25zdCB7IGRhdGEsIGxhc3RfbW9kaWZpZWQgfSA9IGF3YWl0IGNsaWVudC5saXN0UmVjb3Jkcyh7XG4gICAgICAvLyBTaW5jZSBzaG91bGQgYmUgRVRhZyAoc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9LaW50by9raW50by5qcy9pc3N1ZXMvMzU2KVxuICAgICAgc2luY2U6IG9wdGlvbnMubGFzdE1vZGlmaWVkID8gYCR7b3B0aW9ucy5sYXN0TW9kaWZpZWR9YCA6IHVuZGVmaW5lZCxcbiAgICAgIGhlYWRlcnM6IG9wdGlvbnMuaGVhZGVycyxcbiAgICAgIHJldHJ5OiBvcHRpb25zLnJldHJ5LFxuICAgICAgLy8gRmV0Y2ggZXZlcnkgcGFnZSBieSBkZWZhdWx0IChGSVhNRTogb3B0aW9uIHRvIGxpbWl0IHBhZ2VzLCBzZWUgIzI3NylcbiAgICAgIHBhZ2VzOiBJbmZpbml0eSxcbiAgICAgIGZpbHRlcnMsXG4gICAgfSk7XG4gICAgLy8gbGFzdF9tb2RpZmllZCBpcyB0aGUgRVRhZyBoZWFkZXIgdmFsdWUgKHN0cmluZykuXG4gICAgLy8gRm9yIHJldHJvLWNvbXBhdGliaWxpdHkgd2l0aCBmaXJzdCBraW50by5qcyB2ZXJzaW9uc1xuICAgIC8vIHBhcnNlIGl0IHRvIGludGVnZXIuXG4gICAgY29uc3QgdW5xdW90ZWQgPSBsYXN0X21vZGlmaWVkID8gcGFyc2VJbnQobGFzdF9tb2RpZmllZCwgMTApIDogdW5kZWZpbmVkO1xuXG4gICAgLy8gQ2hlY2sgaWYgc2VydmVyIHdhcyBmbHVzaGVkLlxuICAgIC8vIFRoaXMgaXMgcmVsZXZhbnQgZm9yIHRoZSBLaW50byBkZW1vIHNlcnZlclxuICAgIC8vIChhbmQgdGh1cyBmb3IgbWFueSBuZXcgY29tZXJzKS5cbiAgICBjb25zdCBsb2NhbFN5bmNlZCA9IG9wdGlvbnMubGFzdE1vZGlmaWVkO1xuICAgIGNvbnN0IHNlcnZlckNoYW5nZWQgPSB1bnF1b3RlZCA+IG9wdGlvbnMubGFzdE1vZGlmaWVkO1xuICAgIGNvbnN0IGVtcHR5Q29sbGVjdGlvbiA9IGRhdGEubGVuZ3RoID09PSAwO1xuICAgIGlmICghb3B0aW9ucy5leGNsdWRlICYmIGxvY2FsU3luY2VkICYmIHNlcnZlckNoYW5nZWQgJiYgZW1wdHlDb2xsZWN0aW9uKSB7XG4gICAgICBjb25zdCBlID0gbmV3IFNlcnZlcldhc0ZsdXNoZWRFcnJvcihcbiAgICAgICAgbG9jYWxTeW5jZWQsXG4gICAgICAgIHVucXVvdGVkLFxuICAgICAgICBcIlNlcnZlciBoYXMgYmVlbiBmbHVzaGVkLiBDbGllbnQgU2lkZSBUaW1lc3RhbXA6IFwiICtcbiAgICAgICAgICBsb2NhbFN5bmNlZCArXG4gICAgICAgICAgXCIgU2VydmVyIFNpZGUgVGltZXN0YW1wOiBcIiArXG4gICAgICAgICAgdW5xdW90ZWRcbiAgICAgICk7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIC8vIEF0b21pYyB1cGRhdGVzIGFyZSBub3Qgc2Vuc2libGUgaGVyZSBiZWNhdXNlIHVucXVvdGVkIGlzIG5vdFxuICAgIC8vIGNvbXB1dGVkIGFzIGEgZnVuY3Rpb24gb2Ygc3luY1Jlc3VsdE9iamVjdC5sYXN0TW9kaWZpZWQuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlcXVpcmUtYXRvbWljLXVwZGF0ZXNcbiAgICBzeW5jUmVzdWx0T2JqZWN0Lmxhc3RNb2RpZmllZCA9IHVucXVvdGVkO1xuXG4gICAgLy8gRGVjb2RlIGluY29taW5nIGNoYW5nZXMuXG4gICAgY29uc3QgZGVjb2RlZENoYW5nZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGRhdGEubWFwKGNoYW5nZSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWNvZGVSZWNvcmQoXCJyZW1vdGVcIiwgY2hhbmdlKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICAvLyBIb29rIHJlY2VpdmVzIGRlY29kZWQgcmVjb3Jkcy5cbiAgICBjb25zdCBwYXlsb2FkID0geyBsYXN0TW9kaWZpZWQ6IHVucXVvdGVkLCBjaGFuZ2VzOiBkZWNvZGVkQ2hhbmdlcyB9O1xuICAgIGNvbnN0IGFmdGVySG9va3MgPSBhd2FpdCB0aGlzLmFwcGx5SG9vayhcImluY29taW5nLWNoYW5nZXNcIiwgcGF5bG9hZCk7XG5cbiAgICAvLyBObyBjaGFuZ2UsIG5vdGhpbmcgdG8gaW1wb3J0LlxuICAgIGlmIChhZnRlckhvb2tzLmNoYW5nZXMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gUmVmbGVjdCB0aGVzZSBjaGFuZ2VzIGxvY2FsbHlcbiAgICAgIGF3YWl0IHRoaXMuaW1wb3J0Q2hhbmdlcyhcbiAgICAgICAgc3luY1Jlc3VsdE9iamVjdCxcbiAgICAgICAgYWZ0ZXJIb29rcy5jaGFuZ2VzLFxuICAgICAgICBvcHRpb25zLnN0cmF0ZWd5XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gc3luY1Jlc3VsdE9iamVjdDtcbiAgfVxuXG4gIGFwcGx5SG9vayhob29rTmFtZSwgcGF5bG9hZCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5ob29rc1tob29rTmFtZV0gPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShwYXlsb2FkKTtcbiAgICB9XG4gICAgcmV0dXJuIHdhdGVyZmFsbChcbiAgICAgIHRoaXMuaG9va3NbaG9va05hbWVdLm1hcChob29rID0+IHtcbiAgICAgICAgcmV0dXJuIHJlY29yZCA9PiB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gaG9vayhwYXlsb2FkLCB0aGlzKTtcbiAgICAgICAgICBjb25zdCByZXN1bHRUaGVuYWJsZSA9IHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0LnRoZW4gPT09IFwiZnVuY3Rpb25cIjtcbiAgICAgICAgICBjb25zdCByZXN1bHRDaGFuZ2VzID1cbiAgICAgICAgICAgIHJlc3VsdCAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVzdWx0LCBcImNoYW5nZXNcIik7XG4gICAgICAgICAgaWYgKCEocmVzdWx0VGhlbmFibGUgfHwgcmVzdWx0Q2hhbmdlcykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYEludmFsaWQgcmV0dXJuIHZhbHVlIGZvciBob29rOiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgICAgIHJlc3VsdFxuICAgICAgICAgICAgICApfSBoYXMgbm8gJ3RoZW4oKScgb3IgJ2NoYW5nZXMnIHByb3BlcnRpZXNgXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9O1xuICAgICAgfSksXG4gICAgICBwYXlsb2FkXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoIGxvY2FsIGNoYW5nZXMgdG8gdGhlIHJlbW90ZSBzZXJ2ZXIgYW5kIHVwZGF0ZXMgdGhlIHBhc3NlZFxuICAgKiB7QGxpbmsgU3luY1Jlc3VsdE9iamVjdH0gd2l0aCBwdWJsaWNhdGlvbiByZXN1bHRzLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtTdHJpbmd9IHN0cmF0ZWd5OiBUaGUgc2VsZWN0ZWQgc3luYyBzdHJhdGVneS5cbiAgICogLSB7T2JqZWN0fSBoZWFkZXJzOiBUaGUgSFRUUCBoZWFkZXJzIHRvIHVzZSBpbiB0aGUgcmVxdWVzdC5cbiAgICogLSB7aW50fSByZXRyeTogVGhlIG51bWJlciBvZiByZXRyaWVzIHRvIGRvIGlmIHRoZSBIVFRQIHJlcXVlc3QgZmFpbHMuXG4gICAqXG4gICAqIEBwYXJhbSAge0tpbnRvQ2xpZW50LkNvbGxlY3Rpb259IGNsaWVudCAgICAgICAgICAgS2ludG8gY2xpZW50IENvbGxlY3Rpb24gaW5zdGFuY2UuXG4gICAqIEBwYXJhbSAge1N5bmNSZXN1bHRPYmplY3R9ICAgICAgIHN5bmNSZXN1bHRPYmplY3QgVGhlIHN5bmMgcmVzdWx0IG9iamVjdC5cbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICAgICAgICAgICAgY2hhbmdlcyAgICAgICAgICBUaGUgY2hhbmdlIG9iamVjdC5cbiAgICogQHBhcmFtICB7QXJyYXl9ICAgICAgICAgICAgICAgICAgY2hhbmdlcy50b0RlbGV0ZSBUaGUgbGlzdCBvZiByZWNvcmRzIHRvIGRlbGV0ZS5cbiAgICogQHBhcmFtICB7QXJyYXl9ICAgICAgICAgICAgICAgICAgY2hhbmdlcy50b1N5bmMgICBUaGUgbGlzdCBvZiByZWNvcmRzIHRvIGNyZWF0ZS91cGRhdGUuXG4gICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgICAgICAgICAgIG9wdGlvbnMgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgcHVzaENoYW5nZXMoY2xpZW50LCBjaGFuZ2VzLCBzeW5jUmVzdWx0T2JqZWN0LCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAoIXN5bmNSZXN1bHRPYmplY3Qub2spIHtcbiAgICAgIHJldHVybiBzeW5jUmVzdWx0T2JqZWN0O1xuICAgIH1cbiAgICBjb25zdCBzYWZlID1cbiAgICAgICFvcHRpb25zLnN0cmF0ZWd5IHx8IG9wdGlvbnMuc3RyYXRlZ3kgIT09IENvbGxlY3Rpb24uQ0xJRU5UX1dJTlM7XG4gICAgY29uc3QgdG9EZWxldGUgPSBjaGFuZ2VzLmZpbHRlcihyID0+IHIuX3N0YXR1cyA9PSBcImRlbGV0ZWRcIik7XG4gICAgY29uc3QgdG9TeW5jID0gY2hhbmdlcy5maWx0ZXIociA9PiByLl9zdGF0dXMgIT0gXCJkZWxldGVkXCIpO1xuXG4gICAgLy8gUGVyZm9ybSBhIGJhdGNoIHJlcXVlc3Qgd2l0aCBldmVyeSBjaGFuZ2VzLlxuICAgIGNvbnN0IHN5bmNlZCA9IGF3YWl0IGNsaWVudC5iYXRjaChcbiAgICAgIGJhdGNoID0+IHtcbiAgICAgICAgdG9EZWxldGUuZm9yRWFjaChyID0+IHtcbiAgICAgICAgICAvLyBuZXZlciBwdWJsaXNoZWQgbG9jYWxseSBkZWxldGVkIHJlY29yZHMgc2hvdWxkIG5vdCBiZSBwdXNibGlzaGVkXG4gICAgICAgICAgaWYgKHIubGFzdF9tb2RpZmllZCkge1xuICAgICAgICAgICAgYmF0Y2guZGVsZXRlUmVjb3JkKHIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRvU3luYy5mb3JFYWNoKHIgPT4ge1xuICAgICAgICAgIC8vIENsZWFuIGxvY2FsIGZpZWxkcyAobGlrZSBfc3RhdHVzKSBiZWZvcmUgc2VuZGluZyB0byBzZXJ2ZXIuXG4gICAgICAgICAgY29uc3QgcHVibGlzaGVkID0gdGhpcy5jbGVhbkxvY2FsRmllbGRzKHIpO1xuICAgICAgICAgIGlmIChyLl9zdGF0dXMgPT09IFwiY3JlYXRlZFwiKSB7XG4gICAgICAgICAgICBiYXRjaC5jcmVhdGVSZWNvcmQocHVibGlzaGVkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYmF0Y2gudXBkYXRlUmVjb3JkKHB1Ymxpc2hlZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGhlYWRlcnM6IG9wdGlvbnMuaGVhZGVycyxcbiAgICAgICAgcmV0cnk6IG9wdGlvbnMucmV0cnksXG4gICAgICAgIHNhZmUsXG4gICAgICAgIGFnZ3JlZ2F0ZTogdHJ1ZSxcbiAgICAgIH1cbiAgICApO1xuXG4gICAgLy8gU3RvcmUgb3V0Z29pbmcgZXJyb3JzIGludG8gc3luYyByZXN1bHQgb2JqZWN0XG4gICAgc3luY1Jlc3VsdE9iamVjdC5hZGQoXG4gICAgICBcImVycm9yc1wiLFxuICAgICAgc3luY2VkLmVycm9ycy5tYXAoZSA9PiAoeyAuLi5lLCB0eXBlOiBcIm91dGdvaW5nXCIgfSkpXG4gICAgKTtcblxuICAgIC8vIFN0b3JlIG91dGdvaW5nIGNvbmZsaWN0cyBpbnRvIHN5bmMgcmVzdWx0IG9iamVjdFxuICAgIGNvbnN0IGNvbmZsaWN0cyA9IFtdO1xuICAgIGZvciAoY29uc3QgeyB0eXBlLCBsb2NhbCwgcmVtb3RlIH0gb2Ygc3luY2VkLmNvbmZsaWN0cykge1xuICAgICAgLy8gTm90ZTogd2UgZW5zdXJlIHRoYXQgbG9jYWwgZGF0YSBhcmUgYWN0dWFsbHkgYXZhaWxhYmxlLCBhcyB0aGV5IG1heVxuICAgICAgLy8gYmUgbWlzc2luZyBpbiB0aGUgY2FzZSBvZiBhIHB1Ymxpc2hlZCBkZWxldGlvbi5cbiAgICAgIGNvbnN0IHNhZmVMb2NhbCA9IChsb2NhbCAmJiBsb2NhbC5kYXRhKSB8fCB7IGlkOiByZW1vdGUuaWQgfTtcbiAgICAgIGNvbnN0IHJlYWxMb2NhbCA9IGF3YWl0IHRoaXMuX2RlY29kZVJlY29yZChcInJlbW90ZVwiLCBzYWZlTG9jYWwpO1xuICAgICAgLy8gV2UgY2FuIGdldCBcIm51bGxcIiBmcm9tIHRoZSByZW1vdGUgc2lkZSBpZiB3ZSBnb3QgYSBjb25mbGljdFxuICAgICAgLy8gYW5kIHRoZXJlIGlzIG5vIHJlbW90ZSB2ZXJzaW9uIGF2YWlsYWJsZTsgc2VlIGtpbnRvLWh0dHAuanNcbiAgICAgIC8vIGJhdGNoLmpzOmFnZ3JlZ2F0ZS5cbiAgICAgIGNvbnN0IHJlYWxSZW1vdGUgPSByZW1vdGUgJiYgKGF3YWl0IHRoaXMuX2RlY29kZVJlY29yZChcInJlbW90ZVwiLCByZW1vdGUpKTtcbiAgICAgIGNvbnN0IGNvbmZsaWN0ID0geyB0eXBlLCBsb2NhbDogcmVhbExvY2FsLCByZW1vdGU6IHJlYWxSZW1vdGUgfTtcbiAgICAgIGNvbmZsaWN0cy5wdXNoKGNvbmZsaWN0KTtcbiAgICB9XG4gICAgc3luY1Jlc3VsdE9iamVjdC5hZGQoXCJjb25mbGljdHNcIiwgY29uZmxpY3RzKTtcblxuICAgIC8vIFJlY29yZHMgdGhhdCBtdXN0IGJlIGRlbGV0ZWQgYXJlIGVpdGhlciBkZWxldGlvbnMgdGhhdCB3ZXJlIHB1c2hlZFxuICAgIC8vIHRvIHNlcnZlciAocHVibGlzaGVkKSBvciBkZWxldGVkIHJlY29yZHMgdGhhdCB3ZXJlIG5ldmVyIHB1c2hlZCAoc2tpcHBlZCkuXG4gICAgY29uc3QgbWlzc2luZ1JlbW90ZWx5ID0gc3luY2VkLnNraXBwZWQubWFwKHIgPT4gKHsgLi4uciwgZGVsZXRlZDogdHJ1ZSB9KSk7XG5cbiAgICAvLyBGb3IgY3JlYXRlZCBhbmQgdXBkYXRlZCByZWNvcmRzLCB0aGUgbGFzdF9tb2RpZmllZCBjb21pbmcgZnJvbSBzZXJ2ZXJcbiAgICAvLyB3aWxsIGJlIHN0b3JlZCBsb2NhbGx5LlxuICAgIC8vIFJlZmxlY3QgcHVibGljYXRpb24gcmVzdWx0cyBsb2NhbGx5IHVzaW5nIHRoZSByZXNwb25zZSBmcm9tXG4gICAgLy8gdGhlIGJhdGNoIHJlcXVlc3QuXG4gICAgY29uc3QgcHVibGlzaGVkID0gc3luY2VkLnB1Ymxpc2hlZC5tYXAoYyA9PiBjLmRhdGEpO1xuICAgIGNvbnN0IHRvQXBwbHlMb2NhbGx5ID0gcHVibGlzaGVkLmNvbmNhdChtaXNzaW5nUmVtb3RlbHkpO1xuXG4gICAgLy8gQXBwbHkgdGhlIGRlY29kZSB0cmFuc2Zvcm1lcnMsIGlmIGFueVxuICAgIGNvbnN0IGRlY29kZWQgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHRvQXBwbHlMb2NhbGx5Lm1hcChyZWNvcmQgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjb2RlUmVjb3JkKFwicmVtb3RlXCIsIHJlY29yZCk7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICAvLyBXZSBoYXZlIHRvIHVwZGF0ZSB0aGUgbG9jYWwgcmVjb3JkcyB3aXRoIHRoZSByZXNwb25zZXMgb2YgdGhlIHNlcnZlclxuICAgIC8vIChlZy4gbGFzdF9tb2RpZmllZCB2YWx1ZXMgZXRjLikuXG4gICAgaWYgKGRlY29kZWQubGVuZ3RoID4gMCB8fCBjb25mbGljdHMubGVuZ3RoID4gMCkge1xuICAgICAgYXdhaXQgdGhpcy5fYXBwbHlQdXNoZWRSZXN1bHRzKFxuICAgICAgICBzeW5jUmVzdWx0T2JqZWN0LFxuICAgICAgICBkZWNvZGVkLFxuICAgICAgICBjb25mbGljdHMsXG4gICAgICAgIG9wdGlvbnMuc3RyYXRlZ3lcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN5bmNSZXN1bHRPYmplY3Q7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgY29weSBvZiB0aGUgc3BlY2lmaWVkIHJlY29yZCB3aXRob3V0IHRoZSBsb2NhbCBmaWVsZHMuXG4gICAqXG4gICAqIEBwYXJhbSAge09iamVjdH0gcmVjb3JkICBBIHJlY29yZCB3aXRoIHBvdGVudGlhbCBsb2NhbCBmaWVsZHMuXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIGNsZWFuTG9jYWxGaWVsZHMocmVjb3JkKSB7XG4gICAgY29uc3QgbG9jYWxLZXlzID0gUkVDT1JEX0ZJRUxEU19UT19DTEVBTi5jb25jYXQodGhpcy5sb2NhbEZpZWxkcyk7XG4gICAgcmV0dXJuIG9taXRLZXlzKHJlY29yZCwgbG9jYWxLZXlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhIGNvbmZsaWN0LCB1cGRhdGluZyBsb2NhbCByZWNvcmQgYWNjb3JkaW5nIHRvIHByb3Bvc2VkXG4gICAqIHJlc29sdXRpb24g4oCUIGtlZXBpbmcgcmVtb3RlIHJlY29yZCBgbGFzdF9tb2RpZmllZGAgdmFsdWUgYXMgYSByZWZlcmVuY2UgZm9yXG4gICAqIGZ1cnRoZXIgYmF0Y2ggc2VuZGluZy5cbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSBjb25mbGljdCAgIFRoZSBjb25mbGljdCBvYmplY3QuXG4gICAqIEBwYXJhbSAge09iamVjdH0gcmVzb2x1dGlvbiBUaGUgcHJvcG9zZWQgcmVjb3JkLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgcmVzb2x2ZShjb25mbGljdCwgcmVzb2x1dGlvbikge1xuICAgIHJldHVybiB0aGlzLmRiLmV4ZWN1dGUodHJhbnNhY3Rpb24gPT4ge1xuICAgICAgY29uc3QgdXBkYXRlZCA9IHRoaXMuX3Jlc29sdmVSYXcoY29uZmxpY3QsIHJlc29sdXRpb24pO1xuICAgICAgdHJhbnNhY3Rpb24udXBkYXRlKHVwZGF0ZWQpO1xuICAgICAgcmV0dXJuIHsgZGF0YTogdXBkYXRlZCwgcGVybWlzc2lvbnM6IHt9IH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIF9yZXNvbHZlUmF3KGNvbmZsaWN0LCByZXNvbHV0aW9uKSB7XG4gICAgY29uc3QgcmVzb2x2ZWQgPSB7XG4gICAgICAuLi5yZXNvbHV0aW9uLFxuICAgICAgLy8gRW5zdXJlIGxvY2FsIHJlY29yZCBoYXMgdGhlIGxhdGVzdCBhdXRob3JpdGF0aXZlIHRpbWVzdGFtcFxuICAgICAgbGFzdF9tb2RpZmllZDogY29uZmxpY3QucmVtb3RlICYmIGNvbmZsaWN0LnJlbW90ZS5sYXN0X21vZGlmaWVkLFxuICAgIH07XG4gICAgLy8gSWYgdGhlIHJlc29sdXRpb24gb2JqZWN0IGlzIHN0cmljdGx5IGVxdWFsIHRvIHRoZVxuICAgIC8vIHJlbW90ZSByZWNvcmQsIHRoZW4gd2UgY2FuIG1hcmsgaXQgYXMgc3luY2VkIGxvY2FsbHkuXG4gICAgLy8gT3RoZXJ3aXNlLCBtYXJrIGl0IGFzIHVwZGF0ZWQgKHNvIHRoYXQgdGhlIHJlc29sdXRpb24gaXMgcHVzaGVkKS5cbiAgICBjb25zdCBzeW5jZWQgPSBkZWVwRXF1YWwocmVzb2x2ZWQsIGNvbmZsaWN0LnJlbW90ZSk7XG4gICAgcmV0dXJuIG1hcmtTdGF0dXMocmVzb2x2ZWQsIHN5bmNlZCA/IFwic3luY2VkXCIgOiBcInVwZGF0ZWRcIik7XG4gIH1cblxuICAvKipcbiAgICogU3luY2hyb25pemUgcmVtb3RlIGFuZCBsb2NhbCBkYXRhLiBUaGUgcHJvbWlzZSB3aWxsIHJlc29sdmUgd2l0aCBhXG4gICAqIHtAbGluayBTeW5jUmVzdWx0T2JqZWN0fSwgdGhvdWdoIHdpbGwgcmVqZWN0OlxuICAgKlxuICAgKiAtIGlmIHRoZSBzZXJ2ZXIgaXMgY3VycmVudGx5IGJhY2tlZCBvZmY7XG4gICAqIC0gaWYgdGhlIHNlcnZlciBoYXMgYmVlbiBkZXRlY3RlZCBmbHVzaGVkLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtPYmplY3R9IGhlYWRlcnM6IEhUVFAgaGVhZGVycyB0byBhdHRhY2ggdG8gb3V0Z29pbmcgcmVxdWVzdHMuXG4gICAqIC0ge1N0cmluZ30gZXhwZWN0ZWRUaW1lc3RhbXA6IEEgdGltZXN0YW1wIHRvIHVzZSBhcyBhIFwiY2FjaGUgYnVzdGluZ1wiIHF1ZXJ5IHBhcmFtZXRlci5cbiAgICogLSB7TnVtYmVyfSByZXRyeTogTnVtYmVyIG9mIHJldHJpZXMgd2hlbiBzZXJ2ZXIgZmFpbHMgdG8gcHJvY2VzcyB0aGUgcmVxdWVzdCAoZGVmYXVsdDogMSkuXG4gICAqIC0ge0NvbGxlY3Rpb24uc3RyYXRlZ3l9IHN0cmF0ZWd5OiBTZWUge0BsaW5rIENvbGxlY3Rpb24uc3RyYXRlZ3l9LlxuICAgKiAtIHtCb29sZWFufSBpZ25vcmVCYWNrb2ZmOiBGb3JjZSBzeW5jaHJvbml6YXRpb24gZXZlbiBpZiBzZXJ2ZXIgaXMgY3VycmVudGx5XG4gICAqICAgYmFja2VkIG9mZi5cbiAgICogLSB7U3RyaW5nfSBidWNrZXQ6IFRoZSByZW1vdmUgYnVja2V0IGlkIHRvIHVzZSAoZGVmYXVsdDogbnVsbClcbiAgICogLSB7U3RyaW5nfSBjb2xsZWN0aW9uOiBUaGUgcmVtb3ZlIGNvbGxlY3Rpb24gaWQgdG8gdXNlIChkZWZhdWx0OiBudWxsKVxuICAgKiAtIHtTdHJpbmd9IHJlbW90ZSBUaGUgcmVtb3RlIEtpbnRvIHNlcnZlciBlbmRwb2ludCB0byB1c2UgKGRlZmF1bHQ6IG51bGwpLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnMgT3B0aW9ucy5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogQHRocm93cyB7RXJyb3J9IElmIGFuIGludmFsaWQgcmVtb3RlIG9wdGlvbiBpcyBwYXNzZWQuXG4gICAqL1xuICBhc3luYyBzeW5jKFxuICAgIG9wdGlvbnMgPSB7XG4gICAgICBzdHJhdGVneTogQ29sbGVjdGlvbi5zdHJhdGVneS5NQU5VQUwsXG4gICAgICBoZWFkZXJzOiB7fSxcbiAgICAgIHJldHJ5OiAxLFxuICAgICAgaWdub3JlQmFja29mZjogZmFsc2UsXG4gICAgICBidWNrZXQ6IG51bGwsXG4gICAgICBjb2xsZWN0aW9uOiBudWxsLFxuICAgICAgcmVtb3RlOiBudWxsLFxuICAgICAgZXhwZWN0ZWRUaW1lc3RhbXA6IG51bGwsXG4gICAgfVxuICApIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIGJ1Y2tldDogb3B0aW9ucy5idWNrZXQgfHwgdGhpcy5idWNrZXQsXG4gICAgICBjb2xsZWN0aW9uOiBvcHRpb25zLmNvbGxlY3Rpb24gfHwgdGhpcy5uYW1lLFxuICAgIH07XG5cbiAgICBjb25zdCBwcmV2aW91c1JlbW90ZSA9IHRoaXMuYXBpLnJlbW90ZTtcbiAgICBpZiAob3B0aW9ucy5yZW1vdGUpIHtcbiAgICAgIC8vIE5vdGU6IHNldHRpbmcgdGhlIHJlbW90ZSBlbnN1cmVzIGl0J3MgdmFsaWQsIHRocm93cyB3aGVuIGludmFsaWQuXG4gICAgICB0aGlzLmFwaS5yZW1vdGUgPSBvcHRpb25zLnJlbW90ZTtcbiAgICB9XG4gICAgaWYgKCFvcHRpb25zLmlnbm9yZUJhY2tvZmYgJiYgdGhpcy5hcGkuYmFja29mZiA+IDApIHtcbiAgICAgIGNvbnN0IHNlY29uZHMgPSBNYXRoLmNlaWwodGhpcy5hcGkuYmFja29mZiAvIDEwMDApO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICBuZXcgRXJyb3IoXG4gICAgICAgICAgYFNlcnZlciBpcyBhc2tpbmcgY2xpZW50cyB0byBiYWNrIG9mZjsgcmV0cnkgaW4gJHtzZWNvbmRzfXMgb3IgdXNlIHRoZSBpZ25vcmVCYWNrb2ZmIG9wdGlvbi5gXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5hcGlcbiAgICAgIC5idWNrZXQob3B0aW9ucy5idWNrZXQpXG4gICAgICAuY29sbGVjdGlvbihvcHRpb25zLmNvbGxlY3Rpb24pO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IFN5bmNSZXN1bHRPYmplY3QoKTtcbiAgICB0cnkge1xuICAgICAgLy8gRmV0Y2ggY29sbGVjdGlvbiBtZXRhZGF0YS5cbiAgICAgIGF3YWl0IHRoaXMucHVsbE1ldGFkYXRhKGNsaWVudCwgb3B0aW9ucyk7XG5cbiAgICAgIC8vIEZldGNoIGxhc3QgY2hhbmdlcyBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAgICBhd2FpdCB0aGlzLnB1bGxDaGFuZ2VzKGNsaWVudCwgcmVzdWx0LCBvcHRpb25zKTtcbiAgICAgIGNvbnN0IHsgbGFzdE1vZGlmaWVkIH0gPSByZXN1bHQ7XG5cbiAgICAgIGlmIChvcHRpb25zLnN0cmF0ZWd5ICE9IENvbGxlY3Rpb24uc3RyYXRlZ3kuUFVMTF9PTkxZKSB7XG4gICAgICAgIC8vIEZldGNoIGxvY2FsIGNoYW5nZXNcbiAgICAgICAgY29uc3QgdG9TeW5jID0gYXdhaXQgdGhpcy5nYXRoZXJMb2NhbENoYW5nZXMoKTtcblxuICAgICAgICAvLyBQdWJsaXNoIGxvY2FsIGNoYW5nZXMgYW5kIHB1bGwgbG9jYWwgcmVzb2x1dGlvbnNcbiAgICAgICAgYXdhaXQgdGhpcy5wdXNoQ2hhbmdlcyhjbGllbnQsIHRvU3luYywgcmVzdWx0LCBvcHRpb25zKTtcblxuICAgICAgICAvLyBQdWJsaXNoIGxvY2FsIHJlc29sdXRpb24gb2YgcHVzaCBjb25mbGljdHMgdG8gc2VydmVyIChvbiBDTElFTlRfV0lOUylcbiAgICAgICAgY29uc3QgcmVzb2x2ZWRVbnN5bmNlZCA9IHJlc3VsdC5yZXNvbHZlZC5maWx0ZXIoXG4gICAgICAgICAgciA9PiByLl9zdGF0dXMgIT09IFwic3luY2VkXCJcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHJlc29sdmVkVW5zeW5jZWQubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNvbnN0IHJlc29sdmVkRW5jb2RlZCA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgcmVzb2x2ZWRVbnN5bmNlZC5tYXAocmVzb2x1dGlvbiA9PiB7XG4gICAgICAgICAgICAgIGxldCByZWNvcmQgPSByZXNvbHV0aW9uLmFjY2VwdGVkO1xuICAgICAgICAgICAgICBpZiAocmVjb3JkID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVjb3JkID0geyBpZDogcmVzb2x1dGlvbi5pZCwgX3N0YXR1czogcmVzb2x1dGlvbi5fc3RhdHVzIH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2VuY29kZVJlY29yZChcInJlbW90ZVwiLCByZWNvcmQpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgICAgIGF3YWl0IHRoaXMucHVzaENoYW5nZXMoY2xpZW50LCByZXNvbHZlZEVuY29kZWQsIHJlc3VsdCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUGVyZm9ybSBhIGxhc3QgcHVsbCB0byBjYXRjaCBjaGFuZ2VzIHRoYXQgb2NjdXJlZCBhZnRlciB0aGUgbGFzdCBwdWxsLFxuICAgICAgICAvLyB3aGlsZSBsb2NhbCBjaGFuZ2VzIHdlcmUgcHVzaGVkLiBEbyBub3QgZG8gaXQgbm90aGluZyB3YXMgcHVzaGVkLlxuICAgICAgICBpZiAocmVzdWx0LnB1Ymxpc2hlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgLy8gQXZvaWQgcmVkb3dubG9hZGluZyBvdXIgb3duIGNoYW5nZXMgZHVyaW5nIHRoZSBsYXN0IHB1bGwuXG4gICAgICAgICAgY29uc3QgcHVsbE9wdHMgPSB7XG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgbGFzdE1vZGlmaWVkLFxuICAgICAgICAgICAgZXhjbHVkZTogcmVzdWx0LnB1Ymxpc2hlZCxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGF3YWl0IHRoaXMucHVsbENoYW5nZXMoY2xpZW50LCByZXN1bHQsIHB1bGxPcHRzKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBEb24ndCBwZXJzaXN0IGxhc3RNb2RpZmllZCB2YWx1ZSBpZiBhbnkgY29uZmxpY3Qgb3IgZXJyb3Igb2NjdXJlZFxuICAgICAgaWYgKHJlc3VsdC5vaykge1xuICAgICAgICAvLyBObyBjb25mbGljdCBvY2N1cmVkLCBwZXJzaXN0IGNvbGxlY3Rpb24ncyBsYXN0TW9kaWZpZWQgdmFsdWVcbiAgICAgICAgdGhpcy5fbGFzdE1vZGlmaWVkID0gYXdhaXQgdGhpcy5kYi5zYXZlTGFzdE1vZGlmaWVkKFxuICAgICAgICAgIHJlc3VsdC5sYXN0TW9kaWZpZWRcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmV2ZW50cy5lbWl0KFwic3luYzplcnJvclwiLCB7IC4uLm9wdGlvbnMsIGVycm9yOiBlIH0pO1xuICAgICAgdGhyb3cgZTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgLy8gRW5zdXJlIEFQSSBkZWZhdWx0IHJlbW90ZSBpcyByZXZlcnRlZCBpZiBhIGN1c3RvbSBvbmUncyBiZWVuIHVzZWRcbiAgICAgIHRoaXMuYXBpLnJlbW90ZSA9IHByZXZpb3VzUmVtb3RlO1xuICAgIH1cbiAgICB0aGlzLmV2ZW50cy5lbWl0KFwic3luYzpzdWNjZXNzXCIsIHsgLi4ub3B0aW9ucywgcmVzdWx0IH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogTG9hZCBhIGxpc3Qgb2YgcmVjb3JkcyBhbHJlYWR5IHN5bmNlZCB3aXRoIHRoZSByZW1vdGUgc2VydmVyLlxuICAgKlxuICAgKiBUaGUgbG9jYWwgcmVjb3JkcyB3aGljaCBhcmUgdW5zeW5jZWQgb3Igd2hvc2UgdGltZXN0YW1wIGlzIGVpdGhlciBtaXNzaW5nXG4gICAqIG9yIHN1cGVyaW9yIHRvIHRob3NlIGJlaW5nIGxvYWRlZCB3aWxsIGJlIGlnbm9yZWQuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgaW1wb3J0QnVsa30gaW5zdGVhZC5cbiAgICogQHBhcmFtICB7QXJyYXl9IHJlY29yZHMgVGhlIHByZXZpb3VzbHkgZXhwb3J0ZWQgbGlzdCBvZiByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHdpdGggdGhlIGVmZmVjdGl2ZWx5IGltcG9ydGVkIHJlY29yZHMuXG4gICAqL1xuICBhc3luYyBsb2FkRHVtcChyZWNvcmRzKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1wb3J0QnVsayhyZWNvcmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGEgbGlzdCBvZiByZWNvcmRzIGFscmVhZHkgc3luY2VkIHdpdGggdGhlIHJlbW90ZSBzZXJ2ZXIuXG4gICAqXG4gICAqIFRoZSBsb2NhbCByZWNvcmRzIHdoaWNoIGFyZSB1bnN5bmNlZCBvciB3aG9zZSB0aW1lc3RhbXAgaXMgZWl0aGVyIG1pc3NpbmdcbiAgICogb3Igc3VwZXJpb3IgdG8gdGhvc2UgYmVpbmcgbG9hZGVkIHdpbGwgYmUgaWdub3JlZC5cbiAgICpcbiAgICogQHBhcmFtICB7QXJyYXl9IHJlY29yZHMgVGhlIHByZXZpb3VzbHkgZXhwb3J0ZWQgbGlzdCBvZiByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHdpdGggdGhlIGVmZmVjdGl2ZWx5IGltcG9ydGVkIHJlY29yZHMuXG4gICAqL1xuICBhc3luYyBpbXBvcnRCdWxrKHJlY29yZHMpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocmVjb3JkcykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlY29yZHMgaXMgbm90IGFuIGFycmF5LlwiKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiByZWNvcmRzKSB7XG4gICAgICBpZiAoXG4gICAgICAgICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVjb3JkLCBcImlkXCIpIHx8XG4gICAgICAgICF0aGlzLmlkU2NoZW1hLnZhbGlkYXRlKHJlY29yZC5pZClcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZWNvcmQgaGFzIGludmFsaWQgSUQ6IFwiICsgSlNPTi5zdHJpbmdpZnkocmVjb3JkKSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghcmVjb3JkLmxhc3RfbW9kaWZpZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiUmVjb3JkIGhhcyBubyBsYXN0X21vZGlmaWVkIHZhbHVlOiBcIiArIEpTT04uc3RyaW5naWZ5KHJlY29yZClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBGZXRjaCBhbGwgZXhpc3RpbmcgcmVjb3JkcyBmcm9tIGxvY2FsIGRhdGFiYXNlLFxuICAgIC8vIGFuZCBza2lwIHRob3NlIHdobyBhcmUgbmV3ZXIgb3Igbm90IG1hcmtlZCBhcyBzeW5jZWQuXG5cbiAgICAvLyBYWFggZmlsdGVyIGJ5IHN0YXR1cyAvIGlkcyBpbiByZWNvcmRzXG5cbiAgICBjb25zdCB7IGRhdGEgfSA9IGF3YWl0IHRoaXMubGlzdCh7fSwgeyBpbmNsdWRlRGVsZXRlZDogdHJ1ZSB9KTtcbiAgICBjb25zdCBleGlzdGluZ0J5SWQgPSBkYXRhLnJlZHVjZSgoYWNjLCByZWNvcmQpID0+IHtcbiAgICAgIGFjY1tyZWNvcmQuaWRdID0gcmVjb3JkO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG5cbiAgICBjb25zdCBuZXdSZWNvcmRzID0gcmVjb3Jkcy5maWx0ZXIocmVjb3JkID0+IHtcbiAgICAgIGNvbnN0IGxvY2FsUmVjb3JkID0gZXhpc3RpbmdCeUlkW3JlY29yZC5pZF07XG4gICAgICBjb25zdCBzaG91bGRLZWVwID1cbiAgICAgICAgLy8gTm8gbG9jYWwgcmVjb3JkIHdpdGggdGhpcyBpZC5cbiAgICAgICAgbG9jYWxSZWNvcmQgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAvLyBPciBsb2NhbCByZWNvcmQgaXMgc3luY2VkXG4gICAgICAgIChsb2NhbFJlY29yZC5fc3RhdHVzID09PSBcInN5bmNlZFwiICYmXG4gICAgICAgICAgLy8gQW5kIHdhcyBzeW5jZWQgZnJvbSBzZXJ2ZXJcbiAgICAgICAgICBsb2NhbFJlY29yZC5sYXN0X21vZGlmaWVkICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAvLyBBbmQgaXMgb2xkZXIgdGhhbiBpbXBvcnRlZCBvbmUuXG4gICAgICAgICAgcmVjb3JkLmxhc3RfbW9kaWZpZWQgPiBsb2NhbFJlY29yZC5sYXN0X21vZGlmaWVkKTtcbiAgICAgIHJldHVybiBzaG91bGRLZWVwO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZGIuaW1wb3J0QnVsayhuZXdSZWNvcmRzLm1hcChtYXJrU3luY2VkKSk7XG4gIH1cblxuICBhc3luYyBwdWxsTWV0YWRhdGEoY2xpZW50LCBvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCB7IGV4cGVjdGVkVGltZXN0YW1wLCBoZWFkZXJzIH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IHF1ZXJ5ID0gZXhwZWN0ZWRUaW1lc3RhbXBcbiAgICAgID8geyBxdWVyeTogeyBfZXhwZWN0ZWQ6IGV4cGVjdGVkVGltZXN0YW1wIH0gfVxuICAgICAgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBhd2FpdCBjbGllbnQuZ2V0RGF0YSh7XG4gICAgICAuLi5xdWVyeSxcbiAgICAgIGhlYWRlcnMsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuZGIuc2F2ZU1ldGFkYXRhKG1ldGFkYXRhKTtcbiAgfVxuXG4gIGFzeW5jIG1ldGFkYXRhKCkge1xuICAgIHJldHVybiB0aGlzLmRiLmdldE1ldGFkYXRhKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBIENvbGxlY3Rpb24tb3JpZW50ZWQgd3JhcHBlciBmb3IgYW4gYWRhcHRlcidzIHRyYW5zYWN0aW9uLlxuICpcbiAqIFRoaXMgZGVmaW5lcyB0aGUgaGlnaC1sZXZlbCBmdW5jdGlvbnMgYXZhaWxhYmxlIG9uIGEgY29sbGVjdGlvbi5cbiAqIFRoZSBjb2xsZWN0aW9uIGl0c2VsZiBvZmZlcnMgZnVuY3Rpb25zIG9mIHRoZSBzYW1lIG5hbWUuIFRoZXNlIHdpbGxcbiAqIHBlcmZvcm0ganVzdCBvbmUgb3BlcmF0aW9uIGluIGl0cyBvd24gdHJhbnNhY3Rpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBDb2xsZWN0aW9uVHJhbnNhY3Rpb24ge1xuICBjb25zdHJ1Y3Rvcihjb2xsZWN0aW9uLCBhZGFwdGVyVHJhbnNhY3Rpb24pIHtcbiAgICB0aGlzLmNvbGxlY3Rpb24gPSBjb2xsZWN0aW9uO1xuICAgIHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uID0gYWRhcHRlclRyYW5zYWN0aW9uO1xuXG4gICAgdGhpcy5fZXZlbnRzID0gW107XG4gIH1cblxuICBfcXVldWVFdmVudChhY3Rpb24sIHBheWxvYWQpIHtcbiAgICB0aGlzLl9ldmVudHMucHVzaCh7IGFjdGlvbiwgcGF5bG9hZCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0IHF1ZXVlZCBldmVudHMsIHRvIGJlIGNhbGxlZCBvbmNlIGV2ZXJ5IHRyYW5zYWN0aW9uIG9wZXJhdGlvbnMgaGF2ZVxuICAgKiBiZWVuIGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseS5cbiAgICovXG4gIGVtaXRFdmVudHMoKSB7XG4gICAgZm9yIChjb25zdCB7IGFjdGlvbiwgcGF5bG9hZCB9IG9mIHRoaXMuX2V2ZW50cykge1xuICAgICAgdGhpcy5jb2xsZWN0aW9uLmV2ZW50cy5lbWl0KGFjdGlvbiwgcGF5bG9hZCk7XG4gICAgfVxuICAgIGlmICh0aGlzLl9ldmVudHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgdGFyZ2V0cyA9IHRoaXMuX2V2ZW50cy5tYXAoKHsgYWN0aW9uLCBwYXlsb2FkIH0pID0+ICh7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgLi4ucGF5bG9hZCxcbiAgICAgIH0pKTtcbiAgICAgIHRoaXMuY29sbGVjdGlvbi5ldmVudHMuZW1pdChcImNoYW5nZVwiLCB7IHRhcmdldHMgfSk7XG4gICAgfVxuICAgIHRoaXMuX2V2ZW50cyA9IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIGEgcmVjb3JkIGJ5IGl0cyBpZCBmcm9tIHRoZSBsb2NhbCBkYXRhYmFzZSwgb3JcbiAgICogdW5kZWZpbmVkIGlmIG5vbmUgZXhpc3RzLlxuICAgKlxuICAgKiBUaGlzIHdpbGwgYWxzbyByZXR1cm4gdmlydHVhbGx5IGRlbGV0ZWQgcmVjb3Jkcy5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSBpZFxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBnZXRBbnkoaWQpIHtcbiAgICBjb25zdCByZWNvcmQgPSB0aGlzLmFkYXB0ZXJUcmFuc2FjdGlvbi5nZXQoaWQpO1xuICAgIHJldHVybiB7IGRhdGE6IHJlY29yZCwgcGVybWlzc2lvbnM6IHt9IH07XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgYSByZWNvcmQgYnkgaXRzIGlkIGZyb20gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtCb29sZWFufSBpbmNsdWRlRGVsZXRlZDogSW5jbHVkZSB2aXJ0dWFsbHkgZGVsZXRlZCByZWNvcmRzLlxuICAgKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkXG4gICAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9uc1xuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBnZXQoaWQsIG9wdGlvbnMgPSB7IGluY2x1ZGVEZWxldGVkOiBmYWxzZSB9KSB7XG4gICAgY29uc3QgcmVzID0gdGhpcy5nZXRBbnkoaWQpO1xuICAgIGlmIChcbiAgICAgICFyZXMuZGF0YSB8fFxuICAgICAgKCFvcHRpb25zLmluY2x1ZGVEZWxldGVkICYmIHJlcy5kYXRhLl9zdGF0dXMgPT09IFwiZGVsZXRlZFwiKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZWNvcmQgd2l0aCBpZD0ke2lkfSBub3QgZm91bmQuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGEgcmVjb3JkIGZyb20gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtCb29sZWFufSB2aXJ0dWFsOiBXaGVuIHNldCB0byBgdHJ1ZWAsIGRvZXNuJ3QgYWN0dWFsbHkgZGVsZXRlIHRoZSByZWNvcmQsXG4gICAqICAgdXBkYXRlIGl0cyBgX3N0YXR1c2AgYXR0cmlidXRlIHRvIGBkZWxldGVkYCBpbnN0ZWFkIChkZWZhdWx0OiB0cnVlKVxuICAgKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkICAgICAgIFRoZSByZWNvcmQncyBJZC5cbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIGRlbGV0ZShpZCwgb3B0aW9ucyA9IHsgdmlydHVhbDogdHJ1ZSB9KSB7XG4gICAgLy8gRW5zdXJlIHRoZSByZWNvcmQgYWN0dWFsbHkgZXhpc3RzLlxuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24uZ2V0KGlkKTtcbiAgICBjb25zdCBhbHJlYWR5RGVsZXRlZCA9IGV4aXN0aW5nICYmIGV4aXN0aW5nLl9zdGF0dXMgPT0gXCJkZWxldGVkXCI7XG4gICAgaWYgKCFleGlzdGluZyB8fCAoYWxyZWFkeURlbGV0ZWQgJiYgb3B0aW9ucy52aXJ0dWFsKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZWNvcmQgd2l0aCBpZD0ke2lkfSBub3QgZm91bmQuYCk7XG4gICAgfVxuICAgIC8vIFZpcnR1YWwgdXBkYXRlcyBzdGF0dXMuXG4gICAgaWYgKG9wdGlvbnMudmlydHVhbCkge1xuICAgICAgdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24udXBkYXRlKG1hcmtEZWxldGVkKGV4aXN0aW5nKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlbGV0ZSBmb3IgcmVhbC5cbiAgICAgIHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLmRlbGV0ZShpZCk7XG4gICAgfVxuICAgIHRoaXMuX3F1ZXVlRXZlbnQoXCJkZWxldGVcIiwgeyBkYXRhOiBleGlzdGluZyB9KTtcbiAgICByZXR1cm4geyBkYXRhOiBleGlzdGluZywgcGVybWlzc2lvbnM6IHt9IH07XG4gIH1cblxuICAvKipcbiAgICogU29mdCBkZWxldGUgYWxsIHJlY29yZHMgZnJvbSB0aGUgbG9jYWwgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBwYXJhbSAge0FycmF5fSBpZHMgICAgICAgIEFycmF5IG9mIG5vbi1kZWxldGVkIFJlY29yZCBJZHMuXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIGRlbGV0ZUFsbChpZHMpIHtcbiAgICBjb25zdCBleGlzdGluZ1JlY29yZHMgPSBbXTtcbiAgICBpZHMuZm9yRWFjaChpZCA9PiB7XG4gICAgICBleGlzdGluZ1JlY29yZHMucHVzaCh0aGlzLmFkYXB0ZXJUcmFuc2FjdGlvbi5nZXQoaWQpKTtcbiAgICAgIHRoaXMuZGVsZXRlKGlkKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX3F1ZXVlRXZlbnQoXCJkZWxldGVBbGxcIiwgeyBkYXRhOiBleGlzdGluZ1JlY29yZHMgfSk7XG4gICAgcmV0dXJuIHsgZGF0YTogZXhpc3RpbmdSZWNvcmRzLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGEgcmVjb3JkIGZyb20gdGhlIGxvY2FsIGRhdGFiYXNlLCBpZiBhbnkgZXhpc3RzLlxuICAgKiBPdGhlcndpc2UsIGRvIG5vdGhpbmcuXG4gICAqXG4gICAqIEBwYXJhbSAge1N0cmluZ30gaWQgICAgICAgVGhlIHJlY29yZCdzIElkLlxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBkZWxldGVBbnkoaWQpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLmdldChpZCk7XG4gICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICB0aGlzLmFkYXB0ZXJUcmFuc2FjdGlvbi51cGRhdGUobWFya0RlbGV0ZWQoZXhpc3RpbmcpKTtcbiAgICAgIHRoaXMuX3F1ZXVlRXZlbnQoXCJkZWxldGVcIiwgeyBkYXRhOiBleGlzdGluZyB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHsgZGF0YTogeyBpZCwgLi4uZXhpc3RpbmcgfSwgZGVsZXRlZDogISFleGlzdGluZywgcGVybWlzc2lvbnM6IHt9IH07XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlY29yZCB0byB0aGUgbG9jYWwgZGF0YWJhc2UsIGFzc2VydGluZyB0aGF0IG5vbmVcbiAgICogYWxyZWFkeSBleGlzdCB3aXRoIHRoaXMgSUQuXG4gICAqXG4gICAqIEBwYXJhbSAge09iamVjdH0gcmVjb3JkLCB3aGljaCBtdXN0IGNvbnRhaW4gYW4gSURcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgY3JlYXRlKHJlY29yZCkge1xuICAgIGlmICh0eXBlb2YgcmVjb3JkICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZWNvcmQgaXMgbm90IGFuIG9iamVjdC5cIik7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlY29yZCwgXCJpZFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGNyZWF0ZSBhIHJlY29yZCBtaXNzaW5nIGlkXCIpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuY29sbGVjdGlvbi5pZFNjaGVtYS52YWxpZGF0ZShyZWNvcmQuaWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgSWQ6ICR7cmVjb3JkLmlkfWApO1xuICAgIH1cblxuICAgIHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLmNyZWF0ZShyZWNvcmQpO1xuICAgIHRoaXMuX3F1ZXVlRXZlbnQoXCJjcmVhdGVcIiwgeyBkYXRhOiByZWNvcmQgfSk7XG4gICAgcmV0dXJuIHsgZGF0YTogcmVjb3JkLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIGEgcmVjb3JkIGZyb20gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtCb29sZWFufSBzeW5jZWQ6IFNldHMgcmVjb3JkIHN0YXR1cyB0byBcInN5bmNlZFwiIChkZWZhdWx0OiBmYWxzZSlcbiAgICogLSB7Qm9vbGVhbn0gcGF0Y2g6ICBFeHRlbmRzIHRoZSBleGlzdGluZyByZWNvcmQgaW5zdGVhZCBvZiBvdmVyd3JpdGluZyBpdFxuICAgKiAgIChkZWZhdWx0OiBmYWxzZSlcbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSByZWNvcmRcbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIHVwZGF0ZShyZWNvcmQsIG9wdGlvbnMgPSB7IHN5bmNlZDogZmFsc2UsIHBhdGNoOiBmYWxzZSB9KSB7XG4gICAgaWYgKHR5cGVvZiByZWNvcmQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlY29yZCBpcyBub3QgYW4gb2JqZWN0LlwiKTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVjb3JkLCBcImlkXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgdXBkYXRlIGEgcmVjb3JkIG1pc3NpbmcgaWQuXCIpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuY29sbGVjdGlvbi5pZFNjaGVtYS52YWxpZGF0ZShyZWNvcmQuaWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgSWQ6ICR7cmVjb3JkLmlkfWApO1xuICAgIH1cblxuICAgIGNvbnN0IG9sZFJlY29yZCA9IHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLmdldChyZWNvcmQuaWQpO1xuICAgIGlmICghb2xkUmVjb3JkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlY29yZCB3aXRoIGlkPSR7cmVjb3JkLmlkfSBub3QgZm91bmQuYCk7XG4gICAgfVxuICAgIGNvbnN0IG5ld1JlY29yZCA9IG9wdGlvbnMucGF0Y2ggPyB7IC4uLm9sZFJlY29yZCwgLi4ucmVjb3JkIH0gOiByZWNvcmQ7XG4gICAgY29uc3QgdXBkYXRlZCA9IHRoaXMuX3VwZGF0ZVJhdyhvbGRSZWNvcmQsIG5ld1JlY29yZCwgb3B0aW9ucyk7XG4gICAgdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24udXBkYXRlKHVwZGF0ZWQpO1xuICAgIHRoaXMuX3F1ZXVlRXZlbnQoXCJ1cGRhdGVcIiwgeyBkYXRhOiB1cGRhdGVkLCBvbGRSZWNvcmQgfSk7XG4gICAgcmV0dXJuIHsgZGF0YTogdXBkYXRlZCwgb2xkUmVjb3JkLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb3dlci1sZXZlbCBwcmltaXRpdmUgZm9yIHVwZGF0aW5nIGEgcmVjb3JkIHdoaWxlIHJlc3BlY3RpbmdcbiAgICogX3N0YXR1cyBhbmQgbGFzdF9tb2RpZmllZC5cbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSBvbGRSZWNvcmQ6IHRoZSByZWNvcmQgcmV0cmlldmVkIGZyb20gdGhlIERCXG4gICAqIEBwYXJhbSAge09iamVjdH0gbmV3UmVjb3JkOiB0aGUgcmVjb3JkIHRvIHJlcGxhY2UgaXQgd2l0aFxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBfdXBkYXRlUmF3KG9sZFJlY29yZCwgbmV3UmVjb3JkLCB7IHN5bmNlZCA9IGZhbHNlIH0gPSB7fSkge1xuICAgIGNvbnN0IHVwZGF0ZWQgPSB7IC4uLm5ld1JlY29yZCB9O1xuICAgIC8vIE1ha2Ugc3VyZSB0byBuZXZlciBsb29zZSB0aGUgZXhpc3RpbmcgdGltZXN0YW1wLlxuICAgIGlmIChvbGRSZWNvcmQgJiYgb2xkUmVjb3JkLmxhc3RfbW9kaWZpZWQgJiYgIXVwZGF0ZWQubGFzdF9tb2RpZmllZCkge1xuICAgICAgdXBkYXRlZC5sYXN0X21vZGlmaWVkID0gb2xkUmVjb3JkLmxhc3RfbW9kaWZpZWQ7XG4gICAgfVxuICAgIC8vIElmIG9ubHkgbG9jYWwgZmllbGRzIGhhdmUgY2hhbmdlZCwgdGhlbiBrZWVwIHJlY29yZCBhcyBzeW5jZWQuXG4gICAgLy8gSWYgc3RhdHVzIGlzIGNyZWF0ZWQsIGtlZXAgcmVjb3JkIGFzIGNyZWF0ZWQuXG4gICAgLy8gSWYgc3RhdHVzIGlzIGRlbGV0ZWQsIG1hcmsgYXMgdXBkYXRlZC5cbiAgICBjb25zdCBpc0lkZW50aWNhbCA9XG4gICAgICBvbGRSZWNvcmQgJiZcbiAgICAgIHJlY29yZHNFcXVhbChvbGRSZWNvcmQsIHVwZGF0ZWQsIHRoaXMuY29sbGVjdGlvbi5sb2NhbEZpZWxkcyk7XG4gICAgY29uc3Qga2VlcFN5bmNlZCA9IGlzSWRlbnRpY2FsICYmIG9sZFJlY29yZC5fc3RhdHVzID09IFwic3luY2VkXCI7XG4gICAgY29uc3QgbmV2ZXJTeW5jZWQgPVxuICAgICAgIW9sZFJlY29yZCB8fCAob2xkUmVjb3JkICYmIG9sZFJlY29yZC5fc3RhdHVzID09IFwiY3JlYXRlZFwiKTtcbiAgICBjb25zdCBuZXdTdGF0dXMgPVxuICAgICAga2VlcFN5bmNlZCB8fCBzeW5jZWQgPyBcInN5bmNlZFwiIDogbmV2ZXJTeW5jZWQgPyBcImNyZWF0ZWRcIiA6IFwidXBkYXRlZFwiO1xuICAgIHJldHVybiBtYXJrU3RhdHVzKHVwZGF0ZWQsIG5ld1N0YXR1cyk7XG4gIH1cblxuICAvKipcbiAgICogVXBzZXJ0IGEgcmVjb3JkIGludG8gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBUaGlzIHJlY29yZCBtdXN0IGhhdmUgYW4gSUQuXG4gICAqXG4gICAqIElmIGEgcmVjb3JkIHdpdGggdGhpcyBJRCBhbHJlYWR5IGV4aXN0cywgaXQgd2lsbCBiZSByZXBsYWNlZC5cbiAgICogT3RoZXJ3aXNlLCB0aGlzIHJlY29yZCB3aWxsIGJlIGluc2VydGVkLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHJlY29yZFxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICB1cHNlcnQocmVjb3JkKSB7XG4gICAgaWYgKHR5cGVvZiByZWNvcmQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlY29yZCBpcyBub3QgYW4gb2JqZWN0LlwiKTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVjb3JkLCBcImlkXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgdXBkYXRlIGEgcmVjb3JkIG1pc3NpbmcgaWQuXCIpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuY29sbGVjdGlvbi5pZFNjaGVtYS52YWxpZGF0ZShyZWNvcmQuaWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgSWQ6ICR7cmVjb3JkLmlkfWApO1xuICAgIH1cbiAgICBsZXQgb2xkUmVjb3JkID0gdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24uZ2V0KHJlY29yZC5pZCk7XG4gICAgY29uc3QgdXBkYXRlZCA9IHRoaXMuX3VwZGF0ZVJhdyhvbGRSZWNvcmQsIHJlY29yZCk7XG4gICAgdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24udXBkYXRlKHVwZGF0ZWQpO1xuICAgIC8vIERvbid0IHJldHVybiBkZWxldGVkIHJlY29yZHMgLS0gcHJldGVuZCB0aGV5IGFyZSBnb25lXG4gICAgaWYgKG9sZFJlY29yZCAmJiBvbGRSZWNvcmQuX3N0YXR1cyA9PSBcImRlbGV0ZWRcIikge1xuICAgICAgb2xkUmVjb3JkID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBpZiAob2xkUmVjb3JkKSB7XG4gICAgICB0aGlzLl9xdWV1ZUV2ZW50KFwidXBkYXRlXCIsIHsgZGF0YTogdXBkYXRlZCwgb2xkUmVjb3JkIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9xdWV1ZUV2ZW50KFwiY3JlYXRlXCIsIHsgZGF0YTogdXBkYXRlZCB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHsgZGF0YTogdXBkYXRlZCwgb2xkUmVjb3JkLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gXCJldmVudHNcIjtcblxuLy8gYmFiZWwtcG9seWZpbGwgY2FuIG9ubHkgYmUgaW1wb3J0ZWQgb25jZVxuaWYgKCFnbG9iYWwuX2JhYmVsUG9seWZpbGwpIHtcbiAgcmVxdWlyZShcIkBiYWJlbC9wb2x5ZmlsbFwiKTtcbn1cblxuaW1wb3J0IEFwaSBmcm9tIFwia2ludG8taHR0cFwiO1xuaW1wb3J0IEJhc2VBZGFwdGVyIGZyb20gXCIuL2FkYXB0ZXJzL2Jhc2VcIjtcbmltcG9ydCBJREIgZnJvbSBcIi4vYWRhcHRlcnMvSURCXCI7XG5pbXBvcnQgS2ludG9CYXNlIGZyb20gXCIuL0tpbnRvQmFzZVwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBLaW50byBleHRlbmRzIEtpbnRvQmFzZSB7XG4gIC8qKlxuICAgKiBQcm92aWRlcyBhIHB1YmxpYyBhY2Nlc3MgdG8gdGhlIGJhc2UgYWRhcHRlciBjbGFzc2VzLiBVc2VycyBjYW4gY3JlYXRlXG4gICAqIGEgY3VzdG9tIERCIGFkYXB0ZXIgYnkgZXh0ZW5kaW5nIEJhc2VBZGFwdGVyLlxuICAgKlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgc3RhdGljIGdldCBhZGFwdGVycygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgQmFzZUFkYXB0ZXIsXG4gICAgICBJREIsXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IGRlZmF1bHRzID0ge1xuICAgICAgYWRhcHRlcjogS2ludG8uYWRhcHRlcnMuSURCLFxuICAgICAgZXZlbnRzOiBuZXcgRXZlbnRFbWl0dGVyKCksXG4gICAgICBBcGlDbGFzczogQXBpLFxuICAgIH07XG5cbiAgICBzdXBlcih7IC4uLmRlZmF1bHRzLCAuLi5vcHRpb25zIH0pO1xuICB9XG59XG5cbi8vIFRoaXMgZml4ZXMgY29tcGF0aWJpbGl0eSB3aXRoIENvbW1vbkpTIHJlcXVpcmVkIGJ5IGJyb3dzZXJpZnkuXG4vLyBTZWUgaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zMzUwNTk5Mi9iYWJlbC02LWNoYW5nZXMtaG93LWl0LWV4cG9ydHMtZGVmYXVsdC8zMzY4MzQ5NSMzMzY4MzQ5NVxuaWYgKHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBLaW50bztcbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnQgY29uc3QgUkVfUkVDT1JEX0lEID0gL15bYS16QS1aMC05XVthLXpBLVowLTlfLV0qJC87XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgdW5kZWZpbmVkLlxuICogQHBhcmFtICB7QW55fSAgdmFsdWVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIF9pc1VuZGVmaW5lZCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiO1xufVxuXG4vKipcbiAqIFNvcnRzIHJlY29yZHMgaW4gYSBsaXN0IGFjY29yZGluZyB0byBhIGdpdmVuIG9yZGVyaW5nLlxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gb3JkZXIgVGhlIG9yZGVyaW5nLCBlZy4gYC1sYXN0X21vZGlmaWVkYC5cbiAqIEBwYXJhbSAge0FycmF5fSAgbGlzdCAgVGhlIGNvbGxlY3Rpb24gdG8gb3JkZXIuXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNvcnRPYmplY3RzKG9yZGVyLCBsaXN0KSB7XG4gIGNvbnN0IGhhc0Rhc2ggPSBvcmRlclswXSA9PT0gXCItXCI7XG4gIGNvbnN0IGZpZWxkID0gaGFzRGFzaCA/IG9yZGVyLnNsaWNlKDEpIDogb3JkZXI7XG4gIGNvbnN0IGRpcmVjdGlvbiA9IGhhc0Rhc2ggPyAtMSA6IDE7XG4gIHJldHVybiBsaXN0LnNsaWNlKCkuc29ydCgoYSwgYikgPT4ge1xuICAgIGlmIChhW2ZpZWxkXSAmJiBfaXNVbmRlZmluZWQoYltmaWVsZF0pKSB7XG4gICAgICByZXR1cm4gZGlyZWN0aW9uO1xuICAgIH1cbiAgICBpZiAoYltmaWVsZF0gJiYgX2lzVW5kZWZpbmVkKGFbZmllbGRdKSkge1xuICAgICAgcmV0dXJuIC1kaXJlY3Rpb247XG4gICAgfVxuICAgIGlmIChfaXNVbmRlZmluZWQoYVtmaWVsZF0pICYmIF9pc1VuZGVmaW5lZChiW2ZpZWxkXSkpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICByZXR1cm4gYVtmaWVsZF0gPiBiW2ZpZWxkXSA/IGRpcmVjdGlvbiA6IC1kaXJlY3Rpb247XG4gIH0pO1xufVxuXG4vKipcbiAqIFRlc3QgaWYgYSBzaW5nbGUgb2JqZWN0IG1hdGNoZXMgYWxsIGdpdmVuIGZpbHRlcnMuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBmaWx0ZXJzICBUaGUgZmlsdGVycyBvYmplY3QuXG4gKiBAcGFyYW0gIHtPYmplY3R9IGVudHJ5ICAgIFRoZSBvYmplY3QgdG8gZmlsdGVyLlxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbHRlck9iamVjdChmaWx0ZXJzLCBlbnRyeSkge1xuICByZXR1cm4gT2JqZWN0LmtleXMoZmlsdGVycykuZXZlcnkoZmlsdGVyID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IGZpbHRlcnNbZmlsdGVyXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5zb21lKGNhbmRpZGF0ZSA9PiBjYW5kaWRhdGUgPT09IGVudHJ5W2ZpbHRlcl0pO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSB7XG4gICAgICByZXR1cm4gZmlsdGVyT2JqZWN0KHZhbHVlLCBlbnRyeVtmaWx0ZXJdKTtcbiAgICB9IGVsc2UgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZW50cnksIGZpbHRlcikpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFRoZSBwcm9wZXJ0eSAke2ZpbHRlcn0gZG9lcyBub3QgZXhpc3RgKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGVudHJ5W2ZpbHRlcl0gPT09IHZhbHVlO1xuICB9KTtcbn1cblxuLyoqXG4gKiBGaWx0ZXJzIHJlY29yZHMgaW4gYSBsaXN0IG1hdGNoaW5nIGFsbCBnaXZlbiBmaWx0ZXJzLlxuICpcbiAqIEBwYXJhbSAge09iamVjdH0gZmlsdGVycyAgVGhlIGZpbHRlcnMgb2JqZWN0LlxuICogQHBhcmFtICB7QXJyYXl9ICBsaXN0ICAgICBUaGUgY29sbGVjdGlvbiB0byBmaWx0ZXIuXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbHRlck9iamVjdHMoZmlsdGVycywgbGlzdCkge1xuICByZXR1cm4gbGlzdC5maWx0ZXIoZW50cnkgPT4ge1xuICAgIHJldHVybiBmaWx0ZXJPYmplY3QoZmlsdGVycywgZW50cnkpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBhIGxpc3Qgb2YgZnVuY3Rpb25zIHNlcXVlbnRpYWxseSwgd2hpY2ggY2FuIGJlIHN5bmMgb3IgYXN5bmM7IGluXG4gKiBjYXNlIG9mIGFzeW5jLCBmdW5jdGlvbnMgbXVzdCByZXR1cm4gYSBwcm9taXNlLlxuICpcbiAqIEBwYXJhbSAge0FycmF5fSBmbnMgIFRoZSBsaXN0IG9mIGZ1bmN0aW9ucy5cbiAqIEBwYXJhbSAge0FueX0gICBpbml0IFRoZSBpbml0aWFsIHZhbHVlLlxuICogQHJldHVybiB7UHJvbWlzZX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdhdGVyZmFsbChmbnMsIGluaXQpIHtcbiAgaWYgKCFmbnMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShpbml0KTtcbiAgfVxuICByZXR1cm4gZm5zLnJlZHVjZSgocHJvbWlzZSwgbmV4dEZuKSA9PiB7XG4gICAgcmV0dXJuIHByb21pc2UudGhlbihuZXh0Rm4pO1xuICB9LCBQcm9taXNlLnJlc29sdmUoaW5pdCkpO1xufVxuXG4vKipcbiAqIFNpbXBsZSBkZWVwIG9iamVjdCBjb21wYXJpc29uIGZ1bmN0aW9uLiBUaGlzIG9ubHkgc3VwcG9ydHMgY29tcGFyaXNvbiBvZlxuICogc2VyaWFsaXphYmxlIEphdmFTY3JpcHQgb2JqZWN0cy5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGEgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcGFyYW0gIHtPYmplY3R9IGIgVGhlIGNvbXBhcmVkIG9iamVjdC5cbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWVwRXF1YWwoYSwgYikge1xuICBpZiAoYSA9PT0gYikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKCEoYSAmJiB0eXBlb2YgYSA9PSBcIm9iamVjdFwiKSB8fCAhKGIgJiYgdHlwZW9mIGIgPT0gXCJvYmplY3RcIikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKE9iamVjdC5rZXlzKGEpLmxlbmd0aCAhPT0gT2JqZWN0LmtleXMoYikubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGZvciAoY29uc3QgayBpbiBhKSB7XG4gICAgaWYgKCFkZWVwRXF1YWwoYVtrXSwgYltrXSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogUmV0dXJuIGFuIG9iamVjdCB3aXRob3V0IHRoZSBzcGVjaWZpZWQga2V5cy5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9iaiAgICAgICAgVGhlIG9yaWdpbmFsIG9iamVjdC5cbiAqIEBwYXJhbSAge0FycmF5fSAga2V5cyAgICAgICBUaGUgbGlzdCBvZiBrZXlzIHRvIGV4Y2x1ZGUuXG4gKiBAcmV0dXJuIHtPYmplY3R9ICAgICAgICAgICAgQSBjb3B5IHdpdGhvdXQgdGhlIHNwZWNpZmllZCBrZXlzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb21pdEtleXMob2JqLCBrZXlzID0gW10pIHtcbiAgY29uc3QgcmVzdWx0ID0geyAuLi5vYmogfTtcbiAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgIGRlbGV0ZSByZXN1bHRba2V5XTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlFcXVhbChhLCBiKSB7XG4gIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgZm9yIChsZXQgaSA9IGEubGVuZ3RoOyBpLS07ICkge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBtYWtlTmVzdGVkT2JqZWN0RnJvbUFycihhcnIsIHZhbCwgbmVzdGVkRmlsdGVyc09iaikge1xuICBjb25zdCBsYXN0ID0gYXJyLmxlbmd0aCAtIDE7XG4gIHJldHVybiBhcnIucmVkdWNlKChhY2MsIGN2LCBpKSA9PiB7XG4gICAgaWYgKGkgPT09IGxhc3QpIHtcbiAgICAgIHJldHVybiAoYWNjW2N2XSA9IHZhbCk7XG4gICAgfSBlbHNlIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYWNjLCBjdikpIHtcbiAgICAgIHJldHVybiBhY2NbY3ZdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gKGFjY1tjdl0gPSB7fSk7XG4gICAgfVxuICB9LCBuZXN0ZWRGaWx0ZXJzT2JqKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybVN1Yk9iamVjdEZpbHRlcnMoZmlsdGVyc09iaikge1xuICBjb25zdCB0cmFuc2Zvcm1lZEZpbHRlcnMgPSB7fTtcbiAgZm9yIChjb25zdCBrZXkgaW4gZmlsdGVyc09iaikge1xuICAgIGNvbnN0IGtleXNBcnIgPSBrZXkuc3BsaXQoXCIuXCIpO1xuICAgIGNvbnN0IHZhbCA9IGZpbHRlcnNPYmpba2V5XTtcbiAgICBtYWtlTmVzdGVkT2JqZWN0RnJvbUFycihrZXlzQXJyLCB2YWwsIHRyYW5zZm9ybWVkRmlsdGVycyk7XG4gIH1cbiAgcmV0dXJuIHRyYW5zZm9ybWVkRmlsdGVycztcbn1cbiJdfQ==