mirror of
https://github.com/tenrok/vue-select.git
synced 2026-06-10 07:52:23 +03:00
22629 lines
1.6 MiB
Plaintext
22629 lines
1.6 MiB
Plaintext
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({2:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/after/index.js", module);
|
||
(function(){
|
||
module.exports = after
|
||
|
||
function after(count, callback, err_cb) {
|
||
var bail = false
|
||
err_cb = err_cb || noop
|
||
proxy.count = count
|
||
|
||
return (count === 0) ? callback() : proxy
|
||
|
||
function proxy(err, result) {
|
||
if (proxy.count <= 0) {
|
||
throw new Error('after called too many times')
|
||
}
|
||
--proxy.count
|
||
|
||
// after first error, rest are passed to err_cb
|
||
if (err) {
|
||
bail = true
|
||
callback(err)
|
||
// future error callbacks will go to error handler
|
||
callback = err_cb
|
||
} else if (proxy.count === 0 && !bail) {
|
||
callback(null, result)
|
||
}
|
||
}
|
||
}
|
||
|
||
function noop() {}
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],3:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/arraybuffer.slice/index.js", module);
|
||
(function(){
|
||
/**
|
||
* An abstraction for slicing an arraybuffer even when
|
||
* ArrayBuffer.prototype.slice is not supported
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
module.exports = function(arraybuffer, start, end) {
|
||
var bytes = arraybuffer.byteLength;
|
||
start = start || 0;
|
||
end = end || bytes;
|
||
|
||
if (arraybuffer.slice) { return arraybuffer.slice(start, end); }
|
||
|
||
if (start < 0) { start += bytes; }
|
||
if (end < 0) { end += bytes; }
|
||
if (end > bytes) { end = bytes; }
|
||
|
||
if (start >= bytes || start >= end || bytes === 0) {
|
||
return new ArrayBuffer(0);
|
||
}
|
||
|
||
var abv = new Uint8Array(arraybuffer);
|
||
var result = new Uint8Array(end - start);
|
||
for (var i = start, ii = 0; i < end; i++, ii++) {
|
||
result[ii] = abv[i];
|
||
}
|
||
return result.buffer;
|
||
};
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],4:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/babel-runtime/core-js/symbol.js", module);
|
||
(function(){
|
||
module.exports = { "default": require("core-js/library/fn/symbol"), __esModule: true };
|
||
}).apply(this, arguments);
|
||
|
||
},{"core-js/library/fn/symbol":16}],5:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/babel-runtime/helpers/typeof.js", module);
|
||
(function(){
|
||
"use strict";
|
||
|
||
var _Symbol = require("babel-runtime/core-js/symbol")["default"];
|
||
|
||
exports["default"] = function (obj) {
|
||
return obj && obj.constructor === _Symbol ? "symbol" : typeof obj;
|
||
};
|
||
|
||
exports.__esModule = true;
|
||
}).apply(this, arguments);
|
||
|
||
},{"babel-runtime/core-js/symbol":4}],6:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/backo2/index.js", module);
|
||
(function(){
|
||
|
||
/**
|
||
* Expose `Backoff`.
|
||
*/
|
||
|
||
module.exports = Backoff;
|
||
|
||
/**
|
||
* Initialize backoff timer with `opts`.
|
||
*
|
||
* - `min` initial timeout in milliseconds [100]
|
||
* - `max` max timeout [10000]
|
||
* - `jitter` [0]
|
||
* - `factor` [2]
|
||
*
|
||
* @param {Object} opts
|
||
* @api public
|
||
*/
|
||
|
||
function Backoff(opts) {
|
||
opts = opts || {};
|
||
this.ms = opts.min || 100;
|
||
this.max = opts.max || 10000;
|
||
this.factor = opts.factor || 2;
|
||
this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
|
||
this.attempts = 0;
|
||
}
|
||
|
||
/**
|
||
* Return the backoff duration.
|
||
*
|
||
* @return {Number}
|
||
* @api public
|
||
*/
|
||
|
||
Backoff.prototype.duration = function(){
|
||
var ms = this.ms * Math.pow(this.factor, this.attempts++);
|
||
if (this.jitter) {
|
||
var rand = Math.random();
|
||
var deviation = Math.floor(rand * this.jitter * ms);
|
||
ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
|
||
}
|
||
return Math.min(ms, this.max) | 0;
|
||
};
|
||
|
||
/**
|
||
* Reset the number of attempts.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
Backoff.prototype.reset = function(){
|
||
this.attempts = 0;
|
||
};
|
||
|
||
/**
|
||
* Set the minimum duration
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
Backoff.prototype.setMin = function(min){
|
||
this.ms = min;
|
||
};
|
||
|
||
/**
|
||
* Set the maximum duration
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
Backoff.prototype.setMax = function(max){
|
||
this.max = max;
|
||
};
|
||
|
||
/**
|
||
* Set the jitter
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
Backoff.prototype.setJitter = function(jitter){
|
||
this.jitter = jitter;
|
||
};
|
||
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],7:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/base64-arraybuffer/lib/base64-arraybuffer.js", module);
|
||
(function(){
|
||
/*
|
||
* base64-arraybuffer
|
||
* https://github.com/niklasvh/base64-arraybuffer
|
||
*
|
||
* Copyright (c) 2012 Niklas von Hertzen
|
||
* Licensed under the MIT license.
|
||
*/
|
||
(function(chars){
|
||
"use strict";
|
||
|
||
exports.encode = function(arraybuffer) {
|
||
var bytes = new Uint8Array(arraybuffer),
|
||
i, len = bytes.length, base64 = "";
|
||
|
||
for (i = 0; i < len; i+=3) {
|
||
base64 += chars[bytes[i] >> 2];
|
||
base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
|
||
base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
|
||
base64 += chars[bytes[i + 2] & 63];
|
||
}
|
||
|
||
if ((len % 3) === 2) {
|
||
base64 = base64.substring(0, base64.length - 1) + "=";
|
||
} else if (len % 3 === 1) {
|
||
base64 = base64.substring(0, base64.length - 2) + "==";
|
||
}
|
||
|
||
return base64;
|
||
};
|
||
|
||
exports.decode = function(base64) {
|
||
var bufferLength = base64.length * 0.75,
|
||
len = base64.length, i, p = 0,
|
||
encoded1, encoded2, encoded3, encoded4;
|
||
|
||
if (base64[base64.length - 1] === "=") {
|
||
bufferLength--;
|
||
if (base64[base64.length - 2] === "=") {
|
||
bufferLength--;
|
||
}
|
||
}
|
||
|
||
var arraybuffer = new ArrayBuffer(bufferLength),
|
||
bytes = new Uint8Array(arraybuffer);
|
||
|
||
for (i = 0; i < len; i+=4) {
|
||
encoded1 = chars.indexOf(base64[i]);
|
||
encoded2 = chars.indexOf(base64[i+1]);
|
||
encoded3 = chars.indexOf(base64[i+2]);
|
||
encoded4 = chars.indexOf(base64[i+3]);
|
||
|
||
bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
|
||
bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
|
||
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
|
||
}
|
||
|
||
return arraybuffer;
|
||
};
|
||
})("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],8:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/blob/index.js", module);
|
||
(function(){
|
||
(function (global){
|
||
/**
|
||
* Create a blob builder even when vendor prefixes exist
|
||
*/
|
||
|
||
var BlobBuilder = global.BlobBuilder
|
||
|| global.WebKitBlobBuilder
|
||
|| global.MSBlobBuilder
|
||
|| global.MozBlobBuilder;
|
||
|
||
/**
|
||
* Check if Blob constructor is supported
|
||
*/
|
||
|
||
var blobSupported = (function() {
|
||
try {
|
||
var a = new Blob(['hi']);
|
||
return a.size === 2;
|
||
} catch(e) {
|
||
return false;
|
||
}
|
||
})();
|
||
|
||
/**
|
||
* Check if Blob constructor supports ArrayBufferViews
|
||
* Fails in Safari 6, so we need to map to ArrayBuffers there.
|
||
*/
|
||
|
||
var blobSupportsArrayBufferView = blobSupported && (function() {
|
||
try {
|
||
var b = new Blob([new Uint8Array([1,2])]);
|
||
return b.size === 2;
|
||
} catch(e) {
|
||
return false;
|
||
}
|
||
})();
|
||
|
||
/**
|
||
* Check if BlobBuilder is supported
|
||
*/
|
||
|
||
var blobBuilderSupported = BlobBuilder
|
||
&& BlobBuilder.prototype.append
|
||
&& BlobBuilder.prototype.getBlob;
|
||
|
||
/**
|
||
* Helper function that maps ArrayBufferViews to ArrayBuffers
|
||
* Used by BlobBuilder constructor and old browsers that didn't
|
||
* support it in the Blob constructor.
|
||
*/
|
||
|
||
function mapArrayBufferViews(ary) {
|
||
for (var i = 0; i < ary.length; i++) {
|
||
var chunk = ary[i];
|
||
if (chunk.buffer instanceof ArrayBuffer) {
|
||
var buf = chunk.buffer;
|
||
|
||
// if this is a subarray, make a copy so we only
|
||
// include the subarray region from the underlying buffer
|
||
if (chunk.byteLength !== buf.byteLength) {
|
||
var copy = new Uint8Array(chunk.byteLength);
|
||
copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength));
|
||
buf = copy.buffer;
|
||
}
|
||
|
||
ary[i] = buf;
|
||
}
|
||
}
|
||
}
|
||
|
||
function BlobBuilderConstructor(ary, options) {
|
||
options = options || {};
|
||
|
||
var bb = new BlobBuilder();
|
||
mapArrayBufferViews(ary);
|
||
|
||
for (var i = 0; i < ary.length; i++) {
|
||
bb.append(ary[i]);
|
||
}
|
||
|
||
return (options.type) ? bb.getBlob(options.type) : bb.getBlob();
|
||
};
|
||
|
||
function BlobConstructor(ary, options) {
|
||
mapArrayBufferViews(ary);
|
||
return new Blob(ary, options || {});
|
||
};
|
||
|
||
module.exports = (function() {
|
||
if (blobSupported) {
|
||
return blobSupportsArrayBufferView ? global.Blob : BlobConstructor;
|
||
} else if (blobBuilderSupported) {
|
||
return BlobBuilderConstructor;
|
||
} else {
|
||
return undefined;
|
||
}
|
||
})();
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],9:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/browser-resolve/empty.js", module);
|
||
(function(){
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],10:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/browserify-hmr/inc/index.js", module);
|
||
(function(){
|
||
(function (global){
|
||
'use strict';
|
||
|
||
var has = require('../lib/has');
|
||
var StrSet = require('../lib/str-set');
|
||
var forEach = require('lodash/collection/forEach');
|
||
var some = require('lodash/collection/some');
|
||
var map = require('lodash/collection/map');
|
||
var filter = require('lodash/collection/filter');
|
||
var zipObject = require('lodash/array/zipObject');
|
||
var forOwn = require('lodash/object/forOwn');
|
||
var mapValues = require('lodash/object/mapValues');
|
||
var assign = require('lodash/object/assign');
|
||
|
||
function emitError(err) {
|
||
setTimeout(function() {
|
||
throw err;
|
||
}, 0);
|
||
}
|
||
|
||
function makeModuleIndexesToNames(moduleMeta) {
|
||
var moduleIndexesToNames = {};
|
||
forOwn(moduleMeta, function(value, name) {
|
||
moduleIndexesToNames[value.index] = name;
|
||
});
|
||
return moduleIndexesToNames;
|
||
}
|
||
|
||
var console = global.console ? global.console : {
|
||
error: function(){}, log: function() {}
|
||
};
|
||
|
||
function main(
|
||
moduleDefs, cachedModules, moduleMeta, updateUrl,
|
||
updateMode, supportModes, ignoreUnaccepted, updateCacheBust, bundleKey,
|
||
socketio,
|
||
bundle__filename, bundle__dirname
|
||
) {
|
||
var moduleIndexesToNames = makeModuleIndexesToNames(moduleMeta);
|
||
|
||
var socket;
|
||
var name, i, len;
|
||
|
||
if (!global._hmr[bundleKey].setStatus) {
|
||
var runtimeModuleInfo = {};
|
||
var createInfoEntry = function(name) {
|
||
runtimeModuleInfo[name] = {
|
||
index: moduleMeta[name].index,
|
||
hash: moduleMeta[name].hash,
|
||
parents: new StrSet(moduleMeta[name].parents),
|
||
module: null,
|
||
disposeData: null,
|
||
accepters: new StrSet(),
|
||
accepting: new StrSet(),
|
||
decliners: new StrSet(),
|
||
declining: new StrSet(),
|
||
selfAcceptCbs: [], // may contain null. nonzero length means module is self-accepting
|
||
disposeHandlers: []
|
||
};
|
||
};
|
||
for (name in moduleMeta) {
|
||
if (has(moduleMeta, name)) {
|
||
createInfoEntry(name);
|
||
}
|
||
}
|
||
|
||
// loaders take a callback(err, data). They may give null for data if they
|
||
// know there hasn't been an update.
|
||
var fileReloaders = {
|
||
fs: function(cb) {
|
||
var fs;
|
||
try {
|
||
fs = require('f'+'s');
|
||
} catch(e) {
|
||
cb(e);
|
||
return;
|
||
}
|
||
fs.readFile(localHmr.updateUrl || bundle__filename, 'utf8', cb);
|
||
},
|
||
ajax: function(cb) {
|
||
var xhr;
|
||
try {
|
||
xhr = new XMLHttpRequest();
|
||
} catch(e) {
|
||
cb(e);
|
||
return;
|
||
}
|
||
xhr.onreadystatechange = function() {
|
||
if (xhr.readyState === 4) {
|
||
if (xhr.status === 200) {
|
||
cb(null, xhr.responseText);
|
||
} else {
|
||
cb(new Error("Request had response "+xhr.status));
|
||
}
|
||
}
|
||
};
|
||
var url = localHmr.updateUrl + (updateCacheBust?'?_v='+(+new Date()):'');
|
||
xhr.open('GET', url, true);
|
||
xhr.send();
|
||
}
|
||
};
|
||
|
||
var lastScriptData = null;
|
||
|
||
// cb(err, expectUpdate)
|
||
var reloadAndRunScript = function(cb) {
|
||
if (!has(fileReloaders, localHmr.updateMode)) {
|
||
cb(new Error("updateMode "+localHmr.updateMode+" not implemented"));
|
||
return;
|
||
}
|
||
var reloader = fileReloaders[localHmr.updateMode];
|
||
reloader(function(err, data) {
|
||
if (err || !data || lastScriptData === data) {
|
||
cb(err, false);
|
||
return;
|
||
}
|
||
lastScriptData = data;
|
||
localHmr.newLoad = null;
|
||
try {
|
||
//jshint evil:true
|
||
if (bundle__filename || bundle__dirname) {
|
||
new Function('require', '__filename', '__dirname', data)(require, bundle__filename, bundle__dirname);
|
||
} else {
|
||
new Function('require', data)(require);
|
||
}
|
||
// running the file sets _hmr.newLoad
|
||
} catch (err2) {
|
||
localHmr.newLoad = null;
|
||
cb(err2);
|
||
return;
|
||
}
|
||
if (!localHmr.newLoad) {
|
||
cb(new Error("Reloaded script did not set hot module reload data"));
|
||
return;
|
||
}
|
||
cb(null, true);
|
||
});
|
||
};
|
||
|
||
var getOutdatedModules = function() {
|
||
var outdated = [];
|
||
var name;
|
||
// add changed and deleted modules
|
||
for (name in runtimeModuleInfo) {
|
||
if (has(runtimeModuleInfo, name)) {
|
||
if (
|
||
!has(localHmr.newLoad.moduleMeta, name) ||
|
||
runtimeModuleInfo[name].hash !== localHmr.newLoad.moduleMeta[name].hash
|
||
) {
|
||
outdated.push(name);
|
||
}
|
||
}
|
||
}
|
||
// add brand new modules
|
||
for (name in localHmr.newLoad.moduleMeta) {
|
||
if (has(localHmr.newLoad.moduleMeta, name)) {
|
||
if (!has(runtimeModuleInfo, name)) {
|
||
outdated.push(name);
|
||
}
|
||
}
|
||
}
|
||
// add modules that are non-accepting/declining parents of outdated modules.
|
||
// important: if outdated has new elements added during the loop,
|
||
// then we iterate over them too.
|
||
for (var i=0; i<outdated.length; i++) {
|
||
name = outdated[i];
|
||
//jshint -W083
|
||
if (has(runtimeModuleInfo, name)) {
|
||
runtimeModuleInfo[name].parents.forEach(function(parentName) {
|
||
if (
|
||
runtimeModuleInfo[name].selfAcceptCbs.length === 0 &&
|
||
!runtimeModuleInfo[name].accepters.has(parentName) &&
|
||
!runtimeModuleInfo[name].decliners.has(parentName) &&
|
||
outdated.indexOf(parentName) === -1
|
||
) {
|
||
outdated.push(parentName);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
return outdated;
|
||
};
|
||
|
||
var moduleHotCheck = function(autoApply, cb) {
|
||
if (typeof autoApply === 'function') {
|
||
cb = autoApply;
|
||
autoApply = false;
|
||
}
|
||
if (!cb) {
|
||
throw new Error("module.hot.check callback parameter required");
|
||
}
|
||
if (localHmr.status !== 'idle') {
|
||
cb(new Error("module.hot.check can only be called while status is idle"));
|
||
return;
|
||
}
|
||
if (updateMode === 'websocket') {
|
||
cb(new Error("module.hot.check can't be used when update mode is websocket"));
|
||
return;
|
||
}
|
||
|
||
localHmr.setStatus('check');
|
||
reloadAndRunScript(function(err, expectUpdate) {
|
||
if (err || !expectUpdate) {
|
||
localHmr.setStatus('idle');
|
||
cb(err, null);
|
||
return;
|
||
}
|
||
var outdatedModules = getOutdatedModules();
|
||
if (outdatedModules.length === 0) {
|
||
localHmr.setStatus('idle');
|
||
cb(null, null);
|
||
} else {
|
||
localHmr.setStatus('ready');
|
||
if (autoApply) {
|
||
moduleHotApply(autoApply, cb);
|
||
} else {
|
||
cb(null, outdatedModules);
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
var moduleHotApply = function(options, cb) {
|
||
if (typeof options === 'function') {
|
||
cb = options;
|
||
options = null;
|
||
}
|
||
if (!cb) {
|
||
throw new Error("module.hot.apply callback parameter required");
|
||
}
|
||
var ignoreUnaccepted = !!(options && options.ignoreUnaccepted);
|
||
if (localHmr.status !== 'ready') {
|
||
cb(new Error("module.hot.apply can only be called while status is ready"));
|
||
return;
|
||
}
|
||
|
||
var outdatedModules = getOutdatedModules();
|
||
var isValueNotInOutdatedModules = function(value) {
|
||
return outdatedModules.indexOf(value) === -1;
|
||
};
|
||
var i, len;
|
||
var acceptedUpdates = filter(outdatedModules, function(name) {
|
||
if (has(runtimeModuleInfo, name)) {
|
||
if (
|
||
runtimeModuleInfo[name].decliners.some(isValueNotInOutdatedModules) ||
|
||
(
|
||
runtimeModuleInfo[name].accepters.size() === 0 &&
|
||
runtimeModuleInfo[name].selfAcceptCbs.length === 0 &&
|
||
runtimeModuleInfo[name].parents.some(isValueNotInOutdatedModules)
|
||
)
|
||
) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
});
|
||
if (!ignoreUnaccepted && outdatedModules.length !== acceptedUpdates.length) {
|
||
localHmr.setStatus('idle');
|
||
cb(new Error("Some updates were declined"));
|
||
return;
|
||
}
|
||
var an;
|
||
for (i=0, len=acceptedUpdates.length; i<len; i++) {
|
||
an = acceptedUpdates[i];
|
||
if (has(runtimeModuleInfo, an)) {
|
||
runtimeModuleInfo[an].disposeData = {};
|
||
for (var j=0; j<runtimeModuleInfo[an].disposeHandlers.length; j++) {
|
||
try {
|
||
runtimeModuleInfo[an].disposeHandlers[j].call(null, runtimeModuleInfo[an].disposeData);
|
||
} catch(e) {
|
||
localHmr.setStatus('idle');
|
||
cb(e || new Error("Unknown dispose callback error"));
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
var selfAccepters = [];
|
||
for (i=0, len=acceptedUpdates.length; i<len; i++) {
|
||
an = acceptedUpdates[i];
|
||
//jshint -W083
|
||
if (!has(runtimeModuleInfo, an)) {
|
||
// new modules
|
||
runtimeModuleInfo[an] = {
|
||
index: an,
|
||
hash: localHmr.newLoad.moduleMeta[an].hash,
|
||
parents: new StrSet(localHmr.newLoad.moduleMeta[an].parents),
|
||
module: null,
|
||
disposeData: null,
|
||
accepters: new StrSet(),
|
||
accepting: new StrSet(),
|
||
decliners: new StrSet(),
|
||
declining: new StrSet(),
|
||
selfAcceptCbs: [],
|
||
disposeHandlers: []
|
||
};
|
||
} else if (!has(localHmr.newLoad.moduleMeta, an)) {
|
||
// removed modules
|
||
delete cachedModules[runtimeModuleInfo[an].index];
|
||
delete runtimeModuleInfo[an];
|
||
continue;
|
||
} else {
|
||
// updated modules
|
||
runtimeModuleInfo[an].hash = localHmr.newLoad.moduleMeta[an].hash;
|
||
runtimeModuleInfo[an].parents = new StrSet(localHmr.newLoad.moduleMeta[an].parents);
|
||
runtimeModuleInfo[an].module = null;
|
||
runtimeModuleInfo[an].accepting.forEach(function(accepted) {
|
||
runtimeModuleInfo[accepted].accepters.del(an);
|
||
});
|
||
runtimeModuleInfo[an].accepting = new StrSet();
|
||
runtimeModuleInfo[an].declining.forEach(function(accepted) {
|
||
runtimeModuleInfo[accepted].decliners.del(an);
|
||
});
|
||
runtimeModuleInfo[an].declining = new StrSet();
|
||
forEach(runtimeModuleInfo[an].selfAcceptCbs, function(cb) {
|
||
selfAccepters.push({name: an, cb: cb});
|
||
});
|
||
runtimeModuleInfo[an].selfAcceptCbs = [];
|
||
runtimeModuleInfo[an].disposeHandlers = [];
|
||
}
|
||
|
||
moduleDefs[runtimeModuleInfo[an].index] = [
|
||
// module function
|
||
localHmr.newLoad.moduleDefs[localHmr.newLoad.moduleMeta[an].index][0],
|
||
// module deps
|
||
mapValues(localHmr.newLoad.moduleDefs[localHmr.newLoad.moduleMeta[an].index][1], function(depIndex, depRef) {
|
||
var depName = localHmr.newLoad.moduleIndexesToNames[depIndex];
|
||
if (has(localHmr.runtimeModuleInfo, depName)) {
|
||
return localHmr.runtimeModuleInfo[depName].index;
|
||
} else {
|
||
return depName;
|
||
}
|
||
})
|
||
];
|
||
cachedModules[runtimeModuleInfo[an].index] = null;
|
||
}
|
||
|
||
// Update the accept handlers list and call the right ones
|
||
var errCanWait = null;
|
||
var updatedNames = new StrSet(acceptedUpdates);
|
||
var oldUpdateHandlers = localHmr.updateHandlers;
|
||
var relevantUpdateHandlers = [];
|
||
var newUpdateHandlers = [];
|
||
for (i=0, len=oldUpdateHandlers.length; i<len; i++) {
|
||
if (!updatedNames.has(oldUpdateHandlers[i].accepter)) {
|
||
newUpdateHandlers.push(oldUpdateHandlers[i]);
|
||
}
|
||
if (updatedNames.hasIntersection(oldUpdateHandlers[i].deps)) {
|
||
relevantUpdateHandlers.push(oldUpdateHandlers[i]);
|
||
}
|
||
}
|
||
localHmr.updateHandlers = newUpdateHandlers;
|
||
for (i=0, len=relevantUpdateHandlers.length; i<len; i++) {
|
||
try {
|
||
relevantUpdateHandlers[i].cb.call(null, acceptedUpdates);
|
||
} catch(e) {
|
||
if (errCanWait) emitError(errCanWait);
|
||
errCanWait = e;
|
||
}
|
||
}
|
||
|
||
// Call the self-accepting modules
|
||
forEach(selfAccepters, function(obj) {
|
||
try {
|
||
require(runtimeModuleInfo[obj.name].index);
|
||
} catch(e) {
|
||
if (obj.cb) {
|
||
obj.cb.call(null, e);
|
||
} else {
|
||
if (errCanWait) emitError(errCanWait);
|
||
errCanWait = e;
|
||
}
|
||
}
|
||
});
|
||
|
||
localHmr.setStatus('idle');
|
||
cb(errCanWait, acceptedUpdates);
|
||
};
|
||
|
||
var moduleHotSetUpdateMode = function(mode, options) {
|
||
options = options || {};
|
||
|
||
if (supportModes.indexOf(mode) === -1) {
|
||
throw new Error("Mode "+mode+" not in supportModes. Please check the Browserify-HMR plugin options.");
|
||
}
|
||
if (mode === 'ajax' && !options.url) {
|
||
throw new Error("url required for ajax update mode");
|
||
}
|
||
if (localHmr.status !== 'idle') {
|
||
throw new Error("module.hot.setUpdateMode can only be called while status is idle");
|
||
}
|
||
|
||
localHmr.newLoad = null;
|
||
localHmr.updateMode = updateMode = mode;
|
||
localHmr.updateUrl = updateUrl = options.url;
|
||
updateCacheBust = options.cacheBust;
|
||
ignoreUnaccepted = has(options, 'ignoreUnaccepted') ? options.ignoreUnaccepted : true;
|
||
|
||
if (socket) {
|
||
socket.disconnect();
|
||
socket = null;
|
||
}
|
||
if (mode === 'websocket') {
|
||
socket = setupSocket();
|
||
}
|
||
};
|
||
|
||
var setupSocket = function() {
|
||
var url = updateUrl || 'http://localhost:3123';
|
||
var socket = socketio(url, {'force new connection': true});
|
||
console.log('[HMR] Attempting websocket connection to', url);
|
||
|
||
var isAcceptingMessages = false;
|
||
socket.on('connect', function() {
|
||
isAcceptingMessages = false;
|
||
var syncMsg = mapValues(runtimeModuleInfo, function(value, name) {
|
||
return {
|
||
hash: value.hash
|
||
};
|
||
});
|
||
socket.emit('sync', syncMsg);
|
||
});
|
||
var isUpdating = false;
|
||
var queuedUpdateMessages = [];
|
||
socket.on('sync confirm', function() {
|
||
console.log('[HMR] Websocket connection successful.');
|
||
isAcceptingMessages = true;
|
||
queuedUpdateMessages = [];
|
||
});
|
||
socket.on('disconnect', function() {
|
||
console.log('[HMR] Websocket connection lost.');
|
||
});
|
||
var acceptNewModules = function(msg) {
|
||
// Make sure we don't accept new modules before we've synced ourselves.
|
||
if (!isAcceptingMessages) return;
|
||
if (isUpdating) {
|
||
queuedUpdateMessages.push(msg);
|
||
return;
|
||
}
|
||
// Take the message and create a localHmr.newLoad value as if the
|
||
// bundle had been re-executed, then call moduleHotApply.
|
||
isUpdating = true;
|
||
|
||
// random id so we can make the normally unnamed args have random names
|
||
var rid = String(Math.random()).replace(/[^0-9]/g, '');
|
||
|
||
var newModuleDefs = localHmr.newLoad ? localHmr.newLoad.moduleDefs : assign({}, moduleDefs);
|
||
var newModuleMeta = localHmr.newLoad ?
|
||
localHmr.newLoad.moduleMeta : mapValues(runtimeModuleInfo, function(value, key) {
|
||
return {
|
||
index: value.index,
|
||
hash: value.hash,
|
||
parents: value.parents.toArray()
|
||
};
|
||
});
|
||
forOwn(msg.newModuleData, function(value, key) {
|
||
newModuleMeta[key] = {
|
||
index: value.index,
|
||
hash: value.hash,
|
||
parents: value.parents
|
||
};
|
||
});
|
||
forEach(msg.removedModules, function(removedName) {
|
||
delete newModuleDefs[runtimeModuleInfo[removedName].index];
|
||
delete newModuleMeta[removedName];
|
||
});
|
||
var newModuleIndexesToNames = makeModuleIndexesToNames(newModuleMeta);
|
||
forOwn(msg.newModuleData, function(value, key) {
|
||
// this part needs to run after newModuleMeta and
|
||
// newModuleIndexesToNames are populated.
|
||
var newModuleFunction = (function() {
|
||
var fn;
|
||
//jshint evil:true
|
||
if (bundle__filename || bundle__dirname) {
|
||
fn = new Function('require', 'module', 'exports', '_u1'+rid, '_u2'+rid, '__u3'+rid, '__u4'+rid, '__filename', '__dirname', value.source);
|
||
return function(require, module, exports, _u1, _u2, _u3, _u4) {
|
||
global._hmr[bundleKey].initModule(key, module);
|
||
fn.call(this, require, module, exports, _u1, _u2, _u3, _u4, bundle__filename, bundle__dirname);
|
||
};
|
||
} else {
|
||
fn = new Function('require', 'module', 'exports', '_u1'+rid, '_u2'+rid, '__u3'+rid, '__u4'+rid, value.source);
|
||
return function(require, module, exports, _u1, _u2, _u3, _u4) {
|
||
global._hmr[bundleKey].initModule(key, module);
|
||
fn.call(this, require, module, exports, _u1, _u2, _u3, _u4);
|
||
};
|
||
}
|
||
})();
|
||
|
||
newModuleDefs[newModuleMeta[key].index] = [
|
||
// module function
|
||
newModuleFunction,
|
||
// module deps
|
||
mapValues(value.deps, function(depIndex, depRef) {
|
||
var depName = newModuleIndexesToNames[depIndex];
|
||
if (has(newModuleMeta, depName)) {
|
||
return newModuleMeta[depName].index;
|
||
} else {
|
||
return depName;
|
||
}
|
||
})
|
||
];
|
||
});
|
||
localHmr.newLoad = {
|
||
moduleDefs: newModuleDefs,
|
||
moduleMeta: newModuleMeta,
|
||
moduleIndexesToNames: newModuleIndexesToNames
|
||
};
|
||
localHmr.setStatus('ready');
|
||
var outdatedModules = getOutdatedModules();
|
||
moduleHotApply({ignoreUnaccepted: ignoreUnaccepted}, function(err, updatedNames) {
|
||
if (err) {
|
||
console.error('[HMR] Error applying update', err);
|
||
}
|
||
if (updatedNames) {
|
||
console.log('[HMR] Updated modules', updatedNames);
|
||
if (outdatedModules.length !== updatedNames.length) {
|
||
var notUpdatedNames = filter(outdatedModules, function(name) {
|
||
return updatedNames.indexOf(name) === -1;
|
||
});
|
||
console.log('[HMR] Some modules were not updated', notUpdatedNames);
|
||
}
|
||
}
|
||
isUpdating = false;
|
||
var queuedMsg;
|
||
while ((queuedMsg = queuedUpdateMessages.shift())) {
|
||
acceptNewModules(queuedMsg);
|
||
}
|
||
});
|
||
};
|
||
socket.on('new modules', acceptNewModules);
|
||
return socket;
|
||
};
|
||
|
||
var localHmr = {
|
||
updateUrl: updateUrl,
|
||
updateMode: updateMode,
|
||
runtimeModuleInfo: runtimeModuleInfo,
|
||
|
||
status: "idle",
|
||
setStatus: function(status) {
|
||
this.status = status;
|
||
var statusHandlers = this.statusHandlers.slice();
|
||
for (var i=0, len=statusHandlers.length; i<len; i++) {
|
||
statusHandlers[i].call(null, status);
|
||
}
|
||
},
|
||
statusHandlers: [],
|
||
updateHandlers: [],
|
||
|
||
// during a reload this is set to an object with moduleDefs,
|
||
// moduleMeta, and moduleIndexesToNames properties
|
||
newLoad: null,
|
||
|
||
initModule: function(name, module) {
|
||
runtimeModuleInfo[name].module = module;
|
||
module.hot = {
|
||
accept: function(deps, cb) {
|
||
if (!cb && (!deps || typeof deps === 'function')) { // self
|
||
cb = deps;
|
||
deps = null;
|
||
runtimeModuleInfo[name].selfAcceptCbs.push(cb);
|
||
} else {
|
||
if (typeof deps === 'string') {
|
||
deps = [deps];
|
||
}
|
||
var depNames = new StrSet();
|
||
for (var i=0, depsLen=deps.length; i<depsLen; i++) {
|
||
var depIndex = moduleDefs[runtimeModuleInfo[name].index][1][deps[i]];
|
||
if (depIndex === undefined || !has(moduleIndexesToNames, depIndex)) {
|
||
throw new Error("File does not use dependency: "+deps[i]);
|
||
}
|
||
depNames.add(moduleIndexesToNames[depIndex]);
|
||
}
|
||
deps = null;
|
||
depNames.forEach(function(depName) {
|
||
runtimeModuleInfo[depName].accepters.add(name);
|
||
runtimeModuleInfo[name].accepting.add(depName);
|
||
});
|
||
if (cb) {
|
||
localHmr.updateHandlers.push({
|
||
accepter: name,
|
||
deps: depNames,
|
||
cb: cb
|
||
});
|
||
}
|
||
}
|
||
},
|
||
decline: function(deps) {
|
||
if (!deps) { // self
|
||
runtimeModuleInfo[name].decliners.add(name);
|
||
runtimeModuleInfo[name].declining.add(name);
|
||
} else {
|
||
if (typeof deps === 'string') {
|
||
deps = [deps];
|
||
}
|
||
for (var i=0, depsLen=deps.length; i<depsLen; i++) {
|
||
var depIndex = moduleDefs[runtimeModuleInfo[name].index][1][deps[i]];
|
||
if (depIndex === undefined || !has(moduleIndexesToNames, depIndex)) {
|
||
throw new Error("File does not use dependency: "+deps[i]);
|
||
}
|
||
var depName = moduleIndexesToNames[depIndex];
|
||
runtimeModuleInfo[depName].decliners.add(name);
|
||
runtimeModuleInfo[name].declining.add(depName);
|
||
}
|
||
}
|
||
},
|
||
data: runtimeModuleInfo[name].disposeData,
|
||
dispose: function(cb) {
|
||
return this.addDisposeHandler(cb);
|
||
},
|
||
addDisposeHandler: function(cb) {
|
||
runtimeModuleInfo[name].disposeHandlers.push(cb);
|
||
},
|
||
removeDisposeHandler: function(cb) {
|
||
var ix = runtimeModuleInfo[name].disposeHandlers.indexOf(cb);
|
||
if (ix !== -1) {
|
||
runtimeModuleInfo[name].disposeHandlers.splice(ix, 1);
|
||
}
|
||
},
|
||
|
||
// Management
|
||
check: moduleHotCheck,
|
||
apply: moduleHotApply,
|
||
status: function(cb) {
|
||
if (cb) {
|
||
return this.addStatusHandler(cb);
|
||
}
|
||
return localHmr.status;
|
||
},
|
||
addStatusHandler: function(cb) {
|
||
localHmr.statusHandlers.push(cb);
|
||
},
|
||
removeStatusHandler: function(cb) {
|
||
var ix = localHmr.statusHandlers.indexOf(cb);
|
||
if (ix !== -1) {
|
||
localHmr.statusHandlers.splice(ix, 1);
|
||
}
|
||
},
|
||
setUpdateMode: moduleHotSetUpdateMode
|
||
};
|
||
}
|
||
};
|
||
global._hmr[bundleKey] = localHmr;
|
||
|
||
if (updateMode === 'websocket') {
|
||
socket = setupSocket();
|
||
}
|
||
return true;
|
||
} else { // We're in a reload!
|
||
global._hmr[bundleKey].newLoad = {
|
||
moduleDefs: moduleDefs,
|
||
moduleMeta: moduleMeta,
|
||
moduleIndexesToNames: moduleIndexesToNames
|
||
};
|
||
return false;
|
||
}
|
||
}
|
||
|
||
module.exports = main;
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../lib/has":11,"../lib/str-set":12,"lodash/array/zipObject":66,"lodash/collection/filter":67,"lodash/collection/forEach":68,"lodash/collection/map":69,"lodash/collection/some":70,"lodash/object/assign":125,"lodash/object/forOwn":126,"lodash/object/mapValues":129}],11:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/browserify-hmr/lib/has.js", module);
|
||
(function(){
|
||
'use strict';
|
||
|
||
function has(object, propName) {
|
||
return Object.prototype.hasOwnProperty.call(object, propName);
|
||
}
|
||
module.exports = has;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],12:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/browserify-hmr/lib/str-set.js", module);
|
||
(function(){
|
||
'use strict';
|
||
|
||
var has = require('./has');
|
||
|
||
function StrSet(other) {
|
||
this._map = {};
|
||
this._size = 0;
|
||
if (other) {
|
||
for (var i=0,len=other.length; i<len; i++) {
|
||
this.add(other[i]);
|
||
}
|
||
}
|
||
}
|
||
StrSet.prototype.add = function(value) {
|
||
if (!this.has(value)) {
|
||
this._map[value] = true;
|
||
this._size++;
|
||
}
|
||
};
|
||
StrSet.prototype.has = function(value) {
|
||
return has(this._map, value);
|
||
};
|
||
StrSet.prototype.del = function(value) {
|
||
if (this.has(value)) {
|
||
delete this._map[value];
|
||
this._size--;
|
||
}
|
||
};
|
||
StrSet.prototype.size = function() {
|
||
return this._size;
|
||
};
|
||
StrSet.prototype.forEach = function(cb) {
|
||
for (var value in this._map) {
|
||
if (has(this._map, value)) {
|
||
cb(value);
|
||
}
|
||
}
|
||
};
|
||
StrSet.prototype.some = function(cb) {
|
||
for (var value in this._map) {
|
||
if (has(this._map, value)) {
|
||
if (cb(value)) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
StrSet.prototype.every = function(cb) {
|
||
return !this.some(function(x) {
|
||
return !cb(x);
|
||
});
|
||
};
|
||
StrSet.prototype.hasIntersection = function(otherStrSet) {
|
||
var value;
|
||
if (this._size < otherStrSet._size) {
|
||
return this.some(function(value) {
|
||
return otherStrSet.has(value);
|
||
});
|
||
} else {
|
||
var self = this;
|
||
return otherStrSet.some(function(value) {
|
||
return self.has(value);
|
||
});
|
||
}
|
||
};
|
||
StrSet.prototype.toArray = function() {
|
||
var arr = [];
|
||
this.forEach(function(value) {
|
||
arr.push(value);
|
||
});
|
||
return arr;
|
||
};
|
||
|
||
module.exports = StrSet;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./has":11}],13:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/component-bind/index.js", module);
|
||
(function(){
|
||
/**
|
||
* Slice reference.
|
||
*/
|
||
|
||
var slice = [].slice;
|
||
|
||
/**
|
||
* Bind `obj` to `fn`.
|
||
*
|
||
* @param {Object} obj
|
||
* @param {Function|String} fn or string
|
||
* @return {Function}
|
||
* @api public
|
||
*/
|
||
|
||
module.exports = function(obj, fn){
|
||
if ('string' == typeof fn) fn = obj[fn];
|
||
if ('function' != typeof fn) throw new Error('bind() requires a function');
|
||
var args = slice.call(arguments, 2);
|
||
return function(){
|
||
return fn.apply(obj, args.concat(slice.call(arguments)));
|
||
}
|
||
};
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],14:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/component-emitter/index.js", module);
|
||
(function(){
|
||
|
||
/**
|
||
* Expose `Emitter`.
|
||
*/
|
||
|
||
module.exports = Emitter;
|
||
|
||
/**
|
||
* Initialize a new `Emitter`.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
function Emitter(obj) {
|
||
if (obj) return mixin(obj);
|
||
};
|
||
|
||
/**
|
||
* Mixin the emitter properties.
|
||
*
|
||
* @param {Object} obj
|
||
* @return {Object}
|
||
* @api private
|
||
*/
|
||
|
||
function mixin(obj) {
|
||
for (var key in Emitter.prototype) {
|
||
obj[key] = Emitter.prototype[key];
|
||
}
|
||
return obj;
|
||
}
|
||
|
||
/**
|
||
* Listen on the given `event` with `fn`.
|
||
*
|
||
* @param {String} event
|
||
* @param {Function} fn
|
||
* @return {Emitter}
|
||
* @api public
|
||
*/
|
||
|
||
Emitter.prototype.on =
|
||
Emitter.prototype.addEventListener = function(event, fn){
|
||
this._callbacks = this._callbacks || {};
|
||
(this._callbacks[event] = this._callbacks[event] || [])
|
||
.push(fn);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Adds an `event` listener that will be invoked a single
|
||
* time then automatically removed.
|
||
*
|
||
* @param {String} event
|
||
* @param {Function} fn
|
||
* @return {Emitter}
|
||
* @api public
|
||
*/
|
||
|
||
Emitter.prototype.once = function(event, fn){
|
||
var self = this;
|
||
this._callbacks = this._callbacks || {};
|
||
|
||
function on() {
|
||
self.off(event, on);
|
||
fn.apply(this, arguments);
|
||
}
|
||
|
||
on.fn = fn;
|
||
this.on(event, on);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Remove the given callback for `event` or all
|
||
* registered callbacks.
|
||
*
|
||
* @param {String} event
|
||
* @param {Function} fn
|
||
* @return {Emitter}
|
||
* @api public
|
||
*/
|
||
|
||
Emitter.prototype.off =
|
||
Emitter.prototype.removeListener =
|
||
Emitter.prototype.removeAllListeners =
|
||
Emitter.prototype.removeEventListener = function(event, fn){
|
||
this._callbacks = this._callbacks || {};
|
||
|
||
// all
|
||
if (0 == arguments.length) {
|
||
this._callbacks = {};
|
||
return this;
|
||
}
|
||
|
||
// specific event
|
||
var callbacks = this._callbacks[event];
|
||
if (!callbacks) return this;
|
||
|
||
// remove all handlers
|
||
if (1 == arguments.length) {
|
||
delete this._callbacks[event];
|
||
return this;
|
||
}
|
||
|
||
// remove specific handler
|
||
var cb;
|
||
for (var i = 0; i < callbacks.length; i++) {
|
||
cb = callbacks[i];
|
||
if (cb === fn || cb.fn === fn) {
|
||
callbacks.splice(i, 1);
|
||
break;
|
||
}
|
||
}
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Emit `event` with the given args.
|
||
*
|
||
* @param {String} event
|
||
* @param {Mixed} ...
|
||
* @return {Emitter}
|
||
*/
|
||
|
||
Emitter.prototype.emit = function(event){
|
||
this._callbacks = this._callbacks || {};
|
||
var args = [].slice.call(arguments, 1)
|
||
, callbacks = this._callbacks[event];
|
||
|
||
if (callbacks) {
|
||
callbacks = callbacks.slice(0);
|
||
for (var i = 0, len = callbacks.length; i < len; ++i) {
|
||
callbacks[i].apply(this, args);
|
||
}
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Return array of callbacks for `event`.
|
||
*
|
||
* @param {String} event
|
||
* @return {Array}
|
||
* @api public
|
||
*/
|
||
|
||
Emitter.prototype.listeners = function(event){
|
||
this._callbacks = this._callbacks || {};
|
||
return this._callbacks[event] || [];
|
||
};
|
||
|
||
/**
|
||
* Check if this emitter has `event` handlers.
|
||
*
|
||
* @param {String} event
|
||
* @return {Boolean}
|
||
* @api public
|
||
*/
|
||
|
||
Emitter.prototype.hasListeners = function(event){
|
||
return !! this.listeners(event).length;
|
||
};
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],15:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/component-inherit/index.js", module);
|
||
(function(){
|
||
|
||
module.exports = function(a, b){
|
||
var fn = function(){};
|
||
fn.prototype = b.prototype;
|
||
a.prototype = new fn;
|
||
a.prototype.constructor = a;
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{}],16:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/fn/symbol/index.js", module);
|
||
(function(){
|
||
require('../../modules/es6.symbol');
|
||
require('../../modules/es6.object.to-string');
|
||
module.exports = require('../../modules/$.core').Symbol;
|
||
}).apply(this, arguments);
|
||
|
||
},{"../../modules/$.core":20,"../../modules/es6.object.to-string":44,"../../modules/es6.symbol":45}],17:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.a-function.js", module);
|
||
(function(){
|
||
module.exports = function(it){
|
||
if(typeof it != 'function')throw TypeError(it + ' is not a function!');
|
||
return it;
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{}],18:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.an-object.js", module);
|
||
(function(){
|
||
var isObject = require('./$.is-object');
|
||
module.exports = function(it){
|
||
if(!isObject(it))throw TypeError(it + ' is not an object!');
|
||
return it;
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$.is-object":33}],19:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.cof.js", module);
|
||
(function(){
|
||
var toString = {}.toString;
|
||
|
||
module.exports = function(it){
|
||
return toString.call(it).slice(8, -1);
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{}],20:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.core.js", module);
|
||
(function(){
|
||
var core = module.exports = {version: '1.2.6'};
|
||
if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef
|
||
}).apply(this, arguments);
|
||
|
||
},{}],21:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.ctx.js", module);
|
||
(function(){
|
||
// 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);
|
||
};
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$.a-function":17}],22:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.defined.js", module);
|
||
(function(){
|
||
// 7.2.1 RequireObjectCoercible(argument)
|
||
module.exports = function(it){
|
||
if(it == undefined)throw TypeError("Can't call method on " + it);
|
||
return it;
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{}],23:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.descriptors.js", module);
|
||
(function(){
|
||
// Thank's IE8 for his funny defineProperty
|
||
module.exports = !require('./$.fails')(function(){
|
||
return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;
|
||
});
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$.fails":26}],24:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.enum-keys.js", module);
|
||
(function(){
|
||
// all enumerable object keys, includes symbols
|
||
var $ = require('./$');
|
||
module.exports = function(it){
|
||
var keys = $.getKeys(it)
|
||
, getSymbols = $.getSymbols;
|
||
if(getSymbols){
|
||
var symbols = getSymbols(it)
|
||
, isEnum = $.isEnum
|
||
, i = 0
|
||
, key;
|
||
while(symbols.length > i)if(isEnum.call(it, key = symbols[i++]))keys.push(key);
|
||
}
|
||
return keys;
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$":34}],25:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.export.js", module);
|
||
(function(){
|
||
var global = require('./$.global')
|
||
, core = require('./$.core')
|
||
, ctx = require('./$.ctx')
|
||
, PROTOTYPE = 'prototype';
|
||
|
||
var $export = function(type, name, source){
|
||
var IS_FORCED = type & $export.F
|
||
, IS_GLOBAL = type & $export.G
|
||
, IS_STATIC = type & $export.S
|
||
, IS_PROTO = type & $export.P
|
||
, IS_BIND = type & $export.B
|
||
, IS_WRAP = type & $export.W
|
||
, exports = IS_GLOBAL ? core : core[name] || (core[name] = {})
|
||
, target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE]
|
||
, key, own, out;
|
||
if(IS_GLOBAL)source = name;
|
||
for(key in source){
|
||
// contains in native
|
||
own = !IS_FORCED && target && key in target;
|
||
if(own && key in exports)continue;
|
||
// export native or passed
|
||
out = own ? target[key] : source[key];
|
||
// prevent global pollution for namespaces
|
||
exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]
|
||
// bind timers to global for call from export context
|
||
: IS_BIND && own ? ctx(out, global)
|
||
// wrap global constructors for prevent change them in library
|
||
: IS_WRAP && target[key] == out ? (function(C){
|
||
var F = function(param){
|
||
return this instanceof C ? new C(param) : C(param);
|
||
};
|
||
F[PROTOTYPE] = C[PROTOTYPE];
|
||
return F;
|
||
// make static versions for prototype methods
|
||
})(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
|
||
if(IS_PROTO)(exports[PROTOTYPE] || (exports[PROTOTYPE] = {}))[key] = out;
|
||
}
|
||
};
|
||
// 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
|
||
module.exports = $export;
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$.core":20,"./$.ctx":21,"./$.global":28}],26:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.fails.js", module);
|
||
(function(){
|
||
module.exports = function(exec){
|
||
try {
|
||
return !!exec();
|
||
} catch(e){
|
||
return true;
|
||
}
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{}],27:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.get-names.js", module);
|
||
(function(){
|
||
// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
|
||
var toIObject = require('./$.to-iobject')
|
||
, getNames = require('./$').getNames
|
||
, toString = {}.toString;
|
||
|
||
var windowNames = typeof window == 'object' && Object.getOwnPropertyNames
|
||
? Object.getOwnPropertyNames(window) : [];
|
||
|
||
var getWindowNames = function(it){
|
||
try {
|
||
return getNames(it);
|
||
} catch(e){
|
||
return windowNames.slice();
|
||
}
|
||
};
|
||
|
||
module.exports.get = function getOwnPropertyNames(it){
|
||
if(windowNames && toString.call(it) == '[object Window]')return getWindowNames(it);
|
||
return getNames(toIObject(it));
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$":34,"./$.to-iobject":41}],28:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.global.js", module);
|
||
(function(){
|
||
// 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 : Function('return this')();
|
||
if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef
|
||
}).apply(this, arguments);
|
||
|
||
},{}],29:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.has.js", module);
|
||
(function(){
|
||
var hasOwnProperty = {}.hasOwnProperty;
|
||
module.exports = function(it, key){
|
||
return hasOwnProperty.call(it, key);
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{}],30:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.hide.js", module);
|
||
(function(){
|
||
var $ = require('./$')
|
||
, createDesc = require('./$.property-desc');
|
||
module.exports = require('./$.descriptors') ? function(object, key, value){
|
||
return $.setDesc(object, key, createDesc(1, value));
|
||
} : function(object, key, value){
|
||
object[key] = value;
|
||
return object;
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$":34,"./$.descriptors":23,"./$.property-desc":37}],31:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.iobject.js", module);
|
||
(function(){
|
||
// fallback for non-array-like ES3 and non-enumerable old V8 strings
|
||
var cof = require('./$.cof');
|
||
module.exports = Object('z').propertyIsEnumerable(0) ? Object : function(it){
|
||
return cof(it) == 'String' ? it.split('') : Object(it);
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$.cof":19}],32:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.is-array.js", module);
|
||
(function(){
|
||
// 7.2.2 IsArray(argument)
|
||
var cof = require('./$.cof');
|
||
module.exports = Array.isArray || function(arg){
|
||
return cof(arg) == 'Array';
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$.cof":19}],33:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.is-object.js", module);
|
||
(function(){
|
||
module.exports = function(it){
|
||
return typeof it === 'object' ? it !== null : typeof it === 'function';
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{}],34:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.js", module);
|
||
(function(){
|
||
var $Object = Object;
|
||
module.exports = {
|
||
create: $Object.create,
|
||
getProto: $Object.getPrototypeOf,
|
||
isEnum: {}.propertyIsEnumerable,
|
||
getDesc: $Object.getOwnPropertyDescriptor,
|
||
setDesc: $Object.defineProperty,
|
||
setDescs: $Object.defineProperties,
|
||
getKeys: $Object.keys,
|
||
getNames: $Object.getOwnPropertyNames,
|
||
getSymbols: $Object.getOwnPropertySymbols,
|
||
each: [].forEach
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{}],35:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.keyof.js", module);
|
||
(function(){
|
||
var $ = require('./$')
|
||
, toIObject = require('./$.to-iobject');
|
||
module.exports = function(object, el){
|
||
var O = toIObject(object)
|
||
, keys = $.getKeys(O)
|
||
, length = keys.length
|
||
, index = 0
|
||
, key;
|
||
while(length > index)if(O[key = keys[index++]] === el)return key;
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$":34,"./$.to-iobject":41}],36:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.library.js", module);
|
||
(function(){
|
||
module.exports = true;
|
||
}).apply(this, arguments);
|
||
|
||
},{}],37:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.property-desc.js", module);
|
||
(function(){
|
||
module.exports = function(bitmap, value){
|
||
return {
|
||
enumerable : !(bitmap & 1),
|
||
configurable: !(bitmap & 2),
|
||
writable : !(bitmap & 4),
|
||
value : value
|
||
};
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{}],38:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.redefine.js", module);
|
||
(function(){
|
||
module.exports = require('./$.hide');
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$.hide":30}],39:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.set-to-string-tag.js", module);
|
||
(function(){
|
||
var def = require('./$').setDesc
|
||
, has = require('./$.has')
|
||
, 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});
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$":34,"./$.has":29,"./$.wks":43}],40:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.shared.js", module);
|
||
(function(){
|
||
var global = require('./$.global')
|
||
, SHARED = '__core-js_shared__'
|
||
, store = global[SHARED] || (global[SHARED] = {});
|
||
module.exports = function(key){
|
||
return store[key] || (store[key] = {});
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$.global":28}],41:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.to-iobject.js", module);
|
||
(function(){
|
||
// to indexed object, toObject with fallback for non-array-like ES3 strings
|
||
var IObject = require('./$.iobject')
|
||
, defined = require('./$.defined');
|
||
module.exports = function(it){
|
||
return IObject(defined(it));
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$.defined":22,"./$.iobject":31}],42:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.uid.js", module);
|
||
(function(){
|
||
var id = 0
|
||
, px = Math.random();
|
||
module.exports = function(key){
|
||
return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{}],43:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/$.wks.js", module);
|
||
(function(){
|
||
var store = require('./$.shared')('wks')
|
||
, uid = require('./$.uid')
|
||
, Symbol = require('./$.global').Symbol;
|
||
module.exports = function(name){
|
||
return store[name] || (store[name] =
|
||
Symbol && Symbol[name] || (Symbol || uid)('Symbol.' + name));
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$.global":28,"./$.shared":40,"./$.uid":42}],44:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/es6.object.to-string.js", module);
|
||
(function(){
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],45:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/core-js/library/modules/es6.symbol.js", module);
|
||
(function(){
|
||
'use strict';
|
||
// ECMAScript 6 symbols shim
|
||
var $ = require('./$')
|
||
, global = require('./$.global')
|
||
, has = require('./$.has')
|
||
, DESCRIPTORS = require('./$.descriptors')
|
||
, $export = require('./$.export')
|
||
, redefine = require('./$.redefine')
|
||
, $fails = require('./$.fails')
|
||
, shared = require('./$.shared')
|
||
, setToStringTag = require('./$.set-to-string-tag')
|
||
, uid = require('./$.uid')
|
||
, wks = require('./$.wks')
|
||
, keyOf = require('./$.keyof')
|
||
, $names = require('./$.get-names')
|
||
, enumKeys = require('./$.enum-keys')
|
||
, isArray = require('./$.is-array')
|
||
, anObject = require('./$.an-object')
|
||
, toIObject = require('./$.to-iobject')
|
||
, createDesc = require('./$.property-desc')
|
||
, getDesc = $.getDesc
|
||
, setDesc = $.setDesc
|
||
, _create = $.create
|
||
, getNames = $names.get
|
||
, $Symbol = global.Symbol
|
||
, $JSON = global.JSON
|
||
, _stringify = $JSON && $JSON.stringify
|
||
, setter = false
|
||
, HIDDEN = wks('_hidden')
|
||
, isEnum = $.isEnum
|
||
, SymbolRegistry = shared('symbol-registry')
|
||
, AllSymbols = shared('symbols')
|
||
, useNative = typeof $Symbol == 'function'
|
||
, ObjectProto = Object.prototype;
|
||
|
||
// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
|
||
var setSymbolDesc = DESCRIPTORS && $fails(function(){
|
||
return _create(setDesc({}, 'a', {
|
||
get: function(){ return setDesc(this, 'a', {value: 7}).a; }
|
||
})).a != 7;
|
||
}) ? function(it, key, D){
|
||
var protoDesc = getDesc(ObjectProto, key);
|
||
if(protoDesc)delete ObjectProto[key];
|
||
setDesc(it, key, D);
|
||
if(protoDesc && it !== ObjectProto)setDesc(ObjectProto, key, protoDesc);
|
||
} : setDesc;
|
||
|
||
var wrap = function(tag){
|
||
var sym = AllSymbols[tag] = _create($Symbol.prototype);
|
||
sym._k = tag;
|
||
DESCRIPTORS && setter && setSymbolDesc(ObjectProto, tag, {
|
||
configurable: true,
|
||
set: function(value){
|
||
if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false;
|
||
setSymbolDesc(this, tag, createDesc(1, value));
|
||
}
|
||
});
|
||
return sym;
|
||
};
|
||
|
||
var isSymbol = function(it){
|
||
return typeof it == 'symbol';
|
||
};
|
||
|
||
var $defineProperty = function defineProperty(it, key, D){
|
||
if(D && has(AllSymbols, key)){
|
||
if(!D.enumerable){
|
||
if(!has(it, HIDDEN))setDesc(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 setDesc(it, key, D);
|
||
};
|
||
var $defineProperties = function defineProperties(it, P){
|
||
anObject(it);
|
||
var keys = enumKeys(P = toIObject(P))
|
||
, i = 0
|
||
, l = keys.length
|
||
, 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);
|
||
return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key]
|
||
? E : true;
|
||
};
|
||
var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){
|
||
var D = getDesc(it = toIObject(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 = getNames(toIObject(it))
|
||
, result = []
|
||
, i = 0
|
||
, key;
|
||
while(names.length > i)if(!has(AllSymbols, key = names[i++]) && key != HIDDEN)result.push(key);
|
||
return result;
|
||
};
|
||
var $getOwnPropertySymbols = function getOwnPropertySymbols(it){
|
||
var names = getNames(toIObject(it))
|
||
, result = []
|
||
, i = 0
|
||
, key;
|
||
while(names.length > i)if(has(AllSymbols, key = names[i++]))result.push(AllSymbols[key]);
|
||
return result;
|
||
};
|
||
var $stringify = function stringify(it){
|
||
if(it === undefined || isSymbol(it))return; // IE8 returns string on undefined
|
||
var args = [it]
|
||
, i = 1
|
||
, $$ = arguments
|
||
, replacer, $replacer;
|
||
while($$.length > i)args.push($$[i++]);
|
||
replacer = args[1];
|
||
if(typeof replacer == 'function')$replacer = replacer;
|
||
if($replacer || !isArray(replacer))replacer = function(key, value){
|
||
if($replacer)value = $replacer.call(this, key, value);
|
||
if(!isSymbol(value))return value;
|
||
};
|
||
args[1] = replacer;
|
||
return _stringify.apply($JSON, args);
|
||
};
|
||
var buggyJSON = $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)) != '{}';
|
||
});
|
||
|
||
// 19.4.1.1 Symbol([description])
|
||
if(!useNative){
|
||
$Symbol = function Symbol(){
|
||
if(isSymbol(this))throw TypeError('Symbol is not a constructor');
|
||
return wrap(uid(arguments.length > 0 ? arguments[0] : undefined));
|
||
};
|
||
redefine($Symbol.prototype, 'toString', function toString(){
|
||
return this._k;
|
||
});
|
||
|
||
isSymbol = function(it){
|
||
return it instanceof $Symbol;
|
||
};
|
||
|
||
$.create = $create;
|
||
$.isEnum = $propertyIsEnumerable;
|
||
$.getDesc = $getOwnPropertyDescriptor;
|
||
$.setDesc = $defineProperty;
|
||
$.setDescs = $defineProperties;
|
||
$.getNames = $names.get = $getOwnPropertyNames;
|
||
$.getSymbols = $getOwnPropertySymbols;
|
||
|
||
if(DESCRIPTORS && !require('./$.library')){
|
||
redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
|
||
}
|
||
}
|
||
|
||
var symbolStatics = {
|
||
// 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(key){
|
||
return keyOf(SymbolRegistry, key);
|
||
},
|
||
useSetter: function(){ setter = true; },
|
||
useSimple: function(){ setter = false; }
|
||
};
|
||
// 19.4.2.2 Symbol.hasInstance
|
||
// 19.4.2.3 Symbol.isConcatSpreadable
|
||
// 19.4.2.4 Symbol.iterator
|
||
// 19.4.2.6 Symbol.match
|
||
// 19.4.2.8 Symbol.replace
|
||
// 19.4.2.9 Symbol.search
|
||
// 19.4.2.10 Symbol.species
|
||
// 19.4.2.11 Symbol.split
|
||
// 19.4.2.12 Symbol.toPrimitive
|
||
// 19.4.2.13 Symbol.toStringTag
|
||
// 19.4.2.14 Symbol.unscopables
|
||
$.each.call((
|
||
'hasInstance,isConcatSpreadable,iterator,match,replace,search,' +
|
||
'species,split,toPrimitive,toStringTag,unscopables'
|
||
).split(','), function(it){
|
||
var sym = wks(it);
|
||
symbolStatics[it] = useNative ? sym : wrap(sym);
|
||
});
|
||
|
||
setter = true;
|
||
|
||
$export($export.G + $export.W, {Symbol: $Symbol});
|
||
|
||
$export($export.S, 'Symbol', symbolStatics);
|
||
|
||
$export($export.S + $export.F * !useNative, '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 * (!useNative || buggyJSON), 'JSON', {stringify: $stringify});
|
||
|
||
// 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);
|
||
}).apply(this, arguments);
|
||
|
||
},{"./$":34,"./$.an-object":18,"./$.descriptors":23,"./$.enum-keys":24,"./$.export":25,"./$.fails":26,"./$.get-names":27,"./$.global":28,"./$.has":29,"./$.is-array":32,"./$.keyof":35,"./$.library":36,"./$.property-desc":37,"./$.redefine":38,"./$.set-to-string-tag":39,"./$.shared":40,"./$.to-iobject":41,"./$.uid":42,"./$.wks":43}],46:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/debug/browser.js", module);
|
||
(function(){
|
||
|
||
/**
|
||
* This is the web browser implementation of `debug()`.
|
||
*
|
||
* Expose `debug()` as the module.
|
||
*/
|
||
|
||
exports = module.exports = require('./debug');
|
||
exports.log = log;
|
||
exports.formatArgs = formatArgs;
|
||
exports.save = save;
|
||
exports.load = load;
|
||
exports.useColors = useColors;
|
||
exports.storage = 'undefined' != typeof chrome
|
||
&& 'undefined' != typeof chrome.storage
|
||
? chrome.storage.local
|
||
: localstorage();
|
||
|
||
/**
|
||
* Colors.
|
||
*/
|
||
|
||
exports.colors = [
|
||
'lightseagreen',
|
||
'forestgreen',
|
||
'goldenrod',
|
||
'dodgerblue',
|
||
'darkorchid',
|
||
'crimson'
|
||
];
|
||
|
||
/**
|
||
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
|
||
* and the Firebug extension (any Firefox version) are known
|
||
* to support "%c" CSS customizations.
|
||
*
|
||
* TODO: add a `localStorage` variable to explicitly enable/disable colors
|
||
*/
|
||
|
||
function useColors() {
|
||
// is webkit? http://stackoverflow.com/a/16459606/376773
|
||
return ('WebkitAppearance' in document.documentElement.style) ||
|
||
// is firebug? http://stackoverflow.com/a/398120/376773
|
||
(window.console && (console.firebug || (console.exception && console.table))) ||
|
||
// is firefox >= v31?
|
||
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
||
(navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31);
|
||
}
|
||
|
||
/**
|
||
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
|
||
*/
|
||
|
||
exports.formatters.j = function(v) {
|
||
return JSON.stringify(v);
|
||
};
|
||
|
||
|
||
/**
|
||
* Colorize log arguments if enabled.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
function formatArgs() {
|
||
var args = arguments;
|
||
var useColors = this.useColors;
|
||
|
||
args[0] = (useColors ? '%c' : '')
|
||
+ this.namespace
|
||
+ (useColors ? ' %c' : ' ')
|
||
+ args[0]
|
||
+ (useColors ? '%c ' : ' ')
|
||
+ '+' + exports.humanize(this.diff);
|
||
|
||
if (!useColors) return args;
|
||
|
||
var c = 'color: ' + this.color;
|
||
args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));
|
||
|
||
// the final "%c" is somewhat tricky, because there could be other
|
||
// arguments passed either before or after the %c, so we need to
|
||
// figure out the correct index to insert the CSS into
|
||
var index = 0;
|
||
var lastC = 0;
|
||
args[0].replace(/%[a-z%]/g, function(match) {
|
||
if ('%%' === match) return;
|
||
index++;
|
||
if ('%c' === match) {
|
||
// we only are interested in the *last* %c
|
||
// (the user may have provided their own)
|
||
lastC = index;
|
||
}
|
||
});
|
||
|
||
args.splice(lastC, 0, c);
|
||
return args;
|
||
}
|
||
|
||
/**
|
||
* Invokes `console.log()` when available.
|
||
* No-op when `console.log` is not a "function".
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
function log() {
|
||
// this hackery is required for IE8/9, where
|
||
// the `console.log` function doesn't have 'apply'
|
||
return 'object' === typeof console
|
||
&& console.log
|
||
&& Function.prototype.apply.call(console.log, console, arguments);
|
||
}
|
||
|
||
/**
|
||
* Save `namespaces`.
|
||
*
|
||
* @param {String} namespaces
|
||
* @api private
|
||
*/
|
||
|
||
function save(namespaces) {
|
||
try {
|
||
if (null == namespaces) {
|
||
exports.storage.removeItem('debug');
|
||
} else {
|
||
exports.storage.debug = namespaces;
|
||
}
|
||
} catch(e) {}
|
||
}
|
||
|
||
/**
|
||
* Load `namespaces`.
|
||
*
|
||
* @return {String} returns the previously persisted debug modes
|
||
* @api private
|
||
*/
|
||
|
||
function load() {
|
||
var r;
|
||
try {
|
||
r = exports.storage.debug;
|
||
} catch(e) {}
|
||
return r;
|
||
}
|
||
|
||
/**
|
||
* Enable namespaces listed in `localStorage.debug` initially.
|
||
*/
|
||
|
||
exports.enable(load());
|
||
|
||
/**
|
||
* Localstorage attempts to return the localstorage.
|
||
*
|
||
* This is necessary because safari throws
|
||
* when a user disables cookies/localstorage
|
||
* and you attempt to access it.
|
||
*
|
||
* @return {LocalStorage}
|
||
* @api private
|
||
*/
|
||
|
||
function localstorage(){
|
||
try {
|
||
return window.localStorage;
|
||
} catch (e) {}
|
||
}
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./debug":47}],47:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/debug/debug.js", module);
|
||
(function(){
|
||
|
||
/**
|
||
* This is the common logic for both the Node.js and web browser
|
||
* implementations of `debug()`.
|
||
*
|
||
* Expose `debug()` as the module.
|
||
*/
|
||
|
||
exports = module.exports = debug;
|
||
exports.coerce = coerce;
|
||
exports.disable = disable;
|
||
exports.enable = enable;
|
||
exports.enabled = enabled;
|
||
exports.humanize = require('ms');
|
||
|
||
/**
|
||
* The currently active debug mode names, and names to skip.
|
||
*/
|
||
|
||
exports.names = [];
|
||
exports.skips = [];
|
||
|
||
/**
|
||
* Map of special "%n" handling functions, for the debug "format" argument.
|
||
*
|
||
* Valid key names are a single, lowercased letter, i.e. "n".
|
||
*/
|
||
|
||
exports.formatters = {};
|
||
|
||
/**
|
||
* Previously assigned color.
|
||
*/
|
||
|
||
var prevColor = 0;
|
||
|
||
/**
|
||
* Previous log timestamp.
|
||
*/
|
||
|
||
var prevTime;
|
||
|
||
/**
|
||
* Select a color.
|
||
*
|
||
* @return {Number}
|
||
* @api private
|
||
*/
|
||
|
||
function selectColor() {
|
||
return exports.colors[prevColor++ % exports.colors.length];
|
||
}
|
||
|
||
/**
|
||
* Create a debugger with the given `namespace`.
|
||
*
|
||
* @param {String} namespace
|
||
* @return {Function}
|
||
* @api public
|
||
*/
|
||
|
||
function debug(namespace) {
|
||
|
||
// define the `disabled` version
|
||
function disabled() {
|
||
}
|
||
disabled.enabled = false;
|
||
|
||
// define the `enabled` version
|
||
function enabled() {
|
||
|
||
var self = enabled;
|
||
|
||
// set `diff` timestamp
|
||
var curr = +new Date();
|
||
var ms = curr - (prevTime || curr);
|
||
self.diff = ms;
|
||
self.prev = prevTime;
|
||
self.curr = curr;
|
||
prevTime = curr;
|
||
|
||
// add the `color` if not set
|
||
if (null == self.useColors) self.useColors = exports.useColors();
|
||
if (null == self.color && self.useColors) self.color = selectColor();
|
||
|
||
var args = Array.prototype.slice.call(arguments);
|
||
|
||
args[0] = exports.coerce(args[0]);
|
||
|
||
if ('string' !== typeof args[0]) {
|
||
// anything else let's inspect with %o
|
||
args = ['%o'].concat(args);
|
||
}
|
||
|
||
// apply any `formatters` transformations
|
||
var index = 0;
|
||
args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {
|
||
// if we encounter an escaped % then don't increase the array index
|
||
if (match === '%%') return match;
|
||
index++;
|
||
var formatter = exports.formatters[format];
|
||
if ('function' === typeof formatter) {
|
||
var val = args[index];
|
||
match = formatter.call(self, val);
|
||
|
||
// now we need to remove `args[index]` since it's inlined in the `format`
|
||
args.splice(index, 1);
|
||
index--;
|
||
}
|
||
return match;
|
||
});
|
||
|
||
if ('function' === typeof exports.formatArgs) {
|
||
args = exports.formatArgs.apply(self, args);
|
||
}
|
||
var logFn = enabled.log || exports.log || console.log.bind(console);
|
||
logFn.apply(self, args);
|
||
}
|
||
enabled.enabled = true;
|
||
|
||
var fn = exports.enabled(namespace) ? enabled : disabled;
|
||
|
||
fn.namespace = namespace;
|
||
|
||
return fn;
|
||
}
|
||
|
||
/**
|
||
* Enables a debug mode by namespaces. This can include modes
|
||
* separated by a colon and wildcards.
|
||
*
|
||
* @param {String} namespaces
|
||
* @api public
|
||
*/
|
||
|
||
function enable(namespaces) {
|
||
exports.save(namespaces);
|
||
|
||
var split = (namespaces || '').split(/[\s,]+/);
|
||
var len = split.length;
|
||
|
||
for (var i = 0; i < len; i++) {
|
||
if (!split[i]) continue; // ignore empty strings
|
||
namespaces = split[i].replace(/\*/g, '.*?');
|
||
if (namespaces[0] === '-') {
|
||
exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
|
||
} else {
|
||
exports.names.push(new RegExp('^' + namespaces + '$'));
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Disable debug output.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
function disable() {
|
||
exports.enable('');
|
||
}
|
||
|
||
/**
|
||
* Returns true if the given mode name is enabled, false otherwise.
|
||
*
|
||
* @param {String} name
|
||
* @return {Boolean}
|
||
* @api public
|
||
*/
|
||
|
||
function enabled(name) {
|
||
var i, len;
|
||
for (i = 0, len = exports.skips.length; i < len; i++) {
|
||
if (exports.skips[i].test(name)) {
|
||
return false;
|
||
}
|
||
}
|
||
for (i = 0, len = exports.names.length; i < len; i++) {
|
||
if (exports.names[i].test(name)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Coerce `val`.
|
||
*
|
||
* @param {Mixed} val
|
||
* @return {Mixed}
|
||
* @api private
|
||
*/
|
||
|
||
function coerce(val) {
|
||
if (val instanceof Error) return val.stack || val.message;
|
||
return val;
|
||
}
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"ms":133}],48:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-client/index.js", module);
|
||
(function(){
|
||
|
||
module.exports = require('./lib/');
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./lib/":49}],49:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-client/lib/index.js", module);
|
||
(function(){
|
||
|
||
module.exports = require('./socket');
|
||
|
||
/**
|
||
* Exports parser
|
||
*
|
||
* @api public
|
||
*
|
||
*/
|
||
module.exports.parser = require('engine.io-parser');
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./socket":50,"engine.io-parser":58}],50:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-client/lib/socket.js", module);
|
||
(function(){
|
||
(function (global){
|
||
/**
|
||
* Module dependencies.
|
||
*/
|
||
|
||
var transports = require('./transports');
|
||
var Emitter = require('component-emitter');
|
||
var debug = require('debug')('engine.io-client:socket');
|
||
var index = require('indexof');
|
||
var parser = require('engine.io-parser');
|
||
var parseuri = require('parseuri');
|
||
var parsejson = require('parsejson');
|
||
var parseqs = require('parseqs');
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = Socket;
|
||
|
||
/**
|
||
* Noop function.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
function noop(){}
|
||
|
||
/**
|
||
* Socket constructor.
|
||
*
|
||
* @param {String|Object} uri or options
|
||
* @param {Object} options
|
||
* @api public
|
||
*/
|
||
|
||
function Socket(uri, opts){
|
||
if (!(this instanceof Socket)) return new Socket(uri, opts);
|
||
|
||
opts = opts || {};
|
||
|
||
if (uri && 'object' == typeof uri) {
|
||
opts = uri;
|
||
uri = null;
|
||
}
|
||
|
||
if (uri) {
|
||
uri = parseuri(uri);
|
||
opts.hostname = uri.host;
|
||
opts.secure = uri.protocol == 'https' || uri.protocol == 'wss';
|
||
opts.port = uri.port;
|
||
if (uri.query) opts.query = uri.query;
|
||
} else if (opts.host) {
|
||
opts.hostname = parseuri(opts.host).host;
|
||
}
|
||
|
||
this.secure = null != opts.secure ? opts.secure :
|
||
(global.location && 'https:' == location.protocol);
|
||
|
||
if (opts.hostname && !opts.port) {
|
||
// if no port is specified manually, use the protocol default
|
||
opts.port = this.secure ? '443' : '80';
|
||
}
|
||
|
||
this.agent = opts.agent || false;
|
||
this.hostname = opts.hostname ||
|
||
(global.location ? location.hostname : 'localhost');
|
||
this.port = opts.port || (global.location && location.port ?
|
||
location.port :
|
||
(this.secure ? 443 : 80));
|
||
this.query = opts.query || {};
|
||
if ('string' == typeof this.query) this.query = parseqs.decode(this.query);
|
||
this.upgrade = false !== opts.upgrade;
|
||
this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/';
|
||
this.forceJSONP = !!opts.forceJSONP;
|
||
this.jsonp = false !== opts.jsonp;
|
||
this.forceBase64 = !!opts.forceBase64;
|
||
this.enablesXDR = !!opts.enablesXDR;
|
||
this.timestampParam = opts.timestampParam || 't';
|
||
this.timestampRequests = opts.timestampRequests;
|
||
this.transports = opts.transports || ['polling', 'websocket'];
|
||
this.readyState = '';
|
||
this.writeBuffer = [];
|
||
this.policyPort = opts.policyPort || 843;
|
||
this.rememberUpgrade = opts.rememberUpgrade || false;
|
||
this.binaryType = null;
|
||
this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;
|
||
this.perMessageDeflate = false !== opts.perMessageDeflate ? (opts.perMessageDeflate || {}) : false;
|
||
|
||
if (true === this.perMessageDeflate) this.perMessageDeflate = {};
|
||
if (this.perMessageDeflate && null == this.perMessageDeflate.threshold) {
|
||
this.perMessageDeflate.threshold = 1024;
|
||
}
|
||
|
||
// SSL options for Node.js client
|
||
this.pfx = opts.pfx || null;
|
||
this.key = opts.key || null;
|
||
this.passphrase = opts.passphrase || null;
|
||
this.cert = opts.cert || null;
|
||
this.ca = opts.ca || null;
|
||
this.ciphers = opts.ciphers || null;
|
||
this.rejectUnauthorized = opts.rejectUnauthorized === undefined ? null : opts.rejectUnauthorized;
|
||
|
||
// other options for Node.js client
|
||
var freeGlobal = typeof global == 'object' && global;
|
||
if (freeGlobal.global === freeGlobal) {
|
||
if (opts.extraHeaders && Object.keys(opts.extraHeaders).length > 0) {
|
||
this.extraHeaders = opts.extraHeaders;
|
||
}
|
||
}
|
||
|
||
this.open();
|
||
}
|
||
|
||
Socket.priorWebsocketSuccess = false;
|
||
|
||
/**
|
||
* Mix in `Emitter`.
|
||
*/
|
||
|
||
Emitter(Socket.prototype);
|
||
|
||
/**
|
||
* Protocol version.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
Socket.protocol = parser.protocol; // this is an int
|
||
|
||
/**
|
||
* Expose deps for legacy compatibility
|
||
* and standalone browser access.
|
||
*/
|
||
|
||
Socket.Socket = Socket;
|
||
Socket.Transport = require('./transport');
|
||
Socket.transports = require('./transports');
|
||
Socket.parser = require('engine.io-parser');
|
||
|
||
/**
|
||
* Creates transport of the given type.
|
||
*
|
||
* @param {String} transport name
|
||
* @return {Transport}
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.createTransport = function (name) {
|
||
debug('creating transport "%s"', name);
|
||
var query = clone(this.query);
|
||
|
||
// append engine.io protocol identifier
|
||
query.EIO = parser.protocol;
|
||
|
||
// transport name
|
||
query.transport = name;
|
||
|
||
// session id if we already have one
|
||
if (this.id) query.sid = this.id;
|
||
|
||
var transport = new transports[name]({
|
||
agent: this.agent,
|
||
hostname: this.hostname,
|
||
port: this.port,
|
||
secure: this.secure,
|
||
path: this.path,
|
||
query: query,
|
||
forceJSONP: this.forceJSONP,
|
||
jsonp: this.jsonp,
|
||
forceBase64: this.forceBase64,
|
||
enablesXDR: this.enablesXDR,
|
||
timestampRequests: this.timestampRequests,
|
||
timestampParam: this.timestampParam,
|
||
policyPort: this.policyPort,
|
||
socket: this,
|
||
pfx: this.pfx,
|
||
key: this.key,
|
||
passphrase: this.passphrase,
|
||
cert: this.cert,
|
||
ca: this.ca,
|
||
ciphers: this.ciphers,
|
||
rejectUnauthorized: this.rejectUnauthorized,
|
||
perMessageDeflate: this.perMessageDeflate,
|
||
extraHeaders: this.extraHeaders
|
||
});
|
||
|
||
return transport;
|
||
};
|
||
|
||
function clone (obj) {
|
||
var o = {};
|
||
for (var i in obj) {
|
||
if (obj.hasOwnProperty(i)) {
|
||
o[i] = obj[i];
|
||
}
|
||
}
|
||
return o;
|
||
}
|
||
|
||
/**
|
||
* Initializes transport to use and starts probe.
|
||
*
|
||
* @api private
|
||
*/
|
||
Socket.prototype.open = function () {
|
||
var transport;
|
||
if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) {
|
||
transport = 'websocket';
|
||
} else if (0 === this.transports.length) {
|
||
// Emit error on next tick so it can be listened to
|
||
var self = this;
|
||
setTimeout(function() {
|
||
self.emit('error', 'No transports available');
|
||
}, 0);
|
||
return;
|
||
} else {
|
||
transport = this.transports[0];
|
||
}
|
||
this.readyState = 'opening';
|
||
|
||
// Retry with the next transport if the transport is disabled (jsonp: false)
|
||
try {
|
||
transport = this.createTransport(transport);
|
||
} catch (e) {
|
||
this.transports.shift();
|
||
this.open();
|
||
return;
|
||
}
|
||
|
||
transport.open();
|
||
this.setTransport(transport);
|
||
};
|
||
|
||
/**
|
||
* Sets the current transport. Disables the existing one (if any).
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.setTransport = function(transport){
|
||
debug('setting transport %s', transport.name);
|
||
var self = this;
|
||
|
||
if (this.transport) {
|
||
debug('clearing existing transport %s', this.transport.name);
|
||
this.transport.removeAllListeners();
|
||
}
|
||
|
||
// set up transport
|
||
this.transport = transport;
|
||
|
||
// set up transport listeners
|
||
transport
|
||
.on('drain', function(){
|
||
self.onDrain();
|
||
})
|
||
.on('packet', function(packet){
|
||
self.onPacket(packet);
|
||
})
|
||
.on('error', function(e){
|
||
self.onError(e);
|
||
})
|
||
.on('close', function(){
|
||
self.onClose('transport close');
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Probes a transport.
|
||
*
|
||
* @param {String} transport name
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.probe = function (name) {
|
||
debug('probing transport "%s"', name);
|
||
var transport = this.createTransport(name, { probe: 1 })
|
||
, failed = false
|
||
, self = this;
|
||
|
||
Socket.priorWebsocketSuccess = false;
|
||
|
||
function onTransportOpen(){
|
||
if (self.onlyBinaryUpgrades) {
|
||
var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;
|
||
failed = failed || upgradeLosesBinary;
|
||
}
|
||
if (failed) return;
|
||
|
||
debug('probe transport "%s" opened', name);
|
||
transport.send([{ type: 'ping', data: 'probe' }]);
|
||
transport.once('packet', function (msg) {
|
||
if (failed) return;
|
||
if ('pong' == msg.type && 'probe' == msg.data) {
|
||
debug('probe transport "%s" pong', name);
|
||
self.upgrading = true;
|
||
self.emit('upgrading', transport);
|
||
if (!transport) return;
|
||
Socket.priorWebsocketSuccess = 'websocket' == transport.name;
|
||
|
||
debug('pausing current transport "%s"', self.transport.name);
|
||
self.transport.pause(function () {
|
||
if (failed) return;
|
||
if ('closed' == self.readyState) return;
|
||
debug('changing transport and sending upgrade packet');
|
||
|
||
cleanup();
|
||
|
||
self.setTransport(transport);
|
||
transport.send([{ type: 'upgrade' }]);
|
||
self.emit('upgrade', transport);
|
||
transport = null;
|
||
self.upgrading = false;
|
||
self.flush();
|
||
});
|
||
} else {
|
||
debug('probe transport "%s" failed', name);
|
||
var err = new Error('probe error');
|
||
err.transport = transport.name;
|
||
self.emit('upgradeError', err);
|
||
}
|
||
});
|
||
}
|
||
|
||
function freezeTransport() {
|
||
if (failed) return;
|
||
|
||
// Any callback called by transport should be ignored since now
|
||
failed = true;
|
||
|
||
cleanup();
|
||
|
||
transport.close();
|
||
transport = null;
|
||
}
|
||
|
||
//Handle any error that happens while probing
|
||
function onerror(err) {
|
||
var error = new Error('probe error: ' + err);
|
||
error.transport = transport.name;
|
||
|
||
freezeTransport();
|
||
|
||
debug('probe transport "%s" failed because of error: %s', name, err);
|
||
|
||
self.emit('upgradeError', error);
|
||
}
|
||
|
||
function onTransportClose(){
|
||
onerror("transport closed");
|
||
}
|
||
|
||
//When the socket is closed while we're probing
|
||
function onclose(){
|
||
onerror("socket closed");
|
||
}
|
||
|
||
//When the socket is upgraded while we're probing
|
||
function onupgrade(to){
|
||
if (transport && to.name != transport.name) {
|
||
debug('"%s" works - aborting "%s"', to.name, transport.name);
|
||
freezeTransport();
|
||
}
|
||
}
|
||
|
||
//Remove all listeners on the transport and on self
|
||
function cleanup(){
|
||
transport.removeListener('open', onTransportOpen);
|
||
transport.removeListener('error', onerror);
|
||
transport.removeListener('close', onTransportClose);
|
||
self.removeListener('close', onclose);
|
||
self.removeListener('upgrading', onupgrade);
|
||
}
|
||
|
||
transport.once('open', onTransportOpen);
|
||
transport.once('error', onerror);
|
||
transport.once('close', onTransportClose);
|
||
|
||
this.once('close', onclose);
|
||
this.once('upgrading', onupgrade);
|
||
|
||
transport.open();
|
||
|
||
};
|
||
|
||
/**
|
||
* Called when connection is deemed open.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
Socket.prototype.onOpen = function () {
|
||
debug('socket open');
|
||
this.readyState = 'open';
|
||
Socket.priorWebsocketSuccess = 'websocket' == this.transport.name;
|
||
this.emit('open');
|
||
this.flush();
|
||
|
||
// we check for `readyState` in case an `open`
|
||
// listener already closed the socket
|
||
if ('open' == this.readyState && this.upgrade && this.transport.pause) {
|
||
debug('starting upgrade probes');
|
||
for (var i = 0, l = this.upgrades.length; i < l; i++) {
|
||
this.probe(this.upgrades[i]);
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Handles a packet.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.onPacket = function (packet) {
|
||
if ('opening' == this.readyState || 'open' == this.readyState) {
|
||
debug('socket receive: type "%s", data "%s"', packet.type, packet.data);
|
||
|
||
this.emit('packet', packet);
|
||
|
||
// Socket is live - any packet counts
|
||
this.emit('heartbeat');
|
||
|
||
switch (packet.type) {
|
||
case 'open':
|
||
this.onHandshake(parsejson(packet.data));
|
||
break;
|
||
|
||
case 'pong':
|
||
this.setPing();
|
||
this.emit('pong');
|
||
break;
|
||
|
||
case 'error':
|
||
var err = new Error('server error');
|
||
err.code = packet.data;
|
||
this.onError(err);
|
||
break;
|
||
|
||
case 'message':
|
||
this.emit('data', packet.data);
|
||
this.emit('message', packet.data);
|
||
break;
|
||
}
|
||
} else {
|
||
debug('packet received with socket readyState "%s"', this.readyState);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Called upon handshake completion.
|
||
*
|
||
* @param {Object} handshake obj
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.onHandshake = function (data) {
|
||
this.emit('handshake', data);
|
||
this.id = data.sid;
|
||
this.transport.query.sid = data.sid;
|
||
this.upgrades = this.filterUpgrades(data.upgrades);
|
||
this.pingInterval = data.pingInterval;
|
||
this.pingTimeout = data.pingTimeout;
|
||
this.onOpen();
|
||
// In case open handler closes socket
|
||
if ('closed' == this.readyState) return;
|
||
this.setPing();
|
||
|
||
// Prolong liveness of socket on heartbeat
|
||
this.removeListener('heartbeat', this.onHeartbeat);
|
||
this.on('heartbeat', this.onHeartbeat);
|
||
};
|
||
|
||
/**
|
||
* Resets ping timeout.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.onHeartbeat = function (timeout) {
|
||
clearTimeout(this.pingTimeoutTimer);
|
||
var self = this;
|
||
self.pingTimeoutTimer = setTimeout(function () {
|
||
if ('closed' == self.readyState) return;
|
||
self.onClose('ping timeout');
|
||
}, timeout || (self.pingInterval + self.pingTimeout));
|
||
};
|
||
|
||
/**
|
||
* Pings server every `this.pingInterval` and expects response
|
||
* within `this.pingTimeout` or closes connection.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.setPing = function () {
|
||
var self = this;
|
||
clearTimeout(self.pingIntervalTimer);
|
||
self.pingIntervalTimer = setTimeout(function () {
|
||
debug('writing ping packet - expecting pong within %sms', self.pingTimeout);
|
||
self.ping();
|
||
self.onHeartbeat(self.pingTimeout);
|
||
}, self.pingInterval);
|
||
};
|
||
|
||
/**
|
||
* Sends a ping packet.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.ping = function () {
|
||
var self = this;
|
||
this.sendPacket('ping', function(){
|
||
self.emit('ping');
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Called on `drain` event
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.onDrain = function() {
|
||
this.writeBuffer.splice(0, this.prevBufferLen);
|
||
|
||
// setting prevBufferLen = 0 is very important
|
||
// for example, when upgrading, upgrade packet is sent over,
|
||
// and a nonzero prevBufferLen could cause problems on `drain`
|
||
this.prevBufferLen = 0;
|
||
|
||
if (0 === this.writeBuffer.length) {
|
||
this.emit('drain');
|
||
} else {
|
||
this.flush();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Flush write buffers.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.flush = function () {
|
||
if ('closed' != this.readyState && this.transport.writable &&
|
||
!this.upgrading && this.writeBuffer.length) {
|
||
debug('flushing %d packets in socket', this.writeBuffer.length);
|
||
this.transport.send(this.writeBuffer);
|
||
// keep track of current length of writeBuffer
|
||
// splice writeBuffer and callbackBuffer on `drain`
|
||
this.prevBufferLen = this.writeBuffer.length;
|
||
this.emit('flush');
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Sends a message.
|
||
*
|
||
* @param {String} message.
|
||
* @param {Function} callback function.
|
||
* @param {Object} options.
|
||
* @return {Socket} for chaining.
|
||
* @api public
|
||
*/
|
||
|
||
Socket.prototype.write =
|
||
Socket.prototype.send = function (msg, options, fn) {
|
||
this.sendPacket('message', msg, options, fn);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Sends a packet.
|
||
*
|
||
* @param {String} packet type.
|
||
* @param {String} data.
|
||
* @param {Object} options.
|
||
* @param {Function} callback function.
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.sendPacket = function (type, data, options, fn) {
|
||
if('function' == typeof data) {
|
||
fn = data;
|
||
data = undefined;
|
||
}
|
||
|
||
if ('function' == typeof options) {
|
||
fn = options;
|
||
options = null;
|
||
}
|
||
|
||
if ('closing' == this.readyState || 'closed' == this.readyState) {
|
||
return;
|
||
}
|
||
|
||
options = options || {};
|
||
options.compress = false !== options.compress;
|
||
|
||
var packet = {
|
||
type: type,
|
||
data: data,
|
||
options: options
|
||
};
|
||
this.emit('packetCreate', packet);
|
||
this.writeBuffer.push(packet);
|
||
if (fn) this.once('flush', fn);
|
||
this.flush();
|
||
};
|
||
|
||
/**
|
||
* Closes the connection.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.close = function () {
|
||
if ('opening' == this.readyState || 'open' == this.readyState) {
|
||
this.readyState = 'closing';
|
||
|
||
var self = this;
|
||
|
||
if (this.writeBuffer.length) {
|
||
this.once('drain', function() {
|
||
if (this.upgrading) {
|
||
waitForUpgrade();
|
||
} else {
|
||
close();
|
||
}
|
||
});
|
||
} else if (this.upgrading) {
|
||
waitForUpgrade();
|
||
} else {
|
||
close();
|
||
}
|
||
}
|
||
|
||
function close() {
|
||
self.onClose('forced close');
|
||
debug('socket closing - telling transport to close');
|
||
self.transport.close();
|
||
}
|
||
|
||
function cleanupAndClose() {
|
||
self.removeListener('upgrade', cleanupAndClose);
|
||
self.removeListener('upgradeError', cleanupAndClose);
|
||
close();
|
||
}
|
||
|
||
function waitForUpgrade() {
|
||
// wait for upgrade to finish since we can't send packets while pausing a transport
|
||
self.once('upgrade', cleanupAndClose);
|
||
self.once('upgradeError', cleanupAndClose);
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Called upon transport error
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.onError = function (err) {
|
||
debug('socket error %j', err);
|
||
Socket.priorWebsocketSuccess = false;
|
||
this.emit('error', err);
|
||
this.onClose('transport error', err);
|
||
};
|
||
|
||
/**
|
||
* Called upon transport close.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.onClose = function (reason, desc) {
|
||
if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) {
|
||
debug('socket close with reason: "%s"', reason);
|
||
var self = this;
|
||
|
||
// clear timers
|
||
clearTimeout(this.pingIntervalTimer);
|
||
clearTimeout(this.pingTimeoutTimer);
|
||
|
||
// stop event from firing again for transport
|
||
this.transport.removeAllListeners('close');
|
||
|
||
// ensure transport won't stay open
|
||
this.transport.close();
|
||
|
||
// ignore further transport communication
|
||
this.transport.removeAllListeners();
|
||
|
||
// set ready state
|
||
this.readyState = 'closed';
|
||
|
||
// clear session id
|
||
this.id = null;
|
||
|
||
// emit close event
|
||
this.emit('close', reason, desc);
|
||
|
||
// clean buffers after, so users can still
|
||
// grab the buffers on `close` event
|
||
self.writeBuffer = [];
|
||
self.prevBufferLen = 0;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Filters upgrades, returning only those matching client transports.
|
||
*
|
||
* @param {Array} server upgrades
|
||
* @api private
|
||
*
|
||
*/
|
||
|
||
Socket.prototype.filterUpgrades = function (upgrades) {
|
||
var filteredUpgrades = [];
|
||
for (var i = 0, j = upgrades.length; i<j; i++) {
|
||
if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);
|
||
}
|
||
return filteredUpgrades;
|
||
};
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./transport":51,"./transports":52,"component-emitter":14,"debug":46,"engine.io-parser":58,"indexof":63,"parsejson":134,"parseqs":135,"parseuri":136}],51:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-client/lib/transport.js", module);
|
||
(function(){
|
||
/**
|
||
* Module dependencies.
|
||
*/
|
||
|
||
var parser = require('engine.io-parser');
|
||
var Emitter = require('component-emitter');
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = Transport;
|
||
|
||
/**
|
||
* Transport abstract constructor.
|
||
*
|
||
* @param {Object} options.
|
||
* @api private
|
||
*/
|
||
|
||
function Transport (opts) {
|
||
this.path = opts.path;
|
||
this.hostname = opts.hostname;
|
||
this.port = opts.port;
|
||
this.secure = opts.secure;
|
||
this.query = opts.query;
|
||
this.timestampParam = opts.timestampParam;
|
||
this.timestampRequests = opts.timestampRequests;
|
||
this.readyState = '';
|
||
this.agent = opts.agent || false;
|
||
this.socket = opts.socket;
|
||
this.enablesXDR = opts.enablesXDR;
|
||
|
||
// SSL options for Node.js client
|
||
this.pfx = opts.pfx;
|
||
this.key = opts.key;
|
||
this.passphrase = opts.passphrase;
|
||
this.cert = opts.cert;
|
||
this.ca = opts.ca;
|
||
this.ciphers = opts.ciphers;
|
||
this.rejectUnauthorized = opts.rejectUnauthorized;
|
||
|
||
// other options for Node.js client
|
||
this.extraHeaders = opts.extraHeaders;
|
||
}
|
||
|
||
/**
|
||
* Mix in `Emitter`.
|
||
*/
|
||
|
||
Emitter(Transport.prototype);
|
||
|
||
/**
|
||
* Emits an error.
|
||
*
|
||
* @param {String} str
|
||
* @return {Transport} for chaining
|
||
* @api public
|
||
*/
|
||
|
||
Transport.prototype.onError = function (msg, desc) {
|
||
var err = new Error(msg);
|
||
err.type = 'TransportError';
|
||
err.description = desc;
|
||
this.emit('error', err);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Opens the transport.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
Transport.prototype.open = function () {
|
||
if ('closed' == this.readyState || '' == this.readyState) {
|
||
this.readyState = 'opening';
|
||
this.doOpen();
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Closes the transport.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Transport.prototype.close = function () {
|
||
if ('opening' == this.readyState || 'open' == this.readyState) {
|
||
this.doClose();
|
||
this.onClose();
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Sends multiple packets.
|
||
*
|
||
* @param {Array} packets
|
||
* @api private
|
||
*/
|
||
|
||
Transport.prototype.send = function(packets){
|
||
if ('open' == this.readyState) {
|
||
this.write(packets);
|
||
} else {
|
||
throw new Error('Transport not open');
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Called upon open
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Transport.prototype.onOpen = function () {
|
||
this.readyState = 'open';
|
||
this.writable = true;
|
||
this.emit('open');
|
||
};
|
||
|
||
/**
|
||
* Called with data.
|
||
*
|
||
* @param {String} data
|
||
* @api private
|
||
*/
|
||
|
||
Transport.prototype.onData = function(data){
|
||
var packet = parser.decodePacket(data, this.socket.binaryType);
|
||
this.onPacket(packet);
|
||
};
|
||
|
||
/**
|
||
* Called with a decoded packet.
|
||
*/
|
||
|
||
Transport.prototype.onPacket = function (packet) {
|
||
this.emit('packet', packet);
|
||
};
|
||
|
||
/**
|
||
* Called upon close.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Transport.prototype.onClose = function () {
|
||
this.readyState = 'closed';
|
||
this.emit('close');
|
||
};
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"component-emitter":14,"engine.io-parser":58}],52:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-client/lib/transports/index.js", module);
|
||
(function(){
|
||
(function (global){
|
||
/**
|
||
* Module dependencies
|
||
*/
|
||
|
||
var XMLHttpRequest = require('xmlhttprequest-ssl');
|
||
var XHR = require('./polling-xhr');
|
||
var JSONP = require('./polling-jsonp');
|
||
var websocket = require('./websocket');
|
||
|
||
/**
|
||
* Export transports.
|
||
*/
|
||
|
||
exports.polling = polling;
|
||
exports.websocket = websocket;
|
||
|
||
/**
|
||
* Polling transport polymorphic constructor.
|
||
* Decides on xhr vs jsonp based on feature detection.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
function polling(opts){
|
||
var xhr;
|
||
var xd = false;
|
||
var xs = false;
|
||
var jsonp = false !== opts.jsonp;
|
||
|
||
if (global.location) {
|
||
var isSSL = 'https:' == location.protocol;
|
||
var port = location.port;
|
||
|
||
// some user agents have empty `location.port`
|
||
if (!port) {
|
||
port = isSSL ? 443 : 80;
|
||
}
|
||
|
||
xd = opts.hostname != location.hostname || port != opts.port;
|
||
xs = opts.secure != isSSL;
|
||
}
|
||
|
||
opts.xdomain = xd;
|
||
opts.xscheme = xs;
|
||
xhr = new XMLHttpRequest(opts);
|
||
|
||
if ('open' in xhr && !opts.forceJSONP) {
|
||
return new XHR(opts);
|
||
} else {
|
||
if (!jsonp) throw new Error('JSONP disabled');
|
||
return new JSONP(opts);
|
||
}
|
||
}
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./polling-jsonp":53,"./polling-xhr":54,"./websocket":56,"xmlhttprequest-ssl":57}],53:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-client/lib/transports/polling-jsonp.js", module);
|
||
(function(){
|
||
(function (global){
|
||
|
||
/**
|
||
* Module requirements.
|
||
*/
|
||
|
||
var Polling = require('./polling');
|
||
var inherit = require('component-inherit');
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = JSONPPolling;
|
||
|
||
/**
|
||
* Cached regular expressions.
|
||
*/
|
||
|
||
var rNewline = /\n/g;
|
||
var rEscapedNewline = /\\n/g;
|
||
|
||
/**
|
||
* Global JSONP callbacks.
|
||
*/
|
||
|
||
var callbacks;
|
||
|
||
/**
|
||
* Callbacks count.
|
||
*/
|
||
|
||
var index = 0;
|
||
|
||
/**
|
||
* Noop.
|
||
*/
|
||
|
||
function empty () { }
|
||
|
||
/**
|
||
* JSONP Polling constructor.
|
||
*
|
||
* @param {Object} opts.
|
||
* @api public
|
||
*/
|
||
|
||
function JSONPPolling (opts) {
|
||
Polling.call(this, opts);
|
||
|
||
this.query = this.query || {};
|
||
|
||
// define global callbacks array if not present
|
||
// we do this here (lazily) to avoid unneeded global pollution
|
||
if (!callbacks) {
|
||
// we need to consider multiple engines in the same page
|
||
if (!global.___eio) global.___eio = [];
|
||
callbacks = global.___eio;
|
||
}
|
||
|
||
// callback identifier
|
||
this.index = callbacks.length;
|
||
|
||
// add callback to jsonp global
|
||
var self = this;
|
||
callbacks.push(function (msg) {
|
||
self.onData(msg);
|
||
});
|
||
|
||
// append to query string
|
||
this.query.j = this.index;
|
||
|
||
// prevent spurious errors from being emitted when the window is unloaded
|
||
if (global.document && global.addEventListener) {
|
||
global.addEventListener('beforeunload', function () {
|
||
if (self.script) self.script.onerror = empty;
|
||
}, false);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Inherits from Polling.
|
||
*/
|
||
|
||
inherit(JSONPPolling, Polling);
|
||
|
||
/*
|
||
* JSONP only supports binary as base64 encoded strings
|
||
*/
|
||
|
||
JSONPPolling.prototype.supportsBinary = false;
|
||
|
||
/**
|
||
* Closes the socket.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
JSONPPolling.prototype.doClose = function () {
|
||
if (this.script) {
|
||
this.script.parentNode.removeChild(this.script);
|
||
this.script = null;
|
||
}
|
||
|
||
if (this.form) {
|
||
this.form.parentNode.removeChild(this.form);
|
||
this.form = null;
|
||
this.iframe = null;
|
||
}
|
||
|
||
Polling.prototype.doClose.call(this);
|
||
};
|
||
|
||
/**
|
||
* Starts a poll cycle.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
JSONPPolling.prototype.doPoll = function () {
|
||
var self = this;
|
||
var script = document.createElement('script');
|
||
|
||
if (this.script) {
|
||
this.script.parentNode.removeChild(this.script);
|
||
this.script = null;
|
||
}
|
||
|
||
script.async = true;
|
||
script.src = this.uri();
|
||
script.onerror = function(e){
|
||
self.onError('jsonp poll error',e);
|
||
};
|
||
|
||
var insertAt = document.getElementsByTagName('script')[0];
|
||
if (insertAt) {
|
||
insertAt.parentNode.insertBefore(script, insertAt);
|
||
}
|
||
else {
|
||
(document.head || document.body).appendChild(script);
|
||
}
|
||
this.script = script;
|
||
|
||
var isUAgecko = 'undefined' != typeof navigator && /gecko/i.test(navigator.userAgent);
|
||
|
||
if (isUAgecko) {
|
||
setTimeout(function () {
|
||
var iframe = document.createElement('iframe');
|
||
document.body.appendChild(iframe);
|
||
document.body.removeChild(iframe);
|
||
}, 100);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Writes with a hidden iframe.
|
||
*
|
||
* @param {String} data to send
|
||
* @param {Function} called upon flush.
|
||
* @api private
|
||
*/
|
||
|
||
JSONPPolling.prototype.doWrite = function (data, fn) {
|
||
var self = this;
|
||
|
||
if (!this.form) {
|
||
var form = document.createElement('form');
|
||
var area = document.createElement('textarea');
|
||
var id = this.iframeId = 'eio_iframe_' + this.index;
|
||
var iframe;
|
||
|
||
form.className = 'socketio';
|
||
form.style.position = 'absolute';
|
||
form.style.top = '-1000px';
|
||
form.style.left = '-1000px';
|
||
form.target = id;
|
||
form.method = 'POST';
|
||
form.setAttribute('accept-charset', 'utf-8');
|
||
area.name = 'd';
|
||
form.appendChild(area);
|
||
document.body.appendChild(form);
|
||
|
||
this.form = form;
|
||
this.area = area;
|
||
}
|
||
|
||
this.form.action = this.uri();
|
||
|
||
function complete () {
|
||
initIframe();
|
||
fn();
|
||
}
|
||
|
||
function initIframe () {
|
||
if (self.iframe) {
|
||
try {
|
||
self.form.removeChild(self.iframe);
|
||
} catch (e) {
|
||
self.onError('jsonp polling iframe removal error', e);
|
||
}
|
||
}
|
||
|
||
try {
|
||
// ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
|
||
var html = '<iframe src="javascript:0" name="'+ self.iframeId +'">';
|
||
iframe = document.createElement(html);
|
||
} catch (e) {
|
||
iframe = document.createElement('iframe');
|
||
iframe.name = self.iframeId;
|
||
iframe.src = 'javascript:0';
|
||
}
|
||
|
||
iframe.id = self.iframeId;
|
||
|
||
self.form.appendChild(iframe);
|
||
self.iframe = iframe;
|
||
}
|
||
|
||
initIframe();
|
||
|
||
// escape \n to prevent it from being converted into \r\n by some UAs
|
||
// double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side
|
||
data = data.replace(rEscapedNewline, '\\\n');
|
||
this.area.value = data.replace(rNewline, '\\n');
|
||
|
||
try {
|
||
this.form.submit();
|
||
} catch(e) {}
|
||
|
||
if (this.iframe.attachEvent) {
|
||
this.iframe.onreadystatechange = function(){
|
||
if (self.iframe.readyState == 'complete') {
|
||
complete();
|
||
}
|
||
};
|
||
} else {
|
||
this.iframe.onload = complete;
|
||
}
|
||
};
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./polling":55,"component-inherit":15}],54:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-client/lib/transports/polling-xhr.js", module);
|
||
(function(){
|
||
(function (global){
|
||
/**
|
||
* Module requirements.
|
||
*/
|
||
|
||
var XMLHttpRequest = require('xmlhttprequest-ssl');
|
||
var Polling = require('./polling');
|
||
var Emitter = require('component-emitter');
|
||
var inherit = require('component-inherit');
|
||
var debug = require('debug')('engine.io-client:polling-xhr');
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = XHR;
|
||
module.exports.Request = Request;
|
||
|
||
/**
|
||
* Empty function
|
||
*/
|
||
|
||
function empty(){}
|
||
|
||
/**
|
||
* XHR Polling constructor.
|
||
*
|
||
* @param {Object} opts
|
||
* @api public
|
||
*/
|
||
|
||
function XHR(opts){
|
||
Polling.call(this, opts);
|
||
|
||
if (global.location) {
|
||
var isSSL = 'https:' == location.protocol;
|
||
var port = location.port;
|
||
|
||
// some user agents have empty `location.port`
|
||
if (!port) {
|
||
port = isSSL ? 443 : 80;
|
||
}
|
||
|
||
this.xd = opts.hostname != global.location.hostname ||
|
||
port != opts.port;
|
||
this.xs = opts.secure != isSSL;
|
||
} else {
|
||
this.extraHeaders = opts.extraHeaders;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Inherits from Polling.
|
||
*/
|
||
|
||
inherit(XHR, Polling);
|
||
|
||
/**
|
||
* XHR supports binary
|
||
*/
|
||
|
||
XHR.prototype.supportsBinary = true;
|
||
|
||
/**
|
||
* Creates a request.
|
||
*
|
||
* @param {String} method
|
||
* @api private
|
||
*/
|
||
|
||
XHR.prototype.request = function(opts){
|
||
opts = opts || {};
|
||
opts.uri = this.uri();
|
||
opts.xd = this.xd;
|
||
opts.xs = this.xs;
|
||
opts.agent = this.agent || false;
|
||
opts.supportsBinary = this.supportsBinary;
|
||
opts.enablesXDR = this.enablesXDR;
|
||
|
||
// SSL options for Node.js client
|
||
opts.pfx = this.pfx;
|
||
opts.key = this.key;
|
||
opts.passphrase = this.passphrase;
|
||
opts.cert = this.cert;
|
||
opts.ca = this.ca;
|
||
opts.ciphers = this.ciphers;
|
||
opts.rejectUnauthorized = this.rejectUnauthorized;
|
||
|
||
// other options for Node.js client
|
||
opts.extraHeaders = this.extraHeaders;
|
||
|
||
return new Request(opts);
|
||
};
|
||
|
||
/**
|
||
* Sends data.
|
||
*
|
||
* @param {String} data to send.
|
||
* @param {Function} called upon flush.
|
||
* @api private
|
||
*/
|
||
|
||
XHR.prototype.doWrite = function(data, fn){
|
||
var isBinary = typeof data !== 'string' && data !== undefined;
|
||
var req = this.request({ method: 'POST', data: data, isBinary: isBinary });
|
||
var self = this;
|
||
req.on('success', fn);
|
||
req.on('error', function(err){
|
||
self.onError('xhr post error', err);
|
||
});
|
||
this.sendXhr = req;
|
||
};
|
||
|
||
/**
|
||
* Starts a poll cycle.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
XHR.prototype.doPoll = function(){
|
||
debug('xhr poll');
|
||
var req = this.request();
|
||
var self = this;
|
||
req.on('data', function(data){
|
||
self.onData(data);
|
||
});
|
||
req.on('error', function(err){
|
||
self.onError('xhr poll error', err);
|
||
});
|
||
this.pollXhr = req;
|
||
};
|
||
|
||
/**
|
||
* Request constructor
|
||
*
|
||
* @param {Object} options
|
||
* @api public
|
||
*/
|
||
|
||
function Request(opts){
|
||
this.method = opts.method || 'GET';
|
||
this.uri = opts.uri;
|
||
this.xd = !!opts.xd;
|
||
this.xs = !!opts.xs;
|
||
this.async = false !== opts.async;
|
||
this.data = undefined != opts.data ? opts.data : null;
|
||
this.agent = opts.agent;
|
||
this.isBinary = opts.isBinary;
|
||
this.supportsBinary = opts.supportsBinary;
|
||
this.enablesXDR = opts.enablesXDR;
|
||
|
||
// SSL options for Node.js client
|
||
this.pfx = opts.pfx;
|
||
this.key = opts.key;
|
||
this.passphrase = opts.passphrase;
|
||
this.cert = opts.cert;
|
||
this.ca = opts.ca;
|
||
this.ciphers = opts.ciphers;
|
||
this.rejectUnauthorized = opts.rejectUnauthorized;
|
||
|
||
// other options for Node.js client
|
||
this.extraHeaders = opts.extraHeaders;
|
||
|
||
this.create();
|
||
}
|
||
|
||
/**
|
||
* Mix in `Emitter`.
|
||
*/
|
||
|
||
Emitter(Request.prototype);
|
||
|
||
/**
|
||
* Creates the XHR object and sends the request.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Request.prototype.create = function(){
|
||
var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR };
|
||
|
||
// SSL options for Node.js client
|
||
opts.pfx = this.pfx;
|
||
opts.key = this.key;
|
||
opts.passphrase = this.passphrase;
|
||
opts.cert = this.cert;
|
||
opts.ca = this.ca;
|
||
opts.ciphers = this.ciphers;
|
||
opts.rejectUnauthorized = this.rejectUnauthorized;
|
||
|
||
var xhr = this.xhr = new XMLHttpRequest(opts);
|
||
var self = this;
|
||
|
||
try {
|
||
debug('xhr open %s: %s', this.method, this.uri);
|
||
xhr.open(this.method, this.uri, this.async);
|
||
try {
|
||
if (this.extraHeaders) {
|
||
xhr.setDisableHeaderCheck(true);
|
||
for (var i in this.extraHeaders) {
|
||
if (this.extraHeaders.hasOwnProperty(i)) {
|
||
xhr.setRequestHeader(i, this.extraHeaders[i]);
|
||
}
|
||
}
|
||
}
|
||
} catch (e) {}
|
||
if (this.supportsBinary) {
|
||
// This has to be done after open because Firefox is stupid
|
||
// http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension
|
||
xhr.responseType = 'arraybuffer';
|
||
}
|
||
|
||
if ('POST' == this.method) {
|
||
try {
|
||
if (this.isBinary) {
|
||
xhr.setRequestHeader('Content-type', 'application/octet-stream');
|
||
} else {
|
||
xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');
|
||
}
|
||
} catch (e) {}
|
||
}
|
||
|
||
// ie6 check
|
||
if ('withCredentials' in xhr) {
|
||
xhr.withCredentials = true;
|
||
}
|
||
|
||
if (this.hasXDR()) {
|
||
xhr.onload = function(){
|
||
self.onLoad();
|
||
};
|
||
xhr.onerror = function(){
|
||
self.onError(xhr.responseText);
|
||
};
|
||
} else {
|
||
xhr.onreadystatechange = function(){
|
||
if (4 != xhr.readyState) return;
|
||
if (200 == xhr.status || 1223 == xhr.status) {
|
||
self.onLoad();
|
||
} else {
|
||
// make sure the `error` event handler that's user-set
|
||
// does not throw in the same tick and gets caught here
|
||
setTimeout(function(){
|
||
self.onError(xhr.status);
|
||
}, 0);
|
||
}
|
||
};
|
||
}
|
||
|
||
debug('xhr data %s', this.data);
|
||
xhr.send(this.data);
|
||
} catch (e) {
|
||
// Need to defer since .create() is called directly fhrom the constructor
|
||
// and thus the 'error' event can only be only bound *after* this exception
|
||
// occurs. Therefore, also, we cannot throw here at all.
|
||
setTimeout(function() {
|
||
self.onError(e);
|
||
}, 0);
|
||
return;
|
||
}
|
||
|
||
if (global.document) {
|
||
this.index = Request.requestsCount++;
|
||
Request.requests[this.index] = this;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Called upon successful response.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Request.prototype.onSuccess = function(){
|
||
this.emit('success');
|
||
this.cleanup();
|
||
};
|
||
|
||
/**
|
||
* Called if we have data.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Request.prototype.onData = function(data){
|
||
this.emit('data', data);
|
||
this.onSuccess();
|
||
};
|
||
|
||
/**
|
||
* Called upon error.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Request.prototype.onError = function(err){
|
||
this.emit('error', err);
|
||
this.cleanup(true);
|
||
};
|
||
|
||
/**
|
||
* Cleans up house.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Request.prototype.cleanup = function(fromError){
|
||
if ('undefined' == typeof this.xhr || null === this.xhr) {
|
||
return;
|
||
}
|
||
// xmlhttprequest
|
||
if (this.hasXDR()) {
|
||
this.xhr.onload = this.xhr.onerror = empty;
|
||
} else {
|
||
this.xhr.onreadystatechange = empty;
|
||
}
|
||
|
||
if (fromError) {
|
||
try {
|
||
this.xhr.abort();
|
||
} catch(e) {}
|
||
}
|
||
|
||
if (global.document) {
|
||
delete Request.requests[this.index];
|
||
}
|
||
|
||
this.xhr = null;
|
||
};
|
||
|
||
/**
|
||
* Called upon load.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Request.prototype.onLoad = function(){
|
||
var data;
|
||
try {
|
||
var contentType;
|
||
try {
|
||
contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0];
|
||
} catch (e) {}
|
||
if (contentType === 'application/octet-stream') {
|
||
data = this.xhr.response;
|
||
} else {
|
||
if (!this.supportsBinary) {
|
||
data = this.xhr.responseText;
|
||
} else {
|
||
try {
|
||
data = String.fromCharCode.apply(null, new Uint8Array(this.xhr.response));
|
||
} catch (e) {
|
||
var ui8Arr = new Uint8Array(this.xhr.response);
|
||
var dataArray = [];
|
||
for (var idx = 0, length = ui8Arr.length; idx < length; idx++) {
|
||
dataArray.push(ui8Arr[idx]);
|
||
}
|
||
|
||
data = String.fromCharCode.apply(null, dataArray);
|
||
}
|
||
}
|
||
}
|
||
} catch (e) {
|
||
this.onError(e);
|
||
}
|
||
if (null != data) {
|
||
this.onData(data);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Check if it has XDomainRequest.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Request.prototype.hasXDR = function(){
|
||
return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR;
|
||
};
|
||
|
||
/**
|
||
* Aborts the request.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
Request.prototype.abort = function(){
|
||
this.cleanup();
|
||
};
|
||
|
||
/**
|
||
* Aborts pending requests when unloading the window. This is needed to prevent
|
||
* memory leaks (e.g. when using IE) and to ensure that no spurious error is
|
||
* emitted.
|
||
*/
|
||
|
||
if (global.document) {
|
||
Request.requestsCount = 0;
|
||
Request.requests = {};
|
||
if (global.attachEvent) {
|
||
global.attachEvent('onunload', unloadHandler);
|
||
} else if (global.addEventListener) {
|
||
global.addEventListener('beforeunload', unloadHandler, false);
|
||
}
|
||
}
|
||
|
||
function unloadHandler() {
|
||
for (var i in Request.requests) {
|
||
if (Request.requests.hasOwnProperty(i)) {
|
||
Request.requests[i].abort();
|
||
}
|
||
}
|
||
}
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./polling":55,"component-emitter":14,"component-inherit":15,"debug":46,"xmlhttprequest-ssl":57}],55:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-client/lib/transports/polling.js", module);
|
||
(function(){
|
||
/**
|
||
* Module dependencies.
|
||
*/
|
||
|
||
var Transport = require('../transport');
|
||
var parseqs = require('parseqs');
|
||
var parser = require('engine.io-parser');
|
||
var inherit = require('component-inherit');
|
||
var yeast = require('yeast');
|
||
var debug = require('debug')('engine.io-client:polling');
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = Polling;
|
||
|
||
/**
|
||
* Is XHR2 supported?
|
||
*/
|
||
|
||
var hasXHR2 = (function() {
|
||
var XMLHttpRequest = require('xmlhttprequest-ssl');
|
||
var xhr = new XMLHttpRequest({ xdomain: false });
|
||
return null != xhr.responseType;
|
||
})();
|
||
|
||
/**
|
||
* Polling interface.
|
||
*
|
||
* @param {Object} opts
|
||
* @api private
|
||
*/
|
||
|
||
function Polling(opts){
|
||
var forceBase64 = (opts && opts.forceBase64);
|
||
if (!hasXHR2 || forceBase64) {
|
||
this.supportsBinary = false;
|
||
}
|
||
Transport.call(this, opts);
|
||
}
|
||
|
||
/**
|
||
* Inherits from Transport.
|
||
*/
|
||
|
||
inherit(Polling, Transport);
|
||
|
||
/**
|
||
* Transport name.
|
||
*/
|
||
|
||
Polling.prototype.name = 'polling';
|
||
|
||
/**
|
||
* Opens the socket (triggers polling). We write a PING message to determine
|
||
* when the transport is open.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Polling.prototype.doOpen = function(){
|
||
this.poll();
|
||
};
|
||
|
||
/**
|
||
* Pauses polling.
|
||
*
|
||
* @param {Function} callback upon buffers are flushed and transport is paused
|
||
* @api private
|
||
*/
|
||
|
||
Polling.prototype.pause = function(onPause){
|
||
var pending = 0;
|
||
var self = this;
|
||
|
||
this.readyState = 'pausing';
|
||
|
||
function pause(){
|
||
debug('paused');
|
||
self.readyState = 'paused';
|
||
onPause();
|
||
}
|
||
|
||
if (this.polling || !this.writable) {
|
||
var total = 0;
|
||
|
||
if (this.polling) {
|
||
debug('we are currently polling - waiting to pause');
|
||
total++;
|
||
this.once('pollComplete', function(){
|
||
debug('pre-pause polling complete');
|
||
--total || pause();
|
||
});
|
||
}
|
||
|
||
if (!this.writable) {
|
||
debug('we are currently writing - waiting to pause');
|
||
total++;
|
||
this.once('drain', function(){
|
||
debug('pre-pause writing complete');
|
||
--total || pause();
|
||
});
|
||
}
|
||
} else {
|
||
pause();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Starts polling cycle.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
Polling.prototype.poll = function(){
|
||
debug('polling');
|
||
this.polling = true;
|
||
this.doPoll();
|
||
this.emit('poll');
|
||
};
|
||
|
||
/**
|
||
* Overloads onData to detect payloads.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Polling.prototype.onData = function(data){
|
||
var self = this;
|
||
debug('polling got data %s', data);
|
||
var callback = function(packet, index, total) {
|
||
// if its the first message we consider the transport open
|
||
if ('opening' == self.readyState) {
|
||
self.onOpen();
|
||
}
|
||
|
||
// if its a close packet, we close the ongoing requests
|
||
if ('close' == packet.type) {
|
||
self.onClose();
|
||
return false;
|
||
}
|
||
|
||
// otherwise bypass onData and handle the message
|
||
self.onPacket(packet);
|
||
};
|
||
|
||
// decode payload
|
||
parser.decodePayload(data, this.socket.binaryType, callback);
|
||
|
||
// if an event did not trigger closing
|
||
if ('closed' != this.readyState) {
|
||
// if we got data we're not polling
|
||
this.polling = false;
|
||
this.emit('pollComplete');
|
||
|
||
if ('open' == this.readyState) {
|
||
this.poll();
|
||
} else {
|
||
debug('ignoring poll - transport state "%s"', this.readyState);
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* For polling, send a close packet.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Polling.prototype.doClose = function(){
|
||
var self = this;
|
||
|
||
function close(){
|
||
debug('writing close packet');
|
||
self.write([{ type: 'close' }]);
|
||
}
|
||
|
||
if ('open' == this.readyState) {
|
||
debug('transport open - closing');
|
||
close();
|
||
} else {
|
||
// in case we're trying to close while
|
||
// handshaking is in progress (GH-164)
|
||
debug('transport not open - deferring close');
|
||
this.once('open', close);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Writes a packets payload.
|
||
*
|
||
* @param {Array} data packets
|
||
* @param {Function} drain callback
|
||
* @api private
|
||
*/
|
||
|
||
Polling.prototype.write = function(packets){
|
||
var self = this;
|
||
this.writable = false;
|
||
var callbackfn = function() {
|
||
self.writable = true;
|
||
self.emit('drain');
|
||
};
|
||
|
||
var self = this;
|
||
parser.encodePayload(packets, this.supportsBinary, function(data) {
|
||
self.doWrite(data, callbackfn);
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Generates uri for connection.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Polling.prototype.uri = function(){
|
||
var query = this.query || {};
|
||
var schema = this.secure ? 'https' : 'http';
|
||
var port = '';
|
||
|
||
// cache busting is forced
|
||
if (false !== this.timestampRequests) {
|
||
query[this.timestampParam] = yeast();
|
||
}
|
||
|
||
if (!this.supportsBinary && !query.sid) {
|
||
query.b64 = 1;
|
||
}
|
||
|
||
query = parseqs.encode(query);
|
||
|
||
// avoid port if default for schema
|
||
if (this.port && (('https' == schema && this.port != 443) ||
|
||
('http' == schema && this.port != 80))) {
|
||
port = ':' + this.port;
|
||
}
|
||
|
||
// prepend ? to query
|
||
if (query.length) {
|
||
query = '?' + query;
|
||
}
|
||
|
||
var ipv6 = this.hostname.indexOf(':') !== -1;
|
||
return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;
|
||
};
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../transport":51,"component-inherit":15,"debug":46,"engine.io-parser":58,"parseqs":135,"xmlhttprequest-ssl":57,"yeast":154}],56:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-client/lib/transports/websocket.js", module);
|
||
(function(){
|
||
(function (global){
|
||
/**
|
||
* Module dependencies.
|
||
*/
|
||
|
||
var Transport = require('../transport');
|
||
var parser = require('engine.io-parser');
|
||
var parseqs = require('parseqs');
|
||
var inherit = require('component-inherit');
|
||
var yeast = require('yeast');
|
||
var debug = require('debug')('engine.io-client:websocket');
|
||
var BrowserWebSocket = global.WebSocket || global.MozWebSocket;
|
||
|
||
/**
|
||
* Get either the `WebSocket` or `MozWebSocket` globals
|
||
* in the browser or try to resolve WebSocket-compatible
|
||
* interface exposed by `ws` for Node-like environment.
|
||
*/
|
||
|
||
var WebSocket = BrowserWebSocket;
|
||
if (!WebSocket && typeof window === 'undefined') {
|
||
try {
|
||
WebSocket = require('ws');
|
||
} catch (e) { }
|
||
}
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = WS;
|
||
|
||
/**
|
||
* WebSocket transport constructor.
|
||
*
|
||
* @api {Object} connection options
|
||
* @api public
|
||
*/
|
||
|
||
function WS(opts){
|
||
var forceBase64 = (opts && opts.forceBase64);
|
||
if (forceBase64) {
|
||
this.supportsBinary = false;
|
||
}
|
||
this.perMessageDeflate = opts.perMessageDeflate;
|
||
Transport.call(this, opts);
|
||
}
|
||
|
||
/**
|
||
* Inherits from Transport.
|
||
*/
|
||
|
||
inherit(WS, Transport);
|
||
|
||
/**
|
||
* Transport name.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
WS.prototype.name = 'websocket';
|
||
|
||
/*
|
||
* WebSockets support binary
|
||
*/
|
||
|
||
WS.prototype.supportsBinary = true;
|
||
|
||
/**
|
||
* Opens socket.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
WS.prototype.doOpen = function(){
|
||
if (!this.check()) {
|
||
// let probe timeout
|
||
return;
|
||
}
|
||
|
||
var self = this;
|
||
var uri = this.uri();
|
||
var protocols = void(0);
|
||
var opts = {
|
||
agent: this.agent,
|
||
perMessageDeflate: this.perMessageDeflate
|
||
};
|
||
|
||
// SSL options for Node.js client
|
||
opts.pfx = this.pfx;
|
||
opts.key = this.key;
|
||
opts.passphrase = this.passphrase;
|
||
opts.cert = this.cert;
|
||
opts.ca = this.ca;
|
||
opts.ciphers = this.ciphers;
|
||
opts.rejectUnauthorized = this.rejectUnauthorized;
|
||
if (this.extraHeaders) {
|
||
opts.headers = this.extraHeaders;
|
||
}
|
||
|
||
this.ws = BrowserWebSocket ? new WebSocket(uri) : new WebSocket(uri, protocols, opts);
|
||
|
||
if (this.ws.binaryType === undefined) {
|
||
this.supportsBinary = false;
|
||
}
|
||
|
||
if (this.ws.supports && this.ws.supports.binary) {
|
||
this.supportsBinary = true;
|
||
this.ws.binaryType = 'buffer';
|
||
} else {
|
||
this.ws.binaryType = 'arraybuffer';
|
||
}
|
||
|
||
this.addEventListeners();
|
||
};
|
||
|
||
/**
|
||
* Adds event listeners to the socket
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
WS.prototype.addEventListeners = function(){
|
||
var self = this;
|
||
|
||
this.ws.onopen = function(){
|
||
self.onOpen();
|
||
};
|
||
this.ws.onclose = function(){
|
||
self.onClose();
|
||
};
|
||
this.ws.onmessage = function(ev){
|
||
self.onData(ev.data);
|
||
};
|
||
this.ws.onerror = function(e){
|
||
self.onError('websocket error', e);
|
||
};
|
||
};
|
||
|
||
/**
|
||
* Override `onData` to use a timer on iOS.
|
||
* See: https://gist.github.com/mloughran/2052006
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
if ('undefined' != typeof navigator
|
||
&& /iPad|iPhone|iPod/i.test(navigator.userAgent)) {
|
||
WS.prototype.onData = function(data){
|
||
var self = this;
|
||
setTimeout(function(){
|
||
Transport.prototype.onData.call(self, data);
|
||
}, 0);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Writes data to socket.
|
||
*
|
||
* @param {Array} array of packets.
|
||
* @api private
|
||
*/
|
||
|
||
WS.prototype.write = function(packets){
|
||
var self = this;
|
||
this.writable = false;
|
||
|
||
// encodePacket efficient as it uses WS framing
|
||
// no need for encodePayload
|
||
var total = packets.length;
|
||
for (var i = 0, l = total; i < l; i++) {
|
||
(function(packet) {
|
||
parser.encodePacket(packet, self.supportsBinary, function(data) {
|
||
if (!BrowserWebSocket) {
|
||
// always create a new object (GH-437)
|
||
var opts = {};
|
||
if (packet.options) {
|
||
opts.compress = packet.options.compress;
|
||
}
|
||
|
||
if (self.perMessageDeflate) {
|
||
var len = 'string' == typeof data ? global.Buffer.byteLength(data) : data.length;
|
||
if (len < self.perMessageDeflate.threshold) {
|
||
opts.compress = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
//Sometimes the websocket has already been closed but the browser didn't
|
||
//have a chance of informing us about it yet, in that case send will
|
||
//throw an error
|
||
try {
|
||
if (BrowserWebSocket) {
|
||
// TypeError is thrown when passing the second argument on Safari
|
||
self.ws.send(data);
|
||
} else {
|
||
self.ws.send(data, opts);
|
||
}
|
||
} catch (e){
|
||
debug('websocket closed before onclose event');
|
||
}
|
||
|
||
--total || done();
|
||
});
|
||
})(packets[i]);
|
||
}
|
||
|
||
function done(){
|
||
self.emit('flush');
|
||
|
||
// fake drain
|
||
// defer to next tick to allow Socket to clear writeBuffer
|
||
setTimeout(function(){
|
||
self.writable = true;
|
||
self.emit('drain');
|
||
}, 0);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Called upon close
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
WS.prototype.onClose = function(){
|
||
Transport.prototype.onClose.call(this);
|
||
};
|
||
|
||
/**
|
||
* Closes socket.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
WS.prototype.doClose = function(){
|
||
if (typeof this.ws !== 'undefined') {
|
||
this.ws.close();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Generates uri for connection.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
WS.prototype.uri = function(){
|
||
var query = this.query || {};
|
||
var schema = this.secure ? 'wss' : 'ws';
|
||
var port = '';
|
||
|
||
// avoid port if default for schema
|
||
if (this.port && (('wss' == schema && this.port != 443)
|
||
|| ('ws' == schema && this.port != 80))) {
|
||
port = ':' + this.port;
|
||
}
|
||
|
||
// append timestamp to URI
|
||
if (this.timestampRequests) {
|
||
query[this.timestampParam] = yeast();
|
||
}
|
||
|
||
// communicate binary support capabilities
|
||
if (!this.supportsBinary) {
|
||
query.b64 = 1;
|
||
}
|
||
|
||
query = parseqs.encode(query);
|
||
|
||
// prepend ? to query
|
||
if (query.length) {
|
||
query = '?' + query;
|
||
}
|
||
|
||
var ipv6 = this.hostname.indexOf(':') !== -1;
|
||
return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;
|
||
};
|
||
|
||
/**
|
||
* Feature detection for WebSocket.
|
||
*
|
||
* @return {Boolean} whether this transport is available.
|
||
* @api public
|
||
*/
|
||
|
||
WS.prototype.check = function(){
|
||
return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name);
|
||
};
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../transport":51,"component-inherit":15,"debug":46,"engine.io-parser":58,"parseqs":135,"ws":9,"yeast":154}],57:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-client/lib/xmlhttprequest.js", module);
|
||
(function(){
|
||
// browser shim for xmlhttprequest module
|
||
var hasCORS = require('has-cors');
|
||
|
||
module.exports = function(opts) {
|
||
var xdomain = opts.xdomain;
|
||
|
||
// scheme must be same when usign XDomainRequest
|
||
// http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
|
||
var xscheme = opts.xscheme;
|
||
|
||
// XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.
|
||
// https://github.com/Automattic/engine.io-client/pull/217
|
||
var enablesXDR = opts.enablesXDR;
|
||
|
||
// XMLHttpRequest can be disabled on IE
|
||
try {
|
||
if ('undefined' != typeof XMLHttpRequest && (!xdomain || hasCORS)) {
|
||
return new XMLHttpRequest();
|
||
}
|
||
} catch (e) { }
|
||
|
||
// Use XDomainRequest for IE8 if enablesXDR is true
|
||
// because loading bar keeps flashing when using jsonp-polling
|
||
// https://github.com/yujiosaka/socke.io-ie8-loading-example
|
||
try {
|
||
if ('undefined' != typeof XDomainRequest && !xscheme && enablesXDR) {
|
||
return new XDomainRequest();
|
||
}
|
||
} catch (e) { }
|
||
|
||
if (!xdomain) {
|
||
try {
|
||
return new ActiveXObject('Microsoft.XMLHTTP');
|
||
} catch(e) { }
|
||
}
|
||
}
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"has-cors":62}],58:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-parser/lib/browser.js", module);
|
||
(function(){
|
||
(function (global){
|
||
/**
|
||
* Module dependencies.
|
||
*/
|
||
|
||
var keys = require('./keys');
|
||
var hasBinary = require('has-binary');
|
||
var sliceBuffer = require('arraybuffer.slice');
|
||
var base64encoder = require('base64-arraybuffer');
|
||
var after = require('after');
|
||
var utf8 = require('utf8');
|
||
|
||
/**
|
||
* Check if we are running an android browser. That requires us to use
|
||
* ArrayBuffer with polling transports...
|
||
*
|
||
* http://ghinda.net/jpeg-blob-ajax-android/
|
||
*/
|
||
|
||
var isAndroid = navigator.userAgent.match(/Android/i);
|
||
|
||
/**
|
||
* Check if we are running in PhantomJS.
|
||
* Uploading a Blob with PhantomJS does not work correctly, as reported here:
|
||
* https://github.com/ariya/phantomjs/issues/11395
|
||
* @type boolean
|
||
*/
|
||
var isPhantomJS = /PhantomJS/i.test(navigator.userAgent);
|
||
|
||
/**
|
||
* When true, avoids using Blobs to encode payloads.
|
||
* @type boolean
|
||
*/
|
||
var dontSendBlobs = isAndroid || isPhantomJS;
|
||
|
||
/**
|
||
* Current protocol version.
|
||
*/
|
||
|
||
exports.protocol = 3;
|
||
|
||
/**
|
||
* Packet types.
|
||
*/
|
||
|
||
var packets = exports.packets = {
|
||
open: 0 // non-ws
|
||
, close: 1 // non-ws
|
||
, ping: 2
|
||
, pong: 3
|
||
, message: 4
|
||
, upgrade: 5
|
||
, noop: 6
|
||
};
|
||
|
||
var packetslist = keys(packets);
|
||
|
||
/**
|
||
* Premade error packet.
|
||
*/
|
||
|
||
var err = { type: 'error', data: 'parser error' };
|
||
|
||
/**
|
||
* Create a blob api even for blob builder when vendor prefixes exist
|
||
*/
|
||
|
||
var Blob = require('blob');
|
||
|
||
/**
|
||
* Encodes a packet.
|
||
*
|
||
* <packet type id> [ <data> ]
|
||
*
|
||
* Example:
|
||
*
|
||
* 5hello world
|
||
* 3
|
||
* 4
|
||
*
|
||
* Binary is encoded in an identical principle
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {
|
||
if ('function' == typeof supportsBinary) {
|
||
callback = supportsBinary;
|
||
supportsBinary = false;
|
||
}
|
||
|
||
if ('function' == typeof utf8encode) {
|
||
callback = utf8encode;
|
||
utf8encode = null;
|
||
}
|
||
|
||
var data = (packet.data === undefined)
|
||
? undefined
|
||
: packet.data.buffer || packet.data;
|
||
|
||
if (global.ArrayBuffer && data instanceof ArrayBuffer) {
|
||
return encodeArrayBuffer(packet, supportsBinary, callback);
|
||
} else if (Blob && data instanceof global.Blob) {
|
||
return encodeBlob(packet, supportsBinary, callback);
|
||
}
|
||
|
||
// might be an object with { base64: true, data: dataAsBase64String }
|
||
if (data && data.base64) {
|
||
return encodeBase64Object(packet, callback);
|
||
}
|
||
|
||
// Sending data as a utf-8 string
|
||
var encoded = packets[packet.type];
|
||
|
||
// data fragment is optional
|
||
if (undefined !== packet.data) {
|
||
encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data);
|
||
}
|
||
|
||
return callback('' + encoded);
|
||
|
||
};
|
||
|
||
function encodeBase64Object(packet, callback) {
|
||
// packet data is an object { base64: true, data: dataAsBase64String }
|
||
var message = 'b' + exports.packets[packet.type] + packet.data.data;
|
||
return callback(message);
|
||
}
|
||
|
||
/**
|
||
* Encode packet helpers for binary types
|
||
*/
|
||
|
||
function encodeArrayBuffer(packet, supportsBinary, callback) {
|
||
if (!supportsBinary) {
|
||
return exports.encodeBase64Packet(packet, callback);
|
||
}
|
||
|
||
var data = packet.data;
|
||
var contentArray = new Uint8Array(data);
|
||
var resultBuffer = new Uint8Array(1 + data.byteLength);
|
||
|
||
resultBuffer[0] = packets[packet.type];
|
||
for (var i = 0; i < contentArray.length; i++) {
|
||
resultBuffer[i+1] = contentArray[i];
|
||
}
|
||
|
||
return callback(resultBuffer.buffer);
|
||
}
|
||
|
||
function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {
|
||
if (!supportsBinary) {
|
||
return exports.encodeBase64Packet(packet, callback);
|
||
}
|
||
|
||
var fr = new FileReader();
|
||
fr.onload = function() {
|
||
packet.data = fr.result;
|
||
exports.encodePacket(packet, supportsBinary, true, callback);
|
||
};
|
||
return fr.readAsArrayBuffer(packet.data);
|
||
}
|
||
|
||
function encodeBlob(packet, supportsBinary, callback) {
|
||
if (!supportsBinary) {
|
||
return exports.encodeBase64Packet(packet, callback);
|
||
}
|
||
|
||
if (dontSendBlobs) {
|
||
return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);
|
||
}
|
||
|
||
var length = new Uint8Array(1);
|
||
length[0] = packets[packet.type];
|
||
var blob = new Blob([length.buffer, packet.data]);
|
||
|
||
return callback(blob);
|
||
}
|
||
|
||
/**
|
||
* Encodes a packet with binary data in a base64 string
|
||
*
|
||
* @param {Object} packet, has `type` and `data`
|
||
* @return {String} base64 encoded message
|
||
*/
|
||
|
||
exports.encodeBase64Packet = function(packet, callback) {
|
||
var message = 'b' + exports.packets[packet.type];
|
||
if (Blob && packet.data instanceof global.Blob) {
|
||
var fr = new FileReader();
|
||
fr.onload = function() {
|
||
var b64 = fr.result.split(',')[1];
|
||
callback(message + b64);
|
||
};
|
||
return fr.readAsDataURL(packet.data);
|
||
}
|
||
|
||
var b64data;
|
||
try {
|
||
b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));
|
||
} catch (e) {
|
||
// iPhone Safari doesn't let you apply with typed arrays
|
||
var typed = new Uint8Array(packet.data);
|
||
var basic = new Array(typed.length);
|
||
for (var i = 0; i < typed.length; i++) {
|
||
basic[i] = typed[i];
|
||
}
|
||
b64data = String.fromCharCode.apply(null, basic);
|
||
}
|
||
message += global.btoa(b64data);
|
||
return callback(message);
|
||
};
|
||
|
||
/**
|
||
* Decodes a packet. Changes format to Blob if requested.
|
||
*
|
||
* @return {Object} with `type` and `data` (if any)
|
||
* @api private
|
||
*/
|
||
|
||
exports.decodePacket = function (data, binaryType, utf8decode) {
|
||
// String data
|
||
if (typeof data == 'string' || data === undefined) {
|
||
if (data.charAt(0) == 'b') {
|
||
return exports.decodeBase64Packet(data.substr(1), binaryType);
|
||
}
|
||
|
||
if (utf8decode) {
|
||
try {
|
||
data = utf8.decode(data);
|
||
} catch (e) {
|
||
return err;
|
||
}
|
||
}
|
||
var type = data.charAt(0);
|
||
|
||
if (Number(type) != type || !packetslist[type]) {
|
||
return err;
|
||
}
|
||
|
||
if (data.length > 1) {
|
||
return { type: packetslist[type], data: data.substring(1) };
|
||
} else {
|
||
return { type: packetslist[type] };
|
||
}
|
||
}
|
||
|
||
var asArray = new Uint8Array(data);
|
||
var type = asArray[0];
|
||
var rest = sliceBuffer(data, 1);
|
||
if (Blob && binaryType === 'blob') {
|
||
rest = new Blob([rest]);
|
||
}
|
||
return { type: packetslist[type], data: rest };
|
||
};
|
||
|
||
/**
|
||
* Decodes a packet encoded in a base64 string
|
||
*
|
||
* @param {String} base64 encoded message
|
||
* @return {Object} with `type` and `data` (if any)
|
||
*/
|
||
|
||
exports.decodeBase64Packet = function(msg, binaryType) {
|
||
var type = packetslist[msg.charAt(0)];
|
||
if (!global.ArrayBuffer) {
|
||
return { type: type, data: { base64: true, data: msg.substr(1) } };
|
||
}
|
||
|
||
var data = base64encoder.decode(msg.substr(1));
|
||
|
||
if (binaryType === 'blob' && Blob) {
|
||
data = new Blob([data]);
|
||
}
|
||
|
||
return { type: type, data: data };
|
||
};
|
||
|
||
/**
|
||
* Encodes multiple messages (payload).
|
||
*
|
||
* <length>:data
|
||
*
|
||
* Example:
|
||
*
|
||
* 11:hello world2:hi
|
||
*
|
||
* If any contents are binary, they will be encoded as base64 strings. Base64
|
||
* encoded strings are marked with a b before the length specifier
|
||
*
|
||
* @param {Array} packets
|
||
* @api private
|
||
*/
|
||
|
||
exports.encodePayload = function (packets, supportsBinary, callback) {
|
||
if (typeof supportsBinary == 'function') {
|
||
callback = supportsBinary;
|
||
supportsBinary = null;
|
||
}
|
||
|
||
var isBinary = hasBinary(packets);
|
||
|
||
if (supportsBinary && isBinary) {
|
||
if (Blob && !dontSendBlobs) {
|
||
return exports.encodePayloadAsBlob(packets, callback);
|
||
}
|
||
|
||
return exports.encodePayloadAsArrayBuffer(packets, callback);
|
||
}
|
||
|
||
if (!packets.length) {
|
||
return callback('0:');
|
||
}
|
||
|
||
function setLengthHeader(message) {
|
||
return message.length + ':' + message;
|
||
}
|
||
|
||
function encodeOne(packet, doneCallback) {
|
||
exports.encodePacket(packet, !isBinary ? false : supportsBinary, true, function(message) {
|
||
doneCallback(null, setLengthHeader(message));
|
||
});
|
||
}
|
||
|
||
map(packets, encodeOne, function(err, results) {
|
||
return callback(results.join(''));
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Async array map using after
|
||
*/
|
||
|
||
function map(ary, each, done) {
|
||
var result = new Array(ary.length);
|
||
var next = after(ary.length, done);
|
||
|
||
var eachWithIndex = function(i, el, cb) {
|
||
each(el, function(error, msg) {
|
||
result[i] = msg;
|
||
cb(error, result);
|
||
});
|
||
};
|
||
|
||
for (var i = 0; i < ary.length; i++) {
|
||
eachWithIndex(i, ary[i], next);
|
||
}
|
||
}
|
||
|
||
/*
|
||
* Decodes data when a payload is maybe expected. Possible binary contents are
|
||
* decoded from their base64 representation
|
||
*
|
||
* @param {String} data, callback method
|
||
* @api public
|
||
*/
|
||
|
||
exports.decodePayload = function (data, binaryType, callback) {
|
||
if (typeof data != 'string') {
|
||
return exports.decodePayloadAsBinary(data, binaryType, callback);
|
||
}
|
||
|
||
if (typeof binaryType === 'function') {
|
||
callback = binaryType;
|
||
binaryType = null;
|
||
}
|
||
|
||
var packet;
|
||
if (data == '') {
|
||
// parser error - ignoring payload
|
||
return callback(err, 0, 1);
|
||
}
|
||
|
||
var length = ''
|
||
, n, msg;
|
||
|
||
for (var i = 0, l = data.length; i < l; i++) {
|
||
var chr = data.charAt(i);
|
||
|
||
if (':' != chr) {
|
||
length += chr;
|
||
} else {
|
||
if ('' == length || (length != (n = Number(length)))) {
|
||
// parser error - ignoring payload
|
||
return callback(err, 0, 1);
|
||
}
|
||
|
||
msg = data.substr(i + 1, n);
|
||
|
||
if (length != msg.length) {
|
||
// parser error - ignoring payload
|
||
return callback(err, 0, 1);
|
||
}
|
||
|
||
if (msg.length) {
|
||
packet = exports.decodePacket(msg, binaryType, true);
|
||
|
||
if (err.type == packet.type && err.data == packet.data) {
|
||
// parser error in individual packet - ignoring payload
|
||
return callback(err, 0, 1);
|
||
}
|
||
|
||
var ret = callback(packet, i + n, l);
|
||
if (false === ret) return;
|
||
}
|
||
|
||
// advance cursor
|
||
i += n;
|
||
length = '';
|
||
}
|
||
}
|
||
|
||
if (length != '') {
|
||
// parser error - ignoring payload
|
||
return callback(err, 0, 1);
|
||
}
|
||
|
||
};
|
||
|
||
/**
|
||
* Encodes multiple messages (payload) as binary.
|
||
*
|
||
* <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number
|
||
* 255><data>
|
||
*
|
||
* Example:
|
||
* 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers
|
||
*
|
||
* @param {Array} packets
|
||
* @return {ArrayBuffer} encoded payload
|
||
* @api private
|
||
*/
|
||
|
||
exports.encodePayloadAsArrayBuffer = function(packets, callback) {
|
||
if (!packets.length) {
|
||
return callback(new ArrayBuffer(0));
|
||
}
|
||
|
||
function encodeOne(packet, doneCallback) {
|
||
exports.encodePacket(packet, true, true, function(data) {
|
||
return doneCallback(null, data);
|
||
});
|
||
}
|
||
|
||
map(packets, encodeOne, function(err, encodedPackets) {
|
||
var totalLength = encodedPackets.reduce(function(acc, p) {
|
||
var len;
|
||
if (typeof p === 'string'){
|
||
len = p.length;
|
||
} else {
|
||
len = p.byteLength;
|
||
}
|
||
return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2
|
||
}, 0);
|
||
|
||
var resultArray = new Uint8Array(totalLength);
|
||
|
||
var bufferIndex = 0;
|
||
encodedPackets.forEach(function(p) {
|
||
var isString = typeof p === 'string';
|
||
var ab = p;
|
||
if (isString) {
|
||
var view = new Uint8Array(p.length);
|
||
for (var i = 0; i < p.length; i++) {
|
||
view[i] = p.charCodeAt(i);
|
||
}
|
||
ab = view.buffer;
|
||
}
|
||
|
||
if (isString) { // not true binary
|
||
resultArray[bufferIndex++] = 0;
|
||
} else { // true binary
|
||
resultArray[bufferIndex++] = 1;
|
||
}
|
||
|
||
var lenStr = ab.byteLength.toString();
|
||
for (var i = 0; i < lenStr.length; i++) {
|
||
resultArray[bufferIndex++] = parseInt(lenStr[i]);
|
||
}
|
||
resultArray[bufferIndex++] = 255;
|
||
|
||
var view = new Uint8Array(ab);
|
||
for (var i = 0; i < view.length; i++) {
|
||
resultArray[bufferIndex++] = view[i];
|
||
}
|
||
});
|
||
|
||
return callback(resultArray.buffer);
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Encode as Blob
|
||
*/
|
||
|
||
exports.encodePayloadAsBlob = function(packets, callback) {
|
||
function encodeOne(packet, doneCallback) {
|
||
exports.encodePacket(packet, true, true, function(encoded) {
|
||
var binaryIdentifier = new Uint8Array(1);
|
||
binaryIdentifier[0] = 1;
|
||
if (typeof encoded === 'string') {
|
||
var view = new Uint8Array(encoded.length);
|
||
for (var i = 0; i < encoded.length; i++) {
|
||
view[i] = encoded.charCodeAt(i);
|
||
}
|
||
encoded = view.buffer;
|
||
binaryIdentifier[0] = 0;
|
||
}
|
||
|
||
var len = (encoded instanceof ArrayBuffer)
|
||
? encoded.byteLength
|
||
: encoded.size;
|
||
|
||
var lenStr = len.toString();
|
||
var lengthAry = new Uint8Array(lenStr.length + 1);
|
||
for (var i = 0; i < lenStr.length; i++) {
|
||
lengthAry[i] = parseInt(lenStr[i]);
|
||
}
|
||
lengthAry[lenStr.length] = 255;
|
||
|
||
if (Blob) {
|
||
var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);
|
||
doneCallback(null, blob);
|
||
}
|
||
});
|
||
}
|
||
|
||
map(packets, encodeOne, function(err, results) {
|
||
return callback(new Blob(results));
|
||
});
|
||
};
|
||
|
||
/*
|
||
* Decodes data when a payload is maybe expected. Strings are decoded by
|
||
* interpreting each byte as a key code for entries marked to start with 0. See
|
||
* description of encodePayloadAsBinary
|
||
*
|
||
* @param {ArrayBuffer} data, callback method
|
||
* @api public
|
||
*/
|
||
|
||
exports.decodePayloadAsBinary = function (data, binaryType, callback) {
|
||
if (typeof binaryType === 'function') {
|
||
callback = binaryType;
|
||
binaryType = null;
|
||
}
|
||
|
||
var bufferTail = data;
|
||
var buffers = [];
|
||
|
||
var numberTooLong = false;
|
||
while (bufferTail.byteLength > 0) {
|
||
var tailArray = new Uint8Array(bufferTail);
|
||
var isString = tailArray[0] === 0;
|
||
var msgLength = '';
|
||
|
||
for (var i = 1; ; i++) {
|
||
if (tailArray[i] == 255) break;
|
||
|
||
if (msgLength.length > 310) {
|
||
numberTooLong = true;
|
||
break;
|
||
}
|
||
|
||
msgLength += tailArray[i];
|
||
}
|
||
|
||
if(numberTooLong) return callback(err, 0, 1);
|
||
|
||
bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);
|
||
msgLength = parseInt(msgLength);
|
||
|
||
var msg = sliceBuffer(bufferTail, 0, msgLength);
|
||
if (isString) {
|
||
try {
|
||
msg = String.fromCharCode.apply(null, new Uint8Array(msg));
|
||
} catch (e) {
|
||
// iPhone Safari doesn't let you apply to typed arrays
|
||
var typed = new Uint8Array(msg);
|
||
msg = '';
|
||
for (var i = 0; i < typed.length; i++) {
|
||
msg += String.fromCharCode(typed[i]);
|
||
}
|
||
}
|
||
}
|
||
|
||
buffers.push(msg);
|
||
bufferTail = sliceBuffer(bufferTail, msgLength);
|
||
}
|
||
|
||
var total = buffers.length;
|
||
buffers.forEach(function(buffer, i) {
|
||
callback(exports.decodePacket(buffer, binaryType, true), i, total);
|
||
});
|
||
};
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./keys":59,"after":2,"arraybuffer.slice":3,"base64-arraybuffer":7,"blob":8,"has-binary":60,"utf8":149}],59:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-parser/lib/keys.js", module);
|
||
(function(){
|
||
|
||
/**
|
||
* Gets the keys for an object.
|
||
*
|
||
* @return {Array} keys
|
||
* @api private
|
||
*/
|
||
|
||
module.exports = Object.keys || function keys (obj){
|
||
var arr = [];
|
||
var has = Object.prototype.hasOwnProperty;
|
||
|
||
for (var i in obj) {
|
||
if (has.call(obj, i)) {
|
||
arr.push(i);
|
||
}
|
||
}
|
||
return arr;
|
||
};
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],60:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/engine.io-parser/node_modules/has-binary/index.js", module);
|
||
(function(){
|
||
(function (global){
|
||
|
||
/*
|
||
* Module requirements.
|
||
*/
|
||
|
||
var isArray = require('isarray');
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = hasBinary;
|
||
|
||
/**
|
||
* Checks for binary data.
|
||
*
|
||
* Right now only Buffer and ArrayBuffer are supported..
|
||
*
|
||
* @param {Object} anything
|
||
* @api public
|
||
*/
|
||
|
||
function hasBinary(data) {
|
||
|
||
function _hasBinary(obj) {
|
||
if (!obj) return false;
|
||
|
||
if ( (global.Buffer && global.Buffer.isBuffer(obj)) ||
|
||
(global.ArrayBuffer && obj instanceof ArrayBuffer) ||
|
||
(global.Blob && obj instanceof Blob) ||
|
||
(global.File && obj instanceof File)
|
||
) {
|
||
return true;
|
||
}
|
||
|
||
if (isArray(obj)) {
|
||
for (var i = 0; i < obj.length; i++) {
|
||
if (_hasBinary(obj[i])) {
|
||
return true;
|
||
}
|
||
}
|
||
} else if (obj && 'object' == typeof obj) {
|
||
if (obj.toJSON) {
|
||
obj = obj.toJSON();
|
||
}
|
||
|
||
for (var key in obj) {
|
||
if (Object.prototype.hasOwnProperty.call(obj, key) && _hasBinary(obj[key])) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
return _hasBinary(data);
|
||
}
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"isarray":64}],61:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/has-binary/index.js", module);
|
||
(function(){
|
||
(function (global){
|
||
|
||
/*
|
||
* Module requirements.
|
||
*/
|
||
|
||
var isArray = require('isarray');
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = hasBinary;
|
||
|
||
/**
|
||
* Checks for binary data.
|
||
*
|
||
* Right now only Buffer and ArrayBuffer are supported..
|
||
*
|
||
* @param {Object} anything
|
||
* @api public
|
||
*/
|
||
|
||
function hasBinary(data) {
|
||
|
||
function _hasBinary(obj) {
|
||
if (!obj) return false;
|
||
|
||
if ( (global.Buffer && global.Buffer.isBuffer && global.Buffer.isBuffer(obj)) ||
|
||
(global.ArrayBuffer && obj instanceof ArrayBuffer) ||
|
||
(global.Blob && obj instanceof Blob) ||
|
||
(global.File && obj instanceof File)
|
||
) {
|
||
return true;
|
||
}
|
||
|
||
if (isArray(obj)) {
|
||
for (var i = 0; i < obj.length; i++) {
|
||
if (_hasBinary(obj[i])) {
|
||
return true;
|
||
}
|
||
}
|
||
} else if (obj && 'object' == typeof obj) {
|
||
// see: https://github.com/Automattic/has-binary/pull/4
|
||
if (obj.toJSON && 'function' == typeof obj.toJSON) {
|
||
obj = obj.toJSON();
|
||
}
|
||
|
||
for (var key in obj) {
|
||
if (Object.prototype.hasOwnProperty.call(obj, key) && _hasBinary(obj[key])) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
return _hasBinary(data);
|
||
}
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"isarray":64}],62:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/has-cors/index.js", module);
|
||
(function(){
|
||
|
||
/**
|
||
* Module exports.
|
||
*
|
||
* Logic borrowed from Modernizr:
|
||
*
|
||
* - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js
|
||
*/
|
||
|
||
try {
|
||
module.exports = typeof XMLHttpRequest !== 'undefined' &&
|
||
'withCredentials' in new XMLHttpRequest();
|
||
} catch (err) {
|
||
// if XMLHttp support is disabled in IE then it will throw
|
||
// when trying to create
|
||
module.exports = false;
|
||
}
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],63:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/indexof/index.js", module);
|
||
(function(){
|
||
|
||
var indexOf = [].indexOf;
|
||
|
||
module.exports = function(arr, obj){
|
||
if (indexOf) return arr.indexOf(obj);
|
||
for (var i = 0; i < arr.length; ++i) {
|
||
if (arr[i] === obj) return i;
|
||
}
|
||
return -1;
|
||
};
|
||
}).apply(this, arguments);
|
||
|
||
},{}],64:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/isarray/index.js", module);
|
||
(function(){
|
||
module.exports = Array.isArray || function (arr) {
|
||
return Object.prototype.toString.call(arr) == '[object Array]';
|
||
};
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],65:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/array/last.js", module);
|
||
(function(){
|
||
/**
|
||
* Gets the last element of `array`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Array
|
||
* @param {Array} array The array to query.
|
||
* @returns {*} Returns the last element of `array`.
|
||
* @example
|
||
*
|
||
* _.last([1, 2, 3]);
|
||
* // => 3
|
||
*/
|
||
function last(array) {
|
||
var length = array ? array.length : 0;
|
||
return length ? array[length - 1] : undefined;
|
||
}
|
||
|
||
module.exports = last;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],66:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/array/zipObject.js", module);
|
||
(function(){
|
||
var isArray = require('../lang/isArray');
|
||
|
||
/**
|
||
* The inverse of `_.pairs`; this method returns an object composed from arrays
|
||
* of property names and values. Provide either a single two dimensional array,
|
||
* e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names
|
||
* and one of corresponding values.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @alias object
|
||
* @category Array
|
||
* @param {Array} props The property names.
|
||
* @param {Array} [values=[]] The property values.
|
||
* @returns {Object} Returns the new object.
|
||
* @example
|
||
*
|
||
* _.zipObject([['fred', 30], ['barney', 40]]);
|
||
* // => { 'fred': 30, 'barney': 40 }
|
||
*
|
||
* _.zipObject(['fred', 'barney'], [30, 40]);
|
||
* // => { 'fred': 30, 'barney': 40 }
|
||
*/
|
||
function zipObject(props, values) {
|
||
var index = -1,
|
||
length = props ? props.length : 0,
|
||
result = {};
|
||
|
||
if (length && !values && !isArray(props[0])) {
|
||
values = [];
|
||
}
|
||
while (++index < length) {
|
||
var key = props[index];
|
||
if (values) {
|
||
result[key] = values[index];
|
||
} else if (key) {
|
||
result[key[0]] = key[1];
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
module.exports = zipObject;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../lang/isArray":120}],67:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/collection/filter.js", module);
|
||
(function(){
|
||
var arrayFilter = require('../internal/arrayFilter'),
|
||
baseCallback = require('../internal/baseCallback'),
|
||
baseFilter = require('../internal/baseFilter'),
|
||
isArray = require('../lang/isArray');
|
||
|
||
/**
|
||
* Iterates over elements of `collection`, returning an array of all elements
|
||
* `predicate` returns truthy for. The predicate is bound to `thisArg` and
|
||
* invoked with three arguments: (value, index|key, collection).
|
||
*
|
||
* If a property name is provided for `predicate` the created `_.property`
|
||
* style callback returns the property value of the given element.
|
||
*
|
||
* If a value is also provided for `thisArg` the created `_.matchesProperty`
|
||
* style callback returns `true` for elements that have a matching property
|
||
* value, else `false`.
|
||
*
|
||
* If an object is provided for `predicate` the created `_.matches` style
|
||
* callback returns `true` for elements that have the properties of the given
|
||
* object, else `false`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @alias select
|
||
* @category Collection
|
||
* @param {Array|Object|string} collection The collection to iterate over.
|
||
* @param {Function|Object|string} [predicate=_.identity] The function invoked
|
||
* per iteration.
|
||
* @param {*} [thisArg] The `this` binding of `predicate`.
|
||
* @returns {Array} Returns the new filtered array.
|
||
* @example
|
||
*
|
||
* _.filter([4, 5, 6], function(n) {
|
||
* return n % 2 == 0;
|
||
* });
|
||
* // => [4, 6]
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'age': 36, 'active': true },
|
||
* { 'user': 'fred', 'age': 40, 'active': false }
|
||
* ];
|
||
*
|
||
* // using the `_.matches` callback shorthand
|
||
* _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user');
|
||
* // => ['barney']
|
||
*
|
||
* // using the `_.matchesProperty` callback shorthand
|
||
* _.pluck(_.filter(users, 'active', false), 'user');
|
||
* // => ['fred']
|
||
*
|
||
* // using the `_.property` callback shorthand
|
||
* _.pluck(_.filter(users, 'active'), 'user');
|
||
* // => ['barney']
|
||
*/
|
||
function filter(collection, predicate, thisArg) {
|
||
var func = isArray(collection) ? arrayFilter : baseFilter;
|
||
predicate = baseCallback(predicate, thisArg, 3);
|
||
return func(collection, predicate);
|
||
}
|
||
|
||
module.exports = filter;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/arrayFilter":73,"../internal/baseCallback":78,"../internal/baseFilter":81,"../lang/isArray":120}],68:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/collection/forEach.js", module);
|
||
(function(){
|
||
var arrayEach = require('../internal/arrayEach'),
|
||
baseEach = require('../internal/baseEach'),
|
||
createForEach = require('../internal/createForEach');
|
||
|
||
/**
|
||
* Iterates over elements of `collection` invoking `iteratee` for each element.
|
||
* The `iteratee` is bound to `thisArg` and invoked with three arguments:
|
||
* (value, index|key, collection). Iteratee functions may exit iteration early
|
||
* by explicitly returning `false`.
|
||
*
|
||
* **Note:** As with other "Collections" methods, objects with a "length" property
|
||
* are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
|
||
* may be used for object iteration.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @alias each
|
||
* @category Collection
|
||
* @param {Array|Object|string} collection The collection to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @param {*} [thisArg] The `this` binding of `iteratee`.
|
||
* @returns {Array|Object|string} Returns `collection`.
|
||
* @example
|
||
*
|
||
* _([1, 2]).forEach(function(n) {
|
||
* console.log(n);
|
||
* }).value();
|
||
* // => logs each value from left to right and returns the array
|
||
*
|
||
* _.forEach({ 'a': 1, 'b': 2 }, function(n, key) {
|
||
* console.log(n, key);
|
||
* });
|
||
* // => logs each value-key pair and returns the object (iteration order is not guaranteed)
|
||
*/
|
||
var forEach = createForEach(arrayEach, baseEach);
|
||
|
||
module.exports = forEach;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/arrayEach":72,"../internal/baseEach":80,"../internal/createForEach":100}],69:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/collection/map.js", module);
|
||
(function(){
|
||
var arrayMap = require('../internal/arrayMap'),
|
||
baseCallback = require('../internal/baseCallback'),
|
||
baseMap = require('../internal/baseMap'),
|
||
isArray = require('../lang/isArray');
|
||
|
||
/**
|
||
* Creates an array of values by running each element in `collection` through
|
||
* `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three
|
||
* arguments: (value, index|key, collection).
|
||
*
|
||
* If a property name is provided for `iteratee` the created `_.property`
|
||
* style callback returns the property value of the given element.
|
||
*
|
||
* If a value is also provided for `thisArg` the created `_.matchesProperty`
|
||
* style callback returns `true` for elements that have a matching property
|
||
* value, else `false`.
|
||
*
|
||
* If an object is provided for `iteratee` the created `_.matches` style
|
||
* callback returns `true` for elements that have the properties of the given
|
||
* object, else `false`.
|
||
*
|
||
* Many lodash methods are guarded to work as iteratees for methods like
|
||
* `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
|
||
*
|
||
* The guarded methods are:
|
||
* `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`,
|
||
* `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`,
|
||
* `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`,
|
||
* `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`,
|
||
* `sum`, `uniq`, and `words`
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @alias collect
|
||
* @category Collection
|
||
* @param {Array|Object|string} collection The collection to iterate over.
|
||
* @param {Function|Object|string} [iteratee=_.identity] The function invoked
|
||
* per iteration.
|
||
* @param {*} [thisArg] The `this` binding of `iteratee`.
|
||
* @returns {Array} Returns the new mapped array.
|
||
* @example
|
||
*
|
||
* function timesThree(n) {
|
||
* return n * 3;
|
||
* }
|
||
*
|
||
* _.map([1, 2], timesThree);
|
||
* // => [3, 6]
|
||
*
|
||
* _.map({ 'a': 1, 'b': 2 }, timesThree);
|
||
* // => [3, 6] (iteration order is not guaranteed)
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney' },
|
||
* { 'user': 'fred' }
|
||
* ];
|
||
*
|
||
* // using the `_.property` callback shorthand
|
||
* _.map(users, 'user');
|
||
* // => ['barney', 'fred']
|
||
*/
|
||
function map(collection, iteratee, thisArg) {
|
||
var func = isArray(collection) ? arrayMap : baseMap;
|
||
iteratee = baseCallback(iteratee, thisArg, 3);
|
||
return func(collection, iteratee);
|
||
}
|
||
|
||
module.exports = map;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/arrayMap":74,"../internal/baseCallback":78,"../internal/baseMap":88,"../lang/isArray":120}],70:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/collection/some.js", module);
|
||
(function(){
|
||
var arraySome = require('../internal/arraySome'),
|
||
baseCallback = require('../internal/baseCallback'),
|
||
baseSome = require('../internal/baseSome'),
|
||
isArray = require('../lang/isArray'),
|
||
isIterateeCall = require('../internal/isIterateeCall');
|
||
|
||
/**
|
||
* Checks if `predicate` returns truthy for **any** element of `collection`.
|
||
* The function returns as soon as it finds a passing value and does not iterate
|
||
* over the entire collection. The predicate is bound to `thisArg` and invoked
|
||
* with three arguments: (value, index|key, collection).
|
||
*
|
||
* If a property name is provided for `predicate` the created `_.property`
|
||
* style callback returns the property value of the given element.
|
||
*
|
||
* If a value is also provided for `thisArg` the created `_.matchesProperty`
|
||
* style callback returns `true` for elements that have a matching property
|
||
* value, else `false`.
|
||
*
|
||
* If an object is provided for `predicate` the created `_.matches` style
|
||
* callback returns `true` for elements that have the properties of the given
|
||
* object, else `false`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @alias any
|
||
* @category Collection
|
||
* @param {Array|Object|string} collection The collection to iterate over.
|
||
* @param {Function|Object|string} [predicate=_.identity] The function invoked
|
||
* per iteration.
|
||
* @param {*} [thisArg] The `this` binding of `predicate`.
|
||
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
||
* else `false`.
|
||
* @example
|
||
*
|
||
* _.some([null, 0, 'yes', false], Boolean);
|
||
* // => true
|
||
*
|
||
* var users = [
|
||
* { 'user': 'barney', 'active': true },
|
||
* { 'user': 'fred', 'active': false }
|
||
* ];
|
||
*
|
||
* // using the `_.matches` callback shorthand
|
||
* _.some(users, { 'user': 'barney', 'active': false });
|
||
* // => false
|
||
*
|
||
* // using the `_.matchesProperty` callback shorthand
|
||
* _.some(users, 'active', false);
|
||
* // => true
|
||
*
|
||
* // using the `_.property` callback shorthand
|
||
* _.some(users, 'active');
|
||
* // => true
|
||
*/
|
||
function some(collection, predicate, thisArg) {
|
||
var func = isArray(collection) ? arraySome : baseSome;
|
||
if (thisArg && isIterateeCall(collection, predicate, thisArg)) {
|
||
predicate = undefined;
|
||
}
|
||
if (typeof predicate != 'function' || thisArg !== undefined) {
|
||
predicate = baseCallback(predicate, thisArg, 3);
|
||
}
|
||
return func(collection, predicate);
|
||
}
|
||
|
||
module.exports = some;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/arraySome":75,"../internal/baseCallback":78,"../internal/baseSome":94,"../internal/isIterateeCall":111,"../lang/isArray":120}],71:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/function/restParam.js", module);
|
||
(function(){
|
||
/** Used as the `TypeError` message for "Functions" methods. */
|
||
var FUNC_ERROR_TEXT = 'Expected a function';
|
||
|
||
/* Native method references for those with the same name as other `lodash` methods. */
|
||
var nativeMax = Math.max;
|
||
|
||
/**
|
||
* Creates a function that invokes `func` with the `this` binding of the
|
||
* created function and arguments from `start` and beyond provided as an array.
|
||
*
|
||
* **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Function
|
||
* @param {Function} func The function to apply a rest parameter to.
|
||
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
||
* @returns {Function} Returns the new function.
|
||
* @example
|
||
*
|
||
* var say = _.restParam(function(what, names) {
|
||
* return what + ' ' + _.initial(names).join(', ') +
|
||
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
|
||
* });
|
||
*
|
||
* say('hello', 'fred', 'barney', 'pebbles');
|
||
* // => 'hello fred, barney, & pebbles'
|
||
*/
|
||
function restParam(func, start) {
|
||
if (typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
|
||
return function() {
|
||
var args = arguments,
|
||
index = -1,
|
||
length = nativeMax(args.length - start, 0),
|
||
rest = Array(length);
|
||
|
||
while (++index < length) {
|
||
rest[index] = args[start + index];
|
||
}
|
||
switch (start) {
|
||
case 0: return func.call(this, rest);
|
||
case 1: return func.call(this, args[0], rest);
|
||
case 2: return func.call(this, args[0], args[1], rest);
|
||
}
|
||
var otherArgs = Array(start + 1);
|
||
index = -1;
|
||
while (++index < start) {
|
||
otherArgs[index] = args[index];
|
||
}
|
||
otherArgs[start] = rest;
|
||
return func.apply(this, otherArgs);
|
||
};
|
||
}
|
||
|
||
module.exports = restParam;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],72:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/arrayEach.js", module);
|
||
(function(){
|
||
/**
|
||
* A specialized version of `_.forEach` for arrays without support for callback
|
||
* shorthands and `this` binding.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Array} Returns `array`.
|
||
*/
|
||
function arrayEach(array, iteratee) {
|
||
var index = -1,
|
||
length = array.length;
|
||
|
||
while (++index < length) {
|
||
if (iteratee(array[index], index, array) === false) {
|
||
break;
|
||
}
|
||
}
|
||
return array;
|
||
}
|
||
|
||
module.exports = arrayEach;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],73:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/arrayFilter.js", module);
|
||
(function(){
|
||
/**
|
||
* A specialized version of `_.filter` for arrays without support for callback
|
||
* shorthands and `this` binding.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to iterate over.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @returns {Array} Returns the new filtered array.
|
||
*/
|
||
function arrayFilter(array, predicate) {
|
||
var index = -1,
|
||
length = array.length,
|
||
resIndex = -1,
|
||
result = [];
|
||
|
||
while (++index < length) {
|
||
var value = array[index];
|
||
if (predicate(value, index, array)) {
|
||
result[++resIndex] = value;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
module.exports = arrayFilter;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],74:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/arrayMap.js", module);
|
||
(function(){
|
||
/**
|
||
* A specialized version of `_.map` for arrays without support for callback
|
||
* shorthands and `this` binding.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Array} Returns the new mapped array.
|
||
*/
|
||
function arrayMap(array, iteratee) {
|
||
var index = -1,
|
||
length = array.length,
|
||
result = Array(length);
|
||
|
||
while (++index < length) {
|
||
result[index] = iteratee(array[index], index, array);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
module.exports = arrayMap;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],75:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/arraySome.js", module);
|
||
(function(){
|
||
/**
|
||
* A specialized version of `_.some` for arrays without support for callback
|
||
* shorthands and `this` binding.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to iterate over.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
||
* else `false`.
|
||
*/
|
||
function arraySome(array, predicate) {
|
||
var index = -1,
|
||
length = array.length;
|
||
|
||
while (++index < length) {
|
||
if (predicate(array[index], index, array)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
module.exports = arraySome;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],76:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/assignWith.js", module);
|
||
(function(){
|
||
var keys = require('../object/keys');
|
||
|
||
/**
|
||
* A specialized version of `_.assign` for customizing assigned values without
|
||
* support for argument juggling, multiple sources, and `this` binding `customizer`
|
||
* functions.
|
||
*
|
||
* @private
|
||
* @param {Object} object The destination object.
|
||
* @param {Object} source The source object.
|
||
* @param {Function} customizer The function to customize assigned values.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function assignWith(object, source, customizer) {
|
||
var index = -1,
|
||
props = keys(source),
|
||
length = props.length;
|
||
|
||
while (++index < length) {
|
||
var key = props[index],
|
||
value = object[key],
|
||
result = customizer(value, source[key], key, object, source);
|
||
|
||
if ((result === result ? (result !== value) : (value === value)) ||
|
||
(value === undefined && !(key in object))) {
|
||
object[key] = result;
|
||
}
|
||
}
|
||
return object;
|
||
}
|
||
|
||
module.exports = assignWith;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../object/keys":127}],77:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseAssign.js", module);
|
||
(function(){
|
||
var baseCopy = require('./baseCopy'),
|
||
keys = require('../object/keys');
|
||
|
||
/**
|
||
* The base implementation of `_.assign` without support for argument juggling,
|
||
* multiple sources, and `customizer` functions.
|
||
*
|
||
* @private
|
||
* @param {Object} object The destination object.
|
||
* @param {Object} source The source object.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function baseAssign(object, source) {
|
||
return source == null
|
||
? object
|
||
: baseCopy(source, keys(source), object);
|
||
}
|
||
|
||
module.exports = baseAssign;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../object/keys":127,"./baseCopy":79}],78:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseCallback.js", module);
|
||
(function(){
|
||
var baseMatches = require('./baseMatches'),
|
||
baseMatchesProperty = require('./baseMatchesProperty'),
|
||
bindCallback = require('./bindCallback'),
|
||
identity = require('../utility/identity'),
|
||
property = require('../utility/property');
|
||
|
||
/**
|
||
* The base implementation of `_.callback` which supports specifying the
|
||
* number of arguments to provide to `func`.
|
||
*
|
||
* @private
|
||
* @param {*} [func=_.identity] The value to convert to a callback.
|
||
* @param {*} [thisArg] The `this` binding of `func`.
|
||
* @param {number} [argCount] The number of arguments to provide to `func`.
|
||
* @returns {Function} Returns the callback.
|
||
*/
|
||
function baseCallback(func, thisArg, argCount) {
|
||
var type = typeof func;
|
||
if (type == 'function') {
|
||
return thisArg === undefined
|
||
? func
|
||
: bindCallback(func, thisArg, argCount);
|
||
}
|
||
if (func == null) {
|
||
return identity;
|
||
}
|
||
if (type == 'object') {
|
||
return baseMatches(func);
|
||
}
|
||
return thisArg === undefined
|
||
? property(func)
|
||
: baseMatchesProperty(func, thisArg);
|
||
}
|
||
|
||
module.exports = baseCallback;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../utility/identity":131,"../utility/property":132,"./baseMatches":89,"./baseMatchesProperty":90,"./bindCallback":96}],79:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseCopy.js", module);
|
||
(function(){
|
||
/**
|
||
* Copies properties of `source` to `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} source The object to copy properties from.
|
||
* @param {Array} props The property names to copy.
|
||
* @param {Object} [object={}] The object to copy properties to.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function baseCopy(source, props, object) {
|
||
object || (object = {});
|
||
|
||
var index = -1,
|
||
length = props.length;
|
||
|
||
while (++index < length) {
|
||
var key = props[index];
|
||
object[key] = source[key];
|
||
}
|
||
return object;
|
||
}
|
||
|
||
module.exports = baseCopy;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],80:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseEach.js", module);
|
||
(function(){
|
||
var baseForOwn = require('./baseForOwn'),
|
||
createBaseEach = require('./createBaseEach');
|
||
|
||
/**
|
||
* The base implementation of `_.forEach` without support for callback
|
||
* shorthands and `this` binding.
|
||
*
|
||
* @private
|
||
* @param {Array|Object|string} collection The collection to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Array|Object|string} Returns `collection`.
|
||
*/
|
||
var baseEach = createBaseEach(baseForOwn);
|
||
|
||
module.exports = baseEach;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./baseForOwn":83,"./createBaseEach":98}],81:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseFilter.js", module);
|
||
(function(){
|
||
var baseEach = require('./baseEach');
|
||
|
||
/**
|
||
* The base implementation of `_.filter` without support for callback
|
||
* shorthands and `this` binding.
|
||
*
|
||
* @private
|
||
* @param {Array|Object|string} collection The collection to iterate over.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @returns {Array} Returns the new filtered array.
|
||
*/
|
||
function baseFilter(collection, predicate) {
|
||
var result = [];
|
||
baseEach(collection, function(value, index, collection) {
|
||
if (predicate(value, index, collection)) {
|
||
result.push(value);
|
||
}
|
||
});
|
||
return result;
|
||
}
|
||
|
||
module.exports = baseFilter;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./baseEach":80}],82:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseFor.js", module);
|
||
(function(){
|
||
var createBaseFor = require('./createBaseFor');
|
||
|
||
/**
|
||
* The base implementation of `baseForIn` and `baseForOwn` which iterates
|
||
* over `object` properties returned by `keysFunc` invoking `iteratee` for
|
||
* each property. Iteratee functions may exit iteration early by explicitly
|
||
* returning `false`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @param {Function} keysFunc The function to get the keys of `object`.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
var baseFor = createBaseFor();
|
||
|
||
module.exports = baseFor;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./createBaseFor":99}],83:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseForOwn.js", module);
|
||
(function(){
|
||
var baseFor = require('./baseFor'),
|
||
keys = require('../object/keys');
|
||
|
||
/**
|
||
* The base implementation of `_.forOwn` without support for callback
|
||
* shorthands and `this` binding.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function baseForOwn(object, iteratee) {
|
||
return baseFor(object, iteratee, keys);
|
||
}
|
||
|
||
module.exports = baseForOwn;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../object/keys":127,"./baseFor":82}],84:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseGet.js", module);
|
||
(function(){
|
||
var toObject = require('./toObject');
|
||
|
||
/**
|
||
* The base implementation of `get` without support for string paths
|
||
* and default values.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @param {Array} path The path of the property to get.
|
||
* @param {string} [pathKey] The key representation of path.
|
||
* @returns {*} Returns the resolved value.
|
||
*/
|
||
function baseGet(object, path, pathKey) {
|
||
if (object == null) {
|
||
return;
|
||
}
|
||
if (pathKey !== undefined && pathKey in toObject(object)) {
|
||
path = [pathKey];
|
||
}
|
||
var index = 0,
|
||
length = path.length;
|
||
|
||
while (object != null && index < length) {
|
||
object = object[path[index++]];
|
||
}
|
||
return (index && index == length) ? object : undefined;
|
||
}
|
||
|
||
module.exports = baseGet;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./toObject":117}],85:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseIsEqual.js", module);
|
||
(function(){
|
||
var baseIsEqualDeep = require('./baseIsEqualDeep'),
|
||
isObject = require('../lang/isObject'),
|
||
isObjectLike = require('./isObjectLike');
|
||
|
||
/**
|
||
* The base implementation of `_.isEqual` without support for `this` binding
|
||
* `customizer` functions.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @param {Function} [customizer] The function to customize comparing values.
|
||
* @param {boolean} [isLoose] Specify performing partial comparisons.
|
||
* @param {Array} [stackA] Tracks traversed `value` objects.
|
||
* @param {Array} [stackB] Tracks traversed `other` objects.
|
||
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
||
*/
|
||
function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) {
|
||
if (value === other) {
|
||
return true;
|
||
}
|
||
if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
|
||
return value !== value && other !== other;
|
||
}
|
||
return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB);
|
||
}
|
||
|
||
module.exports = baseIsEqual;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../lang/isObject":123,"./baseIsEqualDeep":86,"./isObjectLike":114}],86:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseIsEqualDeep.js", module);
|
||
(function(){
|
||
var equalArrays = require('./equalArrays'),
|
||
equalByTag = require('./equalByTag'),
|
||
equalObjects = require('./equalObjects'),
|
||
isArray = require('../lang/isArray'),
|
||
isTypedArray = require('../lang/isTypedArray');
|
||
|
||
/** `Object#toString` result references. */
|
||
var argsTag = '[object Arguments]',
|
||
arrayTag = '[object Array]',
|
||
objectTag = '[object Object]';
|
||
|
||
/** Used for native method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/** Used to check objects for own properties. */
|
||
var hasOwnProperty = objectProto.hasOwnProperty;
|
||
|
||
/**
|
||
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
||
* of values.
|
||
*/
|
||
var objToString = objectProto.toString;
|
||
|
||
/**
|
||
* A specialized version of `baseIsEqual` for arrays and objects which performs
|
||
* deep comparisons and tracks traversed objects enabling objects with circular
|
||
* references to be compared.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to compare.
|
||
* @param {Object} other The other object to compare.
|
||
* @param {Function} equalFunc The function to determine equivalents of values.
|
||
* @param {Function} [customizer] The function to customize comparing objects.
|
||
* @param {boolean} [isLoose] Specify performing partial comparisons.
|
||
* @param {Array} [stackA=[]] Tracks traversed `value` objects.
|
||
* @param {Array} [stackB=[]] Tracks traversed `other` objects.
|
||
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
||
*/
|
||
function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
|
||
var objIsArr = isArray(object),
|
||
othIsArr = isArray(other),
|
||
objTag = arrayTag,
|
||
othTag = arrayTag;
|
||
|
||
if (!objIsArr) {
|
||
objTag = objToString.call(object);
|
||
if (objTag == argsTag) {
|
||
objTag = objectTag;
|
||
} else if (objTag != objectTag) {
|
||
objIsArr = isTypedArray(object);
|
||
}
|
||
}
|
||
if (!othIsArr) {
|
||
othTag = objToString.call(other);
|
||
if (othTag == argsTag) {
|
||
othTag = objectTag;
|
||
} else if (othTag != objectTag) {
|
||
othIsArr = isTypedArray(other);
|
||
}
|
||
}
|
||
var objIsObj = objTag == objectTag,
|
||
othIsObj = othTag == objectTag,
|
||
isSameTag = objTag == othTag;
|
||
|
||
if (isSameTag && !(objIsArr || objIsObj)) {
|
||
return equalByTag(object, other, objTag);
|
||
}
|
||
if (!isLoose) {
|
||
var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
|
||
othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
|
||
|
||
if (objIsWrapped || othIsWrapped) {
|
||
return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB);
|
||
}
|
||
}
|
||
if (!isSameTag) {
|
||
return false;
|
||
}
|
||
// Assume cyclic values are equal.
|
||
// For more information on detecting circular references see https://es5.github.io/#JO.
|
||
stackA || (stackA = []);
|
||
stackB || (stackB = []);
|
||
|
||
var length = stackA.length;
|
||
while (length--) {
|
||
if (stackA[length] == object) {
|
||
return stackB[length] == other;
|
||
}
|
||
}
|
||
// Add `object` and `other` to the stack of traversed objects.
|
||
stackA.push(object);
|
||
stackB.push(other);
|
||
|
||
var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB);
|
||
|
||
stackA.pop();
|
||
stackB.pop();
|
||
|
||
return result;
|
||
}
|
||
|
||
module.exports = baseIsEqualDeep;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../lang/isArray":120,"../lang/isTypedArray":124,"./equalArrays":103,"./equalByTag":104,"./equalObjects":105}],87:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseIsMatch.js", module);
|
||
(function(){
|
||
var baseIsEqual = require('./baseIsEqual'),
|
||
toObject = require('./toObject');
|
||
|
||
/**
|
||
* The base implementation of `_.isMatch` without support for callback
|
||
* shorthands and `this` binding.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to inspect.
|
||
* @param {Array} matchData The propery names, values, and compare flags to match.
|
||
* @param {Function} [customizer] The function to customize comparing objects.
|
||
* @returns {boolean} Returns `true` if `object` is a match, else `false`.
|
||
*/
|
||
function baseIsMatch(object, matchData, customizer) {
|
||
var index = matchData.length,
|
||
length = index,
|
||
noCustomizer = !customizer;
|
||
|
||
if (object == null) {
|
||
return !length;
|
||
}
|
||
object = toObject(object);
|
||
while (index--) {
|
||
var data = matchData[index];
|
||
if ((noCustomizer && data[2])
|
||
? data[1] !== object[data[0]]
|
||
: !(data[0] in object)
|
||
) {
|
||
return false;
|
||
}
|
||
}
|
||
while (++index < length) {
|
||
data = matchData[index];
|
||
var key = data[0],
|
||
objValue = object[key],
|
||
srcValue = data[1];
|
||
|
||
if (noCustomizer && data[2]) {
|
||
if (objValue === undefined && !(key in object)) {
|
||
return false;
|
||
}
|
||
} else {
|
||
var result = customizer ? customizer(objValue, srcValue, key) : undefined;
|
||
if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
module.exports = baseIsMatch;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./baseIsEqual":85,"./toObject":117}],88:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseMap.js", module);
|
||
(function(){
|
||
var baseEach = require('./baseEach'),
|
||
isArrayLike = require('./isArrayLike');
|
||
|
||
/**
|
||
* The base implementation of `_.map` without support for callback shorthands
|
||
* and `this` binding.
|
||
*
|
||
* @private
|
||
* @param {Array|Object|string} collection The collection to iterate over.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Array} Returns the new mapped array.
|
||
*/
|
||
function baseMap(collection, iteratee) {
|
||
var index = -1,
|
||
result = isArrayLike(collection) ? Array(collection.length) : [];
|
||
|
||
baseEach(collection, function(value, key, collection) {
|
||
result[++index] = iteratee(value, key, collection);
|
||
});
|
||
return result;
|
||
}
|
||
|
||
module.exports = baseMap;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./baseEach":80,"./isArrayLike":109}],89:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseMatches.js", module);
|
||
(function(){
|
||
var baseIsMatch = require('./baseIsMatch'),
|
||
getMatchData = require('./getMatchData'),
|
||
toObject = require('./toObject');
|
||
|
||
/**
|
||
* The base implementation of `_.matches` which does not clone `source`.
|
||
*
|
||
* @private
|
||
* @param {Object} source The object of property values to match.
|
||
* @returns {Function} Returns the new function.
|
||
*/
|
||
function baseMatches(source) {
|
||
var matchData = getMatchData(source);
|
||
if (matchData.length == 1 && matchData[0][2]) {
|
||
var key = matchData[0][0],
|
||
value = matchData[0][1];
|
||
|
||
return function(object) {
|
||
if (object == null) {
|
||
return false;
|
||
}
|
||
return object[key] === value && (value !== undefined || (key in toObject(object)));
|
||
};
|
||
}
|
||
return function(object) {
|
||
return baseIsMatch(object, matchData);
|
||
};
|
||
}
|
||
|
||
module.exports = baseMatches;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./baseIsMatch":87,"./getMatchData":107,"./toObject":117}],90:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseMatchesProperty.js", module);
|
||
(function(){
|
||
var baseGet = require('./baseGet'),
|
||
baseIsEqual = require('./baseIsEqual'),
|
||
baseSlice = require('./baseSlice'),
|
||
isArray = require('../lang/isArray'),
|
||
isKey = require('./isKey'),
|
||
isStrictComparable = require('./isStrictComparable'),
|
||
last = require('../array/last'),
|
||
toObject = require('./toObject'),
|
||
toPath = require('./toPath');
|
||
|
||
/**
|
||
* The base implementation of `_.matchesProperty` which does not clone `srcValue`.
|
||
*
|
||
* @private
|
||
* @param {string} path The path of the property to get.
|
||
* @param {*} srcValue The value to compare.
|
||
* @returns {Function} Returns the new function.
|
||
*/
|
||
function baseMatchesProperty(path, srcValue) {
|
||
var isArr = isArray(path),
|
||
isCommon = isKey(path) && isStrictComparable(srcValue),
|
||
pathKey = (path + '');
|
||
|
||
path = toPath(path);
|
||
return function(object) {
|
||
if (object == null) {
|
||
return false;
|
||
}
|
||
var key = pathKey;
|
||
object = toObject(object);
|
||
if ((isArr || !isCommon) && !(key in object)) {
|
||
object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
|
||
if (object == null) {
|
||
return false;
|
||
}
|
||
key = last(path);
|
||
object = toObject(object);
|
||
}
|
||
return object[key] === srcValue
|
||
? (srcValue !== undefined || (key in object))
|
||
: baseIsEqual(srcValue, object[key], undefined, true);
|
||
};
|
||
}
|
||
|
||
module.exports = baseMatchesProperty;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../array/last":65,"../lang/isArray":120,"./baseGet":84,"./baseIsEqual":85,"./baseSlice":93,"./isKey":112,"./isStrictComparable":115,"./toObject":117,"./toPath":118}],91:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseProperty.js", module);
|
||
(function(){
|
||
/**
|
||
* The base implementation of `_.property` without support for deep paths.
|
||
*
|
||
* @private
|
||
* @param {string} key The key of the property to get.
|
||
* @returns {Function} Returns the new function.
|
||
*/
|
||
function baseProperty(key) {
|
||
return function(object) {
|
||
return object == null ? undefined : object[key];
|
||
};
|
||
}
|
||
|
||
module.exports = baseProperty;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],92:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/basePropertyDeep.js", module);
|
||
(function(){
|
||
var baseGet = require('./baseGet'),
|
||
toPath = require('./toPath');
|
||
|
||
/**
|
||
* A specialized version of `baseProperty` which supports deep paths.
|
||
*
|
||
* @private
|
||
* @param {Array|string} path The path of the property to get.
|
||
* @returns {Function} Returns the new function.
|
||
*/
|
||
function basePropertyDeep(path) {
|
||
var pathKey = (path + '');
|
||
path = toPath(path);
|
||
return function(object) {
|
||
return baseGet(object, path, pathKey);
|
||
};
|
||
}
|
||
|
||
module.exports = basePropertyDeep;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./baseGet":84,"./toPath":118}],93:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseSlice.js", module);
|
||
(function(){
|
||
/**
|
||
* The base implementation of `_.slice` without an iteratee call guard.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to slice.
|
||
* @param {number} [start=0] The start position.
|
||
* @param {number} [end=array.length] The end position.
|
||
* @returns {Array} Returns the slice of `array`.
|
||
*/
|
||
function baseSlice(array, start, end) {
|
||
var index = -1,
|
||
length = array.length;
|
||
|
||
start = start == null ? 0 : (+start || 0);
|
||
if (start < 0) {
|
||
start = -start > length ? 0 : (length + start);
|
||
}
|
||
end = (end === undefined || end > length) ? length : (+end || 0);
|
||
if (end < 0) {
|
||
end += length;
|
||
}
|
||
length = start > end ? 0 : ((end - start) >>> 0);
|
||
start >>>= 0;
|
||
|
||
var result = Array(length);
|
||
while (++index < length) {
|
||
result[index] = array[index + start];
|
||
}
|
||
return result;
|
||
}
|
||
|
||
module.exports = baseSlice;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],94:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseSome.js", module);
|
||
(function(){
|
||
var baseEach = require('./baseEach');
|
||
|
||
/**
|
||
* The base implementation of `_.some` without support for callback shorthands
|
||
* and `this` binding.
|
||
*
|
||
* @private
|
||
* @param {Array|Object|string} collection The collection to iterate over.
|
||
* @param {Function} predicate The function invoked per iteration.
|
||
* @returns {boolean} Returns `true` if any element passes the predicate check,
|
||
* else `false`.
|
||
*/
|
||
function baseSome(collection, predicate) {
|
||
var result;
|
||
|
||
baseEach(collection, function(value, index, collection) {
|
||
result = predicate(value, index, collection);
|
||
return !result;
|
||
});
|
||
return !!result;
|
||
}
|
||
|
||
module.exports = baseSome;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./baseEach":80}],95:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/baseToString.js", module);
|
||
(function(){
|
||
/**
|
||
* Converts `value` to a string if it's not one. An empty string is returned
|
||
* for `null` or `undefined` values.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to process.
|
||
* @returns {string} Returns the string.
|
||
*/
|
||
function baseToString(value) {
|
||
return value == null ? '' : (value + '');
|
||
}
|
||
|
||
module.exports = baseToString;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],96:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/bindCallback.js", module);
|
||
(function(){
|
||
var identity = require('../utility/identity');
|
||
|
||
/**
|
||
* A specialized version of `baseCallback` which only supports `this` binding
|
||
* and specifying the number of arguments to provide to `func`.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to bind.
|
||
* @param {*} thisArg The `this` binding of `func`.
|
||
* @param {number} [argCount] The number of arguments to provide to `func`.
|
||
* @returns {Function} Returns the callback.
|
||
*/
|
||
function bindCallback(func, thisArg, argCount) {
|
||
if (typeof func != 'function') {
|
||
return identity;
|
||
}
|
||
if (thisArg === undefined) {
|
||
return func;
|
||
}
|
||
switch (argCount) {
|
||
case 1: return function(value) {
|
||
return func.call(thisArg, value);
|
||
};
|
||
case 3: return function(value, index, collection) {
|
||
return func.call(thisArg, value, index, collection);
|
||
};
|
||
case 4: return function(accumulator, value, index, collection) {
|
||
return func.call(thisArg, accumulator, value, index, collection);
|
||
};
|
||
case 5: return function(value, other, key, object, source) {
|
||
return func.call(thisArg, value, other, key, object, source);
|
||
};
|
||
}
|
||
return function() {
|
||
return func.apply(thisArg, arguments);
|
||
};
|
||
}
|
||
|
||
module.exports = bindCallback;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../utility/identity":131}],97:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/createAssigner.js", module);
|
||
(function(){
|
||
var bindCallback = require('./bindCallback'),
|
||
isIterateeCall = require('./isIterateeCall'),
|
||
restParam = require('../function/restParam');
|
||
|
||
/**
|
||
* Creates a `_.assign`, `_.defaults`, or `_.merge` function.
|
||
*
|
||
* @private
|
||
* @param {Function} assigner The function to assign values.
|
||
* @returns {Function} Returns the new assigner function.
|
||
*/
|
||
function createAssigner(assigner) {
|
||
return restParam(function(object, sources) {
|
||
var index = -1,
|
||
length = object == null ? 0 : sources.length,
|
||
customizer = length > 2 ? sources[length - 2] : undefined,
|
||
guard = length > 2 ? sources[2] : undefined,
|
||
thisArg = length > 1 ? sources[length - 1] : undefined;
|
||
|
||
if (typeof customizer == 'function') {
|
||
customizer = bindCallback(customizer, thisArg, 5);
|
||
length -= 2;
|
||
} else {
|
||
customizer = typeof thisArg == 'function' ? thisArg : undefined;
|
||
length -= (customizer ? 1 : 0);
|
||
}
|
||
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
||
customizer = length < 3 ? undefined : customizer;
|
||
length = 1;
|
||
}
|
||
while (++index < length) {
|
||
var source = sources[index];
|
||
if (source) {
|
||
assigner(object, source, customizer);
|
||
}
|
||
}
|
||
return object;
|
||
});
|
||
}
|
||
|
||
module.exports = createAssigner;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../function/restParam":71,"./bindCallback":96,"./isIterateeCall":111}],98:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/createBaseEach.js", module);
|
||
(function(){
|
||
var getLength = require('./getLength'),
|
||
isLength = require('./isLength'),
|
||
toObject = require('./toObject');
|
||
|
||
/**
|
||
* Creates a `baseEach` or `baseEachRight` function.
|
||
*
|
||
* @private
|
||
* @param {Function} eachFunc The function to iterate over a collection.
|
||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||
* @returns {Function} Returns the new base function.
|
||
*/
|
||
function createBaseEach(eachFunc, fromRight) {
|
||
return function(collection, iteratee) {
|
||
var length = collection ? getLength(collection) : 0;
|
||
if (!isLength(length)) {
|
||
return eachFunc(collection, iteratee);
|
||
}
|
||
var index = fromRight ? length : -1,
|
||
iterable = toObject(collection);
|
||
|
||
while ((fromRight ? index-- : ++index < length)) {
|
||
if (iteratee(iterable[index], index, iterable) === false) {
|
||
break;
|
||
}
|
||
}
|
||
return collection;
|
||
};
|
||
}
|
||
|
||
module.exports = createBaseEach;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./getLength":106,"./isLength":113,"./toObject":117}],99:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/createBaseFor.js", module);
|
||
(function(){
|
||
var toObject = require('./toObject');
|
||
|
||
/**
|
||
* Creates a base function for `_.forIn` or `_.forInRight`.
|
||
*
|
||
* @private
|
||
* @param {boolean} [fromRight] Specify iterating from right to left.
|
||
* @returns {Function} Returns the new base function.
|
||
*/
|
||
function createBaseFor(fromRight) {
|
||
return function(object, iteratee, keysFunc) {
|
||
var iterable = toObject(object),
|
||
props = keysFunc(object),
|
||
length = props.length,
|
||
index = fromRight ? length : -1;
|
||
|
||
while ((fromRight ? index-- : ++index < length)) {
|
||
var key = props[index];
|
||
if (iteratee(iterable[key], key, iterable) === false) {
|
||
break;
|
||
}
|
||
}
|
||
return object;
|
||
};
|
||
}
|
||
|
||
module.exports = createBaseFor;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./toObject":117}],100:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/createForEach.js", module);
|
||
(function(){
|
||
var bindCallback = require('./bindCallback'),
|
||
isArray = require('../lang/isArray');
|
||
|
||
/**
|
||
* Creates a function for `_.forEach` or `_.forEachRight`.
|
||
*
|
||
* @private
|
||
* @param {Function} arrayFunc The function to iterate over an array.
|
||
* @param {Function} eachFunc The function to iterate over a collection.
|
||
* @returns {Function} Returns the new each function.
|
||
*/
|
||
function createForEach(arrayFunc, eachFunc) {
|
||
return function(collection, iteratee, thisArg) {
|
||
return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection))
|
||
? arrayFunc(collection, iteratee)
|
||
: eachFunc(collection, bindCallback(iteratee, thisArg, 3));
|
||
};
|
||
}
|
||
|
||
module.exports = createForEach;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../lang/isArray":120,"./bindCallback":96}],101:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/createForOwn.js", module);
|
||
(function(){
|
||
var bindCallback = require('./bindCallback');
|
||
|
||
/**
|
||
* Creates a function for `_.forOwn` or `_.forOwnRight`.
|
||
*
|
||
* @private
|
||
* @param {Function} objectFunc The function to iterate over an object.
|
||
* @returns {Function} Returns the new each function.
|
||
*/
|
||
function createForOwn(objectFunc) {
|
||
return function(object, iteratee, thisArg) {
|
||
if (typeof iteratee != 'function' || thisArg !== undefined) {
|
||
iteratee = bindCallback(iteratee, thisArg, 3);
|
||
}
|
||
return objectFunc(object, iteratee);
|
||
};
|
||
}
|
||
|
||
module.exports = createForOwn;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./bindCallback":96}],102:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/createObjectMapper.js", module);
|
||
(function(){
|
||
var baseCallback = require('./baseCallback'),
|
||
baseForOwn = require('./baseForOwn');
|
||
|
||
/**
|
||
* Creates a function for `_.mapKeys` or `_.mapValues`.
|
||
*
|
||
* @private
|
||
* @param {boolean} [isMapKeys] Specify mapping keys instead of values.
|
||
* @returns {Function} Returns the new map function.
|
||
*/
|
||
function createObjectMapper(isMapKeys) {
|
||
return function(object, iteratee, thisArg) {
|
||
var result = {};
|
||
iteratee = baseCallback(iteratee, thisArg, 3);
|
||
|
||
baseForOwn(object, function(value, key, object) {
|
||
var mapped = iteratee(value, key, object);
|
||
key = isMapKeys ? mapped : key;
|
||
value = isMapKeys ? value : mapped;
|
||
result[key] = value;
|
||
});
|
||
return result;
|
||
};
|
||
}
|
||
|
||
module.exports = createObjectMapper;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./baseCallback":78,"./baseForOwn":83}],103:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/equalArrays.js", module);
|
||
(function(){
|
||
var arraySome = require('./arraySome');
|
||
|
||
/**
|
||
* A specialized version of `baseIsEqualDeep` for arrays with support for
|
||
* partial deep comparisons.
|
||
*
|
||
* @private
|
||
* @param {Array} array The array to compare.
|
||
* @param {Array} other The other array to compare.
|
||
* @param {Function} equalFunc The function to determine equivalents of values.
|
||
* @param {Function} [customizer] The function to customize comparing arrays.
|
||
* @param {boolean} [isLoose] Specify performing partial comparisons.
|
||
* @param {Array} [stackA] Tracks traversed `value` objects.
|
||
* @param {Array} [stackB] Tracks traversed `other` objects.
|
||
* @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
|
||
*/
|
||
function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) {
|
||
var index = -1,
|
||
arrLength = array.length,
|
||
othLength = other.length;
|
||
|
||
if (arrLength != othLength && !(isLoose && othLength > arrLength)) {
|
||
return false;
|
||
}
|
||
// Ignore non-index properties.
|
||
while (++index < arrLength) {
|
||
var arrValue = array[index],
|
||
othValue = other[index],
|
||
result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined;
|
||
|
||
if (result !== undefined) {
|
||
if (result) {
|
||
continue;
|
||
}
|
||
return false;
|
||
}
|
||
// Recursively compare arrays (susceptible to call stack limits).
|
||
if (isLoose) {
|
||
if (!arraySome(other, function(othValue) {
|
||
return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB);
|
||
})) {
|
||
return false;
|
||
}
|
||
} else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
module.exports = equalArrays;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./arraySome":75}],104:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/equalByTag.js", module);
|
||
(function(){
|
||
/** `Object#toString` result references. */
|
||
var boolTag = '[object Boolean]',
|
||
dateTag = '[object Date]',
|
||
errorTag = '[object Error]',
|
||
numberTag = '[object Number]',
|
||
regexpTag = '[object RegExp]',
|
||
stringTag = '[object String]';
|
||
|
||
/**
|
||
* A specialized version of `baseIsEqualDeep` for comparing objects of
|
||
* the same `toStringTag`.
|
||
*
|
||
* **Note:** This function only supports comparing values with tags of
|
||
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to compare.
|
||
* @param {Object} other The other object to compare.
|
||
* @param {string} tag The `toStringTag` of the objects to compare.
|
||
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
||
*/
|
||
function equalByTag(object, other, tag) {
|
||
switch (tag) {
|
||
case boolTag:
|
||
case dateTag:
|
||
// Coerce dates and booleans to numbers, dates to milliseconds and booleans
|
||
// to `1` or `0` treating invalid dates coerced to `NaN` as not equal.
|
||
return +object == +other;
|
||
|
||
case errorTag:
|
||
return object.name == other.name && object.message == other.message;
|
||
|
||
case numberTag:
|
||
// Treat `NaN` vs. `NaN` as equal.
|
||
return (object != +object)
|
||
? other != +other
|
||
: object == +other;
|
||
|
||
case regexpTag:
|
||
case stringTag:
|
||
// Coerce regexes to strings and treat strings primitives and string
|
||
// objects as equal. See https://es5.github.io/#x15.10.6.4 for more details.
|
||
return object == (other + '');
|
||
}
|
||
return false;
|
||
}
|
||
|
||
module.exports = equalByTag;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],105:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/equalObjects.js", module);
|
||
(function(){
|
||
var keys = require('../object/keys');
|
||
|
||
/** Used for native method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/** Used to check objects for own properties. */
|
||
var hasOwnProperty = objectProto.hasOwnProperty;
|
||
|
||
/**
|
||
* A specialized version of `baseIsEqualDeep` for objects with support for
|
||
* partial deep comparisons.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to compare.
|
||
* @param {Object} other The other object to compare.
|
||
* @param {Function} equalFunc The function to determine equivalents of values.
|
||
* @param {Function} [customizer] The function to customize comparing values.
|
||
* @param {boolean} [isLoose] Specify performing partial comparisons.
|
||
* @param {Array} [stackA] Tracks traversed `value` objects.
|
||
* @param {Array} [stackB] Tracks traversed `other` objects.
|
||
* @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
|
||
*/
|
||
function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) {
|
||
var objProps = keys(object),
|
||
objLength = objProps.length,
|
||
othProps = keys(other),
|
||
othLength = othProps.length;
|
||
|
||
if (objLength != othLength && !isLoose) {
|
||
return false;
|
||
}
|
||
var index = objLength;
|
||
while (index--) {
|
||
var key = objProps[index];
|
||
if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) {
|
||
return false;
|
||
}
|
||
}
|
||
var skipCtor = isLoose;
|
||
while (++index < objLength) {
|
||
key = objProps[index];
|
||
var objValue = object[key],
|
||
othValue = other[key],
|
||
result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined;
|
||
|
||
// Recursively compare objects (susceptible to call stack limits).
|
||
if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) {
|
||
return false;
|
||
}
|
||
skipCtor || (skipCtor = key == 'constructor');
|
||
}
|
||
if (!skipCtor) {
|
||
var objCtor = object.constructor,
|
||
othCtor = other.constructor;
|
||
|
||
// Non `Object` object instances with different constructors are not equal.
|
||
if (objCtor != othCtor &&
|
||
('constructor' in object && 'constructor' in other) &&
|
||
!(typeof objCtor == 'function' && objCtor instanceof objCtor &&
|
||
typeof othCtor == 'function' && othCtor instanceof othCtor)) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
module.exports = equalObjects;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../object/keys":127}],106:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/getLength.js", module);
|
||
(function(){
|
||
var baseProperty = require('./baseProperty');
|
||
|
||
/**
|
||
* Gets the "length" property value of `object`.
|
||
*
|
||
* **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
|
||
* that affects Safari on at least iOS 8.1-8.3 ARM64.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {*} Returns the "length" value.
|
||
*/
|
||
var getLength = baseProperty('length');
|
||
|
||
module.exports = getLength;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./baseProperty":91}],107:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/getMatchData.js", module);
|
||
(function(){
|
||
var isStrictComparable = require('./isStrictComparable'),
|
||
pairs = require('../object/pairs');
|
||
|
||
/**
|
||
* Gets the propery names, values, and compare flags of `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the match data of `object`.
|
||
*/
|
||
function getMatchData(object) {
|
||
var result = pairs(object),
|
||
length = result.length;
|
||
|
||
while (length--) {
|
||
result[length][2] = isStrictComparable(result[length][1]);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
module.exports = getMatchData;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../object/pairs":130,"./isStrictComparable":115}],108:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/getNative.js", module);
|
||
(function(){
|
||
var isNative = require('../lang/isNative');
|
||
|
||
/**
|
||
* Gets the native function at `key` of `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @param {string} key The key of the method to get.
|
||
* @returns {*} Returns the function if it's native, else `undefined`.
|
||
*/
|
||
function getNative(object, key) {
|
||
var value = object == null ? undefined : object[key];
|
||
return isNative(value) ? value : undefined;
|
||
}
|
||
|
||
module.exports = getNative;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../lang/isNative":122}],109:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/isArrayLike.js", module);
|
||
(function(){
|
||
var getLength = require('./getLength'),
|
||
isLength = require('./isLength');
|
||
|
||
/**
|
||
* Checks if `value` is array-like.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
||
*/
|
||
function isArrayLike(value) {
|
||
return value != null && isLength(getLength(value));
|
||
}
|
||
|
||
module.exports = isArrayLike;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./getLength":106,"./isLength":113}],110:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/isIndex.js", module);
|
||
(function(){
|
||
/** Used to detect unsigned integer values. */
|
||
var reIsUint = /^\d+$/;
|
||
|
||
/**
|
||
* Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
|
||
* of an array-like value.
|
||
*/
|
||
var MAX_SAFE_INTEGER = 9007199254740991;
|
||
|
||
/**
|
||
* Checks if `value` is a valid array-like index.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
||
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
||
*/
|
||
function isIndex(value, length) {
|
||
value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
|
||
length = length == null ? MAX_SAFE_INTEGER : length;
|
||
return value > -1 && value % 1 == 0 && value < length;
|
||
}
|
||
|
||
module.exports = isIndex;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],111:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/isIterateeCall.js", module);
|
||
(function(){
|
||
var isArrayLike = require('./isArrayLike'),
|
||
isIndex = require('./isIndex'),
|
||
isObject = require('../lang/isObject');
|
||
|
||
/**
|
||
* Checks if the provided arguments are from an iteratee call.
|
||
*
|
||
* @private
|
||
* @param {*} value The potential iteratee value argument.
|
||
* @param {*} index The potential iteratee index or key argument.
|
||
* @param {*} object The potential iteratee object argument.
|
||
* @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
|
||
*/
|
||
function isIterateeCall(value, index, object) {
|
||
if (!isObject(object)) {
|
||
return false;
|
||
}
|
||
var type = typeof index;
|
||
if (type == 'number'
|
||
? (isArrayLike(object) && isIndex(index, object.length))
|
||
: (type == 'string' && index in object)) {
|
||
var other = object[index];
|
||
return value === value ? (value === other) : (other !== other);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
module.exports = isIterateeCall;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../lang/isObject":123,"./isArrayLike":109,"./isIndex":110}],112:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/isKey.js", module);
|
||
(function(){
|
||
var isArray = require('../lang/isArray'),
|
||
toObject = require('./toObject');
|
||
|
||
/** Used to match property names within property paths. */
|
||
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,
|
||
reIsPlainProp = /^\w*$/;
|
||
|
||
/**
|
||
* Checks if `value` is a property name and not a property path.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @param {Object} [object] The object to query keys on.
|
||
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
|
||
*/
|
||
function isKey(value, object) {
|
||
var type = typeof value;
|
||
if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') {
|
||
return true;
|
||
}
|
||
if (isArray(value)) {
|
||
return false;
|
||
}
|
||
var result = !reIsDeepProp.test(value);
|
||
return result || (object != null && value in toObject(object));
|
||
}
|
||
|
||
module.exports = isKey;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../lang/isArray":120,"./toObject":117}],113:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/isLength.js", module);
|
||
(function(){
|
||
/**
|
||
* Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
|
||
* of an array-like value.
|
||
*/
|
||
var MAX_SAFE_INTEGER = 9007199254740991;
|
||
|
||
/**
|
||
* Checks if `value` is a valid array-like length.
|
||
*
|
||
* **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
||
*/
|
||
function isLength(value) {
|
||
return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
||
}
|
||
|
||
module.exports = isLength;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],114:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/isObjectLike.js", module);
|
||
(function(){
|
||
/**
|
||
* Checks if `value` is object-like.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
||
*/
|
||
function isObjectLike(value) {
|
||
return !!value && typeof value == 'object';
|
||
}
|
||
|
||
module.exports = isObjectLike;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],115:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/isStrictComparable.js", module);
|
||
(function(){
|
||
var isObject = require('../lang/isObject');
|
||
|
||
/**
|
||
* Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` if suitable for strict
|
||
* equality comparisons, else `false`.
|
||
*/
|
||
function isStrictComparable(value) {
|
||
return value === value && !isObject(value);
|
||
}
|
||
|
||
module.exports = isStrictComparable;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../lang/isObject":123}],116:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/shimKeys.js", module);
|
||
(function(){
|
||
var isArguments = require('../lang/isArguments'),
|
||
isArray = require('../lang/isArray'),
|
||
isIndex = require('./isIndex'),
|
||
isLength = require('./isLength'),
|
||
keysIn = require('../object/keysIn');
|
||
|
||
/** Used for native method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/** Used to check objects for own properties. */
|
||
var hasOwnProperty = objectProto.hasOwnProperty;
|
||
|
||
/**
|
||
* A fallback implementation of `Object.keys` which creates an array of the
|
||
* own enumerable property names of `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property names.
|
||
*/
|
||
function shimKeys(object) {
|
||
var props = keysIn(object),
|
||
propsLength = props.length,
|
||
length = propsLength && object.length;
|
||
|
||
var allowIndexes = !!length && isLength(length) &&
|
||
(isArray(object) || isArguments(object));
|
||
|
||
var index = -1,
|
||
result = [];
|
||
|
||
while (++index < propsLength) {
|
||
var key = props[index];
|
||
if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
|
||
result.push(key);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
module.exports = shimKeys;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../lang/isArguments":119,"../lang/isArray":120,"../object/keysIn":128,"./isIndex":110,"./isLength":113}],117:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/toObject.js", module);
|
||
(function(){
|
||
var isObject = require('../lang/isObject');
|
||
|
||
/**
|
||
* Converts `value` to an object if it's not one.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to process.
|
||
* @returns {Object} Returns the object.
|
||
*/
|
||
function toObject(value) {
|
||
return isObject(value) ? value : Object(value);
|
||
}
|
||
|
||
module.exports = toObject;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../lang/isObject":123}],118:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/internal/toPath.js", module);
|
||
(function(){
|
||
var baseToString = require('./baseToString'),
|
||
isArray = require('../lang/isArray');
|
||
|
||
/** Used to match property names within property paths. */
|
||
var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g;
|
||
|
||
/** Used to match backslashes in property paths. */
|
||
var reEscapeChar = /\\(\\)?/g;
|
||
|
||
/**
|
||
* Converts `value` to property path array if it's not one.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to process.
|
||
* @returns {Array} Returns the property path array.
|
||
*/
|
||
function toPath(value) {
|
||
if (isArray(value)) {
|
||
return value;
|
||
}
|
||
var result = [];
|
||
baseToString(value).replace(rePropName, function(match, number, quote, string) {
|
||
result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
|
||
});
|
||
return result;
|
||
}
|
||
|
||
module.exports = toPath;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../lang/isArray":120,"./baseToString":95}],119:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/lang/isArguments.js", module);
|
||
(function(){
|
||
var isArrayLike = require('../internal/isArrayLike'),
|
||
isObjectLike = require('../internal/isObjectLike');
|
||
|
||
/** Used for native method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/** Used to check objects for own properties. */
|
||
var hasOwnProperty = objectProto.hasOwnProperty;
|
||
|
||
/** Native method references. */
|
||
var propertyIsEnumerable = objectProto.propertyIsEnumerable;
|
||
|
||
/**
|
||
* Checks if `value` is classified as an `arguments` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
||
* @example
|
||
*
|
||
* _.isArguments(function() { return arguments; }());
|
||
* // => true
|
||
*
|
||
* _.isArguments([1, 2, 3]);
|
||
* // => false
|
||
*/
|
||
function isArguments(value) {
|
||
return isObjectLike(value) && isArrayLike(value) &&
|
||
hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
|
||
}
|
||
|
||
module.exports = isArguments;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/isArrayLike":109,"../internal/isObjectLike":114}],120:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/lang/isArray.js", module);
|
||
(function(){
|
||
var getNative = require('../internal/getNative'),
|
||
isLength = require('../internal/isLength'),
|
||
isObjectLike = require('../internal/isObjectLike');
|
||
|
||
/** `Object#toString` result references. */
|
||
var arrayTag = '[object Array]';
|
||
|
||
/** Used for native method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/**
|
||
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
||
* of values.
|
||
*/
|
||
var objToString = objectProto.toString;
|
||
|
||
/* Native method references for those with the same name as other `lodash` methods. */
|
||
var nativeIsArray = getNative(Array, 'isArray');
|
||
|
||
/**
|
||
* Checks if `value` is classified as an `Array` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
||
* @example
|
||
*
|
||
* _.isArray([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isArray(function() { return arguments; }());
|
||
* // => false
|
||
*/
|
||
var isArray = nativeIsArray || function(value) {
|
||
return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
|
||
};
|
||
|
||
module.exports = isArray;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/getNative":108,"../internal/isLength":113,"../internal/isObjectLike":114}],121:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/lang/isFunction.js", module);
|
||
(function(){
|
||
var isObject = require('./isObject');
|
||
|
||
/** `Object#toString` result references. */
|
||
var funcTag = '[object Function]';
|
||
|
||
/** Used for native method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/**
|
||
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
||
* of values.
|
||
*/
|
||
var objToString = objectProto.toString;
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `Function` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
||
* @example
|
||
*
|
||
* _.isFunction(_);
|
||
* // => true
|
||
*
|
||
* _.isFunction(/abc/);
|
||
* // => false
|
||
*/
|
||
function isFunction(value) {
|
||
// The use of `Object#toString` avoids issues with the `typeof` operator
|
||
// in older versions of Chrome and Safari which return 'function' for regexes
|
||
// and Safari 8 which returns 'object' for typed array constructors.
|
||
return isObject(value) && objToString.call(value) == funcTag;
|
||
}
|
||
|
||
module.exports = isFunction;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./isObject":123}],122:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/lang/isNative.js", module);
|
||
(function(){
|
||
var isFunction = require('./isFunction'),
|
||
isObjectLike = require('../internal/isObjectLike');
|
||
|
||
/** Used to detect host constructors (Safari > 5). */
|
||
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
||
|
||
/** Used for native method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/** Used to resolve the decompiled source of functions. */
|
||
var fnToString = Function.prototype.toString;
|
||
|
||
/** Used to check objects for own properties. */
|
||
var hasOwnProperty = objectProto.hasOwnProperty;
|
||
|
||
/** Used to detect if a method is native. */
|
||
var reIsNative = RegExp('^' +
|
||
fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
|
||
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
||
);
|
||
|
||
/**
|
||
* Checks if `value` is a native function.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a native function, else `false`.
|
||
* @example
|
||
*
|
||
* _.isNative(Array.prototype.push);
|
||
* // => true
|
||
*
|
||
* _.isNative(_);
|
||
* // => false
|
||
*/
|
||
function isNative(value) {
|
||
if (value == null) {
|
||
return false;
|
||
}
|
||
if (isFunction(value)) {
|
||
return reIsNative.test(fnToString.call(value));
|
||
}
|
||
return isObjectLike(value) && reIsHostCtor.test(value);
|
||
}
|
||
|
||
module.exports = isNative;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/isObjectLike":114,"./isFunction":121}],123:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/lang/isObject.js", module);
|
||
(function(){
|
||
/**
|
||
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
|
||
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
||
* @example
|
||
*
|
||
* _.isObject({});
|
||
* // => true
|
||
*
|
||
* _.isObject([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isObject(1);
|
||
* // => false
|
||
*/
|
||
function isObject(value) {
|
||
// Avoid a V8 JIT bug in Chrome 19-20.
|
||
// See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
|
||
var type = typeof value;
|
||
return !!value && (type == 'object' || type == 'function');
|
||
}
|
||
|
||
module.exports = isObject;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],124:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/lang/isTypedArray.js", module);
|
||
(function(){
|
||
var isLength = require('../internal/isLength'),
|
||
isObjectLike = require('../internal/isObjectLike');
|
||
|
||
/** `Object#toString` result references. */
|
||
var argsTag = '[object Arguments]',
|
||
arrayTag = '[object Array]',
|
||
boolTag = '[object Boolean]',
|
||
dateTag = '[object Date]',
|
||
errorTag = '[object Error]',
|
||
funcTag = '[object Function]',
|
||
mapTag = '[object Map]',
|
||
numberTag = '[object Number]',
|
||
objectTag = '[object Object]',
|
||
regexpTag = '[object RegExp]',
|
||
setTag = '[object Set]',
|
||
stringTag = '[object String]',
|
||
weakMapTag = '[object WeakMap]';
|
||
|
||
var arrayBufferTag = '[object ArrayBuffer]',
|
||
float32Tag = '[object Float32Array]',
|
||
float64Tag = '[object Float64Array]',
|
||
int8Tag = '[object Int8Array]',
|
||
int16Tag = '[object Int16Array]',
|
||
int32Tag = '[object Int32Array]',
|
||
uint8Tag = '[object Uint8Array]',
|
||
uint8ClampedTag = '[object Uint8ClampedArray]',
|
||
uint16Tag = '[object Uint16Array]',
|
||
uint32Tag = '[object Uint32Array]';
|
||
|
||
/** Used to identify `toStringTag` values of typed arrays. */
|
||
var typedArrayTags = {};
|
||
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
|
||
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
|
||
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
|
||
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
|
||
typedArrayTags[uint32Tag] = true;
|
||
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
|
||
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
|
||
typedArrayTags[dateTag] = typedArrayTags[errorTag] =
|
||
typedArrayTags[funcTag] = typedArrayTags[mapTag] =
|
||
typedArrayTags[numberTag] = typedArrayTags[objectTag] =
|
||
typedArrayTags[regexpTag] = typedArrayTags[setTag] =
|
||
typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;
|
||
|
||
/** Used for native method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/**
|
||
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
||
* of values.
|
||
*/
|
||
var objToString = objectProto.toString;
|
||
|
||
/**
|
||
* Checks if `value` is classified as a typed array.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
||
* @example
|
||
*
|
||
* _.isTypedArray(new Uint8Array);
|
||
* // => true
|
||
*
|
||
* _.isTypedArray([]);
|
||
* // => false
|
||
*/
|
||
function isTypedArray(value) {
|
||
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)];
|
||
}
|
||
|
||
module.exports = isTypedArray;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/isLength":113,"../internal/isObjectLike":114}],125:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/object/assign.js", module);
|
||
(function(){
|
||
var assignWith = require('../internal/assignWith'),
|
||
baseAssign = require('../internal/baseAssign'),
|
||
createAssigner = require('../internal/createAssigner');
|
||
|
||
/**
|
||
* Assigns own enumerable properties of source object(s) to the destination
|
||
* object. Subsequent sources overwrite property assignments of previous sources.
|
||
* If `customizer` is provided it's invoked to produce the assigned values.
|
||
* The `customizer` is bound to `thisArg` and invoked with five arguments:
|
||
* (objectValue, sourceValue, key, object, source).
|
||
*
|
||
* **Note:** This method mutates `object` and is based on
|
||
* [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @alias extend
|
||
* @category Object
|
||
* @param {Object} object The destination object.
|
||
* @param {...Object} [sources] The source objects.
|
||
* @param {Function} [customizer] The function to customize assigned values.
|
||
* @param {*} [thisArg] The `this` binding of `customizer`.
|
||
* @returns {Object} Returns `object`.
|
||
* @example
|
||
*
|
||
* _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' });
|
||
* // => { 'user': 'fred', 'age': 40 }
|
||
*
|
||
* // using a customizer callback
|
||
* var defaults = _.partialRight(_.assign, function(value, other) {
|
||
* return _.isUndefined(value) ? other : value;
|
||
* });
|
||
*
|
||
* defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
|
||
* // => { 'user': 'barney', 'age': 36 }
|
||
*/
|
||
var assign = createAssigner(function(object, source, customizer) {
|
||
return customizer
|
||
? assignWith(object, source, customizer)
|
||
: baseAssign(object, source);
|
||
});
|
||
|
||
module.exports = assign;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/assignWith":76,"../internal/baseAssign":77,"../internal/createAssigner":97}],126:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/object/forOwn.js", module);
|
||
(function(){
|
||
var baseForOwn = require('../internal/baseForOwn'),
|
||
createForOwn = require('../internal/createForOwn');
|
||
|
||
/**
|
||
* Iterates over own enumerable properties of an object invoking `iteratee`
|
||
* for each property. The `iteratee` is bound to `thisArg` and invoked with
|
||
* three arguments: (value, key, object). Iteratee functions may exit iteration
|
||
* early by explicitly returning `false`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
|
||
* @param {*} [thisArg] The `this` binding of `iteratee`.
|
||
* @returns {Object} Returns `object`.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.forOwn(new Foo, function(value, key) {
|
||
* console.log(key);
|
||
* });
|
||
* // => logs 'a' and 'b' (iteration order is not guaranteed)
|
||
*/
|
||
var forOwn = createForOwn(baseForOwn);
|
||
|
||
module.exports = forOwn;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/baseForOwn":83,"../internal/createForOwn":101}],127:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/object/keys.js", module);
|
||
(function(){
|
||
var getNative = require('../internal/getNative'),
|
||
isArrayLike = require('../internal/isArrayLike'),
|
||
isObject = require('../lang/isObject'),
|
||
shimKeys = require('../internal/shimKeys');
|
||
|
||
/* Native method references for those with the same name as other `lodash` methods. */
|
||
var nativeKeys = getNative(Object, 'keys');
|
||
|
||
/**
|
||
* Creates an array of the own enumerable property names of `object`.
|
||
*
|
||
* **Note:** Non-object values are coerced to objects. See the
|
||
* [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
|
||
* for more details.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property names.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.keys(new Foo);
|
||
* // => ['a', 'b'] (iteration order is not guaranteed)
|
||
*
|
||
* _.keys('hi');
|
||
* // => ['0', '1']
|
||
*/
|
||
var keys = !nativeKeys ? shimKeys : function(object) {
|
||
var Ctor = object == null ? undefined : object.constructor;
|
||
if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
|
||
(typeof object != 'function' && isArrayLike(object))) {
|
||
return shimKeys(object);
|
||
}
|
||
return isObject(object) ? nativeKeys(object) : [];
|
||
};
|
||
|
||
module.exports = keys;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/getNative":108,"../internal/isArrayLike":109,"../internal/shimKeys":116,"../lang/isObject":123}],128:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/object/keysIn.js", module);
|
||
(function(){
|
||
var isArguments = require('../lang/isArguments'),
|
||
isArray = require('../lang/isArray'),
|
||
isIndex = require('../internal/isIndex'),
|
||
isLength = require('../internal/isLength'),
|
||
isObject = require('../lang/isObject');
|
||
|
||
/** Used for native method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/** Used to check objects for own properties. */
|
||
var hasOwnProperty = objectProto.hasOwnProperty;
|
||
|
||
/**
|
||
* Creates an array of the own and inherited enumerable property names of `object`.
|
||
*
|
||
* **Note:** Non-object values are coerced to objects.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property names.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.keysIn(new Foo);
|
||
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
|
||
*/
|
||
function keysIn(object) {
|
||
if (object == null) {
|
||
return [];
|
||
}
|
||
if (!isObject(object)) {
|
||
object = Object(object);
|
||
}
|
||
var length = object.length;
|
||
length = (length && isLength(length) &&
|
||
(isArray(object) || isArguments(object)) && length) || 0;
|
||
|
||
var Ctor = object.constructor,
|
||
index = -1,
|
||
isProto = typeof Ctor == 'function' && Ctor.prototype === object,
|
||
result = Array(length),
|
||
skipIndexes = length > 0;
|
||
|
||
while (++index < length) {
|
||
result[index] = (index + '');
|
||
}
|
||
for (var key in object) {
|
||
if (!(skipIndexes && isIndex(key, length)) &&
|
||
!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
|
||
result.push(key);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
module.exports = keysIn;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/isIndex":110,"../internal/isLength":113,"../lang/isArguments":119,"../lang/isArray":120,"../lang/isObject":123}],129:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/object/mapValues.js", module);
|
||
(function(){
|
||
var createObjectMapper = require('../internal/createObjectMapper');
|
||
|
||
/**
|
||
* Creates an object with the same keys as `object` and values generated by
|
||
* running each own enumerable property of `object` through `iteratee`. The
|
||
* iteratee function is bound to `thisArg` and invoked with three arguments:
|
||
* (value, key, object).
|
||
*
|
||
* If a property name is provided for `iteratee` the created `_.property`
|
||
* style callback returns the property value of the given element.
|
||
*
|
||
* If a value is also provided for `thisArg` the created `_.matchesProperty`
|
||
* style callback returns `true` for elements that have a matching property
|
||
* value, else `false`.
|
||
*
|
||
* If an object is provided for `iteratee` the created `_.matches` style
|
||
* callback returns `true` for elements that have the properties of the given
|
||
* object, else `false`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The object to iterate over.
|
||
* @param {Function|Object|string} [iteratee=_.identity] The function invoked
|
||
* per iteration.
|
||
* @param {*} [thisArg] The `this` binding of `iteratee`.
|
||
* @returns {Object} Returns the new mapped object.
|
||
* @example
|
||
*
|
||
* _.mapValues({ 'a': 1, 'b': 2 }, function(n) {
|
||
* return n * 3;
|
||
* });
|
||
* // => { 'a': 3, 'b': 6 }
|
||
*
|
||
* var users = {
|
||
* 'fred': { 'user': 'fred', 'age': 40 },
|
||
* 'pebbles': { 'user': 'pebbles', 'age': 1 }
|
||
* };
|
||
*
|
||
* // using the `_.property` callback shorthand
|
||
* _.mapValues(users, 'age');
|
||
* // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
|
||
*/
|
||
var mapValues = createObjectMapper();
|
||
|
||
module.exports = mapValues;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/createObjectMapper":102}],130:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/object/pairs.js", module);
|
||
(function(){
|
||
var keys = require('./keys'),
|
||
toObject = require('../internal/toObject');
|
||
|
||
/**
|
||
* Creates a two dimensional array of the key-value pairs for `object`,
|
||
* e.g. `[[key1, value1], [key2, value2]]`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the new array of key-value pairs.
|
||
* @example
|
||
*
|
||
* _.pairs({ 'barney': 36, 'fred': 40 });
|
||
* // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed)
|
||
*/
|
||
function pairs(object) {
|
||
object = toObject(object);
|
||
|
||
var index = -1,
|
||
props = keys(object),
|
||
length = props.length,
|
||
result = Array(length);
|
||
|
||
while (++index < length) {
|
||
var key = props[index];
|
||
result[index] = [key, object[key]];
|
||
}
|
||
return result;
|
||
}
|
||
|
||
module.exports = pairs;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/toObject":117,"./keys":127}],131:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/utility/identity.js", module);
|
||
(function(){
|
||
/**
|
||
* This method returns the first argument provided to it.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Utility
|
||
* @param {*} value Any value.
|
||
* @returns {*} Returns `value`.
|
||
* @example
|
||
*
|
||
* var object = { 'user': 'fred' };
|
||
*
|
||
* _.identity(object) === object;
|
||
* // => true
|
||
*/
|
||
function identity(value) {
|
||
return value;
|
||
}
|
||
|
||
module.exports = identity;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],132:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/lodash/utility/property.js", module);
|
||
(function(){
|
||
var baseProperty = require('../internal/baseProperty'),
|
||
basePropertyDeep = require('../internal/basePropertyDeep'),
|
||
isKey = require('../internal/isKey');
|
||
|
||
/**
|
||
* Creates a function that returns the property value at `path` on a
|
||
* given object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Utility
|
||
* @param {Array|string} path The path of the property to get.
|
||
* @returns {Function} Returns the new function.
|
||
* @example
|
||
*
|
||
* var objects = [
|
||
* { 'a': { 'b': { 'c': 2 } } },
|
||
* { 'a': { 'b': { 'c': 1 } } }
|
||
* ];
|
||
*
|
||
* _.map(objects, _.property('a.b.c'));
|
||
* // => [2, 1]
|
||
*
|
||
* _.pluck(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
|
||
* // => [1, 2]
|
||
*/
|
||
function property(path) {
|
||
return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
|
||
}
|
||
|
||
module.exports = property;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"../internal/baseProperty":91,"../internal/basePropertyDeep":92,"../internal/isKey":112}],133:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/ms/index.js", module);
|
||
(function(){
|
||
/**
|
||
* Helpers.
|
||
*/
|
||
|
||
var s = 1000;
|
||
var m = s * 60;
|
||
var h = m * 60;
|
||
var d = h * 24;
|
||
var y = d * 365.25;
|
||
|
||
/**
|
||
* Parse or format the given `val`.
|
||
*
|
||
* Options:
|
||
*
|
||
* - `long` verbose formatting [false]
|
||
*
|
||
* @param {String|Number} val
|
||
* @param {Object} options
|
||
* @return {String|Number}
|
||
* @api public
|
||
*/
|
||
|
||
module.exports = function(val, options){
|
||
options = options || {};
|
||
if ('string' == typeof val) return parse(val);
|
||
return options.long
|
||
? long(val)
|
||
: short(val);
|
||
};
|
||
|
||
/**
|
||
* Parse the given `str` and return milliseconds.
|
||
*
|
||
* @param {String} str
|
||
* @return {Number}
|
||
* @api private
|
||
*/
|
||
|
||
function parse(str) {
|
||
str = '' + str;
|
||
if (str.length > 10000) return;
|
||
var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);
|
||
if (!match) return;
|
||
var n = parseFloat(match[1]);
|
||
var type = (match[2] || 'ms').toLowerCase();
|
||
switch (type) {
|
||
case 'years':
|
||
case 'year':
|
||
case 'yrs':
|
||
case 'yr':
|
||
case 'y':
|
||
return n * y;
|
||
case 'days':
|
||
case 'day':
|
||
case 'd':
|
||
return n * d;
|
||
case 'hours':
|
||
case 'hour':
|
||
case 'hrs':
|
||
case 'hr':
|
||
case 'h':
|
||
return n * h;
|
||
case 'minutes':
|
||
case 'minute':
|
||
case 'mins':
|
||
case 'min':
|
||
case 'm':
|
||
return n * m;
|
||
case 'seconds':
|
||
case 'second':
|
||
case 'secs':
|
||
case 'sec':
|
||
case 's':
|
||
return n * s;
|
||
case 'milliseconds':
|
||
case 'millisecond':
|
||
case 'msecs':
|
||
case 'msec':
|
||
case 'ms':
|
||
return n;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Short format for `ms`.
|
||
*
|
||
* @param {Number} ms
|
||
* @return {String}
|
||
* @api private
|
||
*/
|
||
|
||
function short(ms) {
|
||
if (ms >= d) return Math.round(ms / d) + 'd';
|
||
if (ms >= h) return Math.round(ms / h) + 'h';
|
||
if (ms >= m) return Math.round(ms / m) + 'm';
|
||
if (ms >= s) return Math.round(ms / s) + 's';
|
||
return ms + 'ms';
|
||
}
|
||
|
||
/**
|
||
* Long format for `ms`.
|
||
*
|
||
* @param {Number} ms
|
||
* @return {String}
|
||
* @api private
|
||
*/
|
||
|
||
function long(ms) {
|
||
return plural(ms, d, 'day')
|
||
|| plural(ms, h, 'hour')
|
||
|| plural(ms, m, 'minute')
|
||
|| plural(ms, s, 'second')
|
||
|| ms + ' ms';
|
||
}
|
||
|
||
/**
|
||
* Pluralization helper.
|
||
*/
|
||
|
||
function plural(ms, n, name) {
|
||
if (ms < n) return;
|
||
if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
|
||
return Math.ceil(ms / n) + ' ' + name + 's';
|
||
}
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],134:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/parsejson/index.js", module);
|
||
(function(){
|
||
(function (global){
|
||
/**
|
||
* JSON parse.
|
||
*
|
||
* @see Based on jQuery#parseJSON (MIT) and JSON2
|
||
* @api private
|
||
*/
|
||
|
||
var rvalidchars = /^[\],:{}\s]*$/;
|
||
var rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
|
||
var rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
|
||
var rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g;
|
||
var rtrimLeft = /^\s+/;
|
||
var rtrimRight = /\s+$/;
|
||
|
||
module.exports = function parsejson(data) {
|
||
if ('string' != typeof data || !data) {
|
||
return null;
|
||
}
|
||
|
||
data = data.replace(rtrimLeft, '').replace(rtrimRight, '');
|
||
|
||
// Attempt to parse using the native JSON parser first
|
||
if (global.JSON && JSON.parse) {
|
||
return JSON.parse(data);
|
||
}
|
||
|
||
if (rvalidchars.test(data.replace(rvalidescape, '@')
|
||
.replace(rvalidtokens, ']')
|
||
.replace(rvalidbraces, ''))) {
|
||
return (new Function('return ' + data))();
|
||
}
|
||
};
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],135:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/parseqs/index.js", module);
|
||
(function(){
|
||
/**
|
||
* Compiles a querystring
|
||
* Returns string representation of the object
|
||
*
|
||
* @param {Object}
|
||
* @api private
|
||
*/
|
||
|
||
exports.encode = function (obj) {
|
||
var str = '';
|
||
|
||
for (var i in obj) {
|
||
if (obj.hasOwnProperty(i)) {
|
||
if (str.length) str += '&';
|
||
str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);
|
||
}
|
||
}
|
||
|
||
return str;
|
||
};
|
||
|
||
/**
|
||
* Parses a simple querystring into an object
|
||
*
|
||
* @param {String} qs
|
||
* @api private
|
||
*/
|
||
|
||
exports.decode = function(qs){
|
||
var qry = {};
|
||
var pairs = qs.split('&');
|
||
for (var i = 0, l = pairs.length; i < l; i++) {
|
||
var pair = pairs[i].split('=');
|
||
qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
|
||
}
|
||
return qry;
|
||
};
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],136:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/parseuri/index.js", module);
|
||
(function(){
|
||
/**
|
||
* Parses an URI
|
||
*
|
||
* @author Steven Levithan <stevenlevithan.com> (MIT license)
|
||
* @api private
|
||
*/
|
||
|
||
var re = /^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;
|
||
|
||
var parts = [
|
||
'source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'
|
||
];
|
||
|
||
module.exports = function parseuri(str) {
|
||
var src = str,
|
||
b = str.indexOf('['),
|
||
e = str.indexOf(']');
|
||
|
||
if (b != -1 && e != -1) {
|
||
str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);
|
||
}
|
||
|
||
var m = re.exec(str || ''),
|
||
uri = {},
|
||
i = 14;
|
||
|
||
while (i--) {
|
||
uri[parts[i]] = m[i] || '';
|
||
}
|
||
|
||
if (b != -1 && e != -1) {
|
||
uri.source = src;
|
||
uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');
|
||
uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');
|
||
uri.ipv6uri = true;
|
||
}
|
||
|
||
return uri;
|
||
};
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],137:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/process/browser.js", module);
|
||
(function(){
|
||
// shim for using process in browser
|
||
|
||
var process = module.exports = {};
|
||
var queue = [];
|
||
var draining = false;
|
||
var currentQueue;
|
||
var queueIndex = -1;
|
||
|
||
function cleanUpNextTick() {
|
||
draining = false;
|
||
if (currentQueue.length) {
|
||
queue = currentQueue.concat(queue);
|
||
} else {
|
||
queueIndex = -1;
|
||
}
|
||
if (queue.length) {
|
||
drainQueue();
|
||
}
|
||
}
|
||
|
||
function drainQueue() {
|
||
if (draining) {
|
||
return;
|
||
}
|
||
var timeout = setTimeout(cleanUpNextTick);
|
||
draining = true;
|
||
|
||
var len = queue.length;
|
||
while(len) {
|
||
currentQueue = queue;
|
||
queue = [];
|
||
while (++queueIndex < len) {
|
||
if (currentQueue) {
|
||
currentQueue[queueIndex].run();
|
||
}
|
||
}
|
||
queueIndex = -1;
|
||
len = queue.length;
|
||
}
|
||
currentQueue = null;
|
||
draining = false;
|
||
clearTimeout(timeout);
|
||
}
|
||
|
||
process.nextTick = function (fun) {
|
||
var args = new Array(arguments.length - 1);
|
||
if (arguments.length > 1) {
|
||
for (var i = 1; i < arguments.length; i++) {
|
||
args[i - 1] = arguments[i];
|
||
}
|
||
}
|
||
queue.push(new Item(fun, args));
|
||
if (queue.length === 1 && !draining) {
|
||
setTimeout(drainQueue, 0);
|
||
}
|
||
};
|
||
|
||
// v8 likes predictible objects
|
||
function Item(fun, array) {
|
||
this.fun = fun;
|
||
this.array = array;
|
||
}
|
||
Item.prototype.run = function () {
|
||
this.fun.apply(null, this.array);
|
||
};
|
||
process.title = 'browser';
|
||
process.browser = true;
|
||
process.env = {};
|
||
process.argv = [];
|
||
process.version = ''; // empty string to avoid regexp issues
|
||
process.versions = {};
|
||
|
||
function noop() {}
|
||
|
||
process.on = noop;
|
||
process.addListener = noop;
|
||
process.once = noop;
|
||
process.off = noop;
|
||
process.removeListener = noop;
|
||
process.removeAllListeners = noop;
|
||
process.emit = noop;
|
||
|
||
process.binding = function (name) {
|
||
throw new Error('process.binding is not supported');
|
||
};
|
||
|
||
process.cwd = function () { return '/' };
|
||
process.chdir = function (dir) {
|
||
throw new Error('process.chdir is not supported');
|
||
};
|
||
process.umask = function() { return 0; };
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],138:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/socket.io-client/lib/index.js", module);
|
||
(function(){
|
||
|
||
/**
|
||
* Module dependencies.
|
||
*/
|
||
|
||
var url = require('./url');
|
||
var parser = require('socket.io-parser');
|
||
var Manager = require('./manager');
|
||
var debug = require('debug')('socket.io-client');
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = exports = lookup;
|
||
|
||
/**
|
||
* Managers cache.
|
||
*/
|
||
|
||
var cache = exports.managers = {};
|
||
|
||
/**
|
||
* Looks up an existing `Manager` for multiplexing.
|
||
* If the user summons:
|
||
*
|
||
* `io('http://localhost/a');`
|
||
* `io('http://localhost/b');`
|
||
*
|
||
* We reuse the existing instance based on same scheme/port/host,
|
||
* and we initialize sockets for each namespace.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
function lookup(uri, opts) {
|
||
if (typeof uri == 'object') {
|
||
opts = uri;
|
||
uri = undefined;
|
||
}
|
||
|
||
opts = opts || {};
|
||
|
||
var parsed = url(uri);
|
||
var source = parsed.source;
|
||
var id = parsed.id;
|
||
var path = parsed.path;
|
||
var sameNamespace = cache[id] && path in cache[id].nsps;
|
||
var newConnection = opts.forceNew || opts['force new connection'] ||
|
||
false === opts.multiplex || sameNamespace;
|
||
|
||
var io;
|
||
|
||
if (newConnection) {
|
||
debug('ignoring socket cache for %s', source);
|
||
io = Manager(source, opts);
|
||
} else {
|
||
if (!cache[id]) {
|
||
debug('new io instance for %s', source);
|
||
cache[id] = Manager(source, opts);
|
||
}
|
||
io = cache[id];
|
||
}
|
||
|
||
return io.socket(parsed.path);
|
||
}
|
||
|
||
/**
|
||
* Protocol version.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.protocol = parser.protocol;
|
||
|
||
/**
|
||
* `connect`.
|
||
*
|
||
* @param {String} uri
|
||
* @api public
|
||
*/
|
||
|
||
exports.connect = lookup;
|
||
|
||
/**
|
||
* Expose constructors for standalone build.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.Manager = require('./manager');
|
||
exports.Socket = require('./socket');
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./manager":139,"./socket":141,"./url":142,"debug":46,"socket.io-parser":145}],139:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/socket.io-client/lib/manager.js", module);
|
||
(function(){
|
||
|
||
/**
|
||
* Module dependencies.
|
||
*/
|
||
|
||
var eio = require('engine.io-client');
|
||
var Socket = require('./socket');
|
||
var Emitter = require('component-emitter');
|
||
var parser = require('socket.io-parser');
|
||
var on = require('./on');
|
||
var bind = require('component-bind');
|
||
var debug = require('debug')('socket.io-client:manager');
|
||
var indexOf = require('indexof');
|
||
var Backoff = require('backo2');
|
||
|
||
/**
|
||
* IE6+ hasOwnProperty
|
||
*/
|
||
|
||
var has = Object.prototype.hasOwnProperty;
|
||
|
||
/**
|
||
* Module exports
|
||
*/
|
||
|
||
module.exports = Manager;
|
||
|
||
/**
|
||
* `Manager` constructor.
|
||
*
|
||
* @param {String} engine instance or engine uri/opts
|
||
* @param {Object} options
|
||
* @api public
|
||
*/
|
||
|
||
function Manager(uri, opts){
|
||
if (!(this instanceof Manager)) return new Manager(uri, opts);
|
||
if (uri && ('object' == typeof uri)) {
|
||
opts = uri;
|
||
uri = undefined;
|
||
}
|
||
opts = opts || {};
|
||
|
||
opts.path = opts.path || '/socket.io';
|
||
this.nsps = {};
|
||
this.subs = [];
|
||
this.opts = opts;
|
||
this.reconnection(opts.reconnection !== false);
|
||
this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);
|
||
this.reconnectionDelay(opts.reconnectionDelay || 1000);
|
||
this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
|
||
this.randomizationFactor(opts.randomizationFactor || 0.5);
|
||
this.backoff = new Backoff({
|
||
min: this.reconnectionDelay(),
|
||
max: this.reconnectionDelayMax(),
|
||
jitter: this.randomizationFactor()
|
||
});
|
||
this.timeout(null == opts.timeout ? 20000 : opts.timeout);
|
||
this.readyState = 'closed';
|
||
this.uri = uri;
|
||
this.connecting = [];
|
||
this.lastPing = null;
|
||
this.encoding = false;
|
||
this.packetBuffer = [];
|
||
this.encoder = new parser.Encoder();
|
||
this.decoder = new parser.Decoder();
|
||
this.autoConnect = opts.autoConnect !== false;
|
||
if (this.autoConnect) this.open();
|
||
}
|
||
|
||
/**
|
||
* Propagate given event to sockets and emit on `this`
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.emitAll = function() {
|
||
this.emit.apply(this, arguments);
|
||
for (var nsp in this.nsps) {
|
||
if (has.call(this.nsps, nsp)) {
|
||
this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Update `socket.id` of all sockets
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.updateSocketIds = function(){
|
||
for (var nsp in this.nsps) {
|
||
if (has.call(this.nsps, nsp)) {
|
||
this.nsps[nsp].id = this.engine.id;
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Mix in `Emitter`.
|
||
*/
|
||
|
||
Emitter(Manager.prototype);
|
||
|
||
/**
|
||
* Sets the `reconnection` config.
|
||
*
|
||
* @param {Boolean} true/false if it should automatically reconnect
|
||
* @return {Manager} self or value
|
||
* @api public
|
||
*/
|
||
|
||
Manager.prototype.reconnection = function(v){
|
||
if (!arguments.length) return this._reconnection;
|
||
this._reconnection = !!v;
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Sets the reconnection attempts config.
|
||
*
|
||
* @param {Number} max reconnection attempts before giving up
|
||
* @return {Manager} self or value
|
||
* @api public
|
||
*/
|
||
|
||
Manager.prototype.reconnectionAttempts = function(v){
|
||
if (!arguments.length) return this._reconnectionAttempts;
|
||
this._reconnectionAttempts = v;
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Sets the delay between reconnections.
|
||
*
|
||
* @param {Number} delay
|
||
* @return {Manager} self or value
|
||
* @api public
|
||
*/
|
||
|
||
Manager.prototype.reconnectionDelay = function(v){
|
||
if (!arguments.length) return this._reconnectionDelay;
|
||
this._reconnectionDelay = v;
|
||
this.backoff && this.backoff.setMin(v);
|
||
return this;
|
||
};
|
||
|
||
Manager.prototype.randomizationFactor = function(v){
|
||
if (!arguments.length) return this._randomizationFactor;
|
||
this._randomizationFactor = v;
|
||
this.backoff && this.backoff.setJitter(v);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Sets the maximum delay between reconnections.
|
||
*
|
||
* @param {Number} delay
|
||
* @return {Manager} self or value
|
||
* @api public
|
||
*/
|
||
|
||
Manager.prototype.reconnectionDelayMax = function(v){
|
||
if (!arguments.length) return this._reconnectionDelayMax;
|
||
this._reconnectionDelayMax = v;
|
||
this.backoff && this.backoff.setMax(v);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Sets the connection timeout. `false` to disable
|
||
*
|
||
* @return {Manager} self or value
|
||
* @api public
|
||
*/
|
||
|
||
Manager.prototype.timeout = function(v){
|
||
if (!arguments.length) return this._timeout;
|
||
this._timeout = v;
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Starts trying to reconnect if reconnection is enabled and we have not
|
||
* started reconnecting yet
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.maybeReconnectOnOpen = function() {
|
||
// Only try to reconnect if it's the first time we're connecting
|
||
if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) {
|
||
// keeps reconnection from firing twice for the same reconnection loop
|
||
this.reconnect();
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Sets the current transport `socket`.
|
||
*
|
||
* @param {Function} optional, callback
|
||
* @return {Manager} self
|
||
* @api public
|
||
*/
|
||
|
||
Manager.prototype.open =
|
||
Manager.prototype.connect = function(fn){
|
||
debug('readyState %s', this.readyState);
|
||
if (~this.readyState.indexOf('open')) return this;
|
||
|
||
debug('opening %s', this.uri);
|
||
this.engine = eio(this.uri, this.opts);
|
||
var socket = this.engine;
|
||
var self = this;
|
||
this.readyState = 'opening';
|
||
this.skipReconnect = false;
|
||
|
||
// emit `open`
|
||
var openSub = on(socket, 'open', function() {
|
||
self.onopen();
|
||
fn && fn();
|
||
});
|
||
|
||
// emit `connect_error`
|
||
var errorSub = on(socket, 'error', function(data){
|
||
debug('connect_error');
|
||
self.cleanup();
|
||
self.readyState = 'closed';
|
||
self.emitAll('connect_error', data);
|
||
if (fn) {
|
||
var err = new Error('Connection error');
|
||
err.data = data;
|
||
fn(err);
|
||
} else {
|
||
// Only do this if there is no fn to handle the error
|
||
self.maybeReconnectOnOpen();
|
||
}
|
||
});
|
||
|
||
// emit `connect_timeout`
|
||
if (false !== this._timeout) {
|
||
var timeout = this._timeout;
|
||
debug('connect attempt will timeout after %d', timeout);
|
||
|
||
// set timer
|
||
var timer = setTimeout(function(){
|
||
debug('connect attempt timed out after %d', timeout);
|
||
openSub.destroy();
|
||
socket.close();
|
||
socket.emit('error', 'timeout');
|
||
self.emitAll('connect_timeout', timeout);
|
||
}, timeout);
|
||
|
||
this.subs.push({
|
||
destroy: function(){
|
||
clearTimeout(timer);
|
||
}
|
||
});
|
||
}
|
||
|
||
this.subs.push(openSub);
|
||
this.subs.push(errorSub);
|
||
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Called upon transport open.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.onopen = function(){
|
||
debug('open');
|
||
|
||
// clear old subs
|
||
this.cleanup();
|
||
|
||
// mark as open
|
||
this.readyState = 'open';
|
||
this.emit('open');
|
||
|
||
// add new subs
|
||
var socket = this.engine;
|
||
this.subs.push(on(socket, 'data', bind(this, 'ondata')));
|
||
this.subs.push(on(socket, 'ping', bind(this, 'onping')));
|
||
this.subs.push(on(socket, 'pong', bind(this, 'onpong')));
|
||
this.subs.push(on(socket, 'error', bind(this, 'onerror')));
|
||
this.subs.push(on(socket, 'close', bind(this, 'onclose')));
|
||
this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));
|
||
};
|
||
|
||
/**
|
||
* Called upon a ping.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.onping = function(){
|
||
this.lastPing = new Date;
|
||
this.emitAll('ping');
|
||
};
|
||
|
||
/**
|
||
* Called upon a packet.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.onpong = function(){
|
||
this.emitAll('pong', new Date - this.lastPing);
|
||
};
|
||
|
||
/**
|
||
* Called with data.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.ondata = function(data){
|
||
this.decoder.add(data);
|
||
};
|
||
|
||
/**
|
||
* Called when parser fully decodes a packet.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.ondecoded = function(packet) {
|
||
this.emit('packet', packet);
|
||
};
|
||
|
||
/**
|
||
* Called upon socket error.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.onerror = function(err){
|
||
debug('error', err);
|
||
this.emitAll('error', err);
|
||
};
|
||
|
||
/**
|
||
* Creates a new socket for the given `nsp`.
|
||
*
|
||
* @return {Socket}
|
||
* @api public
|
||
*/
|
||
|
||
Manager.prototype.socket = function(nsp){
|
||
var socket = this.nsps[nsp];
|
||
if (!socket) {
|
||
socket = new Socket(this, nsp);
|
||
this.nsps[nsp] = socket;
|
||
var self = this;
|
||
socket.on('connecting', onConnecting);
|
||
socket.on('connect', function(){
|
||
socket.id = self.engine.id;
|
||
});
|
||
|
||
if (this.autoConnect) {
|
||
// manually call here since connecting evnet is fired before listening
|
||
onConnecting();
|
||
}
|
||
}
|
||
|
||
function onConnecting() {
|
||
if (!~indexOf(self.connecting, socket)) {
|
||
self.connecting.push(socket);
|
||
}
|
||
}
|
||
|
||
return socket;
|
||
};
|
||
|
||
/**
|
||
* Called upon a socket close.
|
||
*
|
||
* @param {Socket} socket
|
||
*/
|
||
|
||
Manager.prototype.destroy = function(socket){
|
||
var index = indexOf(this.connecting, socket);
|
||
if (~index) this.connecting.splice(index, 1);
|
||
if (this.connecting.length) return;
|
||
|
||
this.close();
|
||
};
|
||
|
||
/**
|
||
* Writes a packet.
|
||
*
|
||
* @param {Object} packet
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.packet = function(packet){
|
||
debug('writing packet %j', packet);
|
||
var self = this;
|
||
|
||
if (!self.encoding) {
|
||
// encode, then write to engine with result
|
||
self.encoding = true;
|
||
this.encoder.encode(packet, function(encodedPackets) {
|
||
for (var i = 0; i < encodedPackets.length; i++) {
|
||
self.engine.write(encodedPackets[i], packet.options);
|
||
}
|
||
self.encoding = false;
|
||
self.processPacketQueue();
|
||
});
|
||
} else { // add packet to the queue
|
||
self.packetBuffer.push(packet);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* If packet buffer is non-empty, begins encoding the
|
||
* next packet in line.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.processPacketQueue = function() {
|
||
if (this.packetBuffer.length > 0 && !this.encoding) {
|
||
var pack = this.packetBuffer.shift();
|
||
this.packet(pack);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Clean up transport subscriptions and packet buffer.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.cleanup = function(){
|
||
debug('cleanup');
|
||
|
||
var sub;
|
||
while (sub = this.subs.shift()) sub.destroy();
|
||
|
||
this.packetBuffer = [];
|
||
this.encoding = false;
|
||
this.lastPing = null;
|
||
|
||
this.decoder.destroy();
|
||
};
|
||
|
||
/**
|
||
* Close the current socket.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.close =
|
||
Manager.prototype.disconnect = function(){
|
||
debug('disconnect');
|
||
this.skipReconnect = true;
|
||
this.reconnecting = false;
|
||
if ('opening' == this.readyState) {
|
||
// `onclose` will not fire because
|
||
// an open event never happened
|
||
this.cleanup();
|
||
}
|
||
this.backoff.reset();
|
||
this.readyState = 'closed';
|
||
if (this.engine) this.engine.close();
|
||
};
|
||
|
||
/**
|
||
* Called upon engine close.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.onclose = function(reason){
|
||
debug('onclose');
|
||
|
||
this.cleanup();
|
||
this.backoff.reset();
|
||
this.readyState = 'closed';
|
||
this.emit('close', reason);
|
||
|
||
if (this._reconnection && !this.skipReconnect) {
|
||
this.reconnect();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Attempt a reconnection.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.reconnect = function(){
|
||
if (this.reconnecting || this.skipReconnect) return this;
|
||
|
||
var self = this;
|
||
|
||
if (this.backoff.attempts >= this._reconnectionAttempts) {
|
||
debug('reconnect failed');
|
||
this.backoff.reset();
|
||
this.emitAll('reconnect_failed');
|
||
this.reconnecting = false;
|
||
} else {
|
||
var delay = this.backoff.duration();
|
||
debug('will wait %dms before reconnect attempt', delay);
|
||
|
||
this.reconnecting = true;
|
||
var timer = setTimeout(function(){
|
||
if (self.skipReconnect) return;
|
||
|
||
debug('attempting reconnect');
|
||
self.emitAll('reconnect_attempt', self.backoff.attempts);
|
||
self.emitAll('reconnecting', self.backoff.attempts);
|
||
|
||
// check again for the case socket closed in above events
|
||
if (self.skipReconnect) return;
|
||
|
||
self.open(function(err){
|
||
if (err) {
|
||
debug('reconnect attempt error');
|
||
self.reconnecting = false;
|
||
self.reconnect();
|
||
self.emitAll('reconnect_error', err.data);
|
||
} else {
|
||
debug('reconnect success');
|
||
self.onreconnect();
|
||
}
|
||
});
|
||
}, delay);
|
||
|
||
this.subs.push({
|
||
destroy: function(){
|
||
clearTimeout(timer);
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Called upon successful reconnect.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Manager.prototype.onreconnect = function(){
|
||
var attempt = this.backoff.attempts;
|
||
this.reconnecting = false;
|
||
this.backoff.reset();
|
||
this.updateSocketIds();
|
||
this.emitAll('reconnect', attempt);
|
||
};
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./on":140,"./socket":141,"backo2":6,"component-bind":13,"component-emitter":143,"debug":46,"engine.io-client":48,"indexof":63,"socket.io-parser":145}],140:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/socket.io-client/lib/on.js", module);
|
||
(function(){
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = on;
|
||
|
||
/**
|
||
* Helper for subscriptions.
|
||
*
|
||
* @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`
|
||
* @param {String} event name
|
||
* @param {Function} callback
|
||
* @api public
|
||
*/
|
||
|
||
function on(obj, ev, fn) {
|
||
obj.on(ev, fn);
|
||
return {
|
||
destroy: function(){
|
||
obj.removeListener(ev, fn);
|
||
}
|
||
};
|
||
}
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],141:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/socket.io-client/lib/socket.js", module);
|
||
(function(){
|
||
|
||
/**
|
||
* Module dependencies.
|
||
*/
|
||
|
||
var parser = require('socket.io-parser');
|
||
var Emitter = require('component-emitter');
|
||
var toArray = require('to-array');
|
||
var on = require('./on');
|
||
var bind = require('component-bind');
|
||
var debug = require('debug')('socket.io-client:socket');
|
||
var hasBin = require('has-binary');
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = exports = Socket;
|
||
|
||
/**
|
||
* Internal events (blacklisted).
|
||
* These events can't be emitted by the user.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
var events = {
|
||
connect: 1,
|
||
connect_error: 1,
|
||
connect_timeout: 1,
|
||
connecting: 1,
|
||
disconnect: 1,
|
||
error: 1,
|
||
reconnect: 1,
|
||
reconnect_attempt: 1,
|
||
reconnect_failed: 1,
|
||
reconnect_error: 1,
|
||
reconnecting: 1,
|
||
ping: 1,
|
||
pong: 1
|
||
};
|
||
|
||
/**
|
||
* Shortcut to `Emitter#emit`.
|
||
*/
|
||
|
||
var emit = Emitter.prototype.emit;
|
||
|
||
/**
|
||
* `Socket` constructor.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
function Socket(io, nsp){
|
||
this.io = io;
|
||
this.nsp = nsp;
|
||
this.json = this; // compat
|
||
this.ids = 0;
|
||
this.acks = {};
|
||
this.receiveBuffer = [];
|
||
this.sendBuffer = [];
|
||
this.connected = false;
|
||
this.disconnected = true;
|
||
if (this.io.autoConnect) this.open();
|
||
}
|
||
|
||
/**
|
||
* Mix in `Emitter`.
|
||
*/
|
||
|
||
Emitter(Socket.prototype);
|
||
|
||
/**
|
||
* Subscribe to open, close and packet events
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.subEvents = function() {
|
||
if (this.subs) return;
|
||
|
||
var io = this.io;
|
||
this.subs = [
|
||
on(io, 'open', bind(this, 'onopen')),
|
||
on(io, 'packet', bind(this, 'onpacket')),
|
||
on(io, 'close', bind(this, 'onclose'))
|
||
];
|
||
};
|
||
|
||
/**
|
||
* "Opens" the socket.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
Socket.prototype.open =
|
||
Socket.prototype.connect = function(){
|
||
if (this.connected) return this;
|
||
|
||
this.subEvents();
|
||
this.io.open(); // ensure open
|
||
if ('open' == this.io.readyState) this.onopen();
|
||
this.emit('connecting');
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Sends a `message` event.
|
||
*
|
||
* @return {Socket} self
|
||
* @api public
|
||
*/
|
||
|
||
Socket.prototype.send = function(){
|
||
var args = toArray(arguments);
|
||
args.unshift('message');
|
||
this.emit.apply(this, args);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Override `emit`.
|
||
* If the event is in `events`, it's emitted normally.
|
||
*
|
||
* @param {String} event name
|
||
* @return {Socket} self
|
||
* @api public
|
||
*/
|
||
|
||
Socket.prototype.emit = function(ev){
|
||
if (events.hasOwnProperty(ev)) {
|
||
emit.apply(this, arguments);
|
||
return this;
|
||
}
|
||
|
||
var args = toArray(arguments);
|
||
var parserType = parser.EVENT; // default
|
||
if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary
|
||
var packet = { type: parserType, data: args };
|
||
|
||
packet.options = {};
|
||
packet.options.compress = !this.flags || false !== this.flags.compress;
|
||
|
||
// event ack callback
|
||
if ('function' == typeof args[args.length - 1]) {
|
||
debug('emitting packet with ack id %d', this.ids);
|
||
this.acks[this.ids] = args.pop();
|
||
packet.id = this.ids++;
|
||
}
|
||
|
||
if (this.connected) {
|
||
this.packet(packet);
|
||
} else {
|
||
this.sendBuffer.push(packet);
|
||
}
|
||
|
||
delete this.flags;
|
||
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Sends a packet.
|
||
*
|
||
* @param {Object} packet
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.packet = function(packet){
|
||
packet.nsp = this.nsp;
|
||
this.io.packet(packet);
|
||
};
|
||
|
||
/**
|
||
* Called upon engine `open`.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.onopen = function(){
|
||
debug('transport is open - connecting');
|
||
|
||
// write connect packet if necessary
|
||
if ('/' != this.nsp) {
|
||
this.packet({ type: parser.CONNECT });
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Called upon engine `close`.
|
||
*
|
||
* @param {String} reason
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.onclose = function(reason){
|
||
debug('close (%s)', reason);
|
||
this.connected = false;
|
||
this.disconnected = true;
|
||
delete this.id;
|
||
this.emit('disconnect', reason);
|
||
};
|
||
|
||
/**
|
||
* Called with socket packet.
|
||
*
|
||
* @param {Object} packet
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.onpacket = function(packet){
|
||
if (packet.nsp != this.nsp) return;
|
||
|
||
switch (packet.type) {
|
||
case parser.CONNECT:
|
||
this.onconnect();
|
||
break;
|
||
|
||
case parser.EVENT:
|
||
this.onevent(packet);
|
||
break;
|
||
|
||
case parser.BINARY_EVENT:
|
||
this.onevent(packet);
|
||
break;
|
||
|
||
case parser.ACK:
|
||
this.onack(packet);
|
||
break;
|
||
|
||
case parser.BINARY_ACK:
|
||
this.onack(packet);
|
||
break;
|
||
|
||
case parser.DISCONNECT:
|
||
this.ondisconnect();
|
||
break;
|
||
|
||
case parser.ERROR:
|
||
this.emit('error', packet.data);
|
||
break;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Called upon a server event.
|
||
*
|
||
* @param {Object} packet
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.onevent = function(packet){
|
||
var args = packet.data || [];
|
||
debug('emitting event %j', args);
|
||
|
||
if (null != packet.id) {
|
||
debug('attaching ack callback to event');
|
||
args.push(this.ack(packet.id));
|
||
}
|
||
|
||
if (this.connected) {
|
||
emit.apply(this, args);
|
||
} else {
|
||
this.receiveBuffer.push(args);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Produces an ack callback to emit with an event.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.ack = function(id){
|
||
var self = this;
|
||
var sent = false;
|
||
return function(){
|
||
// prevent double callbacks
|
||
if (sent) return;
|
||
sent = true;
|
||
var args = toArray(arguments);
|
||
debug('sending ack %j', args);
|
||
|
||
var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;
|
||
self.packet({
|
||
type: type,
|
||
id: id,
|
||
data: args
|
||
});
|
||
};
|
||
};
|
||
|
||
/**
|
||
* Called upon a server acknowlegement.
|
||
*
|
||
* @param {Object} packet
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.onack = function(packet){
|
||
var ack = this.acks[packet.id];
|
||
if ('function' == typeof ack) {
|
||
debug('calling ack %s with %j', packet.id, packet.data);
|
||
ack.apply(this, packet.data);
|
||
delete this.acks[packet.id];
|
||
} else {
|
||
debug('bad ack %s', packet.id);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Called upon server connect.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.onconnect = function(){
|
||
this.connected = true;
|
||
this.disconnected = false;
|
||
this.emit('connect');
|
||
this.emitBuffered();
|
||
};
|
||
|
||
/**
|
||
* Emit buffered events (received and emitted).
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.emitBuffered = function(){
|
||
var i;
|
||
for (i = 0; i < this.receiveBuffer.length; i++) {
|
||
emit.apply(this, this.receiveBuffer[i]);
|
||
}
|
||
this.receiveBuffer = [];
|
||
|
||
for (i = 0; i < this.sendBuffer.length; i++) {
|
||
this.packet(this.sendBuffer[i]);
|
||
}
|
||
this.sendBuffer = [];
|
||
};
|
||
|
||
/**
|
||
* Called upon server disconnect.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
Socket.prototype.ondisconnect = function(){
|
||
debug('server disconnect (%s)', this.nsp);
|
||
this.destroy();
|
||
this.onclose('io server disconnect');
|
||
};
|
||
|
||
/**
|
||
* Called upon forced client/server side disconnections,
|
||
* this method ensures the manager stops tracking us and
|
||
* that reconnections don't get triggered for this.
|
||
*
|
||
* @api private.
|
||
*/
|
||
|
||
Socket.prototype.destroy = function(){
|
||
if (this.subs) {
|
||
// clean subscriptions to avoid reconnections
|
||
for (var i = 0; i < this.subs.length; i++) {
|
||
this.subs[i].destroy();
|
||
}
|
||
this.subs = null;
|
||
}
|
||
|
||
this.io.destroy(this);
|
||
};
|
||
|
||
/**
|
||
* Disconnects the socket manually.
|
||
*
|
||
* @return {Socket} self
|
||
* @api public
|
||
*/
|
||
|
||
Socket.prototype.close =
|
||
Socket.prototype.disconnect = function(){
|
||
if (this.connected) {
|
||
debug('performing disconnect (%s)', this.nsp);
|
||
this.packet({ type: parser.DISCONNECT });
|
||
}
|
||
|
||
// remove socket from pool
|
||
this.destroy();
|
||
|
||
if (this.connected) {
|
||
// fire events
|
||
this.onclose('io client disconnect');
|
||
}
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Sets the compress flag.
|
||
*
|
||
* @param {Boolean} if `true`, compresses the sending data
|
||
* @return {Socket} self
|
||
* @api public
|
||
*/
|
||
|
||
Socket.prototype.compress = function(compress){
|
||
this.flags = this.flags || {};
|
||
this.flags.compress = compress;
|
||
return this;
|
||
};
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./on":140,"component-bind":13,"component-emitter":143,"debug":46,"has-binary":61,"socket.io-parser":145,"to-array":148}],142:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/socket.io-client/lib/url.js", module);
|
||
(function(){
|
||
(function (global){
|
||
|
||
/**
|
||
* Module dependencies.
|
||
*/
|
||
|
||
var parseuri = require('parseuri');
|
||
var debug = require('debug')('socket.io-client:url');
|
||
|
||
/**
|
||
* Module exports.
|
||
*/
|
||
|
||
module.exports = url;
|
||
|
||
/**
|
||
* URL parser.
|
||
*
|
||
* @param {String} url
|
||
* @param {Object} An object meant to mimic window.location.
|
||
* Defaults to window.location.
|
||
* @api public
|
||
*/
|
||
|
||
function url(uri, loc){
|
||
var obj = uri;
|
||
|
||
// default to window.location
|
||
var loc = loc || global.location;
|
||
if (null == uri) uri = loc.protocol + '//' + loc.host;
|
||
|
||
// relative path support
|
||
if ('string' == typeof uri) {
|
||
if ('/' == uri.charAt(0)) {
|
||
if ('/' == uri.charAt(1)) {
|
||
uri = loc.protocol + uri;
|
||
} else {
|
||
uri = loc.host + uri;
|
||
}
|
||
}
|
||
|
||
if (!/^(https?|wss?):\/\//.test(uri)) {
|
||
debug('protocol-less url %s', uri);
|
||
if ('undefined' != typeof loc) {
|
||
uri = loc.protocol + '//' + uri;
|
||
} else {
|
||
uri = 'https://' + uri;
|
||
}
|
||
}
|
||
|
||
// parse
|
||
debug('parse %s', uri);
|
||
obj = parseuri(uri);
|
||
}
|
||
|
||
// make sure we treat `localhost:80` and `localhost` equally
|
||
if (!obj.port) {
|
||
if (/^(http|ws)$/.test(obj.protocol)) {
|
||
obj.port = '80';
|
||
}
|
||
else if (/^(http|ws)s$/.test(obj.protocol)) {
|
||
obj.port = '443';
|
||
}
|
||
}
|
||
|
||
obj.path = obj.path || '/';
|
||
|
||
var ipv6 = obj.host.indexOf(':') !== -1;
|
||
var host = ipv6 ? '[' + obj.host + ']' : obj.host;
|
||
|
||
// define unique id
|
||
obj.id = obj.protocol + '://' + host + ':' + obj.port;
|
||
// define href
|
||
obj.href = obj.protocol + '://' + host + (loc && loc.port == obj.port ? '' : (':' + obj.port));
|
||
|
||
return obj;
|
||
}
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"debug":46,"parseuri":136}],143:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/socket.io-client/node_modules/component-emitter/index.js", module);
|
||
(function(){
|
||
|
||
/**
|
||
* Expose `Emitter`.
|
||
*/
|
||
|
||
module.exports = Emitter;
|
||
|
||
/**
|
||
* Initialize a new `Emitter`.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
function Emitter(obj) {
|
||
if (obj) return mixin(obj);
|
||
};
|
||
|
||
/**
|
||
* Mixin the emitter properties.
|
||
*
|
||
* @param {Object} obj
|
||
* @return {Object}
|
||
* @api private
|
||
*/
|
||
|
||
function mixin(obj) {
|
||
for (var key in Emitter.prototype) {
|
||
obj[key] = Emitter.prototype[key];
|
||
}
|
||
return obj;
|
||
}
|
||
|
||
/**
|
||
* Listen on the given `event` with `fn`.
|
||
*
|
||
* @param {String} event
|
||
* @param {Function} fn
|
||
* @return {Emitter}
|
||
* @api public
|
||
*/
|
||
|
||
Emitter.prototype.on =
|
||
Emitter.prototype.addEventListener = function(event, fn){
|
||
this._callbacks = this._callbacks || {};
|
||
(this._callbacks['$' + event] = this._callbacks['$' + event] || [])
|
||
.push(fn);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Adds an `event` listener that will be invoked a single
|
||
* time then automatically removed.
|
||
*
|
||
* @param {String} event
|
||
* @param {Function} fn
|
||
* @return {Emitter}
|
||
* @api public
|
||
*/
|
||
|
||
Emitter.prototype.once = function(event, fn){
|
||
function on() {
|
||
this.off(event, on);
|
||
fn.apply(this, arguments);
|
||
}
|
||
|
||
on.fn = fn;
|
||
this.on(event, on);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Remove the given callback for `event` or all
|
||
* registered callbacks.
|
||
*
|
||
* @param {String} event
|
||
* @param {Function} fn
|
||
* @return {Emitter}
|
||
* @api public
|
||
*/
|
||
|
||
Emitter.prototype.off =
|
||
Emitter.prototype.removeListener =
|
||
Emitter.prototype.removeAllListeners =
|
||
Emitter.prototype.removeEventListener = function(event, fn){
|
||
this._callbacks = this._callbacks || {};
|
||
|
||
// all
|
||
if (0 == arguments.length) {
|
||
this._callbacks = {};
|
||
return this;
|
||
}
|
||
|
||
// specific event
|
||
var callbacks = this._callbacks['$' + event];
|
||
if (!callbacks) return this;
|
||
|
||
// remove all handlers
|
||
if (1 == arguments.length) {
|
||
delete this._callbacks['$' + event];
|
||
return this;
|
||
}
|
||
|
||
// remove specific handler
|
||
var cb;
|
||
for (var i = 0; i < callbacks.length; i++) {
|
||
cb = callbacks[i];
|
||
if (cb === fn || cb.fn === fn) {
|
||
callbacks.splice(i, 1);
|
||
break;
|
||
}
|
||
}
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Emit `event` with the given args.
|
||
*
|
||
* @param {String} event
|
||
* @param {Mixed} ...
|
||
* @return {Emitter}
|
||
*/
|
||
|
||
Emitter.prototype.emit = function(event){
|
||
this._callbacks = this._callbacks || {};
|
||
var args = [].slice.call(arguments, 1)
|
||
, callbacks = this._callbacks['$' + event];
|
||
|
||
if (callbacks) {
|
||
callbacks = callbacks.slice(0);
|
||
for (var i = 0, len = callbacks.length; i < len; ++i) {
|
||
callbacks[i].apply(this, args);
|
||
}
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Return array of callbacks for `event`.
|
||
*
|
||
* @param {String} event
|
||
* @return {Array}
|
||
* @api public
|
||
*/
|
||
|
||
Emitter.prototype.listeners = function(event){
|
||
this._callbacks = this._callbacks || {};
|
||
return this._callbacks['$' + event] || [];
|
||
};
|
||
|
||
/**
|
||
* Check if this emitter has `event` handlers.
|
||
*
|
||
* @param {String} event
|
||
* @return {Boolean}
|
||
* @api public
|
||
*/
|
||
|
||
Emitter.prototype.hasListeners = function(event){
|
||
return !! this.listeners(event).length;
|
||
};
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],144:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/socket.io-parser/binary.js", module);
|
||
(function(){
|
||
(function (global){
|
||
/*global Blob,File*/
|
||
|
||
/**
|
||
* Module requirements
|
||
*/
|
||
|
||
var isArray = require('isarray');
|
||
var isBuf = require('./is-buffer');
|
||
|
||
/**
|
||
* Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.
|
||
* Anything with blobs or files should be fed through removeBlobs before coming
|
||
* here.
|
||
*
|
||
* @param {Object} packet - socket.io event packet
|
||
* @return {Object} with deconstructed packet and list of buffers
|
||
* @api public
|
||
*/
|
||
|
||
exports.deconstructPacket = function(packet){
|
||
var buffers = [];
|
||
var packetData = packet.data;
|
||
|
||
function _deconstructPacket(data) {
|
||
if (!data) return data;
|
||
|
||
if (isBuf(data)) {
|
||
var placeholder = { _placeholder: true, num: buffers.length };
|
||
buffers.push(data);
|
||
return placeholder;
|
||
} else if (isArray(data)) {
|
||
var newData = new Array(data.length);
|
||
for (var i = 0; i < data.length; i++) {
|
||
newData[i] = _deconstructPacket(data[i]);
|
||
}
|
||
return newData;
|
||
} else if ('object' == typeof data && !(data instanceof Date)) {
|
||
var newData = {};
|
||
for (var key in data) {
|
||
newData[key] = _deconstructPacket(data[key]);
|
||
}
|
||
return newData;
|
||
}
|
||
return data;
|
||
}
|
||
|
||
var pack = packet;
|
||
pack.data = _deconstructPacket(packetData);
|
||
pack.attachments = buffers.length; // number of binary 'attachments'
|
||
return {packet: pack, buffers: buffers};
|
||
};
|
||
|
||
/**
|
||
* Reconstructs a binary packet from its placeholder packet and buffers
|
||
*
|
||
* @param {Object} packet - event packet with placeholders
|
||
* @param {Array} buffers - binary buffers to put in placeholder positions
|
||
* @return {Object} reconstructed packet
|
||
* @api public
|
||
*/
|
||
|
||
exports.reconstructPacket = function(packet, buffers) {
|
||
var curPlaceHolder = 0;
|
||
|
||
function _reconstructPacket(data) {
|
||
if (data && data._placeholder) {
|
||
var buf = buffers[data.num]; // appropriate buffer (should be natural order anyway)
|
||
return buf;
|
||
} else if (isArray(data)) {
|
||
for (var i = 0; i < data.length; i++) {
|
||
data[i] = _reconstructPacket(data[i]);
|
||
}
|
||
return data;
|
||
} else if (data && 'object' == typeof data) {
|
||
for (var key in data) {
|
||
data[key] = _reconstructPacket(data[key]);
|
||
}
|
||
return data;
|
||
}
|
||
return data;
|
||
}
|
||
|
||
packet.data = _reconstructPacket(packet.data);
|
||
packet.attachments = undefined; // no longer useful
|
||
return packet;
|
||
};
|
||
|
||
/**
|
||
* Asynchronously removes Blobs or Files from data via
|
||
* FileReader's readAsArrayBuffer method. Used before encoding
|
||
* data as msgpack. Calls callback with the blobless data.
|
||
*
|
||
* @param {Object} data
|
||
* @param {Function} callback
|
||
* @api private
|
||
*/
|
||
|
||
exports.removeBlobs = function(data, callback) {
|
||
function _removeBlobs(obj, curKey, containingObject) {
|
||
if (!obj) return obj;
|
||
|
||
// convert any blob
|
||
if ((global.Blob && obj instanceof Blob) ||
|
||
(global.File && obj instanceof File)) {
|
||
pendingBlobs++;
|
||
|
||
// async filereader
|
||
var fileReader = new FileReader();
|
||
fileReader.onload = function() { // this.result == arraybuffer
|
||
if (containingObject) {
|
||
containingObject[curKey] = this.result;
|
||
}
|
||
else {
|
||
bloblessData = this.result;
|
||
}
|
||
|
||
// if nothing pending its callback time
|
||
if(! --pendingBlobs) {
|
||
callback(bloblessData);
|
||
}
|
||
};
|
||
|
||
fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer
|
||
} else if (isArray(obj)) { // handle array
|
||
for (var i = 0; i < obj.length; i++) {
|
||
_removeBlobs(obj[i], i, obj);
|
||
}
|
||
} else if (obj && 'object' == typeof obj && !isBuf(obj)) { // and object
|
||
for (var key in obj) {
|
||
_removeBlobs(obj[key], key, obj);
|
||
}
|
||
}
|
||
}
|
||
|
||
var pendingBlobs = 0;
|
||
var bloblessData = data;
|
||
_removeBlobs(bloblessData);
|
||
if (!pendingBlobs) {
|
||
callback(bloblessData);
|
||
}
|
||
};
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./is-buffer":146,"isarray":64}],145:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/socket.io-parser/index.js", module);
|
||
(function(){
|
||
|
||
/**
|
||
* Module dependencies.
|
||
*/
|
||
|
||
var debug = require('debug')('socket.io-parser');
|
||
var json = require('json3');
|
||
var isArray = require('isarray');
|
||
var Emitter = require('component-emitter');
|
||
var binary = require('./binary');
|
||
var isBuf = require('./is-buffer');
|
||
|
||
/**
|
||
* Protocol version.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.protocol = 4;
|
||
|
||
/**
|
||
* Packet types.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.types = [
|
||
'CONNECT',
|
||
'DISCONNECT',
|
||
'EVENT',
|
||
'ACK',
|
||
'ERROR',
|
||
'BINARY_EVENT',
|
||
'BINARY_ACK'
|
||
];
|
||
|
||
/**
|
||
* Packet type `connect`.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.CONNECT = 0;
|
||
|
||
/**
|
||
* Packet type `disconnect`.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.DISCONNECT = 1;
|
||
|
||
/**
|
||
* Packet type `event`.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.EVENT = 2;
|
||
|
||
/**
|
||
* Packet type `ack`.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.ACK = 3;
|
||
|
||
/**
|
||
* Packet type `error`.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.ERROR = 4;
|
||
|
||
/**
|
||
* Packet type 'binary event'
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.BINARY_EVENT = 5;
|
||
|
||
/**
|
||
* Packet type `binary ack`. For acks with binary arguments.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.BINARY_ACK = 6;
|
||
|
||
/**
|
||
* Encoder constructor.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.Encoder = Encoder;
|
||
|
||
/**
|
||
* Decoder constructor.
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
exports.Decoder = Decoder;
|
||
|
||
/**
|
||
* A socket.io Encoder instance
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
function Encoder() {}
|
||
|
||
/**
|
||
* Encode a packet as a single string if non-binary, or as a
|
||
* buffer sequence, depending on packet type.
|
||
*
|
||
* @param {Object} obj - packet object
|
||
* @param {Function} callback - function to handle encodings (likely engine.write)
|
||
* @return Calls callback with Array of encodings
|
||
* @api public
|
||
*/
|
||
|
||
Encoder.prototype.encode = function(obj, callback){
|
||
debug('encoding packet %j', obj);
|
||
|
||
if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {
|
||
encodeAsBinary(obj, callback);
|
||
}
|
||
else {
|
||
var encoding = encodeAsString(obj);
|
||
callback([encoding]);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Encode packet as string.
|
||
*
|
||
* @param {Object} packet
|
||
* @return {String} encoded
|
||
* @api private
|
||
*/
|
||
|
||
function encodeAsString(obj) {
|
||
var str = '';
|
||
var nsp = false;
|
||
|
||
// first is type
|
||
str += obj.type;
|
||
|
||
// attachments if we have them
|
||
if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {
|
||
str += obj.attachments;
|
||
str += '-';
|
||
}
|
||
|
||
// if we have a namespace other than `/`
|
||
// we append it followed by a comma `,`
|
||
if (obj.nsp && '/' != obj.nsp) {
|
||
nsp = true;
|
||
str += obj.nsp;
|
||
}
|
||
|
||
// immediately followed by the id
|
||
if (null != obj.id) {
|
||
if (nsp) {
|
||
str += ',';
|
||
nsp = false;
|
||
}
|
||
str += obj.id;
|
||
}
|
||
|
||
// json data
|
||
if (null != obj.data) {
|
||
if (nsp) str += ',';
|
||
str += json.stringify(obj.data);
|
||
}
|
||
|
||
debug('encoded %j as %s', obj, str);
|
||
return str;
|
||
}
|
||
|
||
/**
|
||
* Encode packet as 'buffer sequence' by removing blobs, and
|
||
* deconstructing packet into object with placeholders and
|
||
* a list of buffers.
|
||
*
|
||
* @param {Object} packet
|
||
* @return {Buffer} encoded
|
||
* @api private
|
||
*/
|
||
|
||
function encodeAsBinary(obj, callback) {
|
||
|
||
function writeEncoding(bloblessData) {
|
||
var deconstruction = binary.deconstructPacket(bloblessData);
|
||
var pack = encodeAsString(deconstruction.packet);
|
||
var buffers = deconstruction.buffers;
|
||
|
||
buffers.unshift(pack); // add packet info to beginning of data list
|
||
callback(buffers); // write all the buffers
|
||
}
|
||
|
||
binary.removeBlobs(obj, writeEncoding);
|
||
}
|
||
|
||
/**
|
||
* A socket.io Decoder instance
|
||
*
|
||
* @return {Object} decoder
|
||
* @api public
|
||
*/
|
||
|
||
function Decoder() {
|
||
this.reconstructor = null;
|
||
}
|
||
|
||
/**
|
||
* Mix in `Emitter` with Decoder.
|
||
*/
|
||
|
||
Emitter(Decoder.prototype);
|
||
|
||
/**
|
||
* Decodes an ecoded packet string into packet JSON.
|
||
*
|
||
* @param {String} obj - encoded packet
|
||
* @return {Object} packet
|
||
* @api public
|
||
*/
|
||
|
||
Decoder.prototype.add = function(obj) {
|
||
var packet;
|
||
if ('string' == typeof obj) {
|
||
packet = decodeString(obj);
|
||
if (exports.BINARY_EVENT == packet.type || exports.BINARY_ACK == packet.type) { // binary packet's json
|
||
this.reconstructor = new BinaryReconstructor(packet);
|
||
|
||
// no attachments, labeled binary but no binary data to follow
|
||
if (this.reconstructor.reconPack.attachments === 0) {
|
||
this.emit('decoded', packet);
|
||
}
|
||
} else { // non-binary full packet
|
||
this.emit('decoded', packet);
|
||
}
|
||
}
|
||
else if (isBuf(obj) || obj.base64) { // raw binary data
|
||
if (!this.reconstructor) {
|
||
throw new Error('got binary data when not reconstructing a packet');
|
||
} else {
|
||
packet = this.reconstructor.takeBinaryData(obj);
|
||
if (packet) { // received final buffer
|
||
this.reconstructor = null;
|
||
this.emit('decoded', packet);
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
throw new Error('Unknown type: ' + obj);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Decode a packet String (JSON data)
|
||
*
|
||
* @param {String} str
|
||
* @return {Object} packet
|
||
* @api private
|
||
*/
|
||
|
||
function decodeString(str) {
|
||
var p = {};
|
||
var i = 0;
|
||
|
||
// look up type
|
||
p.type = Number(str.charAt(0));
|
||
if (null == exports.types[p.type]) return error();
|
||
|
||
// look up attachments if type binary
|
||
if (exports.BINARY_EVENT == p.type || exports.BINARY_ACK == p.type) {
|
||
var buf = '';
|
||
while (str.charAt(++i) != '-') {
|
||
buf += str.charAt(i);
|
||
if (i == str.length) break;
|
||
}
|
||
if (buf != Number(buf) || str.charAt(i) != '-') {
|
||
throw new Error('Illegal attachments');
|
||
}
|
||
p.attachments = Number(buf);
|
||
}
|
||
|
||
// look up namespace (if any)
|
||
if ('/' == str.charAt(i + 1)) {
|
||
p.nsp = '';
|
||
while (++i) {
|
||
var c = str.charAt(i);
|
||
if (',' == c) break;
|
||
p.nsp += c;
|
||
if (i == str.length) break;
|
||
}
|
||
} else {
|
||
p.nsp = '/';
|
||
}
|
||
|
||
// look up id
|
||
var next = str.charAt(i + 1);
|
||
if ('' !== next && Number(next) == next) {
|
||
p.id = '';
|
||
while (++i) {
|
||
var c = str.charAt(i);
|
||
if (null == c || Number(c) != c) {
|
||
--i;
|
||
break;
|
||
}
|
||
p.id += str.charAt(i);
|
||
if (i == str.length) break;
|
||
}
|
||
p.id = Number(p.id);
|
||
}
|
||
|
||
// look up json data
|
||
if (str.charAt(++i)) {
|
||
try {
|
||
p.data = json.parse(str.substr(i));
|
||
} catch(e){
|
||
return error();
|
||
}
|
||
}
|
||
|
||
debug('decoded %s as %j', str, p);
|
||
return p;
|
||
}
|
||
|
||
/**
|
||
* Deallocates a parser's resources
|
||
*
|
||
* @api public
|
||
*/
|
||
|
||
Decoder.prototype.destroy = function() {
|
||
if (this.reconstructor) {
|
||
this.reconstructor.finishedReconstruction();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* A manager of a binary event's 'buffer sequence'. Should
|
||
* be constructed whenever a packet of type BINARY_EVENT is
|
||
* decoded.
|
||
*
|
||
* @param {Object} packet
|
||
* @return {BinaryReconstructor} initialized reconstructor
|
||
* @api private
|
||
*/
|
||
|
||
function BinaryReconstructor(packet) {
|
||
this.reconPack = packet;
|
||
this.buffers = [];
|
||
}
|
||
|
||
/**
|
||
* Method to be called when binary data received from connection
|
||
* after a BINARY_EVENT packet.
|
||
*
|
||
* @param {Buffer | ArrayBuffer} binData - the raw binary data received
|
||
* @return {null | Object} returns null if more binary data is expected or
|
||
* a reconstructed packet object if all buffers have been received.
|
||
* @api private
|
||
*/
|
||
|
||
BinaryReconstructor.prototype.takeBinaryData = function(binData) {
|
||
this.buffers.push(binData);
|
||
if (this.buffers.length == this.reconPack.attachments) { // done with buffer list
|
||
var packet = binary.reconstructPacket(this.reconPack, this.buffers);
|
||
this.finishedReconstruction();
|
||
return packet;
|
||
}
|
||
return null;
|
||
};
|
||
|
||
/**
|
||
* Cleans up binary packet reconstruction variables.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
BinaryReconstructor.prototype.finishedReconstruction = function() {
|
||
this.reconPack = null;
|
||
this.buffers = [];
|
||
};
|
||
|
||
function error(data){
|
||
return {
|
||
type: exports.ERROR,
|
||
data: 'parser error'
|
||
};
|
||
}
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./binary":144,"./is-buffer":146,"component-emitter":14,"debug":46,"isarray":64,"json3":147}],146:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/socket.io-parser/is-buffer.js", module);
|
||
(function(){
|
||
(function (global){
|
||
|
||
module.exports = isBuf;
|
||
|
||
/**
|
||
* Returns true if obj is a buffer or an arraybuffer.
|
||
*
|
||
* @api private
|
||
*/
|
||
|
||
function isBuf(obj) {
|
||
return (global.Buffer && global.Buffer.isBuffer(obj)) ||
|
||
(global.ArrayBuffer && obj instanceof ArrayBuffer);
|
||
}
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],147:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/socket.io-parser/node_modules/json3/lib/json3.js", module);
|
||
(function(){
|
||
(function (global){
|
||
/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */
|
||
;(function () {
|
||
// Detect the `define` function exposed by asynchronous module loaders. The
|
||
// strict `define` check is necessary for compatibility with `r.js`.
|
||
var isLoader = typeof define === "function" && define.amd;
|
||
|
||
// A set of types used to distinguish objects from primitives.
|
||
var objectTypes = {
|
||
"function": true,
|
||
"object": true
|
||
};
|
||
|
||
// Detect the `exports` object exposed by CommonJS implementations.
|
||
var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
|
||
|
||
// Use the `global` object exposed by Node (including Browserify via
|
||
// `insert-module-globals`), Narwhal, and Ringo as the default context,
|
||
// and the `window` object in browsers. Rhino exports a `global` function
|
||
// instead.
|
||
var root = objectTypes[typeof window] && window || this,
|
||
freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == "object" && global;
|
||
|
||
if (freeGlobal && (freeGlobal["global"] === freeGlobal || freeGlobal["window"] === freeGlobal || freeGlobal["self"] === freeGlobal)) {
|
||
root = freeGlobal;
|
||
}
|
||
|
||
// Public: Initializes JSON 3 using the given `context` object, attaching the
|
||
// `stringify` and `parse` functions to the specified `exports` object.
|
||
function runInContext(context, exports) {
|
||
context || (context = root["Object"]());
|
||
exports || (exports = root["Object"]());
|
||
|
||
// Native constructor aliases.
|
||
var Number = context["Number"] || root["Number"],
|
||
String = context["String"] || root["String"],
|
||
Object = context["Object"] || root["Object"],
|
||
Date = context["Date"] || root["Date"],
|
||
SyntaxError = context["SyntaxError"] || root["SyntaxError"],
|
||
TypeError = context["TypeError"] || root["TypeError"],
|
||
Math = context["Math"] || root["Math"],
|
||
nativeJSON = context["JSON"] || root["JSON"];
|
||
|
||
// Delegate to the native `stringify` and `parse` implementations.
|
||
if (typeof nativeJSON == "object" && nativeJSON) {
|
||
exports.stringify = nativeJSON.stringify;
|
||
exports.parse = nativeJSON.parse;
|
||
}
|
||
|
||
// Convenience aliases.
|
||
var objectProto = Object.prototype,
|
||
getClass = objectProto.toString,
|
||
isProperty, forEach, undef;
|
||
|
||
// Test the `Date#getUTC*` methods. Based on work by @Yaffle.
|
||
var isExtended = new Date(-3509827334573292);
|
||
try {
|
||
// The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical
|
||
// results for certain dates in Opera >= 10.53.
|
||
isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&
|
||
// Safari < 2.0.2 stores the internal millisecond time value correctly,
|
||
// but clips the values returned by the date methods to the range of
|
||
// signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).
|
||
isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;
|
||
} catch (exception) {}
|
||
|
||
// Internal: Determines whether the native `JSON.stringify` and `parse`
|
||
// implementations are spec-compliant. Based on work by Ken Snyder.
|
||
function has(name) {
|
||
if (has[name] !== undef) {
|
||
// Return cached feature test result.
|
||
return has[name];
|
||
}
|
||
var isSupported;
|
||
if (name == "bug-string-char-index") {
|
||
// IE <= 7 doesn't support accessing string characters using square
|
||
// bracket notation. IE 8 only supports this for primitives.
|
||
isSupported = "a"[0] != "a";
|
||
} else if (name == "json") {
|
||
// Indicates whether both `JSON.stringify` and `JSON.parse` are
|
||
// supported.
|
||
isSupported = has("json-stringify") && has("json-parse");
|
||
} else {
|
||
var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';
|
||
// Test `JSON.stringify`.
|
||
if (name == "json-stringify") {
|
||
var stringify = exports.stringify, stringifySupported = typeof stringify == "function" && isExtended;
|
||
if (stringifySupported) {
|
||
// A test function object with a custom `toJSON` method.
|
||
(value = function () {
|
||
return 1;
|
||
}).toJSON = value;
|
||
try {
|
||
stringifySupported =
|
||
// Firefox 3.1b1 and b2 serialize string, number, and boolean
|
||
// primitives as object literals.
|
||
stringify(0) === "0" &&
|
||
// FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object
|
||
// literals.
|
||
stringify(new Number()) === "0" &&
|
||
stringify(new String()) == '""' &&
|
||
// FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or
|
||
// does not define a canonical JSON representation (this applies to
|
||
// objects with `toJSON` properties as well, *unless* they are nested
|
||
// within an object or array).
|
||
stringify(getClass) === undef &&
|
||
// IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and
|
||
// FF 3.1b3 pass this test.
|
||
stringify(undef) === undef &&
|
||
// Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,
|
||
// respectively, if the value is omitted entirely.
|
||
stringify() === undef &&
|
||
// FF 3.1b1, 2 throw an error if the given value is not a number,
|
||
// string, array, object, Boolean, or `null` literal. This applies to
|
||
// objects with custom `toJSON` methods as well, unless they are nested
|
||
// inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`
|
||
// methods entirely.
|
||
stringify(value) === "1" &&
|
||
stringify([value]) == "[1]" &&
|
||
// Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of
|
||
// `"[null]"`.
|
||
stringify([undef]) == "[null]" &&
|
||
// YUI 3.0.0b1 fails to serialize `null` literals.
|
||
stringify(null) == "null" &&
|
||
// FF 3.1b1, 2 halts serialization if an array contains a function:
|
||
// `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3
|
||
// elides non-JSON values from objects and arrays, unless they
|
||
// define custom `toJSON` methods.
|
||
stringify([undef, getClass, null]) == "[null,null,null]" &&
|
||
// Simple serialization test. FF 3.1b1 uses Unicode escape sequences
|
||
// where character escape codes are expected (e.g., `\b` => `\u0008`).
|
||
stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized &&
|
||
// FF 3.1b1 and b2 ignore the `filter` and `width` arguments.
|
||
stringify(null, value) === "1" &&
|
||
stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" &&
|
||
// JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly
|
||
// serialize extended years.
|
||
stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' &&
|
||
// The milliseconds are optional in ES 5, but required in 5.1.
|
||
stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' &&
|
||
// Firefox <= 11.0 incorrectly serializes years prior to 0 as negative
|
||
// four-digit years instead of six-digit years. Credits: @Yaffle.
|
||
stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' &&
|
||
// Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond
|
||
// values less than 1000. Credits: @Yaffle.
|
||
stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"';
|
||
} catch (exception) {
|
||
stringifySupported = false;
|
||
}
|
||
}
|
||
isSupported = stringifySupported;
|
||
}
|
||
// Test `JSON.parse`.
|
||
if (name == "json-parse") {
|
||
var parse = exports.parse;
|
||
if (typeof parse == "function") {
|
||
try {
|
||
// FF 3.1b1, b2 will throw an exception if a bare literal is provided.
|
||
// Conforming implementations should also coerce the initial argument to
|
||
// a string prior to parsing.
|
||
if (parse("0") === 0 && !parse(false)) {
|
||
// Simple parsing test.
|
||
value = parse(serialized);
|
||
var parseSupported = value["a"].length == 5 && value["a"][0] === 1;
|
||
if (parseSupported) {
|
||
try {
|
||
// Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.
|
||
parseSupported = !parse('"\t"');
|
||
} catch (exception) {}
|
||
if (parseSupported) {
|
||
try {
|
||
// FF 4.0 and 4.0.1 allow leading `+` signs and leading
|
||
// decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow
|
||
// certain octal literals.
|
||
parseSupported = parse("01") !== 1;
|
||
} catch (exception) {}
|
||
}
|
||
if (parseSupported) {
|
||
try {
|
||
// FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal
|
||
// points. These environments, along with FF 3.1b1 and 2,
|
||
// also allow trailing commas in JSON objects and arrays.
|
||
parseSupported = parse("1.") !== 1;
|
||
} catch (exception) {}
|
||
}
|
||
}
|
||
}
|
||
} catch (exception) {
|
||
parseSupported = false;
|
||
}
|
||
}
|
||
isSupported = parseSupported;
|
||
}
|
||
}
|
||
return has[name] = !!isSupported;
|
||
}
|
||
|
||
if (!has("json")) {
|
||
// Common `[[Class]]` name aliases.
|
||
var functionClass = "[object Function]",
|
||
dateClass = "[object Date]",
|
||
numberClass = "[object Number]",
|
||
stringClass = "[object String]",
|
||
arrayClass = "[object Array]",
|
||
booleanClass = "[object Boolean]";
|
||
|
||
// Detect incomplete support for accessing string characters by index.
|
||
var charIndexBuggy = has("bug-string-char-index");
|
||
|
||
// Define additional utility methods if the `Date` methods are buggy.
|
||
if (!isExtended) {
|
||
var floor = Math.floor;
|
||
// A mapping between the months of the year and the number of days between
|
||
// January 1st and the first of the respective month.
|
||
var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
|
||
// Internal: Calculates the number of days between the Unix epoch and the
|
||
// first day of the given month.
|
||
var getDay = function (year, month) {
|
||
return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);
|
||
};
|
||
}
|
||
|
||
// Internal: Determines if a property is a direct property of the given
|
||
// object. Delegates to the native `Object#hasOwnProperty` method.
|
||
if (!(isProperty = objectProto.hasOwnProperty)) {
|
||
isProperty = function (property) {
|
||
var members = {}, constructor;
|
||
if ((members.__proto__ = null, members.__proto__ = {
|
||
// The *proto* property cannot be set multiple times in recent
|
||
// versions of Firefox and SeaMonkey.
|
||
"toString": 1
|
||
}, members).toString != getClass) {
|
||
// Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but
|
||
// supports the mutable *proto* property.
|
||
isProperty = function (property) {
|
||
// Capture and break the object's prototype chain (see section 8.6.2
|
||
// of the ES 5.1 spec). The parenthesized expression prevents an
|
||
// unsafe transformation by the Closure Compiler.
|
||
var original = this.__proto__, result = property in (this.__proto__ = null, this);
|
||
// Restore the original prototype chain.
|
||
this.__proto__ = original;
|
||
return result;
|
||
};
|
||
} else {
|
||
// Capture a reference to the top-level `Object` constructor.
|
||
constructor = members.constructor;
|
||
// Use the `constructor` property to simulate `Object#hasOwnProperty` in
|
||
// other environments.
|
||
isProperty = function (property) {
|
||
var parent = (this.constructor || constructor).prototype;
|
||
return property in this && !(property in parent && this[property] === parent[property]);
|
||
};
|
||
}
|
||
members = null;
|
||
return isProperty.call(this, property);
|
||
};
|
||
}
|
||
|
||
// Internal: Normalizes the `for...in` iteration algorithm across
|
||
// environments. Each enumerated key is yielded to a `callback` function.
|
||
forEach = function (object, callback) {
|
||
var size = 0, Properties, members, property;
|
||
|
||
// Tests for bugs in the current environment's `for...in` algorithm. The
|
||
// `valueOf` property inherits the non-enumerable flag from
|
||
// `Object.prototype` in older versions of IE, Netscape, and Mozilla.
|
||
(Properties = function () {
|
||
this.valueOf = 0;
|
||
}).prototype.valueOf = 0;
|
||
|
||
// Iterate over a new instance of the `Properties` class.
|
||
members = new Properties();
|
||
for (property in members) {
|
||
// Ignore all properties inherited from `Object.prototype`.
|
||
if (isProperty.call(members, property)) {
|
||
size++;
|
||
}
|
||
}
|
||
Properties = members = null;
|
||
|
||
// Normalize the iteration algorithm.
|
||
if (!size) {
|
||
// A list of non-enumerable properties inherited from `Object.prototype`.
|
||
members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"];
|
||
// IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable
|
||
// properties.
|
||
forEach = function (object, callback) {
|
||
var isFunction = getClass.call(object) == functionClass, property, length;
|
||
var hasProperty = !isFunction && typeof object.constructor != "function" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty;
|
||
for (property in object) {
|
||
// Gecko <= 1.0 enumerates the `prototype` property of functions under
|
||
// certain conditions; IE does not.
|
||
if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) {
|
||
callback(property);
|
||
}
|
||
}
|
||
// Manually invoke the callback for each non-enumerable property.
|
||
for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property));
|
||
};
|
||
} else if (size == 2) {
|
||
// Safari <= 2.0.4 enumerates shadowed properties twice.
|
||
forEach = function (object, callback) {
|
||
// Create a set of iterated properties.
|
||
var members = {}, isFunction = getClass.call(object) == functionClass, property;
|
||
for (property in object) {
|
||
// Store each property name to prevent double enumeration. The
|
||
// `prototype` property of functions is not enumerated due to cross-
|
||
// environment inconsistencies.
|
||
if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {
|
||
callback(property);
|
||
}
|
||
}
|
||
};
|
||
} else {
|
||
// No bugs detected; use the standard `for...in` algorithm.
|
||
forEach = function (object, callback) {
|
||
var isFunction = getClass.call(object) == functionClass, property, isConstructor;
|
||
for (property in object) {
|
||
if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) {
|
||
callback(property);
|
||
}
|
||
}
|
||
// Manually invoke the callback for the `constructor` property due to
|
||
// cross-environment inconsistencies.
|
||
if (isConstructor || isProperty.call(object, (property = "constructor"))) {
|
||
callback(property);
|
||
}
|
||
};
|
||
}
|
||
return forEach(object, callback);
|
||
};
|
||
|
||
// Public: Serializes a JavaScript `value` as a JSON string. The optional
|
||
// `filter` argument may specify either a function that alters how object and
|
||
// array members are serialized, or an array of strings and numbers that
|
||
// indicates which properties should be serialized. The optional `width`
|
||
// argument may be either a string or number that specifies the indentation
|
||
// level of the output.
|
||
if (!has("json-stringify")) {
|
||
// Internal: A map of control characters and their escaped equivalents.
|
||
var Escapes = {
|
||
92: "\\\\",
|
||
34: '\\"',
|
||
8: "\\b",
|
||
12: "\\f",
|
||
10: "\\n",
|
||
13: "\\r",
|
||
9: "\\t"
|
||
};
|
||
|
||
// Internal: Converts `value` into a zero-padded string such that its
|
||
// length is at least equal to `width`. The `width` must be <= 6.
|
||
var leadingZeroes = "000000";
|
||
var toPaddedString = function (width, value) {
|
||
// The `|| 0` expression is necessary to work around a bug in
|
||
// Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`.
|
||
return (leadingZeroes + (value || 0)).slice(-width);
|
||
};
|
||
|
||
// Internal: Double-quotes a string `value`, replacing all ASCII control
|
||
// characters (characters with code unit values between 0 and 31) with
|
||
// their escaped equivalents. This is an implementation of the
|
||
// `Quote(value)` operation defined in ES 5.1 section 15.12.3.
|
||
var unicodePrefix = "\\u00";
|
||
var quote = function (value) {
|
||
var result = '"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10;
|
||
var symbols = useCharIndex && (charIndexBuggy ? value.split("") : value);
|
||
for (; index < length; index++) {
|
||
var charCode = value.charCodeAt(index);
|
||
// If the character is a control character, append its Unicode or
|
||
// shorthand escape sequence; otherwise, append the character as-is.
|
||
switch (charCode) {
|
||
case 8: case 9: case 10: case 12: case 13: case 34: case 92:
|
||
result += Escapes[charCode];
|
||
break;
|
||
default:
|
||
if (charCode < 32) {
|
||
result += unicodePrefix + toPaddedString(2, charCode.toString(16));
|
||
break;
|
||
}
|
||
result += useCharIndex ? symbols[index] : value.charAt(index);
|
||
}
|
||
}
|
||
return result + '"';
|
||
};
|
||
|
||
// Internal: Recursively serializes an object. Implements the
|
||
// `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.
|
||
var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {
|
||
var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;
|
||
try {
|
||
// Necessary for host object support.
|
||
value = object[property];
|
||
} catch (exception) {}
|
||
if (typeof value == "object" && value) {
|
||
className = getClass.call(value);
|
||
if (className == dateClass && !isProperty.call(value, "toJSON")) {
|
||
if (value > -1 / 0 && value < 1 / 0) {
|
||
// Dates are serialized according to the `Date#toJSON` method
|
||
// specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15
|
||
// for the ISO 8601 date time string format.
|
||
if (getDay) {
|
||
// Manually compute the year, month, date, hours, minutes,
|
||
// seconds, and milliseconds if the `getUTC*` methods are
|
||
// buggy. Adapted from @Yaffle's `date-shim` project.
|
||
date = floor(value / 864e5);
|
||
for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);
|
||
for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);
|
||
date = 1 + date - getDay(year, month);
|
||
// The `time` value specifies the time within the day (see ES
|
||
// 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used
|
||
// to compute `A modulo B`, as the `%` operator does not
|
||
// correspond to the `modulo` operation for negative numbers.
|
||
time = (value % 864e5 + 864e5) % 864e5;
|
||
// The hours, minutes, seconds, and milliseconds are obtained by
|
||
// decomposing the time within the day. See section 15.9.1.10.
|
||
hours = floor(time / 36e5) % 24;
|
||
minutes = floor(time / 6e4) % 60;
|
||
seconds = floor(time / 1e3) % 60;
|
||
milliseconds = time % 1e3;
|
||
} else {
|
||
year = value.getUTCFullYear();
|
||
month = value.getUTCMonth();
|
||
date = value.getUTCDate();
|
||
hours = value.getUTCHours();
|
||
minutes = value.getUTCMinutes();
|
||
seconds = value.getUTCSeconds();
|
||
milliseconds = value.getUTCMilliseconds();
|
||
}
|
||
// Serialize extended years correctly.
|
||
value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +
|
||
"-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) +
|
||
// Months, dates, hours, minutes, and seconds should have two
|
||
// digits; milliseconds should have three.
|
||
"T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) +
|
||
// Milliseconds are optional in ES 5.0, but required in 5.1.
|
||
"." + toPaddedString(3, milliseconds) + "Z";
|
||
} else {
|
||
value = null;
|
||
}
|
||
} else if (typeof value.toJSON == "function" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, "toJSON"))) {
|
||
// Prototype <= 1.6.1 adds non-standard `toJSON` methods to the
|
||
// `Number`, `String`, `Date`, and `Array` prototypes. JSON 3
|
||
// ignores all `toJSON` methods on these objects unless they are
|
||
// defined directly on an instance.
|
||
value = value.toJSON(property);
|
||
}
|
||
}
|
||
if (callback) {
|
||
// If a replacement function was provided, call it to obtain the value
|
||
// for serialization.
|
||
value = callback.call(object, property, value);
|
||
}
|
||
if (value === null) {
|
||
return "null";
|
||
}
|
||
className = getClass.call(value);
|
||
if (className == booleanClass) {
|
||
// Booleans are represented literally.
|
||
return "" + value;
|
||
} else if (className == numberClass) {
|
||
// JSON numbers must be finite. `Infinity` and `NaN` are serialized as
|
||
// `"null"`.
|
||
return value > -1 / 0 && value < 1 / 0 ? "" + value : "null";
|
||
} else if (className == stringClass) {
|
||
// Strings are double-quoted and escaped.
|
||
return quote("" + value);
|
||
}
|
||
// Recursively serialize objects and arrays.
|
||
if (typeof value == "object") {
|
||
// Check for cyclic structures. This is a linear search; performance
|
||
// is inversely proportional to the number of unique nested objects.
|
||
for (length = stack.length; length--;) {
|
||
if (stack[length] === value) {
|
||
// Cyclic structures cannot be serialized by `JSON.stringify`.
|
||
throw TypeError();
|
||
}
|
||
}
|
||
// Add the object to the stack of traversed objects.
|
||
stack.push(value);
|
||
results = [];
|
||
// Save the current indentation level and indent one additional level.
|
||
prefix = indentation;
|
||
indentation += whitespace;
|
||
if (className == arrayClass) {
|
||
// Recursively serialize array elements.
|
||
for (index = 0, length = value.length; index < length; index++) {
|
||
element = serialize(index, value, callback, properties, whitespace, indentation, stack);
|
||
results.push(element === undef ? "null" : element);
|
||
}
|
||
result = results.length ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]";
|
||
} else {
|
||
// Recursively serialize object members. Members are selected from
|
||
// either a user-specified list of property names, or the object
|
||
// itself.
|
||
forEach(properties || value, function (property) {
|
||
var element = serialize(property, value, callback, properties, whitespace, indentation, stack);
|
||
if (element !== undef) {
|
||
// According to ES 5.1 section 15.12.3: "If `gap` {whitespace}
|
||
// is not the empty string, let `member` {quote(property) + ":"}
|
||
// be the concatenation of `member` and the `space` character."
|
||
// The "`space` character" refers to the literal space
|
||
// character, not the `space` {width} argument provided to
|
||
// `JSON.stringify`.
|
||
results.push(quote(property) + ":" + (whitespace ? " " : "") + element);
|
||
}
|
||
});
|
||
result = results.length ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}";
|
||
}
|
||
// Remove the object from the traversed object stack.
|
||
stack.pop();
|
||
return result;
|
||
}
|
||
};
|
||
|
||
// Public: `JSON.stringify`. See ES 5.1 section 15.12.3.
|
||
exports.stringify = function (source, filter, width) {
|
||
var whitespace, callback, properties, className;
|
||
if (objectTypes[typeof filter] && filter) {
|
||
if ((className = getClass.call(filter)) == functionClass) {
|
||
callback = filter;
|
||
} else if (className == arrayClass) {
|
||
// Convert the property names array into a makeshift set.
|
||
properties = {};
|
||
for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1));
|
||
}
|
||
}
|
||
if (width) {
|
||
if ((className = getClass.call(width)) == numberClass) {
|
||
// Convert the `width` to an integer and create a string containing
|
||
// `width` number of space characters.
|
||
if ((width -= width % 1) > 0) {
|
||
for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " ");
|
||
}
|
||
} else if (className == stringClass) {
|
||
whitespace = width.length <= 10 ? width : width.slice(0, 10);
|
||
}
|
||
}
|
||
// Opera <= 7.54u2 discards the values associated with empty string keys
|
||
// (`""`) only if they are used directly within an object member list
|
||
// (e.g., `!("" in { "": 1})`).
|
||
return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []);
|
||
};
|
||
}
|
||
|
||
// Public: Parses a JSON source string.
|
||
if (!has("json-parse")) {
|
||
var fromCharCode = String.fromCharCode;
|
||
|
||
// Internal: A map of escaped control characters and their unescaped
|
||
// equivalents.
|
||
var Unescapes = {
|
||
92: "\\",
|
||
34: '"',
|
||
47: "/",
|
||
98: "\b",
|
||
116: "\t",
|
||
110: "\n",
|
||
102: "\f",
|
||
114: "\r"
|
||
};
|
||
|
||
// Internal: Stores the parser state.
|
||
var Index, Source;
|
||
|
||
// Internal: Resets the parser state and throws a `SyntaxError`.
|
||
var abort = function () {
|
||
Index = Source = null;
|
||
throw SyntaxError();
|
||
};
|
||
|
||
// Internal: Returns the next token, or `"$"` if the parser has reached
|
||
// the end of the source string. A token may be a string, number, `null`
|
||
// literal, or Boolean literal.
|
||
var lex = function () {
|
||
var source = Source, length = source.length, value, begin, position, isSigned, charCode;
|
||
while (Index < length) {
|
||
charCode = source.charCodeAt(Index);
|
||
switch (charCode) {
|
||
case 9: case 10: case 13: case 32:
|
||
// Skip whitespace tokens, including tabs, carriage returns, line
|
||
// feeds, and space characters.
|
||
Index++;
|
||
break;
|
||
case 123: case 125: case 91: case 93: case 58: case 44:
|
||
// Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at
|
||
// the current position.
|
||
value = charIndexBuggy ? source.charAt(Index) : source[Index];
|
||
Index++;
|
||
return value;
|
||
case 34:
|
||
// `"` delimits a JSON string; advance to the next character and
|
||
// begin parsing the string. String tokens are prefixed with the
|
||
// sentinel `@` character to distinguish them from punctuators and
|
||
// end-of-string tokens.
|
||
for (value = "@", Index++; Index < length;) {
|
||
charCode = source.charCodeAt(Index);
|
||
if (charCode < 32) {
|
||
// Unescaped ASCII control characters (those with a code unit
|
||
// less than the space character) are not permitted.
|
||
abort();
|
||
} else if (charCode == 92) {
|
||
// A reverse solidus (`\`) marks the beginning of an escaped
|
||
// control character (including `"`, `\`, and `/`) or Unicode
|
||
// escape sequence.
|
||
charCode = source.charCodeAt(++Index);
|
||
switch (charCode) {
|
||
case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114:
|
||
// Revive escaped control characters.
|
||
value += Unescapes[charCode];
|
||
Index++;
|
||
break;
|
||
case 117:
|
||
// `\u` marks the beginning of a Unicode escape sequence.
|
||
// Advance to the first character and validate the
|
||
// four-digit code point.
|
||
begin = ++Index;
|
||
for (position = Index + 4; Index < position; Index++) {
|
||
charCode = source.charCodeAt(Index);
|
||
// A valid sequence comprises four hexdigits (case-
|
||
// insensitive) that form a single hexadecimal value.
|
||
if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {
|
||
// Invalid Unicode escape sequence.
|
||
abort();
|
||
}
|
||
}
|
||
// Revive the escaped character.
|
||
value += fromCharCode("0x" + source.slice(begin, Index));
|
||
break;
|
||
default:
|
||
// Invalid escape sequence.
|
||
abort();
|
||
}
|
||
} else {
|
||
if (charCode == 34) {
|
||
// An unescaped double-quote character marks the end of the
|
||
// string.
|
||
break;
|
||
}
|
||
charCode = source.charCodeAt(Index);
|
||
begin = Index;
|
||
// Optimize for the common case where a string is valid.
|
||
while (charCode >= 32 && charCode != 92 && charCode != 34) {
|
||
charCode = source.charCodeAt(++Index);
|
||
}
|
||
// Append the string as-is.
|
||
value += source.slice(begin, Index);
|
||
}
|
||
}
|
||
if (source.charCodeAt(Index) == 34) {
|
||
// Advance to the next character and return the revived string.
|
||
Index++;
|
||
return value;
|
||
}
|
||
// Unterminated string.
|
||
abort();
|
||
default:
|
||
// Parse numbers and literals.
|
||
begin = Index;
|
||
// Advance past the negative sign, if one is specified.
|
||
if (charCode == 45) {
|
||
isSigned = true;
|
||
charCode = source.charCodeAt(++Index);
|
||
}
|
||
// Parse an integer or floating-point value.
|
||
if (charCode >= 48 && charCode <= 57) {
|
||
// Leading zeroes are interpreted as octal literals.
|
||
if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {
|
||
// Illegal octal literal.
|
||
abort();
|
||
}
|
||
isSigned = false;
|
||
// Parse the integer component.
|
||
for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++);
|
||
// Floats cannot contain a leading decimal point; however, this
|
||
// case is already accounted for by the parser.
|
||
if (source.charCodeAt(Index) == 46) {
|
||
position = ++Index;
|
||
// Parse the decimal component.
|
||
for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);
|
||
if (position == Index) {
|
||
// Illegal trailing decimal.
|
||
abort();
|
||
}
|
||
Index = position;
|
||
}
|
||
// Parse exponents. The `e` denoting the exponent is
|
||
// case-insensitive.
|
||
charCode = source.charCodeAt(Index);
|
||
if (charCode == 101 || charCode == 69) {
|
||
charCode = source.charCodeAt(++Index);
|
||
// Skip past the sign following the exponent, if one is
|
||
// specified.
|
||
if (charCode == 43 || charCode == 45) {
|
||
Index++;
|
||
}
|
||
// Parse the exponential component.
|
||
for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);
|
||
if (position == Index) {
|
||
// Illegal empty exponent.
|
||
abort();
|
||
}
|
||
Index = position;
|
||
}
|
||
// Coerce the parsed value to a JavaScript number.
|
||
return +source.slice(begin, Index);
|
||
}
|
||
// A negative sign may only precede numbers.
|
||
if (isSigned) {
|
||
abort();
|
||
}
|
||
// `true`, `false`, and `null` literals.
|
||
if (source.slice(Index, Index + 4) == "true") {
|
||
Index += 4;
|
||
return true;
|
||
} else if (source.slice(Index, Index + 5) == "false") {
|
||
Index += 5;
|
||
return false;
|
||
} else if (source.slice(Index, Index + 4) == "null") {
|
||
Index += 4;
|
||
return null;
|
||
}
|
||
// Unrecognized token.
|
||
abort();
|
||
}
|
||
}
|
||
// Return the sentinel `$` character if the parser has reached the end
|
||
// of the source string.
|
||
return "$";
|
||
};
|
||
|
||
// Internal: Parses a JSON `value` token.
|
||
var get = function (value) {
|
||
var results, hasMembers;
|
||
if (value == "$") {
|
||
// Unexpected end of input.
|
||
abort();
|
||
}
|
||
if (typeof value == "string") {
|
||
if ((charIndexBuggy ? value.charAt(0) : value[0]) == "@") {
|
||
// Remove the sentinel `@` character.
|
||
return value.slice(1);
|
||
}
|
||
// Parse object and array literals.
|
||
if (value == "[") {
|
||
// Parses a JSON array, returning a new JavaScript array.
|
||
results = [];
|
||
for (;; hasMembers || (hasMembers = true)) {
|
||
value = lex();
|
||
// A closing square bracket marks the end of the array literal.
|
||
if (value == "]") {
|
||
break;
|
||
}
|
||
// If the array literal contains elements, the current token
|
||
// should be a comma separating the previous element from the
|
||
// next.
|
||
if (hasMembers) {
|
||
if (value == ",") {
|
||
value = lex();
|
||
if (value == "]") {
|
||
// Unexpected trailing `,` in array literal.
|
||
abort();
|
||
}
|
||
} else {
|
||
// A `,` must separate each array element.
|
||
abort();
|
||
}
|
||
}
|
||
// Elisions and leading commas are not permitted.
|
||
if (value == ",") {
|
||
abort();
|
||
}
|
||
results.push(get(value));
|
||
}
|
||
return results;
|
||
} else if (value == "{") {
|
||
// Parses a JSON object, returning a new JavaScript object.
|
||
results = {};
|
||
for (;; hasMembers || (hasMembers = true)) {
|
||
value = lex();
|
||
// A closing curly brace marks the end of the object literal.
|
||
if (value == "}") {
|
||
break;
|
||
}
|
||
// If the object literal contains members, the current token
|
||
// should be a comma separator.
|
||
if (hasMembers) {
|
||
if (value == ",") {
|
||
value = lex();
|
||
if (value == "}") {
|
||
// Unexpected trailing `,` in object literal.
|
||
abort();
|
||
}
|
||
} else {
|
||
// A `,` must separate each object member.
|
||
abort();
|
||
}
|
||
}
|
||
// Leading commas are not permitted, object property names must be
|
||
// double-quoted strings, and a `:` must separate each property
|
||
// name and value.
|
||
if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") {
|
||
abort();
|
||
}
|
||
results[value.slice(1)] = get(lex());
|
||
}
|
||
return results;
|
||
}
|
||
// Unexpected token encountered.
|
||
abort();
|
||
}
|
||
return value;
|
||
};
|
||
|
||
// Internal: Updates a traversed object member.
|
||
var update = function (source, property, callback) {
|
||
var element = walk(source, property, callback);
|
||
if (element === undef) {
|
||
delete source[property];
|
||
} else {
|
||
source[property] = element;
|
||
}
|
||
};
|
||
|
||
// Internal: Recursively traverses a parsed JSON object, invoking the
|
||
// `callback` function for each value. This is an implementation of the
|
||
// `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.
|
||
var walk = function (source, property, callback) {
|
||
var value = source[property], length;
|
||
if (typeof value == "object" && value) {
|
||
// `forEach` can't be used to traverse an array in Opera <= 8.54
|
||
// because its `Object#hasOwnProperty` implementation returns `false`
|
||
// for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`).
|
||
if (getClass.call(value) == arrayClass) {
|
||
for (length = value.length; length--;) {
|
||
update(value, length, callback);
|
||
}
|
||
} else {
|
||
forEach(value, function (property) {
|
||
update(value, property, callback);
|
||
});
|
||
}
|
||
}
|
||
return callback.call(source, property, value);
|
||
};
|
||
|
||
// Public: `JSON.parse`. See ES 5.1 section 15.12.2.
|
||
exports.parse = function (source, callback) {
|
||
var result, value;
|
||
Index = 0;
|
||
Source = "" + source;
|
||
result = get(lex());
|
||
// If a JSON string contains multiple tokens, it is invalid.
|
||
if (lex() != "$") {
|
||
abort();
|
||
}
|
||
// Reset the parser state.
|
||
Index = Source = null;
|
||
return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result;
|
||
};
|
||
}
|
||
}
|
||
|
||
exports["runInContext"] = runInContext;
|
||
return exports;
|
||
}
|
||
|
||
if (freeExports && !isLoader) {
|
||
// Export for CommonJS environments.
|
||
runInContext(root, freeExports);
|
||
} else {
|
||
// Export for web browsers and JavaScript engines.
|
||
var nativeJSON = root.JSON,
|
||
previousJSON = root["JSON3"],
|
||
isRestored = false;
|
||
|
||
var JSON3 = runInContext(root, (root["JSON3"] = {
|
||
// Public: Restores the original value of the global `JSON` object and
|
||
// returns a reference to the `JSON3` object.
|
||
"noConflict": function () {
|
||
if (!isRestored) {
|
||
isRestored = true;
|
||
root.JSON = nativeJSON;
|
||
root["JSON3"] = previousJSON;
|
||
nativeJSON = previousJSON = null;
|
||
}
|
||
return JSON3;
|
||
}
|
||
}));
|
||
|
||
root.JSON = {
|
||
"parse": JSON3.parse,
|
||
"stringify": JSON3.stringify
|
||
};
|
||
}
|
||
|
||
// Export for asynchronous module loaders.
|
||
if (isLoader) {
|
||
define(function () {
|
||
return JSON3;
|
||
});
|
||
}
|
||
}).call(this);
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],148:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/to-array/index.js", module);
|
||
(function(){
|
||
module.exports = toArray
|
||
|
||
function toArray(list, index) {
|
||
var array = []
|
||
|
||
index = index || 0
|
||
|
||
for (var i = index || 0; i < list.length; i++) {
|
||
array[i - index] = list[i]
|
||
}
|
||
|
||
return array
|
||
}
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],149:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/utf8/utf8.js", module);
|
||
(function(){
|
||
(function (global){
|
||
/*! https://mths.be/utf8js v2.0.0 by @mathias */
|
||
;(function(root) {
|
||
|
||
// Detect free variables `exports`
|
||
var freeExports = typeof exports == 'object' && exports;
|
||
|
||
// Detect free variable `module`
|
||
var freeModule = typeof module == 'object' && module &&
|
||
module.exports == freeExports && module;
|
||
|
||
// Detect free variable `global`, from Node.js or Browserified code,
|
||
// and use it as `root`
|
||
var freeGlobal = typeof global == 'object' && global;
|
||
if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
|
||
root = freeGlobal;
|
||
}
|
||
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
var stringFromCharCode = String.fromCharCode;
|
||
|
||
// Taken from https://mths.be/punycode
|
||
function ucs2decode(string) {
|
||
var output = [];
|
||
var counter = 0;
|
||
var length = string.length;
|
||
var value;
|
||
var extra;
|
||
while (counter < length) {
|
||
value = string.charCodeAt(counter++);
|
||
if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
|
||
// high surrogate, and there is a next character
|
||
extra = string.charCodeAt(counter++);
|
||
if ((extra & 0xFC00) == 0xDC00) { // low surrogate
|
||
output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
|
||
} else {
|
||
// unmatched surrogate; only append this code unit, in case the next
|
||
// code unit is the high surrogate of a surrogate pair
|
||
output.push(value);
|
||
counter--;
|
||
}
|
||
} else {
|
||
output.push(value);
|
||
}
|
||
}
|
||
return output;
|
||
}
|
||
|
||
// Taken from https://mths.be/punycode
|
||
function ucs2encode(array) {
|
||
var length = array.length;
|
||
var index = -1;
|
||
var value;
|
||
var output = '';
|
||
while (++index < length) {
|
||
value = array[index];
|
||
if (value > 0xFFFF) {
|
||
value -= 0x10000;
|
||
output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
|
||
value = 0xDC00 | value & 0x3FF;
|
||
}
|
||
output += stringFromCharCode(value);
|
||
}
|
||
return output;
|
||
}
|
||
|
||
function checkScalarValue(codePoint) {
|
||
if (codePoint >= 0xD800 && codePoint <= 0xDFFF) {
|
||
throw Error(
|
||
'Lone surrogate U+' + codePoint.toString(16).toUpperCase() +
|
||
' is not a scalar value'
|
||
);
|
||
}
|
||
}
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
function createByte(codePoint, shift) {
|
||
return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80);
|
||
}
|
||
|
||
function encodeCodePoint(codePoint) {
|
||
if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence
|
||
return stringFromCharCode(codePoint);
|
||
}
|
||
var symbol = '';
|
||
if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence
|
||
symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0);
|
||
}
|
||
else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence
|
||
checkScalarValue(codePoint);
|
||
symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0);
|
||
symbol += createByte(codePoint, 6);
|
||
}
|
||
else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence
|
||
symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0);
|
||
symbol += createByte(codePoint, 12);
|
||
symbol += createByte(codePoint, 6);
|
||
}
|
||
symbol += stringFromCharCode((codePoint & 0x3F) | 0x80);
|
||
return symbol;
|
||
}
|
||
|
||
function utf8encode(string) {
|
||
var codePoints = ucs2decode(string);
|
||
var length = codePoints.length;
|
||
var index = -1;
|
||
var codePoint;
|
||
var byteString = '';
|
||
while (++index < length) {
|
||
codePoint = codePoints[index];
|
||
byteString += encodeCodePoint(codePoint);
|
||
}
|
||
return byteString;
|
||
}
|
||
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
function readContinuationByte() {
|
||
if (byteIndex >= byteCount) {
|
||
throw Error('Invalid byte index');
|
||
}
|
||
|
||
var continuationByte = byteArray[byteIndex] & 0xFF;
|
||
byteIndex++;
|
||
|
||
if ((continuationByte & 0xC0) == 0x80) {
|
||
return continuationByte & 0x3F;
|
||
}
|
||
|
||
// If we end up here, it’s not a continuation byte
|
||
throw Error('Invalid continuation byte');
|
||
}
|
||
|
||
function decodeSymbol() {
|
||
var byte1;
|
||
var byte2;
|
||
var byte3;
|
||
var byte4;
|
||
var codePoint;
|
||
|
||
if (byteIndex > byteCount) {
|
||
throw Error('Invalid byte index');
|
||
}
|
||
|
||
if (byteIndex == byteCount) {
|
||
return false;
|
||
}
|
||
|
||
// Read first byte
|
||
byte1 = byteArray[byteIndex] & 0xFF;
|
||
byteIndex++;
|
||
|
||
// 1-byte sequence (no continuation bytes)
|
||
if ((byte1 & 0x80) == 0) {
|
||
return byte1;
|
||
}
|
||
|
||
// 2-byte sequence
|
||
if ((byte1 & 0xE0) == 0xC0) {
|
||
var byte2 = readContinuationByte();
|
||
codePoint = ((byte1 & 0x1F) << 6) | byte2;
|
||
if (codePoint >= 0x80) {
|
||
return codePoint;
|
||
} else {
|
||
throw Error('Invalid continuation byte');
|
||
}
|
||
}
|
||
|
||
// 3-byte sequence (may include unpaired surrogates)
|
||
if ((byte1 & 0xF0) == 0xE0) {
|
||
byte2 = readContinuationByte();
|
||
byte3 = readContinuationByte();
|
||
codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
|
||
if (codePoint >= 0x0800) {
|
||
checkScalarValue(codePoint);
|
||
return codePoint;
|
||
} else {
|
||
throw Error('Invalid continuation byte');
|
||
}
|
||
}
|
||
|
||
// 4-byte sequence
|
||
if ((byte1 & 0xF8) == 0xF0) {
|
||
byte2 = readContinuationByte();
|
||
byte3 = readContinuationByte();
|
||
byte4 = readContinuationByte();
|
||
codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) |
|
||
(byte3 << 0x06) | byte4;
|
||
if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {
|
||
return codePoint;
|
||
}
|
||
}
|
||
|
||
throw Error('Invalid UTF-8 detected');
|
||
}
|
||
|
||
var byteArray;
|
||
var byteCount;
|
||
var byteIndex;
|
||
function utf8decode(byteString) {
|
||
byteArray = ucs2decode(byteString);
|
||
byteCount = byteArray.length;
|
||
byteIndex = 0;
|
||
var codePoints = [];
|
||
var tmp;
|
||
while ((tmp = decodeSymbol()) !== false) {
|
||
codePoints.push(tmp);
|
||
}
|
||
return ucs2encode(codePoints);
|
||
}
|
||
|
||
/*--------------------------------------------------------------------------*/
|
||
|
||
var utf8 = {
|
||
'version': '2.0.0',
|
||
'encode': utf8encode,
|
||
'decode': utf8decode
|
||
};
|
||
|
||
// Some AMD build optimizers, like r.js, check for specific condition patterns
|
||
// like the following:
|
||
if (
|
||
typeof define == 'function' &&
|
||
typeof define.amd == 'object' &&
|
||
define.amd
|
||
) {
|
||
define(function() {
|
||
return utf8;
|
||
});
|
||
} else if (freeExports && !freeExports.nodeType) {
|
||
if (freeModule) { // in Node.js or RingoJS v0.8.0+
|
||
freeModule.exports = utf8;
|
||
} else { // in Narwhal or RingoJS v0.7.0-
|
||
var object = {};
|
||
var hasOwnProperty = object.hasOwnProperty;
|
||
for (var key in utf8) {
|
||
hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]);
|
||
}
|
||
}
|
||
} else { // in Rhino or a web browser
|
||
root.utf8 = utf8;
|
||
}
|
||
|
||
}(this));
|
||
|
||
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],150:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/vue-hot-reload-api/index.js", module);
|
||
(function(){
|
||
var Vue // late bind
|
||
var map = Object.create(null)
|
||
var shimmed = false
|
||
var isBrowserify = false
|
||
|
||
/**
|
||
* Determine compatibility and apply patch.
|
||
*
|
||
* @param {Function} vue
|
||
* @param {Boolean} browserify
|
||
*/
|
||
|
||
exports.install = function (vue, browserify) {
|
||
if (shimmed) return
|
||
shimmed = true
|
||
|
||
Vue = vue
|
||
isBrowserify = browserify
|
||
|
||
exports.compatible = !!Vue.internalDirectives
|
||
if (!exports.compatible) {
|
||
console.warn(
|
||
'[HMR] vue-loader hot reload is only compatible with ' +
|
||
'Vue.js 1.0.0+.'
|
||
)
|
||
return
|
||
}
|
||
|
||
// patch view directive
|
||
patchView(Vue.internalDirectives.component)
|
||
console.log('[HMR] Vue component hot reload shim applied.')
|
||
// shim router-view if present
|
||
var routerView = Vue.elementDirective('router-view')
|
||
if (routerView) {
|
||
patchView(routerView)
|
||
console.log('[HMR] vue-router <router-view> hot reload shim applied.')
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Shim the view directive (component or router-view).
|
||
*
|
||
* @param {Object} View
|
||
*/
|
||
|
||
function patchView (View) {
|
||
var unbuild = View.unbuild
|
||
View.unbuild = function (defer) {
|
||
if (!this.hotUpdating) {
|
||
var prevComponent = this.childVM && this.childVM.constructor
|
||
removeView(prevComponent, this)
|
||
// defer = true means we are transitioning to a new
|
||
// Component. Register this new component to the list.
|
||
if (defer) {
|
||
addView(this.Component, this)
|
||
}
|
||
}
|
||
// call original
|
||
return unbuild.call(this, defer)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Add a component view to a Component's hot list
|
||
*
|
||
* @param {Function} Component
|
||
* @param {Directive} view - view directive instance
|
||
*/
|
||
|
||
function addView (Component, view) {
|
||
var id = Component && Component.options.hotID
|
||
if (id) {
|
||
if (!map[id]) {
|
||
map[id] = {
|
||
Component: Component,
|
||
views: [],
|
||
instances: []
|
||
}
|
||
}
|
||
map[id].views.push(view)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Remove a component view from a Component's hot list
|
||
*
|
||
* @param {Function} Component
|
||
* @param {Directive} view - view directive instance
|
||
*/
|
||
|
||
function removeView (Component, view) {
|
||
var id = Component && Component.options.hotID
|
||
if (id) {
|
||
map[id].views.$remove(view)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Create a record for a hot module, which keeps track of its construcotr,
|
||
* instnaces and views (component directives or router-views).
|
||
*
|
||
* @param {String} id
|
||
* @param {Object} options
|
||
*/
|
||
|
||
exports.createRecord = function (id, options) {
|
||
if (typeof options === 'function') {
|
||
options = options.options
|
||
}
|
||
if (typeof options.el !== 'string' && typeof options.data !== 'object') {
|
||
makeOptionsHot(id, options)
|
||
map[id] = {
|
||
Component: null,
|
||
views: [],
|
||
instances: []
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Make a Component options object hot.
|
||
*
|
||
* @param {String} id
|
||
* @param {Object} options
|
||
*/
|
||
|
||
function makeOptionsHot (id, options) {
|
||
options.hotID = id
|
||
injectHook(options, 'created', function () {
|
||
var record = map[id]
|
||
if (!record.Component) {
|
||
record.Component = this.constructor
|
||
}
|
||
record.instances.push(this)
|
||
})
|
||
injectHook(options, 'beforeDestroy', function () {
|
||
map[id].instances.$remove(this)
|
||
})
|
||
}
|
||
|
||
/**
|
||
* Inject a hook to a hot reloadable component so that
|
||
* we can keep track of it.
|
||
*
|
||
* @param {Object} options
|
||
* @param {String} name
|
||
* @param {Function} hook
|
||
*/
|
||
|
||
function injectHook (options, name, hook) {
|
||
var existing = options[name]
|
||
options[name] = existing
|
||
? Array.isArray(existing)
|
||
? existing.concat(hook)
|
||
: [existing, hook]
|
||
: [hook]
|
||
}
|
||
|
||
/**
|
||
* Update a hot component.
|
||
*
|
||
* @param {String} id
|
||
* @param {Object|null} newOptions
|
||
* @param {String|null} newTemplate
|
||
*/
|
||
|
||
exports.update = function (id, newOptions, newTemplate) {
|
||
var record = map[id]
|
||
// force full-reload if an instance of the component is active but is not
|
||
// managed by a view
|
||
if (!record || (record.instances.length && !record.views.length)) {
|
||
console.log('[HMR] Root or manually-mounted instance modified. Full reload may be required.')
|
||
if (!isBrowserify) {
|
||
window.location.reload()
|
||
} else {
|
||
// browserify-hmr somehow sends incomplete bundle if we reload here
|
||
return
|
||
}
|
||
}
|
||
if (!isBrowserify) {
|
||
// browserify-hmr already logs this
|
||
console.log('[HMR] Updating component: ' + format(id))
|
||
}
|
||
var Component = record.Component
|
||
// update constructor
|
||
if (newOptions) {
|
||
// in case the user exports a constructor
|
||
Component = record.Component = typeof newOptions === 'function'
|
||
? newOptions
|
||
: Vue.extend(newOptions)
|
||
makeOptionsHot(id, Component.options)
|
||
}
|
||
if (newTemplate) {
|
||
Component.options.template = newTemplate
|
||
}
|
||
// handle recursive lookup
|
||
if (Component.options.name) {
|
||
Component.options.components[Component.options.name] = Component
|
||
}
|
||
// reset constructor cached linker
|
||
Component.linker = null
|
||
// reload all views
|
||
record.views.forEach(function (view) {
|
||
updateView(view, Component)
|
||
})
|
||
// flush devtools
|
||
if (window.__VUE_DEVTOOLS_GLOBAL_HOOK__) {
|
||
window.__VUE_DEVTOOLS_GLOBAL_HOOK__.emit('flush')
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Update a component view instance
|
||
*
|
||
* @param {Directive} view
|
||
* @param {Function} Component
|
||
*/
|
||
|
||
function updateView (view, Component) {
|
||
if (!view._bound) {
|
||
return
|
||
}
|
||
view.Component = Component
|
||
view.hotUpdating = true
|
||
// disable transitions
|
||
view.vm._isCompiled = false
|
||
// save state
|
||
var state = extractState(view.childVM)
|
||
// remount, make sure to disable keep-alive
|
||
var keepAlive = view.keepAlive
|
||
view.keepAlive = false
|
||
view.mountComponent()
|
||
view.keepAlive = keepAlive
|
||
// restore state
|
||
restoreState(view.childVM, state, true)
|
||
// re-eanble transitions
|
||
view.vm._isCompiled = true
|
||
view.hotUpdating = false
|
||
}
|
||
|
||
/**
|
||
* Extract state from a Vue instance.
|
||
*
|
||
* @param {Vue} vm
|
||
* @return {Object}
|
||
*/
|
||
|
||
function extractState (vm) {
|
||
return {
|
||
cid: vm.constructor.cid,
|
||
data: vm.$data,
|
||
children: vm.$children.map(extractState)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Restore state to a reloaded Vue instance.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {Object} state
|
||
*/
|
||
|
||
function restoreState (vm, state, isRoot) {
|
||
var oldAsyncConfig
|
||
if (isRoot) {
|
||
// set Vue into sync mode during state rehydration
|
||
oldAsyncConfig = Vue.config.async
|
||
Vue.config.async = false
|
||
}
|
||
// actual restore
|
||
if (isRoot || !vm._props) {
|
||
vm.$data = state.data
|
||
} else {
|
||
Object.keys(state.data).forEach(function (key) {
|
||
if (!vm._props[key]) {
|
||
// for non-root, only restore non-props fields
|
||
vm.$data[key] = state.data[key]
|
||
}
|
||
})
|
||
}
|
||
// verify child consistency
|
||
var hasSameChildren = vm.$children.every(function (c, i) {
|
||
return state.children[i] && state.children[i].cid === c.constructor.cid
|
||
})
|
||
if (hasSameChildren) {
|
||
// rehydrate children
|
||
vm.$children.forEach(function (c, i) {
|
||
restoreState(c, state.children[i])
|
||
})
|
||
}
|
||
if (isRoot) {
|
||
Vue.config.async = oldAsyncConfig
|
||
}
|
||
}
|
||
|
||
function format (id) {
|
||
return id.match(/[^\/]+\.vue$/)[0]
|
||
}
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],151:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/vue/dist/vue.common.js", module);
|
||
(function(){
|
||
(function (process,global){
|
||
/*!
|
||
* Vue.js v1.0.17
|
||
* (c) 2016 Evan You
|
||
* Released under the MIT License.
|
||
*/
|
||
'use strict';
|
||
|
||
function set(obj, key, val) {
|
||
if (hasOwn(obj, key)) {
|
||
obj[key] = val;
|
||
return;
|
||
}
|
||
if (obj._isVue) {
|
||
set(obj._data, key, val);
|
||
return;
|
||
}
|
||
var ob = obj.__ob__;
|
||
if (!ob) {
|
||
obj[key] = val;
|
||
return;
|
||
}
|
||
ob.convert(key, val);
|
||
ob.dep.notify();
|
||
if (ob.vms) {
|
||
var i = ob.vms.length;
|
||
while (i--) {
|
||
var vm = ob.vms[i];
|
||
vm._proxy(key);
|
||
vm._digest();
|
||
}
|
||
}
|
||
return val;
|
||
}
|
||
|
||
/**
|
||
* Delete a property and trigger change if necessary.
|
||
*
|
||
* @param {Object} obj
|
||
* @param {String} key
|
||
*/
|
||
|
||
function del(obj, key) {
|
||
if (!hasOwn(obj, key)) {
|
||
return;
|
||
}
|
||
delete obj[key];
|
||
var ob = obj.__ob__;
|
||
if (!ob) {
|
||
return;
|
||
}
|
||
ob.dep.notify();
|
||
if (ob.vms) {
|
||
var i = ob.vms.length;
|
||
while (i--) {
|
||
var vm = ob.vms[i];
|
||
vm._unproxy(key);
|
||
vm._digest();
|
||
}
|
||
}
|
||
}
|
||
|
||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||
/**
|
||
* Check whether the object has the property.
|
||
*
|
||
* @param {Object} obj
|
||
* @param {String} key
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
function hasOwn(obj, key) {
|
||
return hasOwnProperty.call(obj, key);
|
||
}
|
||
|
||
/**
|
||
* Check if an expression is a literal value.
|
||
*
|
||
* @param {String} exp
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
var literalValueRE = /^\s?(true|false|-?[\d\.]+|'[^']*'|"[^"]*")\s?$/;
|
||
|
||
function isLiteral(exp) {
|
||
return literalValueRE.test(exp);
|
||
}
|
||
|
||
/**
|
||
* Check if a string starts with $ or _
|
||
*
|
||
* @param {String} str
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
function isReserved(str) {
|
||
var c = (str + '').charCodeAt(0);
|
||
return c === 0x24 || c === 0x5F;
|
||
}
|
||
|
||
/**
|
||
* Guard text output, make sure undefined outputs
|
||
* empty string
|
||
*
|
||
* @param {*} value
|
||
* @return {String}
|
||
*/
|
||
|
||
function _toString(value) {
|
||
return value == null ? '' : value.toString();
|
||
}
|
||
|
||
/**
|
||
* Check and convert possible numeric strings to numbers
|
||
* before setting back to data
|
||
*
|
||
* @param {*} value
|
||
* @return {*|Number}
|
||
*/
|
||
|
||
function toNumber(value) {
|
||
if (typeof value !== 'string') {
|
||
return value;
|
||
} else {
|
||
var parsed = Number(value);
|
||
return isNaN(parsed) ? value : parsed;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Convert string boolean literals into real booleans.
|
||
*
|
||
* @param {*} value
|
||
* @return {*|Boolean}
|
||
*/
|
||
|
||
function toBoolean(value) {
|
||
return value === 'true' ? true : value === 'false' ? false : value;
|
||
}
|
||
|
||
/**
|
||
* Strip quotes from a string
|
||
*
|
||
* @param {String} str
|
||
* @return {String | false}
|
||
*/
|
||
|
||
function stripQuotes(str) {
|
||
var a = str.charCodeAt(0);
|
||
var b = str.charCodeAt(str.length - 1);
|
||
return a === b && (a === 0x22 || a === 0x27) ? str.slice(1, -1) : str;
|
||
}
|
||
|
||
/**
|
||
* Camelize a hyphen-delmited string.
|
||
*
|
||
* @param {String} str
|
||
* @return {String}
|
||
*/
|
||
|
||
var camelizeRE = /-(\w)/g;
|
||
|
||
function camelize(str) {
|
||
return str.replace(camelizeRE, toUpper);
|
||
}
|
||
|
||
function toUpper(_, c) {
|
||
return c ? c.toUpperCase() : '';
|
||
}
|
||
|
||
/**
|
||
* Hyphenate a camelCase string.
|
||
*
|
||
* @param {String} str
|
||
* @return {String}
|
||
*/
|
||
|
||
var hyphenateRE = /([a-z\d])([A-Z])/g;
|
||
|
||
function hyphenate(str) {
|
||
return str.replace(hyphenateRE, '$1-$2').toLowerCase();
|
||
}
|
||
|
||
/**
|
||
* Converts hyphen/underscore/slash delimitered names into
|
||
* camelized classNames.
|
||
*
|
||
* e.g. my-component => MyComponent
|
||
* some_else => SomeElse
|
||
* some/comp => SomeComp
|
||
*
|
||
* @param {String} str
|
||
* @return {String}
|
||
*/
|
||
|
||
var classifyRE = /(?:^|[-_\/])(\w)/g;
|
||
|
||
function classify(str) {
|
||
return str.replace(classifyRE, toUpper);
|
||
}
|
||
|
||
/**
|
||
* Simple bind, faster than native
|
||
*
|
||
* @param {Function} fn
|
||
* @param {Object} ctx
|
||
* @return {Function}
|
||
*/
|
||
|
||
function bind(fn, ctx) {
|
||
return function (a) {
|
||
var l = arguments.length;
|
||
return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Convert an Array-like object to a real Array.
|
||
*
|
||
* @param {Array-like} list
|
||
* @param {Number} [start] - start index
|
||
* @return {Array}
|
||
*/
|
||
|
||
function toArray(list, start) {
|
||
start = start || 0;
|
||
var i = list.length - start;
|
||
var ret = new Array(i);
|
||
while (i--) {
|
||
ret[i] = list[i + start];
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
/**
|
||
* Mix properties into target object.
|
||
*
|
||
* @param {Object} to
|
||
* @param {Object} from
|
||
*/
|
||
|
||
function extend(to, from) {
|
||
var keys = Object.keys(from);
|
||
var i = keys.length;
|
||
while (i--) {
|
||
to[keys[i]] = from[keys[i]];
|
||
}
|
||
return to;
|
||
}
|
||
|
||
/**
|
||
* Quick object check - this is primarily used to tell
|
||
* Objects from primitive values when we know the value
|
||
* is a JSON-compliant type.
|
||
*
|
||
* @param {*} obj
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
function isObject(obj) {
|
||
return obj !== null && typeof obj === 'object';
|
||
}
|
||
|
||
/**
|
||
* Strict object type check. Only returns true
|
||
* for plain JavaScript objects.
|
||
*
|
||
* @param {*} obj
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
var toString = Object.prototype.toString;
|
||
var OBJECT_STRING = '[object Object]';
|
||
|
||
function isPlainObject(obj) {
|
||
return toString.call(obj) === OBJECT_STRING;
|
||
}
|
||
|
||
/**
|
||
* Array type check.
|
||
*
|
||
* @param {*} obj
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
var isArray = Array.isArray;
|
||
|
||
/**
|
||
* Define a non-enumerable property
|
||
*
|
||
* @param {Object} obj
|
||
* @param {String} key
|
||
* @param {*} val
|
||
* @param {Boolean} [enumerable]
|
||
*/
|
||
|
||
function def(obj, key, val, enumerable) {
|
||
Object.defineProperty(obj, key, {
|
||
value: val,
|
||
enumerable: !!enumerable,
|
||
writable: true,
|
||
configurable: true
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Debounce a function so it only gets called after the
|
||
* input stops arriving after the given wait period.
|
||
*
|
||
* @param {Function} func
|
||
* @param {Number} wait
|
||
* @return {Function} - the debounced function
|
||
*/
|
||
|
||
function _debounce(func, wait) {
|
||
var timeout, args, context, timestamp, result;
|
||
var later = function later() {
|
||
var last = Date.now() - timestamp;
|
||
if (last < wait && last >= 0) {
|
||
timeout = setTimeout(later, wait - last);
|
||
} else {
|
||
timeout = null;
|
||
result = func.apply(context, args);
|
||
if (!timeout) context = args = null;
|
||
}
|
||
};
|
||
return function () {
|
||
context = this;
|
||
args = arguments;
|
||
timestamp = Date.now();
|
||
if (!timeout) {
|
||
timeout = setTimeout(later, wait);
|
||
}
|
||
return result;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Manual indexOf because it's slightly faster than
|
||
* native.
|
||
*
|
||
* @param {Array} arr
|
||
* @param {*} obj
|
||
*/
|
||
|
||
function indexOf(arr, obj) {
|
||
var i = arr.length;
|
||
while (i--) {
|
||
if (arr[i] === obj) return i;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
/**
|
||
* Make a cancellable version of an async callback.
|
||
*
|
||
* @param {Function} fn
|
||
* @return {Function}
|
||
*/
|
||
|
||
function cancellable(fn) {
|
||
var cb = function cb() {
|
||
if (!cb.cancelled) {
|
||
return fn.apply(this, arguments);
|
||
}
|
||
};
|
||
cb.cancel = function () {
|
||
cb.cancelled = true;
|
||
};
|
||
return cb;
|
||
}
|
||
|
||
/**
|
||
* Check if two values are loosely equal - that is,
|
||
* if they are plain objects, do they have the same shape?
|
||
*
|
||
* @param {*} a
|
||
* @param {*} b
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
function looseEqual(a, b) {
|
||
/* eslint-disable eqeqeq */
|
||
return a == b || (isObject(a) && isObject(b) ? JSON.stringify(a) === JSON.stringify(b) : false);
|
||
/* eslint-enable eqeqeq */
|
||
}
|
||
|
||
var hasProto = ('__proto__' in {});
|
||
|
||
// Browser environment sniffing
|
||
var inBrowser = typeof window !== 'undefined' && Object.prototype.toString.call(window) !== '[object Object]';
|
||
|
||
// detect devtools
|
||
var devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
|
||
|
||
// UA sniffing for working around browser-specific quirks
|
||
var UA = inBrowser && window.navigator.userAgent.toLowerCase();
|
||
var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
|
||
var isAndroid = UA && UA.indexOf('android') > 0;
|
||
|
||
var transitionProp = undefined;
|
||
var transitionEndEvent = undefined;
|
||
var animationProp = undefined;
|
||
var animationEndEvent = undefined;
|
||
|
||
// Transition property/event sniffing
|
||
if (inBrowser && !isIE9) {
|
||
var isWebkitTrans = window.ontransitionend === undefined && window.onwebkittransitionend !== undefined;
|
||
var isWebkitAnim = window.onanimationend === undefined && window.onwebkitanimationend !== undefined;
|
||
transitionProp = isWebkitTrans ? 'WebkitTransition' : 'transition';
|
||
transitionEndEvent = isWebkitTrans ? 'webkitTransitionEnd' : 'transitionend';
|
||
animationProp = isWebkitAnim ? 'WebkitAnimation' : 'animation';
|
||
animationEndEvent = isWebkitAnim ? 'webkitAnimationEnd' : 'animationend';
|
||
}
|
||
|
||
/**
|
||
* Defer a task to execute it asynchronously. Ideally this
|
||
* should be executed as a microtask, so we leverage
|
||
* MutationObserver if it's available, and fallback to
|
||
* setTimeout(0).
|
||
*
|
||
* @param {Function} cb
|
||
* @param {Object} ctx
|
||
*/
|
||
|
||
var nextTick = (function () {
|
||
var callbacks = [];
|
||
var pending = false;
|
||
var timerFunc;
|
||
function nextTickHandler() {
|
||
pending = false;
|
||
var copies = callbacks.slice(0);
|
||
callbacks = [];
|
||
for (var i = 0; i < copies.length; i++) {
|
||
copies[i]();
|
||
}
|
||
}
|
||
|
||
/* istanbul ignore if */
|
||
if (typeof MutationObserver !== 'undefined') {
|
||
var counter = 1;
|
||
var observer = new MutationObserver(nextTickHandler);
|
||
var textNode = document.createTextNode(counter);
|
||
observer.observe(textNode, {
|
||
characterData: true
|
||
});
|
||
timerFunc = function () {
|
||
counter = (counter + 1) % 2;
|
||
textNode.data = counter;
|
||
};
|
||
} else {
|
||
// webpack attempts to inject a shim for setImmediate
|
||
// if it is used as a global, so we have to work around that to
|
||
// avoid bundling unnecessary code.
|
||
var context = inBrowser ? window : typeof global !== 'undefined' ? global : {};
|
||
timerFunc = context.setImmediate || setTimeout;
|
||
}
|
||
return function (cb, ctx) {
|
||
var func = ctx ? function () {
|
||
cb.call(ctx);
|
||
} : cb;
|
||
callbacks.push(func);
|
||
if (pending) return;
|
||
pending = true;
|
||
timerFunc(nextTickHandler, 0);
|
||
};
|
||
})();
|
||
|
||
function Cache(limit) {
|
||
this.size = 0;
|
||
this.limit = limit;
|
||
this.head = this.tail = undefined;
|
||
this._keymap = Object.create(null);
|
||
}
|
||
|
||
var p = Cache.prototype;
|
||
|
||
/**
|
||
* Put <value> into the cache associated with <key>.
|
||
* Returns the entry which was removed to make room for
|
||
* the new entry. Otherwise undefined is returned.
|
||
* (i.e. if there was enough room already).
|
||
*
|
||
* @param {String} key
|
||
* @param {*} value
|
||
* @return {Entry|undefined}
|
||
*/
|
||
|
||
p.put = function (key, value) {
|
||
var removed;
|
||
if (this.size === this.limit) {
|
||
removed = this.shift();
|
||
}
|
||
|
||
var entry = this.get(key, true);
|
||
if (!entry) {
|
||
entry = {
|
||
key: key
|
||
};
|
||
this._keymap[key] = entry;
|
||
if (this.tail) {
|
||
this.tail.newer = entry;
|
||
entry.older = this.tail;
|
||
} else {
|
||
this.head = entry;
|
||
}
|
||
this.tail = entry;
|
||
this.size++;
|
||
}
|
||
entry.value = value;
|
||
|
||
return removed;
|
||
};
|
||
|
||
/**
|
||
* Purge the least recently used (oldest) entry from the
|
||
* cache. Returns the removed entry or undefined if the
|
||
* cache was empty.
|
||
*/
|
||
|
||
p.shift = function () {
|
||
var entry = this.head;
|
||
if (entry) {
|
||
this.head = this.head.newer;
|
||
this.head.older = undefined;
|
||
entry.newer = entry.older = undefined;
|
||
this._keymap[entry.key] = undefined;
|
||
this.size--;
|
||
}
|
||
return entry;
|
||
};
|
||
|
||
/**
|
||
* Get and register recent use of <key>. Returns the value
|
||
* associated with <key> or undefined if not in cache.
|
||
*
|
||
* @param {String} key
|
||
* @param {Boolean} returnEntry
|
||
* @return {Entry|*}
|
||
*/
|
||
|
||
p.get = function (key, returnEntry) {
|
||
var entry = this._keymap[key];
|
||
if (entry === undefined) return;
|
||
if (entry === this.tail) {
|
||
return returnEntry ? entry : entry.value;
|
||
}
|
||
// HEAD--------------TAIL
|
||
// <.older .newer>
|
||
// <--- add direction --
|
||
// A B C <D> E
|
||
if (entry.newer) {
|
||
if (entry === this.head) {
|
||
this.head = entry.newer;
|
||
}
|
||
entry.newer.older = entry.older; // C <-- E.
|
||
}
|
||
if (entry.older) {
|
||
entry.older.newer = entry.newer; // C. --> E
|
||
}
|
||
entry.newer = undefined; // D --x
|
||
entry.older = this.tail; // D. --> E
|
||
if (this.tail) {
|
||
this.tail.newer = entry; // E. <-- D
|
||
}
|
||
this.tail = entry;
|
||
return returnEntry ? entry : entry.value;
|
||
};
|
||
|
||
var cache$1 = new Cache(1000);
|
||
var filterTokenRE = /[^\s'"]+|'[^']*'|"[^"]*"/g;
|
||
var reservedArgRE = /^in$|^-?\d+/;
|
||
|
||
/**
|
||
* Parser state
|
||
*/
|
||
|
||
var str;
|
||
var dir;
|
||
var c;
|
||
var prev;
|
||
var i;
|
||
var l;
|
||
var lastFilterIndex;
|
||
var inSingle;
|
||
var inDouble;
|
||
var curly;
|
||
var square;
|
||
var paren;
|
||
/**
|
||
* Push a filter to the current directive object
|
||
*/
|
||
|
||
function pushFilter() {
|
||
var exp = str.slice(lastFilterIndex, i).trim();
|
||
var filter;
|
||
if (exp) {
|
||
filter = {};
|
||
var tokens = exp.match(filterTokenRE);
|
||
filter.name = tokens[0];
|
||
if (tokens.length > 1) {
|
||
filter.args = tokens.slice(1).map(processFilterArg);
|
||
}
|
||
}
|
||
if (filter) {
|
||
(dir.filters = dir.filters || []).push(filter);
|
||
}
|
||
lastFilterIndex = i + 1;
|
||
}
|
||
|
||
/**
|
||
* Check if an argument is dynamic and strip quotes.
|
||
*
|
||
* @param {String} arg
|
||
* @return {Object}
|
||
*/
|
||
|
||
function processFilterArg(arg) {
|
||
if (reservedArgRE.test(arg)) {
|
||
return {
|
||
value: toNumber(arg),
|
||
dynamic: false
|
||
};
|
||
} else {
|
||
var stripped = stripQuotes(arg);
|
||
var dynamic = stripped === arg;
|
||
return {
|
||
value: dynamic ? arg : stripped,
|
||
dynamic: dynamic
|
||
};
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Parse a directive value and extract the expression
|
||
* and its filters into a descriptor.
|
||
*
|
||
* Example:
|
||
*
|
||
* "a + 1 | uppercase" will yield:
|
||
* {
|
||
* expression: 'a + 1',
|
||
* filters: [
|
||
* { name: 'uppercase', args: null }
|
||
* ]
|
||
* }
|
||
*
|
||
* @param {String} str
|
||
* @return {Object}
|
||
*/
|
||
|
||
function parseDirective(s) {
|
||
var hit = cache$1.get(s);
|
||
if (hit) {
|
||
return hit;
|
||
}
|
||
|
||
// reset parser state
|
||
str = s;
|
||
inSingle = inDouble = false;
|
||
curly = square = paren = 0;
|
||
lastFilterIndex = 0;
|
||
dir = {};
|
||
|
||
for (i = 0, l = str.length; i < l; i++) {
|
||
prev = c;
|
||
c = str.charCodeAt(i);
|
||
if (inSingle) {
|
||
// check single quote
|
||
if (c === 0x27 && prev !== 0x5C) inSingle = !inSingle;
|
||
} else if (inDouble) {
|
||
// check double quote
|
||
if (c === 0x22 && prev !== 0x5C) inDouble = !inDouble;
|
||
} else if (c === 0x7C && // pipe
|
||
str.charCodeAt(i + 1) !== 0x7C && str.charCodeAt(i - 1) !== 0x7C) {
|
||
if (dir.expression == null) {
|
||
// first filter, end of expression
|
||
lastFilterIndex = i + 1;
|
||
dir.expression = str.slice(0, i).trim();
|
||
} else {
|
||
// already has filter
|
||
pushFilter();
|
||
}
|
||
} else {
|
||
switch (c) {
|
||
case 0x22:
|
||
inDouble = true;break; // "
|
||
case 0x27:
|
||
inSingle = true;break; // '
|
||
case 0x28:
|
||
paren++;break; // (
|
||
case 0x29:
|
||
paren--;break; // )
|
||
case 0x5B:
|
||
square++;break; // [
|
||
case 0x5D:
|
||
square--;break; // ]
|
||
case 0x7B:
|
||
curly++;break; // {
|
||
case 0x7D:
|
||
curly--;break; // }
|
||
}
|
||
}
|
||
}
|
||
|
||
if (dir.expression == null) {
|
||
dir.expression = str.slice(0, i).trim();
|
||
} else if (lastFilterIndex !== 0) {
|
||
pushFilter();
|
||
}
|
||
|
||
cache$1.put(s, dir);
|
||
return dir;
|
||
}
|
||
|
||
var directive = Object.freeze({
|
||
parseDirective: parseDirective
|
||
});
|
||
|
||
var regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g;
|
||
var cache = undefined;
|
||
var tagRE = undefined;
|
||
var htmlRE = undefined;
|
||
/**
|
||
* Escape a string so it can be used in a RegExp
|
||
* constructor.
|
||
*
|
||
* @param {String} str
|
||
*/
|
||
|
||
function escapeRegex(str) {
|
||
return str.replace(regexEscapeRE, '\\$&');
|
||
}
|
||
|
||
function compileRegex() {
|
||
var open = escapeRegex(config.delimiters[0]);
|
||
var close = escapeRegex(config.delimiters[1]);
|
||
var unsafeOpen = escapeRegex(config.unsafeDelimiters[0]);
|
||
var unsafeClose = escapeRegex(config.unsafeDelimiters[1]);
|
||
tagRE = new RegExp(unsafeOpen + '(.+?)' + unsafeClose + '|' + open + '(.+?)' + close, 'g');
|
||
htmlRE = new RegExp('^' + unsafeOpen + '.*' + unsafeClose + '$');
|
||
// reset cache
|
||
cache = new Cache(1000);
|
||
}
|
||
|
||
/**
|
||
* Parse a template text string into an array of tokens.
|
||
*
|
||
* @param {String} text
|
||
* @return {Array<Object> | null}
|
||
* - {String} type
|
||
* - {String} value
|
||
* - {Boolean} [html]
|
||
* - {Boolean} [oneTime]
|
||
*/
|
||
|
||
function parseText(text) {
|
||
if (!cache) {
|
||
compileRegex();
|
||
}
|
||
var hit = cache.get(text);
|
||
if (hit) {
|
||
return hit;
|
||
}
|
||
text = text.replace(/\n/g, '');
|
||
if (!tagRE.test(text)) {
|
||
return null;
|
||
}
|
||
var tokens = [];
|
||
var lastIndex = tagRE.lastIndex = 0;
|
||
var match, index, html, value, first, oneTime;
|
||
/* eslint-disable no-cond-assign */
|
||
while (match = tagRE.exec(text)) {
|
||
/* eslint-enable no-cond-assign */
|
||
index = match.index;
|
||
// push text token
|
||
if (index > lastIndex) {
|
||
tokens.push({
|
||
value: text.slice(lastIndex, index)
|
||
});
|
||
}
|
||
// tag token
|
||
html = htmlRE.test(match[0]);
|
||
value = html ? match[1] : match[2];
|
||
first = value.charCodeAt(0);
|
||
oneTime = first === 42; // *
|
||
value = oneTime ? value.slice(1) : value;
|
||
tokens.push({
|
||
tag: true,
|
||
value: value.trim(),
|
||
html: html,
|
||
oneTime: oneTime
|
||
});
|
||
lastIndex = index + match[0].length;
|
||
}
|
||
if (lastIndex < text.length) {
|
||
tokens.push({
|
||
value: text.slice(lastIndex)
|
||
});
|
||
}
|
||
cache.put(text, tokens);
|
||
return tokens;
|
||
}
|
||
|
||
/**
|
||
* Format a list of tokens into an expression.
|
||
* e.g. tokens parsed from 'a {{b}} c' can be serialized
|
||
* into one single expression as '"a " + b + " c"'.
|
||
*
|
||
* @param {Array} tokens
|
||
* @param {Vue} [vm]
|
||
* @return {String}
|
||
*/
|
||
|
||
function tokensToExp(tokens, vm) {
|
||
if (tokens.length > 1) {
|
||
return tokens.map(function (token) {
|
||
return formatToken(token, vm);
|
||
}).join('+');
|
||
} else {
|
||
return formatToken(tokens[0], vm, true);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Format a single token.
|
||
*
|
||
* @param {Object} token
|
||
* @param {Vue} [vm]
|
||
* @param {Boolean} [single]
|
||
* @return {String}
|
||
*/
|
||
|
||
function formatToken(token, vm, single) {
|
||
return token.tag ? token.oneTime && vm ? '"' + vm.$eval(token.value) + '"' : inlineFilters(token.value, single) : '"' + token.value + '"';
|
||
}
|
||
|
||
/**
|
||
* For an attribute with multiple interpolation tags,
|
||
* e.g. attr="some-{{thing | filter}}", in order to combine
|
||
* the whole thing into a single watchable expression, we
|
||
* have to inline those filters. This function does exactly
|
||
* that. This is a bit hacky but it avoids heavy changes
|
||
* to directive parser and watcher mechanism.
|
||
*
|
||
* @param {String} exp
|
||
* @param {Boolean} single
|
||
* @return {String}
|
||
*/
|
||
|
||
var filterRE = /[^|]\|[^|]/;
|
||
function inlineFilters(exp, single) {
|
||
if (!filterRE.test(exp)) {
|
||
return single ? exp : '(' + exp + ')';
|
||
} else {
|
||
var dir = parseDirective(exp);
|
||
if (!dir.filters) {
|
||
return '(' + exp + ')';
|
||
} else {
|
||
return 'this._applyFilters(' + dir.expression + // value
|
||
',null,' + // oldValue (null for read)
|
||
JSON.stringify(dir.filters) + // filter descriptors
|
||
',false)'; // write?
|
||
}
|
||
}
|
||
}
|
||
|
||
var text = Object.freeze({
|
||
compileRegex: compileRegex,
|
||
parseText: parseText,
|
||
tokensToExp: tokensToExp
|
||
});
|
||
|
||
var delimiters = ['{{', '}}'];
|
||
var unsafeDelimiters = ['{{{', '}}}'];
|
||
|
||
var config = Object.defineProperties({
|
||
|
||
/**
|
||
* Whether to print debug messages.
|
||
* Also enables stack trace for warnings.
|
||
*
|
||
* @type {Boolean}
|
||
*/
|
||
|
||
debug: false,
|
||
|
||
/**
|
||
* Whether to suppress warnings.
|
||
*
|
||
* @type {Boolean}
|
||
*/
|
||
|
||
silent: false,
|
||
|
||
/**
|
||
* Whether to use async rendering.
|
||
*/
|
||
|
||
async: true,
|
||
|
||
/**
|
||
* Whether to warn against errors caught when evaluating
|
||
* expressions.
|
||
*/
|
||
|
||
warnExpressionErrors: true,
|
||
|
||
/**
|
||
* Internal flag to indicate the delimiters have been
|
||
* changed.
|
||
*
|
||
* @type {Boolean}
|
||
*/
|
||
|
||
_delimitersChanged: true,
|
||
|
||
/**
|
||
* List of asset types that a component can own.
|
||
*
|
||
* @type {Array}
|
||
*/
|
||
|
||
_assetTypes: ['component', 'directive', 'elementDirective', 'filter', 'transition', 'partial'],
|
||
|
||
/**
|
||
* prop binding modes
|
||
*/
|
||
|
||
_propBindingModes: {
|
||
ONE_WAY: 0,
|
||
TWO_WAY: 1,
|
||
ONE_TIME: 2
|
||
},
|
||
|
||
/**
|
||
* Max circular updates allowed in a batcher flush cycle.
|
||
*/
|
||
|
||
_maxUpdateCount: 100
|
||
|
||
}, {
|
||
delimiters: { /**
|
||
* Interpolation delimiters. Changing these would trigger
|
||
* the text parser to re-compile the regular expressions.
|
||
*
|
||
* @type {Array<String>}
|
||
*/
|
||
|
||
get: function get() {
|
||
return delimiters;
|
||
},
|
||
set: function set(val) {
|
||
delimiters = val;
|
||
compileRegex();
|
||
},
|
||
configurable: true,
|
||
enumerable: true
|
||
},
|
||
unsafeDelimiters: {
|
||
get: function get() {
|
||
return unsafeDelimiters;
|
||
},
|
||
set: function set(val) {
|
||
unsafeDelimiters = val;
|
||
compileRegex();
|
||
},
|
||
configurable: true,
|
||
enumerable: true
|
||
}
|
||
});
|
||
|
||
var warn = undefined;
|
||
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
(function () {
|
||
var hasConsole = typeof console !== 'undefined';
|
||
warn = function (msg, e) {
|
||
if (hasConsole && (!config.silent || config.debug)) {
|
||
console.warn('[Vue warn]: ' + msg);
|
||
/* istanbul ignore if */
|
||
if (config.debug) {
|
||
if (e) {
|
||
throw e;
|
||
} else {
|
||
console.warn(new Error('Warning Stack Trace').stack);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
})();
|
||
}
|
||
|
||
/**
|
||
* Append with transition.
|
||
*
|
||
* @param {Element} el
|
||
* @param {Element} target
|
||
* @param {Vue} vm
|
||
* @param {Function} [cb]
|
||
*/
|
||
|
||
function appendWithTransition(el, target, vm, cb) {
|
||
applyTransition(el, 1, function () {
|
||
target.appendChild(el);
|
||
}, vm, cb);
|
||
}
|
||
|
||
/**
|
||
* InsertBefore with transition.
|
||
*
|
||
* @param {Element} el
|
||
* @param {Element} target
|
||
* @param {Vue} vm
|
||
* @param {Function} [cb]
|
||
*/
|
||
|
||
function beforeWithTransition(el, target, vm, cb) {
|
||
applyTransition(el, 1, function () {
|
||
before(el, target);
|
||
}, vm, cb);
|
||
}
|
||
|
||
/**
|
||
* Remove with transition.
|
||
*
|
||
* @param {Element} el
|
||
* @param {Vue} vm
|
||
* @param {Function} [cb]
|
||
*/
|
||
|
||
function removeWithTransition(el, vm, cb) {
|
||
applyTransition(el, -1, function () {
|
||
remove(el);
|
||
}, vm, cb);
|
||
}
|
||
|
||
/**
|
||
* Apply transitions with an operation callback.
|
||
*
|
||
* @param {Element} el
|
||
* @param {Number} direction
|
||
* 1: enter
|
||
* -1: leave
|
||
* @param {Function} op - the actual DOM operation
|
||
* @param {Vue} vm
|
||
* @param {Function} [cb]
|
||
*/
|
||
|
||
function applyTransition(el, direction, op, vm, cb) {
|
||
var transition = el.__v_trans;
|
||
if (!transition ||
|
||
// skip if there are no js hooks and CSS transition is
|
||
// not supported
|
||
!transition.hooks && !transitionEndEvent ||
|
||
// skip transitions for initial compile
|
||
!vm._isCompiled ||
|
||
// if the vm is being manipulated by a parent directive
|
||
// during the parent's compilation phase, skip the
|
||
// animation.
|
||
vm.$parent && !vm.$parent._isCompiled) {
|
||
op();
|
||
if (cb) cb();
|
||
return;
|
||
}
|
||
var action = direction > 0 ? 'enter' : 'leave';
|
||
transition[action](op, cb);
|
||
}
|
||
|
||
var transition = Object.freeze({
|
||
appendWithTransition: appendWithTransition,
|
||
beforeWithTransition: beforeWithTransition,
|
||
removeWithTransition: removeWithTransition,
|
||
applyTransition: applyTransition
|
||
});
|
||
|
||
/**
|
||
* Query an element selector if it's not an element already.
|
||
*
|
||
* @param {String|Element} el
|
||
* @return {Element}
|
||
*/
|
||
|
||
function query(el) {
|
||
if (typeof el === 'string') {
|
||
var selector = el;
|
||
el = document.querySelector(el);
|
||
if (!el) {
|
||
process.env.NODE_ENV !== 'production' && warn('Cannot find element: ' + selector);
|
||
}
|
||
}
|
||
return el;
|
||
}
|
||
|
||
/**
|
||
* Check if a node is in the document.
|
||
* Note: document.documentElement.contains should work here
|
||
* but always returns false for comment nodes in phantomjs,
|
||
* making unit tests difficult. This is fixed by doing the
|
||
* contains() check on the node's parentNode instead of
|
||
* the node itself.
|
||
*
|
||
* @param {Node} node
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
function inDoc(node) {
|
||
var doc = document.documentElement;
|
||
var parent = node && node.parentNode;
|
||
return doc === node || doc === parent || !!(parent && parent.nodeType === 1 && doc.contains(parent));
|
||
}
|
||
|
||
/**
|
||
* Get and remove an attribute from a node.
|
||
*
|
||
* @param {Node} node
|
||
* @param {String} _attr
|
||
*/
|
||
|
||
function getAttr(node, _attr) {
|
||
var val = node.getAttribute(_attr);
|
||
if (val !== null) {
|
||
node.removeAttribute(_attr);
|
||
}
|
||
return val;
|
||
}
|
||
|
||
/**
|
||
* Get an attribute with colon or v-bind: prefix.
|
||
*
|
||
* @param {Node} node
|
||
* @param {String} name
|
||
* @return {String|null}
|
||
*/
|
||
|
||
function getBindAttr(node, name) {
|
||
var val = getAttr(node, ':' + name);
|
||
if (val === null) {
|
||
val = getAttr(node, 'v-bind:' + name);
|
||
}
|
||
return val;
|
||
}
|
||
|
||
/**
|
||
* Check the presence of a bind attribute.
|
||
*
|
||
* @param {Node} node
|
||
* @param {String} name
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
function hasBindAttr(node, name) {
|
||
return node.hasAttribute(name) || node.hasAttribute(':' + name) || node.hasAttribute('v-bind:' + name);
|
||
}
|
||
|
||
/**
|
||
* Insert el before target
|
||
*
|
||
* @param {Element} el
|
||
* @param {Element} target
|
||
*/
|
||
|
||
function before(el, target) {
|
||
target.parentNode.insertBefore(el, target);
|
||
}
|
||
|
||
/**
|
||
* Insert el after target
|
||
*
|
||
* @param {Element} el
|
||
* @param {Element} target
|
||
*/
|
||
|
||
function after(el, target) {
|
||
if (target.nextSibling) {
|
||
before(el, target.nextSibling);
|
||
} else {
|
||
target.parentNode.appendChild(el);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Remove el from DOM
|
||
*
|
||
* @param {Element} el
|
||
*/
|
||
|
||
function remove(el) {
|
||
el.parentNode.removeChild(el);
|
||
}
|
||
|
||
/**
|
||
* Prepend el to target
|
||
*
|
||
* @param {Element} el
|
||
* @param {Element} target
|
||
*/
|
||
|
||
function prepend(el, target) {
|
||
if (target.firstChild) {
|
||
before(el, target.firstChild);
|
||
} else {
|
||
target.appendChild(el);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Replace target with el
|
||
*
|
||
* @param {Element} target
|
||
* @param {Element} el
|
||
*/
|
||
|
||
function replace(target, el) {
|
||
var parent = target.parentNode;
|
||
if (parent) {
|
||
parent.replaceChild(el, target);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Add event listener shorthand.
|
||
*
|
||
* @param {Element} el
|
||
* @param {String} event
|
||
* @param {Function} cb
|
||
* @param {Boolean} [useCapture]
|
||
*/
|
||
|
||
function on(el, event, cb, useCapture) {
|
||
el.addEventListener(event, cb, useCapture);
|
||
}
|
||
|
||
/**
|
||
* Remove event listener shorthand.
|
||
*
|
||
* @param {Element} el
|
||
* @param {String} event
|
||
* @param {Function} cb
|
||
*/
|
||
|
||
function off(el, event, cb) {
|
||
el.removeEventListener(event, cb);
|
||
}
|
||
|
||
/**
|
||
* In IE9, setAttribute('class') will result in empty class
|
||
* if the element also has the :class attribute; However in
|
||
* PhantomJS, setting `className` does not work on SVG elements...
|
||
* So we have to do a conditional check here.
|
||
*
|
||
* @param {Element} el
|
||
* @param {String} cls
|
||
*/
|
||
|
||
function setClass(el, cls) {
|
||
/* istanbul ignore if */
|
||
if (isIE9 && !/svg$/.test(el.namespaceURI)) {
|
||
el.className = cls;
|
||
} else {
|
||
el.setAttribute('class', cls);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Add class with compatibility for IE & SVG
|
||
*
|
||
* @param {Element} el
|
||
* @param {String} cls
|
||
*/
|
||
|
||
function addClass(el, cls) {
|
||
if (el.classList) {
|
||
el.classList.add(cls);
|
||
} else {
|
||
var cur = ' ' + (el.getAttribute('class') || '') + ' ';
|
||
if (cur.indexOf(' ' + cls + ' ') < 0) {
|
||
setClass(el, (cur + cls).trim());
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Remove class with compatibility for IE & SVG
|
||
*
|
||
* @param {Element} el
|
||
* @param {String} cls
|
||
*/
|
||
|
||
function removeClass(el, cls) {
|
||
if (el.classList) {
|
||
el.classList.remove(cls);
|
||
} else {
|
||
var cur = ' ' + (el.getAttribute('class') || '') + ' ';
|
||
var tar = ' ' + cls + ' ';
|
||
while (cur.indexOf(tar) >= 0) {
|
||
cur = cur.replace(tar, ' ');
|
||
}
|
||
setClass(el, cur.trim());
|
||
}
|
||
if (!el.className) {
|
||
el.removeAttribute('class');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Extract raw content inside an element into a temporary
|
||
* container div
|
||
*
|
||
* @param {Element} el
|
||
* @param {Boolean} asFragment
|
||
* @return {Element|DocumentFragment}
|
||
*/
|
||
|
||
function extractContent(el, asFragment) {
|
||
var child;
|
||
var rawContent;
|
||
/* istanbul ignore if */
|
||
if (isTemplate(el) && isFragment(el.content)) {
|
||
el = el.content;
|
||
}
|
||
if (el.hasChildNodes()) {
|
||
trimNode(el);
|
||
rawContent = asFragment ? document.createDocumentFragment() : document.createElement('div');
|
||
/* eslint-disable no-cond-assign */
|
||
while (child = el.firstChild) {
|
||
/* eslint-enable no-cond-assign */
|
||
rawContent.appendChild(child);
|
||
}
|
||
}
|
||
return rawContent;
|
||
}
|
||
|
||
/**
|
||
* Trim possible empty head/tail text and comment
|
||
* nodes inside a parent.
|
||
*
|
||
* @param {Node} node
|
||
*/
|
||
|
||
function trimNode(node) {
|
||
var child;
|
||
/* eslint-disable no-sequences */
|
||
while ((child = node.firstChild, isTrimmable(child))) {
|
||
node.removeChild(child);
|
||
}
|
||
while ((child = node.lastChild, isTrimmable(child))) {
|
||
node.removeChild(child);
|
||
}
|
||
/* eslint-enable no-sequences */
|
||
}
|
||
|
||
function isTrimmable(node) {
|
||
return node && (node.nodeType === 3 && !node.data.trim() || node.nodeType === 8);
|
||
}
|
||
|
||
/**
|
||
* Check if an element is a template tag.
|
||
* Note if the template appears inside an SVG its tagName
|
||
* will be in lowercase.
|
||
*
|
||
* @param {Element} el
|
||
*/
|
||
|
||
function isTemplate(el) {
|
||
return el.tagName && el.tagName.toLowerCase() === 'template';
|
||
}
|
||
|
||
/**
|
||
* Create an "anchor" for performing dom insertion/removals.
|
||
* This is used in a number of scenarios:
|
||
* - fragment instance
|
||
* - v-html
|
||
* - v-if
|
||
* - v-for
|
||
* - component
|
||
*
|
||
* @param {String} content
|
||
* @param {Boolean} persist - IE trashes empty textNodes on
|
||
* cloneNode(true), so in certain
|
||
* cases the anchor needs to be
|
||
* non-empty to be persisted in
|
||
* templates.
|
||
* @return {Comment|Text}
|
||
*/
|
||
|
||
function createAnchor(content, persist) {
|
||
var anchor = config.debug ? document.createComment(content) : document.createTextNode(persist ? ' ' : '');
|
||
anchor.__v_anchor = true;
|
||
return anchor;
|
||
}
|
||
|
||
/**
|
||
* Find a component ref attribute that starts with $.
|
||
*
|
||
* @param {Element} node
|
||
* @return {String|undefined}
|
||
*/
|
||
|
||
var refRE = /^v-ref:/;
|
||
|
||
function findRef(node) {
|
||
if (node.hasAttributes()) {
|
||
var attrs = node.attributes;
|
||
for (var i = 0, l = attrs.length; i < l; i++) {
|
||
var name = attrs[i].name;
|
||
if (refRE.test(name)) {
|
||
return camelize(name.replace(refRE, ''));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Map a function to a range of nodes .
|
||
*
|
||
* @param {Node} node
|
||
* @param {Node} end
|
||
* @param {Function} op
|
||
*/
|
||
|
||
function mapNodeRange(node, end, op) {
|
||
var next;
|
||
while (node !== end) {
|
||
next = node.nextSibling;
|
||
op(node);
|
||
node = next;
|
||
}
|
||
op(end);
|
||
}
|
||
|
||
/**
|
||
* Remove a range of nodes with transition, store
|
||
* the nodes in a fragment with correct ordering,
|
||
* and call callback when done.
|
||
*
|
||
* @param {Node} start
|
||
* @param {Node} end
|
||
* @param {Vue} vm
|
||
* @param {DocumentFragment} frag
|
||
* @param {Function} cb
|
||
*/
|
||
|
||
function removeNodeRange(start, end, vm, frag, cb) {
|
||
var done = false;
|
||
var removed = 0;
|
||
var nodes = [];
|
||
mapNodeRange(start, end, function (node) {
|
||
if (node === end) done = true;
|
||
nodes.push(node);
|
||
removeWithTransition(node, vm, onRemoved);
|
||
});
|
||
function onRemoved() {
|
||
removed++;
|
||
if (done && removed >= nodes.length) {
|
||
for (var i = 0; i < nodes.length; i++) {
|
||
frag.appendChild(nodes[i]);
|
||
}
|
||
cb && cb();
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check if a node is a DocumentFragment.
|
||
*
|
||
* @param {Node} node
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
function isFragment(node) {
|
||
return node && node.nodeType === 11;
|
||
}
|
||
|
||
/**
|
||
* Get outerHTML of elements, taking care
|
||
* of SVG elements in IE as well.
|
||
*
|
||
* @param {Element} el
|
||
* @return {String}
|
||
*/
|
||
|
||
function getOuterHTML(el) {
|
||
if (el.outerHTML) {
|
||
return el.outerHTML;
|
||
} else {
|
||
var container = document.createElement('div');
|
||
container.appendChild(el.cloneNode(true));
|
||
return container.innerHTML;
|
||
}
|
||
}
|
||
|
||
var commonTagRE = /^(div|p|span|img|a|b|i|br|ul|ol|li|h1|h2|h3|h4|h5|h6|code|pre|table|th|td|tr|form|label|input|select|option|nav|article|section|header|footer)$/;
|
||
var reservedTagRE = /^(slot|partial|component)$/;
|
||
|
||
var isUnknownElement = undefined;
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
isUnknownElement = function (el, tag) {
|
||
if (tag.indexOf('-') > -1) {
|
||
// http://stackoverflow.com/a/28210364/1070244
|
||
return el.constructor === window.HTMLUnknownElement || el.constructor === window.HTMLElement;
|
||
} else {
|
||
return (/HTMLUnknownElement/.test(el.toString()) &&
|
||
// Chrome returns unknown for several HTML5 elements.
|
||
// https://code.google.com/p/chromium/issues/detail?id=540526
|
||
!/^(data|time|rtc|rb)$/.test(tag)
|
||
);
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Check if an element is a component, if yes return its
|
||
* component id.
|
||
*
|
||
* @param {Element} el
|
||
* @param {Object} options
|
||
* @return {Object|undefined}
|
||
*/
|
||
|
||
function checkComponentAttr(el, options) {
|
||
var tag = el.tagName.toLowerCase();
|
||
var hasAttrs = el.hasAttributes();
|
||
if (!commonTagRE.test(tag) && !reservedTagRE.test(tag)) {
|
||
if (resolveAsset(options, 'components', tag)) {
|
||
return { id: tag };
|
||
} else {
|
||
var is = hasAttrs && getIsBinding(el);
|
||
if (is) {
|
||
return is;
|
||
} else if (process.env.NODE_ENV !== 'production') {
|
||
var expectedTag = options._componentNameMap && options._componentNameMap[tag];
|
||
if (expectedTag) {
|
||
warn('Unknown custom element: <' + tag + '> - ' + 'did you mean <' + expectedTag + '>? ' + 'HTML is case-insensitive, remember to use kebab-case in templates.');
|
||
} else if (isUnknownElement(el, tag)) {
|
||
warn('Unknown custom element: <' + tag + '> - did you ' + 'register the component correctly? For recursive components, ' + 'make sure to provide the "name" option.');
|
||
}
|
||
}
|
||
}
|
||
} else if (hasAttrs) {
|
||
return getIsBinding(el);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get "is" binding from an element.
|
||
*
|
||
* @param {Element} el
|
||
* @return {Object|undefined}
|
||
*/
|
||
|
||
function getIsBinding(el) {
|
||
// dynamic syntax
|
||
var exp = getAttr(el, 'is');
|
||
if (exp != null) {
|
||
return { id: exp };
|
||
} else {
|
||
exp = getBindAttr(el, 'is');
|
||
if (exp != null) {
|
||
return { id: exp, dynamic: true };
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set a prop's initial value on a vm and its data object.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {Object} prop
|
||
* @param {*} value
|
||
*/
|
||
|
||
function initProp(vm, prop, value) {
|
||
var key = prop.path;
|
||
value = coerceProp(prop, value);
|
||
vm[key] = vm._data[key] = assertProp(prop, value) ? value : undefined;
|
||
}
|
||
|
||
/**
|
||
* Assert whether a prop is valid.
|
||
*
|
||
* @param {Object} prop
|
||
* @param {*} value
|
||
*/
|
||
|
||
function assertProp(prop, value) {
|
||
if (!prop.options.required && ( // non-required
|
||
prop.raw === null || // abscent
|
||
value == null) // null or undefined
|
||
) {
|
||
return true;
|
||
}
|
||
var options = prop.options;
|
||
var type = options.type;
|
||
var valid = true;
|
||
var expectedType;
|
||
if (type) {
|
||
if (type === String) {
|
||
expectedType = 'string';
|
||
valid = typeof value === expectedType;
|
||
} else if (type === Number) {
|
||
expectedType = 'number';
|
||
valid = typeof value === 'number';
|
||
} else if (type === Boolean) {
|
||
expectedType = 'boolean';
|
||
valid = typeof value === 'boolean';
|
||
} else if (type === Function) {
|
||
expectedType = 'function';
|
||
valid = typeof value === 'function';
|
||
} else if (type === Object) {
|
||
expectedType = 'object';
|
||
valid = isPlainObject(value);
|
||
} else if (type === Array) {
|
||
expectedType = 'array';
|
||
valid = isArray(value);
|
||
} else {
|
||
valid = value instanceof type;
|
||
}
|
||
}
|
||
if (!valid) {
|
||
process.env.NODE_ENV !== 'production' && warn('Invalid prop: type check failed for ' + prop.path + '="' + prop.raw + '".' + ' Expected ' + formatType(expectedType) + ', got ' + formatValue(value) + '.');
|
||
return false;
|
||
}
|
||
var validator = options.validator;
|
||
if (validator) {
|
||
if (!validator(value)) {
|
||
process.env.NODE_ENV !== 'production' && warn('Invalid prop: custom validator check failed for ' + prop.path + '="' + prop.raw + '"');
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Force parsing value with coerce option.
|
||
*
|
||
* @param {*} value
|
||
* @param {Object} options
|
||
* @return {*}
|
||
*/
|
||
|
||
function coerceProp(prop, value) {
|
||
var coerce = prop.options.coerce;
|
||
if (!coerce) {
|
||
return value;
|
||
}
|
||
// coerce is a function
|
||
return coerce(value);
|
||
}
|
||
|
||
function formatType(val) {
|
||
return val ? val.charAt(0).toUpperCase() + val.slice(1) : 'custom type';
|
||
}
|
||
|
||
function formatValue(val) {
|
||
return Object.prototype.toString.call(val).slice(8, -1);
|
||
}
|
||
|
||
/**
|
||
* Option overwriting strategies are functions that handle
|
||
* how to merge a parent option value and a child option
|
||
* value into the final value.
|
||
*
|
||
* All strategy functions follow the same signature:
|
||
*
|
||
* @param {*} parentVal
|
||
* @param {*} childVal
|
||
* @param {Vue} [vm]
|
||
*/
|
||
|
||
var strats = config.optionMergeStrategies = Object.create(null);
|
||
|
||
/**
|
||
* Helper that recursively merges two data objects together.
|
||
*/
|
||
|
||
function mergeData(to, from) {
|
||
var key, toVal, fromVal;
|
||
for (key in from) {
|
||
toVal = to[key];
|
||
fromVal = from[key];
|
||
if (!hasOwn(to, key)) {
|
||
set(to, key, fromVal);
|
||
} else if (isObject(toVal) && isObject(fromVal)) {
|
||
mergeData(toVal, fromVal);
|
||
}
|
||
}
|
||
return to;
|
||
}
|
||
|
||
/**
|
||
* Data
|
||
*/
|
||
|
||
strats.data = function (parentVal, childVal, vm) {
|
||
if (!vm) {
|
||
// in a Vue.extend merge, both should be functions
|
||
if (!childVal) {
|
||
return parentVal;
|
||
}
|
||
if (typeof childVal !== 'function') {
|
||
process.env.NODE_ENV !== 'production' && warn('The "data" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.');
|
||
return parentVal;
|
||
}
|
||
if (!parentVal) {
|
||
return childVal;
|
||
}
|
||
// when parentVal & childVal are both present,
|
||
// we need to return a function that returns the
|
||
// merged result of both functions... no need to
|
||
// check if parentVal is a function here because
|
||
// it has to be a function to pass previous merges.
|
||
return function mergedDataFn() {
|
||
return mergeData(childVal.call(this), parentVal.call(this));
|
||
};
|
||
} else if (parentVal || childVal) {
|
||
return function mergedInstanceDataFn() {
|
||
// instance merge
|
||
var instanceData = typeof childVal === 'function' ? childVal.call(vm) : childVal;
|
||
var defaultData = typeof parentVal === 'function' ? parentVal.call(vm) : undefined;
|
||
if (instanceData) {
|
||
return mergeData(instanceData, defaultData);
|
||
} else {
|
||
return defaultData;
|
||
}
|
||
};
|
||
}
|
||
};
|
||
|
||
/**
|
||
* El
|
||
*/
|
||
|
||
strats.el = function (parentVal, childVal, vm) {
|
||
if (!vm && childVal && typeof childVal !== 'function') {
|
||
process.env.NODE_ENV !== 'production' && warn('The "el" option should be a function ' + 'that returns a per-instance value in component ' + 'definitions.');
|
||
return;
|
||
}
|
||
var ret = childVal || parentVal;
|
||
// invoke the element factory if this is instance merge
|
||
return vm && typeof ret === 'function' ? ret.call(vm) : ret;
|
||
};
|
||
|
||
/**
|
||
* Hooks and param attributes are merged as arrays.
|
||
*/
|
||
|
||
strats.init = strats.created = strats.ready = strats.attached = strats.detached = strats.beforeCompile = strats.compiled = strats.beforeDestroy = strats.destroyed = strats.activate = function (parentVal, childVal) {
|
||
return childVal ? parentVal ? parentVal.concat(childVal) : isArray(childVal) ? childVal : [childVal] : parentVal;
|
||
};
|
||
|
||
/**
|
||
* 0.11 deprecation warning
|
||
*/
|
||
|
||
strats.paramAttributes = function () {
|
||
/* istanbul ignore next */
|
||
process.env.NODE_ENV !== 'production' && warn('"paramAttributes" option has been deprecated in 0.12. ' + 'Use "props" instead.');
|
||
};
|
||
|
||
/**
|
||
* Assets
|
||
*
|
||
* When a vm is present (instance creation), we need to do
|
||
* a three-way merge between constructor options, instance
|
||
* options and parent options.
|
||
*/
|
||
|
||
function mergeAssets(parentVal, childVal) {
|
||
var res = Object.create(parentVal);
|
||
return childVal ? extend(res, guardArrayAssets(childVal)) : res;
|
||
}
|
||
|
||
config._assetTypes.forEach(function (type) {
|
||
strats[type + 's'] = mergeAssets;
|
||
});
|
||
|
||
/**
|
||
* Events & Watchers.
|
||
*
|
||
* Events & watchers hashes should not overwrite one
|
||
* another, so we merge them as arrays.
|
||
*/
|
||
|
||
strats.watch = strats.events = function (parentVal, childVal) {
|
||
if (!childVal) return parentVal;
|
||
if (!parentVal) return childVal;
|
||
var ret = {};
|
||
extend(ret, parentVal);
|
||
for (var key in childVal) {
|
||
var parent = ret[key];
|
||
var child = childVal[key];
|
||
if (parent && !isArray(parent)) {
|
||
parent = [parent];
|
||
}
|
||
ret[key] = parent ? parent.concat(child) : [child];
|
||
}
|
||
return ret;
|
||
};
|
||
|
||
/**
|
||
* Other object hashes.
|
||
*/
|
||
|
||
strats.props = strats.methods = strats.computed = function (parentVal, childVal) {
|
||
if (!childVal) return parentVal;
|
||
if (!parentVal) return childVal;
|
||
var ret = Object.create(null);
|
||
extend(ret, parentVal);
|
||
extend(ret, childVal);
|
||
return ret;
|
||
};
|
||
|
||
/**
|
||
* Default strategy.
|
||
*/
|
||
|
||
var defaultStrat = function defaultStrat(parentVal, childVal) {
|
||
return childVal === undefined ? parentVal : childVal;
|
||
};
|
||
|
||
/**
|
||
* Make sure component options get converted to actual
|
||
* constructors.
|
||
*
|
||
* @param {Object} options
|
||
*/
|
||
|
||
function guardComponents(options) {
|
||
if (options.components) {
|
||
var components = options.components = guardArrayAssets(options.components);
|
||
var ids = Object.keys(components);
|
||
var def;
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
var map = options._componentNameMap = {};
|
||
}
|
||
for (var i = 0, l = ids.length; i < l; i++) {
|
||
var key = ids[i];
|
||
if (commonTagRE.test(key) || reservedTagRE.test(key)) {
|
||
process.env.NODE_ENV !== 'production' && warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + key);
|
||
continue;
|
||
}
|
||
// record a all lowercase <-> kebab-case mapping for
|
||
// possible custom element case error warning
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
map[key.replace(/-/g, '').toLowerCase()] = hyphenate(key);
|
||
}
|
||
def = components[key];
|
||
if (isPlainObject(def)) {
|
||
components[key] = Vue.extend(def);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Ensure all props option syntax are normalized into the
|
||
* Object-based format.
|
||
*
|
||
* @param {Object} options
|
||
*/
|
||
|
||
function guardProps(options) {
|
||
var props = options.props;
|
||
var i, val;
|
||
if (isArray(props)) {
|
||
options.props = {};
|
||
i = props.length;
|
||
while (i--) {
|
||
val = props[i];
|
||
if (typeof val === 'string') {
|
||
options.props[val] = null;
|
||
} else if (val.name) {
|
||
options.props[val.name] = val;
|
||
}
|
||
}
|
||
} else if (isPlainObject(props)) {
|
||
var keys = Object.keys(props);
|
||
i = keys.length;
|
||
while (i--) {
|
||
val = props[keys[i]];
|
||
if (typeof val === 'function') {
|
||
props[keys[i]] = { type: val };
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Guard an Array-format assets option and converted it
|
||
* into the key-value Object format.
|
||
*
|
||
* @param {Object|Array} assets
|
||
* @return {Object}
|
||
*/
|
||
|
||
function guardArrayAssets(assets) {
|
||
if (isArray(assets)) {
|
||
var res = {};
|
||
var i = assets.length;
|
||
var asset;
|
||
while (i--) {
|
||
asset = assets[i];
|
||
var id = typeof asset === 'function' ? asset.options && asset.options.name || asset.id : asset.name || asset.id;
|
||
if (!id) {
|
||
process.env.NODE_ENV !== 'production' && warn('Array-syntax assets must provide a "name" or "id" field.');
|
||
} else {
|
||
res[id] = asset;
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
return assets;
|
||
}
|
||
|
||
/**
|
||
* Merge two option objects into a new one.
|
||
* Core utility used in both instantiation and inheritance.
|
||
*
|
||
* @param {Object} parent
|
||
* @param {Object} child
|
||
* @param {Vue} [vm] - if vm is present, indicates this is
|
||
* an instantiation merge.
|
||
*/
|
||
|
||
function mergeOptions(parent, child, vm) {
|
||
guardComponents(child);
|
||
guardProps(child);
|
||
var options = {};
|
||
var key;
|
||
if (child.mixins) {
|
||
for (var i = 0, l = child.mixins.length; i < l; i++) {
|
||
parent = mergeOptions(parent, child.mixins[i], vm);
|
||
}
|
||
}
|
||
for (key in parent) {
|
||
mergeField(key);
|
||
}
|
||
for (key in child) {
|
||
if (!hasOwn(parent, key)) {
|
||
mergeField(key);
|
||
}
|
||
}
|
||
function mergeField(key) {
|
||
var strat = strats[key] || defaultStrat;
|
||
options[key] = strat(parent[key], child[key], vm, key);
|
||
}
|
||
return options;
|
||
}
|
||
|
||
/**
|
||
* Resolve an asset.
|
||
* This function is used because child instances need access
|
||
* to assets defined in its ancestor chain.
|
||
*
|
||
* @param {Object} options
|
||
* @param {String} type
|
||
* @param {String} id
|
||
* @return {Object|Function}
|
||
*/
|
||
|
||
function resolveAsset(options, type, id) {
|
||
/* istanbul ignore if */
|
||
if (typeof id !== 'string') {
|
||
return;
|
||
}
|
||
var assets = options[type];
|
||
var camelizedId;
|
||
return assets[id] ||
|
||
// camelCase ID
|
||
assets[camelizedId = camelize(id)] ||
|
||
// Pascal Case ID
|
||
assets[camelizedId.charAt(0).toUpperCase() + camelizedId.slice(1)];
|
||
}
|
||
|
||
/**
|
||
* Assert asset exists
|
||
*/
|
||
|
||
function assertAsset(val, type, id) {
|
||
if (!val) {
|
||
process.env.NODE_ENV !== 'production' && warn('Failed to resolve ' + type + ': ' + id);
|
||
}
|
||
}
|
||
|
||
var uid$1 = 0;
|
||
|
||
/**
|
||
* A dep is an observable that can have multiple
|
||
* directives subscribing to it.
|
||
*
|
||
* @constructor
|
||
*/
|
||
function Dep() {
|
||
this.id = uid$1++;
|
||
this.subs = [];
|
||
}
|
||
|
||
// the current target watcher being evaluated.
|
||
// this is globally unique because there could be only one
|
||
// watcher being evaluated at any time.
|
||
Dep.target = null;
|
||
|
||
/**
|
||
* Add a directive subscriber.
|
||
*
|
||
* @param {Directive} sub
|
||
*/
|
||
|
||
Dep.prototype.addSub = function (sub) {
|
||
this.subs.push(sub);
|
||
};
|
||
|
||
/**
|
||
* Remove a directive subscriber.
|
||
*
|
||
* @param {Directive} sub
|
||
*/
|
||
|
||
Dep.prototype.removeSub = function (sub) {
|
||
this.subs.$remove(sub);
|
||
};
|
||
|
||
/**
|
||
* Add self as a dependency to the target watcher.
|
||
*/
|
||
|
||
Dep.prototype.depend = function () {
|
||
Dep.target.addDep(this);
|
||
};
|
||
|
||
/**
|
||
* Notify all subscribers of a new value.
|
||
*/
|
||
|
||
Dep.prototype.notify = function () {
|
||
// stablize the subscriber list first
|
||
var subs = toArray(this.subs);
|
||
for (var i = 0, l = subs.length; i < l; i++) {
|
||
subs[i].update();
|
||
}
|
||
};
|
||
|
||
var arrayProto = Array.prototype;
|
||
var arrayMethods = Object.create(arrayProto)
|
||
|
||
/**
|
||
* Intercept mutating methods and emit events
|
||
*/
|
||
|
||
;['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(function (method) {
|
||
// cache original method
|
||
var original = arrayProto[method];
|
||
def(arrayMethods, method, function mutator() {
|
||
// avoid leaking arguments:
|
||
// http://jsperf.com/closure-with-arguments
|
||
var i = arguments.length;
|
||
var args = new Array(i);
|
||
while (i--) {
|
||
args[i] = arguments[i];
|
||
}
|
||
var result = original.apply(this, args);
|
||
var ob = this.__ob__;
|
||
var inserted;
|
||
switch (method) {
|
||
case 'push':
|
||
inserted = args;
|
||
break;
|
||
case 'unshift':
|
||
inserted = args;
|
||
break;
|
||
case 'splice':
|
||
inserted = args.slice(2);
|
||
break;
|
||
}
|
||
if (inserted) ob.observeArray(inserted);
|
||
// notify change
|
||
ob.dep.notify();
|
||
return result;
|
||
});
|
||
});
|
||
|
||
/**
|
||
* Swap the element at the given index with a new value
|
||
* and emits corresponding event.
|
||
*
|
||
* @param {Number} index
|
||
* @param {*} val
|
||
* @return {*} - replaced element
|
||
*/
|
||
|
||
def(arrayProto, '$set', function $set(index, val) {
|
||
if (index >= this.length) {
|
||
this.length = Number(index) + 1;
|
||
}
|
||
return this.splice(index, 1, val)[0];
|
||
});
|
||
|
||
/**
|
||
* Convenience method to remove the element at given index.
|
||
*
|
||
* @param {Number} index
|
||
* @param {*} val
|
||
*/
|
||
|
||
def(arrayProto, '$remove', function $remove(item) {
|
||
/* istanbul ignore if */
|
||
if (!this.length) return;
|
||
var index = indexOf(this, item);
|
||
if (index > -1) {
|
||
return this.splice(index, 1);
|
||
}
|
||
});
|
||
|
||
var arrayKeys = Object.getOwnPropertyNames(arrayMethods);
|
||
|
||
/**
|
||
* Observer class that are attached to each observed
|
||
* object. Once attached, the observer converts target
|
||
* object's property keys into getter/setters that
|
||
* collect dependencies and dispatches updates.
|
||
*
|
||
* @param {Array|Object} value
|
||
* @constructor
|
||
*/
|
||
|
||
function Observer(value) {
|
||
this.value = value;
|
||
this.dep = new Dep();
|
||
def(value, '__ob__', this);
|
||
if (isArray(value)) {
|
||
var augment = hasProto ? protoAugment : copyAugment;
|
||
augment(value, arrayMethods, arrayKeys);
|
||
this.observeArray(value);
|
||
} else {
|
||
this.walk(value);
|
||
}
|
||
}
|
||
|
||
// Instance methods
|
||
|
||
/**
|
||
* Walk through each property and convert them into
|
||
* getter/setters. This method should only be called when
|
||
* value type is Object.
|
||
*
|
||
* @param {Object} obj
|
||
*/
|
||
|
||
Observer.prototype.walk = function (obj) {
|
||
var keys = Object.keys(obj);
|
||
for (var i = 0, l = keys.length; i < l; i++) {
|
||
this.convert(keys[i], obj[keys[i]]);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Observe a list of Array items.
|
||
*
|
||
* @param {Array} items
|
||
*/
|
||
|
||
Observer.prototype.observeArray = function (items) {
|
||
for (var i = 0, l = items.length; i < l; i++) {
|
||
observe(items[i]);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Convert a property into getter/setter so we can emit
|
||
* the events when the property is accessed/changed.
|
||
*
|
||
* @param {String} key
|
||
* @param {*} val
|
||
*/
|
||
|
||
Observer.prototype.convert = function (key, val) {
|
||
defineReactive(this.value, key, val);
|
||
};
|
||
|
||
/**
|
||
* Add an owner vm, so that when $set/$delete mutations
|
||
* happen we can notify owner vms to proxy the keys and
|
||
* digest the watchers. This is only called when the object
|
||
* is observed as an instance's root $data.
|
||
*
|
||
* @param {Vue} vm
|
||
*/
|
||
|
||
Observer.prototype.addVm = function (vm) {
|
||
(this.vms || (this.vms = [])).push(vm);
|
||
};
|
||
|
||
/**
|
||
* Remove an owner vm. This is called when the object is
|
||
* swapped out as an instance's $data object.
|
||
*
|
||
* @param {Vue} vm
|
||
*/
|
||
|
||
Observer.prototype.removeVm = function (vm) {
|
||
this.vms.$remove(vm);
|
||
};
|
||
|
||
// helpers
|
||
|
||
/**
|
||
* Augment an target Object or Array by intercepting
|
||
* the prototype chain using __proto__
|
||
*
|
||
* @param {Object|Array} target
|
||
* @param {Object} proto
|
||
*/
|
||
|
||
function protoAugment(target, src) {
|
||
/* eslint-disable no-proto */
|
||
target.__proto__ = src;
|
||
/* eslint-enable no-proto */
|
||
}
|
||
|
||
/**
|
||
* Augment an target Object or Array by defining
|
||
* hidden properties.
|
||
*
|
||
* @param {Object|Array} target
|
||
* @param {Object} proto
|
||
*/
|
||
|
||
function copyAugment(target, src, keys) {
|
||
for (var i = 0, l = keys.length; i < l; i++) {
|
||
var key = keys[i];
|
||
def(target, key, src[key]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Attempt to create an observer instance for a value,
|
||
* returns the new observer if successfully observed,
|
||
* or the existing observer if the value already has one.
|
||
*
|
||
* @param {*} value
|
||
* @param {Vue} [vm]
|
||
* @return {Observer|undefined}
|
||
* @static
|
||
*/
|
||
|
||
function observe(value, vm) {
|
||
if (!value || typeof value !== 'object') {
|
||
return;
|
||
}
|
||
var ob;
|
||
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
|
||
ob = value.__ob__;
|
||
} else if ((isArray(value) || isPlainObject(value)) && Object.isExtensible(value) && !value._isVue) {
|
||
ob = new Observer(value);
|
||
}
|
||
if (ob && vm) {
|
||
ob.addVm(vm);
|
||
}
|
||
return ob;
|
||
}
|
||
|
||
/**
|
||
* Define a reactive property on an Object.
|
||
*
|
||
* @param {Object} obj
|
||
* @param {String} key
|
||
* @param {*} val
|
||
*/
|
||
|
||
function defineReactive(obj, key, val) {
|
||
var dep = new Dep();
|
||
|
||
var property = Object.getOwnPropertyDescriptor(obj, key);
|
||
if (property && property.configurable === false) {
|
||
return;
|
||
}
|
||
|
||
// cater for pre-defined getter/setters
|
||
var getter = property && property.get;
|
||
var setter = property && property.set;
|
||
|
||
var childOb = observe(val);
|
||
Object.defineProperty(obj, key, {
|
||
enumerable: true,
|
||
configurable: true,
|
||
get: function reactiveGetter() {
|
||
var value = getter ? getter.call(obj) : val;
|
||
if (Dep.target) {
|
||
dep.depend();
|
||
if (childOb) {
|
||
childOb.dep.depend();
|
||
}
|
||
if (isArray(value)) {
|
||
for (var e, i = 0, l = value.length; i < l; i++) {
|
||
e = value[i];
|
||
e && e.__ob__ && e.__ob__.dep.depend();
|
||
}
|
||
}
|
||
}
|
||
return value;
|
||
},
|
||
set: function reactiveSetter(newVal) {
|
||
var value = getter ? getter.call(obj) : val;
|
||
if (newVal === value) {
|
||
return;
|
||
}
|
||
if (setter) {
|
||
setter.call(obj, newVal);
|
||
} else {
|
||
val = newVal;
|
||
}
|
||
childOb = observe(newVal);
|
||
dep.notify();
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
|
||
var util = Object.freeze({
|
||
defineReactive: defineReactive,
|
||
set: set,
|
||
del: del,
|
||
hasOwn: hasOwn,
|
||
isLiteral: isLiteral,
|
||
isReserved: isReserved,
|
||
_toString: _toString,
|
||
toNumber: toNumber,
|
||
toBoolean: toBoolean,
|
||
stripQuotes: stripQuotes,
|
||
camelize: camelize,
|
||
hyphenate: hyphenate,
|
||
classify: classify,
|
||
bind: bind,
|
||
toArray: toArray,
|
||
extend: extend,
|
||
isObject: isObject,
|
||
isPlainObject: isPlainObject,
|
||
def: def,
|
||
debounce: _debounce,
|
||
indexOf: indexOf,
|
||
cancellable: cancellable,
|
||
looseEqual: looseEqual,
|
||
isArray: isArray,
|
||
hasProto: hasProto,
|
||
inBrowser: inBrowser,
|
||
devtools: devtools,
|
||
isIE9: isIE9,
|
||
isAndroid: isAndroid,
|
||
get transitionProp () { return transitionProp; },
|
||
get transitionEndEvent () { return transitionEndEvent; },
|
||
get animationProp () { return animationProp; },
|
||
get animationEndEvent () { return animationEndEvent; },
|
||
nextTick: nextTick,
|
||
query: query,
|
||
inDoc: inDoc,
|
||
getAttr: getAttr,
|
||
getBindAttr: getBindAttr,
|
||
hasBindAttr: hasBindAttr,
|
||
before: before,
|
||
after: after,
|
||
remove: remove,
|
||
prepend: prepend,
|
||
replace: replace,
|
||
on: on,
|
||
off: off,
|
||
setClass: setClass,
|
||
addClass: addClass,
|
||
removeClass: removeClass,
|
||
extractContent: extractContent,
|
||
trimNode: trimNode,
|
||
isTemplate: isTemplate,
|
||
createAnchor: createAnchor,
|
||
findRef: findRef,
|
||
mapNodeRange: mapNodeRange,
|
||
removeNodeRange: removeNodeRange,
|
||
isFragment: isFragment,
|
||
getOuterHTML: getOuterHTML,
|
||
mergeOptions: mergeOptions,
|
||
resolveAsset: resolveAsset,
|
||
assertAsset: assertAsset,
|
||
checkComponentAttr: checkComponentAttr,
|
||
initProp: initProp,
|
||
assertProp: assertProp,
|
||
coerceProp: coerceProp,
|
||
commonTagRE: commonTagRE,
|
||
reservedTagRE: reservedTagRE,
|
||
get warn () { return warn; }
|
||
});
|
||
|
||
var uid = 0;
|
||
|
||
function initMixin (Vue) {
|
||
/**
|
||
* The main init sequence. This is called for every
|
||
* instance, including ones that are created from extended
|
||
* constructors.
|
||
*
|
||
* @param {Object} options - this options object should be
|
||
* the result of merging class
|
||
* options and the options passed
|
||
* in to the constructor.
|
||
*/
|
||
|
||
Vue.prototype._init = function (options) {
|
||
options = options || {};
|
||
|
||
this.$el = null;
|
||
this.$parent = options.parent;
|
||
this.$root = this.$parent ? this.$parent.$root : this;
|
||
this.$children = [];
|
||
this.$refs = {}; // child vm references
|
||
this.$els = {}; // element references
|
||
this._watchers = []; // all watchers as an array
|
||
this._directives = []; // all directives
|
||
|
||
// a uid
|
||
this._uid = uid++;
|
||
|
||
// a flag to avoid this being observed
|
||
this._isVue = true;
|
||
|
||
// events bookkeeping
|
||
this._events = {}; // registered callbacks
|
||
this._eventsCount = {}; // for $broadcast optimization
|
||
|
||
// fragment instance properties
|
||
this._isFragment = false;
|
||
this._fragment = // @type {DocumentFragment}
|
||
this._fragmentStart = // @type {Text|Comment}
|
||
this._fragmentEnd = null; // @type {Text|Comment}
|
||
|
||
// lifecycle state
|
||
this._isCompiled = this._isDestroyed = this._isReady = this._isAttached = this._isBeingDestroyed = this._vForRemoving = false;
|
||
this._unlinkFn = null;
|
||
|
||
// context:
|
||
// if this is a transcluded component, context
|
||
// will be the common parent vm of this instance
|
||
// and its host.
|
||
this._context = options._context || this.$parent;
|
||
|
||
// scope:
|
||
// if this is inside an inline v-for, the scope
|
||
// will be the intermediate scope created for this
|
||
// repeat fragment. this is used for linking props
|
||
// and container directives.
|
||
this._scope = options._scope;
|
||
|
||
// fragment:
|
||
// if this instance is compiled inside a Fragment, it
|
||
// needs to reigster itself as a child of that fragment
|
||
// for attach/detach to work properly.
|
||
this._frag = options._frag;
|
||
if (this._frag) {
|
||
this._frag.children.push(this);
|
||
}
|
||
|
||
// push self into parent / transclusion host
|
||
if (this.$parent) {
|
||
this.$parent.$children.push(this);
|
||
}
|
||
|
||
// save raw constructor data before merge
|
||
// so that we know which properties are provided at
|
||
// instantiation.
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
this._runtimeData = options.data;
|
||
}
|
||
|
||
// merge options.
|
||
options = this.$options = mergeOptions(this.constructor.options, options, this);
|
||
|
||
// set ref
|
||
this._updateRef();
|
||
|
||
// initialize data as empty object.
|
||
// it will be filled up in _initScope().
|
||
this._data = {};
|
||
|
||
// call init hook
|
||
this._callHook('init');
|
||
|
||
// initialize data observation and scope inheritance.
|
||
this._initState();
|
||
|
||
// setup event system and option events.
|
||
this._initEvents();
|
||
|
||
// call created hook
|
||
this._callHook('created');
|
||
|
||
// if `el` option is passed, start compilation.
|
||
if (options.el) {
|
||
this.$mount(options.el);
|
||
}
|
||
};
|
||
}
|
||
|
||
var pathCache = new Cache(1000);
|
||
|
||
// actions
|
||
var APPEND = 0;
|
||
var PUSH = 1;
|
||
var INC_SUB_PATH_DEPTH = 2;
|
||
var PUSH_SUB_PATH = 3;
|
||
|
||
// states
|
||
var BEFORE_PATH = 0;
|
||
var IN_PATH = 1;
|
||
var BEFORE_IDENT = 2;
|
||
var IN_IDENT = 3;
|
||
var IN_SUB_PATH = 4;
|
||
var IN_SINGLE_QUOTE = 5;
|
||
var IN_DOUBLE_QUOTE = 6;
|
||
var AFTER_PATH = 7;
|
||
var ERROR = 8;
|
||
|
||
var pathStateMachine = [];
|
||
|
||
pathStateMachine[BEFORE_PATH] = {
|
||
'ws': [BEFORE_PATH],
|
||
'ident': [IN_IDENT, APPEND],
|
||
'[': [IN_SUB_PATH],
|
||
'eof': [AFTER_PATH]
|
||
};
|
||
|
||
pathStateMachine[IN_PATH] = {
|
||
'ws': [IN_PATH],
|
||
'.': [BEFORE_IDENT],
|
||
'[': [IN_SUB_PATH],
|
||
'eof': [AFTER_PATH]
|
||
};
|
||
|
||
pathStateMachine[BEFORE_IDENT] = {
|
||
'ws': [BEFORE_IDENT],
|
||
'ident': [IN_IDENT, APPEND]
|
||
};
|
||
|
||
pathStateMachine[IN_IDENT] = {
|
||
'ident': [IN_IDENT, APPEND],
|
||
'0': [IN_IDENT, APPEND],
|
||
'number': [IN_IDENT, APPEND],
|
||
'ws': [IN_PATH, PUSH],
|
||
'.': [BEFORE_IDENT, PUSH],
|
||
'[': [IN_SUB_PATH, PUSH],
|
||
'eof': [AFTER_PATH, PUSH]
|
||
};
|
||
|
||
pathStateMachine[IN_SUB_PATH] = {
|
||
"'": [IN_SINGLE_QUOTE, APPEND],
|
||
'"': [IN_DOUBLE_QUOTE, APPEND],
|
||
'[': [IN_SUB_PATH, INC_SUB_PATH_DEPTH],
|
||
']': [IN_PATH, PUSH_SUB_PATH],
|
||
'eof': ERROR,
|
||
'else': [IN_SUB_PATH, APPEND]
|
||
};
|
||
|
||
pathStateMachine[IN_SINGLE_QUOTE] = {
|
||
"'": [IN_SUB_PATH, APPEND],
|
||
'eof': ERROR,
|
||
'else': [IN_SINGLE_QUOTE, APPEND]
|
||
};
|
||
|
||
pathStateMachine[IN_DOUBLE_QUOTE] = {
|
||
'"': [IN_SUB_PATH, APPEND],
|
||
'eof': ERROR,
|
||
'else': [IN_DOUBLE_QUOTE, APPEND]
|
||
};
|
||
|
||
/**
|
||
* Determine the type of a character in a keypath.
|
||
*
|
||
* @param {Char} ch
|
||
* @return {String} type
|
||
*/
|
||
|
||
function getPathCharType(ch) {
|
||
if (ch === undefined) {
|
||
return 'eof';
|
||
}
|
||
|
||
var code = ch.charCodeAt(0);
|
||
|
||
switch (code) {
|
||
case 0x5B: // [
|
||
case 0x5D: // ]
|
||
case 0x2E: // .
|
||
case 0x22: // "
|
||
case 0x27: // '
|
||
case 0x30:
|
||
// 0
|
||
return ch;
|
||
|
||
case 0x5F: // _
|
||
case 0x24:
|
||
// $
|
||
return 'ident';
|
||
|
||
case 0x20: // Space
|
||
case 0x09: // Tab
|
||
case 0x0A: // Newline
|
||
case 0x0D: // Return
|
||
case 0xA0: // No-break space
|
||
case 0xFEFF: // Byte Order Mark
|
||
case 0x2028: // Line Separator
|
||
case 0x2029:
|
||
// Paragraph Separator
|
||
return 'ws';
|
||
}
|
||
|
||
// a-z, A-Z
|
||
if (code >= 0x61 && code <= 0x7A || code >= 0x41 && code <= 0x5A) {
|
||
return 'ident';
|
||
}
|
||
|
||
// 1-9
|
||
if (code >= 0x31 && code <= 0x39) {
|
||
return 'number';
|
||
}
|
||
|
||
return 'else';
|
||
}
|
||
|
||
/**
|
||
* Format a subPath, return its plain form if it is
|
||
* a literal string or number. Otherwise prepend the
|
||
* dynamic indicator (*).
|
||
*
|
||
* @param {String} path
|
||
* @return {String}
|
||
*/
|
||
|
||
function formatSubPath(path) {
|
||
var trimmed = path.trim();
|
||
// invalid leading 0
|
||
if (path.charAt(0) === '0' && isNaN(path)) {
|
||
return false;
|
||
}
|
||
return isLiteral(trimmed) ? stripQuotes(trimmed) : '*' + trimmed;
|
||
}
|
||
|
||
/**
|
||
* Parse a string path into an array of segments
|
||
*
|
||
* @param {String} path
|
||
* @return {Array|undefined}
|
||
*/
|
||
|
||
function parse(path) {
|
||
var keys = [];
|
||
var index = -1;
|
||
var mode = BEFORE_PATH;
|
||
var subPathDepth = 0;
|
||
var c, newChar, key, type, transition, action, typeMap;
|
||
|
||
var actions = [];
|
||
|
||
actions[PUSH] = function () {
|
||
if (key !== undefined) {
|
||
keys.push(key);
|
||
key = undefined;
|
||
}
|
||
};
|
||
|
||
actions[APPEND] = function () {
|
||
if (key === undefined) {
|
||
key = newChar;
|
||
} else {
|
||
key += newChar;
|
||
}
|
||
};
|
||
|
||
actions[INC_SUB_PATH_DEPTH] = function () {
|
||
actions[APPEND]();
|
||
subPathDepth++;
|
||
};
|
||
|
||
actions[PUSH_SUB_PATH] = function () {
|
||
if (subPathDepth > 0) {
|
||
subPathDepth--;
|
||
mode = IN_SUB_PATH;
|
||
actions[APPEND]();
|
||
} else {
|
||
subPathDepth = 0;
|
||
key = formatSubPath(key);
|
||
if (key === false) {
|
||
return false;
|
||
} else {
|
||
actions[PUSH]();
|
||
}
|
||
}
|
||
};
|
||
|
||
function maybeUnescapeQuote() {
|
||
var nextChar = path[index + 1];
|
||
if (mode === IN_SINGLE_QUOTE && nextChar === "'" || mode === IN_DOUBLE_QUOTE && nextChar === '"') {
|
||
index++;
|
||
newChar = '\\' + nextChar;
|
||
actions[APPEND]();
|
||
return true;
|
||
}
|
||
}
|
||
|
||
while (mode != null) {
|
||
index++;
|
||
c = path[index];
|
||
|
||
if (c === '\\' && maybeUnescapeQuote()) {
|
||
continue;
|
||
}
|
||
|
||
type = getPathCharType(c);
|
||
typeMap = pathStateMachine[mode];
|
||
transition = typeMap[type] || typeMap['else'] || ERROR;
|
||
|
||
if (transition === ERROR) {
|
||
return; // parse error
|
||
}
|
||
|
||
mode = transition[0];
|
||
action = actions[transition[1]];
|
||
if (action) {
|
||
newChar = transition[2];
|
||
newChar = newChar === undefined ? c : newChar;
|
||
if (action() === false) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (mode === AFTER_PATH) {
|
||
keys.raw = path;
|
||
return keys;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* External parse that check for a cache hit first
|
||
*
|
||
* @param {String} path
|
||
* @return {Array|undefined}
|
||
*/
|
||
|
||
function parsePath(path) {
|
||
var hit = pathCache.get(path);
|
||
if (!hit) {
|
||
hit = parse(path);
|
||
if (hit) {
|
||
pathCache.put(path, hit);
|
||
}
|
||
}
|
||
return hit;
|
||
}
|
||
|
||
/**
|
||
* Get from an object from a path string
|
||
*
|
||
* @param {Object} obj
|
||
* @param {String} path
|
||
*/
|
||
|
||
function getPath(obj, path) {
|
||
return parseExpression(path).get(obj);
|
||
}
|
||
|
||
/**
|
||
* Warn against setting non-existent root path on a vm.
|
||
*/
|
||
|
||
var warnNonExistent;
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
warnNonExistent = function (path) {
|
||
warn('You are setting a non-existent path "' + path.raw + '" ' + 'on a vm instance. Consider pre-initializing the property ' + 'with the "data" option for more reliable reactivity ' + 'and better performance.');
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Set on an object from a path
|
||
*
|
||
* @param {Object} obj
|
||
* @param {String | Array} path
|
||
* @param {*} val
|
||
*/
|
||
|
||
function setPath(obj, path, val) {
|
||
var original = obj;
|
||
if (typeof path === 'string') {
|
||
path = parse(path);
|
||
}
|
||
if (!path || !isObject(obj)) {
|
||
return false;
|
||
}
|
||
var last, key;
|
||
for (var i = 0, l = path.length; i < l; i++) {
|
||
last = obj;
|
||
key = path[i];
|
||
if (key.charAt(0) === '*') {
|
||
key = parseExpression(key.slice(1)).get.call(original, original);
|
||
}
|
||
if (i < l - 1) {
|
||
obj = obj[key];
|
||
if (!isObject(obj)) {
|
||
obj = {};
|
||
if (process.env.NODE_ENV !== 'production' && last._isVue) {
|
||
warnNonExistent(path);
|
||
}
|
||
set(last, key, obj);
|
||
}
|
||
} else {
|
||
if (isArray(obj)) {
|
||
obj.$set(key, val);
|
||
} else if (key in obj) {
|
||
obj[key] = val;
|
||
} else {
|
||
if (process.env.NODE_ENV !== 'production' && obj._isVue) {
|
||
warnNonExistent(path);
|
||
}
|
||
set(obj, key, val);
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
var path = Object.freeze({
|
||
parsePath: parsePath,
|
||
getPath: getPath,
|
||
setPath: setPath
|
||
});
|
||
|
||
var expressionCache = new Cache(1000);
|
||
|
||
var allowedKeywords = 'Math,Date,this,true,false,null,undefined,Infinity,NaN,' + 'isNaN,isFinite,decodeURI,decodeURIComponent,encodeURI,' + 'encodeURIComponent,parseInt,parseFloat';
|
||
var allowedKeywordsRE = new RegExp('^(' + allowedKeywords.replace(/,/g, '\\b|') + '\\b)');
|
||
|
||
// keywords that don't make sense inside expressions
|
||
var improperKeywords = 'break,case,class,catch,const,continue,debugger,default,' + 'delete,do,else,export,extends,finally,for,function,if,' + 'import,in,instanceof,let,return,super,switch,throw,try,' + 'var,while,with,yield,enum,await,implements,package,' + 'proctected,static,interface,private,public';
|
||
var improperKeywordsRE = new RegExp('^(' + improperKeywords.replace(/,/g, '\\b|') + '\\b)');
|
||
|
||
var wsRE = /\s/g;
|
||
var newlineRE = /\n/g;
|
||
var saveRE = /[\{,]\s*[\w\$_]+\s*:|('(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|`(?:[^`\\]|\\.)*\$\{|\}(?:[^`\\]|\\.)*`|`(?:[^`\\]|\\.)*`)|new |typeof |void /g;
|
||
var restoreRE = /"(\d+)"/g;
|
||
var pathTestRE = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['.*?'\]|\[".*?"\]|\[\d+\]|\[[A-Za-z_$][\w$]*\])*$/;
|
||
var identRE = /[^\w$\.](?:[A-Za-z_$][\w$]*)/g;
|
||
var booleanLiteralRE = /^(?:true|false)$/;
|
||
|
||
/**
|
||
* Save / Rewrite / Restore
|
||
*
|
||
* When rewriting paths found in an expression, it is
|
||
* possible for the same letter sequences to be found in
|
||
* strings and Object literal property keys. Therefore we
|
||
* remove and store these parts in a temporary array, and
|
||
* restore them after the path rewrite.
|
||
*/
|
||
|
||
var saved = [];
|
||
|
||
/**
|
||
* Save replacer
|
||
*
|
||
* The save regex can match two possible cases:
|
||
* 1. An opening object literal
|
||
* 2. A string
|
||
* If matched as a plain string, we need to escape its
|
||
* newlines, since the string needs to be preserved when
|
||
* generating the function body.
|
||
*
|
||
* @param {String} str
|
||
* @param {String} isString - str if matched as a string
|
||
* @return {String} - placeholder with index
|
||
*/
|
||
|
||
function save(str, isString) {
|
||
var i = saved.length;
|
||
saved[i] = isString ? str.replace(newlineRE, '\\n') : str;
|
||
return '"' + i + '"';
|
||
}
|
||
|
||
/**
|
||
* Path rewrite replacer
|
||
*
|
||
* @param {String} raw
|
||
* @return {String}
|
||
*/
|
||
|
||
function rewrite(raw) {
|
||
var c = raw.charAt(0);
|
||
var path = raw.slice(1);
|
||
if (allowedKeywordsRE.test(path)) {
|
||
return raw;
|
||
} else {
|
||
path = path.indexOf('"') > -1 ? path.replace(restoreRE, restore) : path;
|
||
return c + 'scope.' + path;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Restore replacer
|
||
*
|
||
* @param {String} str
|
||
* @param {String} i - matched save index
|
||
* @return {String}
|
||
*/
|
||
|
||
function restore(str, i) {
|
||
return saved[i];
|
||
}
|
||
|
||
/**
|
||
* Rewrite an expression, prefixing all path accessors with
|
||
* `scope.` and generate getter/setter functions.
|
||
*
|
||
* @param {String} exp
|
||
* @return {Function}
|
||
*/
|
||
|
||
function compileGetter(exp) {
|
||
if (improperKeywordsRE.test(exp)) {
|
||
process.env.NODE_ENV !== 'production' && warn('Avoid using reserved keywords in expression: ' + exp);
|
||
}
|
||
// reset state
|
||
saved.length = 0;
|
||
// save strings and object literal keys
|
||
var body = exp.replace(saveRE, save).replace(wsRE, '');
|
||
// rewrite all paths
|
||
// pad 1 space here becaue the regex matches 1 extra char
|
||
body = (' ' + body).replace(identRE, rewrite).replace(restoreRE, restore);
|
||
return makeGetterFn(body);
|
||
}
|
||
|
||
/**
|
||
* Build a getter function. Requires eval.
|
||
*
|
||
* We isolate the try/catch so it doesn't affect the
|
||
* optimization of the parse function when it is not called.
|
||
*
|
||
* @param {String} body
|
||
* @return {Function|undefined}
|
||
*/
|
||
|
||
function makeGetterFn(body) {
|
||
try {
|
||
/* eslint-disable no-new-func */
|
||
return new Function('scope', 'return ' + body + ';');
|
||
/* eslint-enable no-new-func */
|
||
} catch (e) {
|
||
process.env.NODE_ENV !== 'production' && warn('Invalid expression. ' + 'Generated function body: ' + body);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Compile a setter function for the expression.
|
||
*
|
||
* @param {String} exp
|
||
* @return {Function|undefined}
|
||
*/
|
||
|
||
function compileSetter(exp) {
|
||
var path = parsePath(exp);
|
||
if (path) {
|
||
return function (scope, val) {
|
||
setPath(scope, path, val);
|
||
};
|
||
} else {
|
||
process.env.NODE_ENV !== 'production' && warn('Invalid setter expression: ' + exp);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Parse an expression into re-written getter/setters.
|
||
*
|
||
* @param {String} exp
|
||
* @param {Boolean} needSet
|
||
* @return {Function}
|
||
*/
|
||
|
||
function parseExpression(exp, needSet) {
|
||
exp = exp.trim();
|
||
// try cache
|
||
var hit = expressionCache.get(exp);
|
||
if (hit) {
|
||
if (needSet && !hit.set) {
|
||
hit.set = compileSetter(hit.exp);
|
||
}
|
||
return hit;
|
||
}
|
||
var res = { exp: exp };
|
||
res.get = isSimplePath(exp) && exp.indexOf('[') < 0
|
||
// optimized super simple getter
|
||
? makeGetterFn('scope.' + exp)
|
||
// dynamic getter
|
||
: compileGetter(exp);
|
||
if (needSet) {
|
||
res.set = compileSetter(exp);
|
||
}
|
||
expressionCache.put(exp, res);
|
||
return res;
|
||
}
|
||
|
||
/**
|
||
* Check if an expression is a simple path.
|
||
*
|
||
* @param {String} exp
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
function isSimplePath(exp) {
|
||
return pathTestRE.test(exp) &&
|
||
// don't treat true/false as paths
|
||
!booleanLiteralRE.test(exp) &&
|
||
// Math constants e.g. Math.PI, Math.E etc.
|
||
exp.slice(0, 5) !== 'Math.';
|
||
}
|
||
|
||
var expression = Object.freeze({
|
||
parseExpression: parseExpression,
|
||
isSimplePath: isSimplePath
|
||
});
|
||
|
||
// we have two separate queues: one for directive updates
|
||
// and one for user watcher registered via $watch().
|
||
// we want to guarantee directive updates to be called
|
||
// before user watchers so that when user watchers are
|
||
// triggered, the DOM would have already been in updated
|
||
// state.
|
||
var queue = [];
|
||
var userQueue = [];
|
||
var has = {};
|
||
var circular = {};
|
||
var waiting = false;
|
||
var internalQueueDepleted = false;
|
||
|
||
/**
|
||
* Reset the batcher's state.
|
||
*/
|
||
|
||
function resetBatcherState() {
|
||
queue = [];
|
||
userQueue = [];
|
||
has = {};
|
||
circular = {};
|
||
waiting = internalQueueDepleted = false;
|
||
}
|
||
|
||
/**
|
||
* Flush both queues and run the watchers.
|
||
*/
|
||
|
||
function flushBatcherQueue() {
|
||
runBatcherQueue(queue);
|
||
internalQueueDepleted = true;
|
||
runBatcherQueue(userQueue);
|
||
// dev tool hook
|
||
/* istanbul ignore if */
|
||
if (devtools) {
|
||
devtools.emit('flush');
|
||
}
|
||
resetBatcherState();
|
||
}
|
||
|
||
/**
|
||
* Run the watchers in a single queue.
|
||
*
|
||
* @param {Array} queue
|
||
*/
|
||
|
||
function runBatcherQueue(queue) {
|
||
// do not cache length because more watchers might be pushed
|
||
// as we run existing watchers
|
||
for (var i = 0; i < queue.length; i++) {
|
||
var watcher = queue[i];
|
||
var id = watcher.id;
|
||
has[id] = null;
|
||
watcher.run();
|
||
// in dev build, check and stop circular updates.
|
||
if (process.env.NODE_ENV !== 'production' && has[id] != null) {
|
||
circular[id] = (circular[id] || 0) + 1;
|
||
if (circular[id] > config._maxUpdateCount) {
|
||
queue.splice(has[id], 1);
|
||
warn('You may have an infinite update loop for watcher ' + 'with expression: ' + watcher.expression);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Push a watcher into the watcher queue.
|
||
* Jobs with duplicate IDs will be skipped unless it's
|
||
* pushed when the queue is being flushed.
|
||
*
|
||
* @param {Watcher} watcher
|
||
* properties:
|
||
* - {Number} id
|
||
* - {Function} run
|
||
*/
|
||
|
||
function pushWatcher(watcher) {
|
||
var id = watcher.id;
|
||
if (has[id] == null) {
|
||
// if an internal watcher is pushed, but the internal
|
||
// queue is already depleted, we run it immediately.
|
||
if (internalQueueDepleted && !watcher.user) {
|
||
watcher.run();
|
||
return;
|
||
}
|
||
// push watcher into appropriate queue
|
||
var q = watcher.user ? userQueue : queue;
|
||
has[id] = q.length;
|
||
q.push(watcher);
|
||
// queue the flush
|
||
if (!waiting) {
|
||
waiting = true;
|
||
nextTick(flushBatcherQueue);
|
||
}
|
||
}
|
||
}
|
||
|
||
var uid$2 = 0;
|
||
|
||
/**
|
||
* A watcher parses an expression, collects dependencies,
|
||
* and fires callback when the expression value changes.
|
||
* This is used for both the $watch() api and directives.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {String} expression
|
||
* @param {Function} cb
|
||
* @param {Object} options
|
||
* - {Array} filters
|
||
* - {Boolean} twoWay
|
||
* - {Boolean} deep
|
||
* - {Boolean} user
|
||
* - {Boolean} sync
|
||
* - {Boolean} lazy
|
||
* - {Function} [preProcess]
|
||
* - {Function} [postProcess]
|
||
* @constructor
|
||
*/
|
||
function Watcher(vm, expOrFn, cb, options) {
|
||
// mix in options
|
||
if (options) {
|
||
extend(this, options);
|
||
}
|
||
var isFn = typeof expOrFn === 'function';
|
||
this.vm = vm;
|
||
vm._watchers.push(this);
|
||
this.expression = isFn ? expOrFn.toString() : expOrFn;
|
||
this.cb = cb;
|
||
this.id = ++uid$2; // uid for batching
|
||
this.active = true;
|
||
this.dirty = this.lazy; // for lazy watchers
|
||
this.deps = Object.create(null);
|
||
this.newDeps = null;
|
||
this.prevError = null; // for async error stacks
|
||
// parse expression for getter/setter
|
||
if (isFn) {
|
||
this.getter = expOrFn;
|
||
this.setter = undefined;
|
||
} else {
|
||
var res = parseExpression(expOrFn, this.twoWay);
|
||
this.getter = res.get;
|
||
this.setter = res.set;
|
||
}
|
||
this.value = this.lazy ? undefined : this.get();
|
||
// state for avoiding false triggers for deep and Array
|
||
// watchers during vm._digest()
|
||
this.queued = this.shallow = false;
|
||
}
|
||
|
||
/**
|
||
* Add a dependency to this directive.
|
||
*
|
||
* @param {Dep} dep
|
||
*/
|
||
|
||
Watcher.prototype.addDep = function (dep) {
|
||
var id = dep.id;
|
||
if (!this.newDeps[id]) {
|
||
this.newDeps[id] = dep;
|
||
if (!this.deps[id]) {
|
||
this.deps[id] = dep;
|
||
dep.addSub(this);
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Evaluate the getter, and re-collect dependencies.
|
||
*/
|
||
|
||
Watcher.prototype.get = function () {
|
||
this.beforeGet();
|
||
var scope = this.scope || this.vm;
|
||
var value;
|
||
try {
|
||
value = this.getter.call(scope, scope);
|
||
} catch (e) {
|
||
if (process.env.NODE_ENV !== 'production' && config.warnExpressionErrors) {
|
||
warn('Error when evaluating expression "' + this.expression + '". ' + (config.debug ? '' : 'Turn on debug mode to see stack trace.'), e);
|
||
}
|
||
}
|
||
// "touch" every property so they are all tracked as
|
||
// dependencies for deep watching
|
||
if (this.deep) {
|
||
traverse(value);
|
||
}
|
||
if (this.preProcess) {
|
||
value = this.preProcess(value);
|
||
}
|
||
if (this.filters) {
|
||
value = scope._applyFilters(value, null, this.filters, false);
|
||
}
|
||
if (this.postProcess) {
|
||
value = this.postProcess(value);
|
||
}
|
||
this.afterGet();
|
||
return value;
|
||
};
|
||
|
||
/**
|
||
* Set the corresponding value with the setter.
|
||
*
|
||
* @param {*} value
|
||
*/
|
||
|
||
Watcher.prototype.set = function (value) {
|
||
var scope = this.scope || this.vm;
|
||
if (this.filters) {
|
||
value = scope._applyFilters(value, this.value, this.filters, true);
|
||
}
|
||
try {
|
||
this.setter.call(scope, scope, value);
|
||
} catch (e) {
|
||
if (process.env.NODE_ENV !== 'production' && config.warnExpressionErrors) {
|
||
warn('Error when evaluating setter "' + this.expression + '"', e);
|
||
}
|
||
}
|
||
// two-way sync for v-for alias
|
||
var forContext = scope.$forContext;
|
||
if (forContext && forContext.alias === this.expression) {
|
||
if (forContext.filters) {
|
||
process.env.NODE_ENV !== 'production' && warn('It seems you are using two-way binding on ' + 'a v-for alias (' + this.expression + '), and the ' + 'v-for has filters. This will not work properly. ' + 'Either remove the filters or use an array of ' + 'objects and bind to object properties instead.');
|
||
return;
|
||
}
|
||
forContext._withLock(function () {
|
||
if (scope.$key) {
|
||
// original is an object
|
||
forContext.rawValue[scope.$key] = value;
|
||
} else {
|
||
forContext.rawValue.$set(scope.$index, value);
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Prepare for dependency collection.
|
||
*/
|
||
|
||
Watcher.prototype.beforeGet = function () {
|
||
Dep.target = this;
|
||
this.newDeps = Object.create(null);
|
||
};
|
||
|
||
/**
|
||
* Clean up for dependency collection.
|
||
*/
|
||
|
||
Watcher.prototype.afterGet = function () {
|
||
Dep.target = null;
|
||
var ids = Object.keys(this.deps);
|
||
var i = ids.length;
|
||
while (i--) {
|
||
var id = ids[i];
|
||
if (!this.newDeps[id]) {
|
||
this.deps[id].removeSub(this);
|
||
}
|
||
}
|
||
this.deps = this.newDeps;
|
||
};
|
||
|
||
/**
|
||
* Subscriber interface.
|
||
* Will be called when a dependency changes.
|
||
*
|
||
* @param {Boolean} shallow
|
||
*/
|
||
|
||
Watcher.prototype.update = function (shallow) {
|
||
if (this.lazy) {
|
||
this.dirty = true;
|
||
} else if (this.sync || !config.async) {
|
||
this.run();
|
||
} else {
|
||
// if queued, only overwrite shallow with non-shallow,
|
||
// but not the other way around.
|
||
this.shallow = this.queued ? shallow ? this.shallow : false : !!shallow;
|
||
this.queued = true;
|
||
// record before-push error stack in debug mode
|
||
/* istanbul ignore if */
|
||
if (process.env.NODE_ENV !== 'production' && config.debug) {
|
||
this.prevError = new Error('[vue] async stack trace');
|
||
}
|
||
pushWatcher(this);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Batcher job interface.
|
||
* Will be called by the batcher.
|
||
*/
|
||
|
||
Watcher.prototype.run = function () {
|
||
if (this.active) {
|
||
var value = this.get();
|
||
if (value !== this.value ||
|
||
// Deep watchers and watchers on Object/Arrays should fire even
|
||
// when the value is the same, because the value may
|
||
// have mutated; but only do so if this is a
|
||
// non-shallow update (caused by a vm digest).
|
||
(isObject(value) || this.deep) && !this.shallow) {
|
||
// set new value
|
||
var oldValue = this.value;
|
||
this.value = value;
|
||
// in debug + async mode, when a watcher callbacks
|
||
// throws, we also throw the saved before-push error
|
||
// so the full cross-tick stack trace is available.
|
||
var prevError = this.prevError;
|
||
/* istanbul ignore if */
|
||
if (process.env.NODE_ENV !== 'production' && config.debug && prevError) {
|
||
this.prevError = null;
|
||
try {
|
||
this.cb.call(this.vm, value, oldValue);
|
||
} catch (e) {
|
||
nextTick(function () {
|
||
throw prevError;
|
||
}, 0);
|
||
throw e;
|
||
}
|
||
} else {
|
||
this.cb.call(this.vm, value, oldValue);
|
||
}
|
||
}
|
||
this.queued = this.shallow = false;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Evaluate the value of the watcher.
|
||
* This only gets called for lazy watchers.
|
||
*/
|
||
|
||
Watcher.prototype.evaluate = function () {
|
||
// avoid overwriting another watcher that is being
|
||
// collected.
|
||
var current = Dep.target;
|
||
this.value = this.get();
|
||
this.dirty = false;
|
||
Dep.target = current;
|
||
};
|
||
|
||
/**
|
||
* Depend on all deps collected by this watcher.
|
||
*/
|
||
|
||
Watcher.prototype.depend = function () {
|
||
var depIds = Object.keys(this.deps);
|
||
var i = depIds.length;
|
||
while (i--) {
|
||
this.deps[depIds[i]].depend();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Remove self from all dependencies' subcriber list.
|
||
*/
|
||
|
||
Watcher.prototype.teardown = function () {
|
||
if (this.active) {
|
||
// remove self from vm's watcher list
|
||
// this is a somewhat expensive operation so we skip it
|
||
// if the vm is being destroyed or is performing a v-for
|
||
// re-render (the watcher list is then filtered by v-for).
|
||
if (!this.vm._isBeingDestroyed && !this.vm._vForRemoving) {
|
||
this.vm._watchers.$remove(this);
|
||
}
|
||
var depIds = Object.keys(this.deps);
|
||
var i = depIds.length;
|
||
while (i--) {
|
||
this.deps[depIds[i]].removeSub(this);
|
||
}
|
||
this.active = false;
|
||
this.vm = this.cb = this.value = null;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Recrusively traverse an object to evoke all converted
|
||
* getters, so that every nested property inside the object
|
||
* is collected as a "deep" dependency.
|
||
*
|
||
* @param {*} val
|
||
*/
|
||
|
||
function traverse(val) {
|
||
var i, keys;
|
||
if (isArray(val)) {
|
||
i = val.length;
|
||
while (i--) traverse(val[i]);
|
||
} else if (isObject(val)) {
|
||
keys = Object.keys(val);
|
||
i = keys.length;
|
||
while (i--) traverse(val[keys[i]]);
|
||
}
|
||
}
|
||
|
||
var text$1 = {
|
||
|
||
bind: function bind() {
|
||
this.attr = this.el.nodeType === 3 ? 'data' : 'textContent';
|
||
},
|
||
|
||
update: function update(value) {
|
||
this.el[this.attr] = _toString(value);
|
||
}
|
||
};
|
||
|
||
var templateCache = new Cache(1000);
|
||
var idSelectorCache = new Cache(1000);
|
||
|
||
var map = {
|
||
efault: [0, '', ''],
|
||
legend: [1, '<fieldset>', '</fieldset>'],
|
||
tr: [2, '<table><tbody>', '</tbody></table>'],
|
||
col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>']
|
||
};
|
||
|
||
map.td = map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
|
||
|
||
map.option = map.optgroup = [1, '<select multiple="multiple">', '</select>'];
|
||
|
||
map.thead = map.tbody = map.colgroup = map.caption = map.tfoot = [1, '<table>', '</table>'];
|
||
|
||
map.g = map.defs = map.symbol = map.use = map.image = map.text = map.circle = map.ellipse = map.line = map.path = map.polygon = map.polyline = map.rect = [1, '<svg ' + 'xmlns="http://www.w3.org/2000/svg" ' + 'xmlns:xlink="http://www.w3.org/1999/xlink" ' + 'xmlns:ev="http://www.w3.org/2001/xml-events"' + 'version="1.1">', '</svg>'];
|
||
|
||
/**
|
||
* Check if a node is a supported template node with a
|
||
* DocumentFragment content.
|
||
*
|
||
* @param {Node} node
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
function isRealTemplate(node) {
|
||
return isTemplate(node) && isFragment(node.content);
|
||
}
|
||
|
||
var tagRE$1 = /<([\w:]+)/;
|
||
var entityRE = /&#?\w+?;/;
|
||
|
||
/**
|
||
* Convert a string template to a DocumentFragment.
|
||
* Determines correct wrapping by tag types. Wrapping
|
||
* strategy found in jQuery & component/domify.
|
||
*
|
||
* @param {String} templateString
|
||
* @param {Boolean} raw
|
||
* @return {DocumentFragment}
|
||
*/
|
||
|
||
function stringToFragment(templateString, raw) {
|
||
// try a cache hit first
|
||
var cacheKey = raw ? templateString : templateString.trim();
|
||
var hit = templateCache.get(cacheKey);
|
||
if (hit) {
|
||
return hit;
|
||
}
|
||
|
||
var frag = document.createDocumentFragment();
|
||
var tagMatch = templateString.match(tagRE$1);
|
||
var entityMatch = entityRE.test(templateString);
|
||
|
||
if (!tagMatch && !entityMatch) {
|
||
// text only, return a single text node.
|
||
frag.appendChild(document.createTextNode(templateString));
|
||
} else {
|
||
var tag = tagMatch && tagMatch[1];
|
||
var wrap = map[tag] || map.efault;
|
||
var depth = wrap[0];
|
||
var prefix = wrap[1];
|
||
var suffix = wrap[2];
|
||
var node = document.createElement('div');
|
||
|
||
node.innerHTML = prefix + templateString + suffix;
|
||
while (depth--) {
|
||
node = node.lastChild;
|
||
}
|
||
|
||
var child;
|
||
/* eslint-disable no-cond-assign */
|
||
while (child = node.firstChild) {
|
||
/* eslint-enable no-cond-assign */
|
||
frag.appendChild(child);
|
||
}
|
||
}
|
||
if (!raw) {
|
||
trimNode(frag);
|
||
}
|
||
templateCache.put(cacheKey, frag);
|
||
return frag;
|
||
}
|
||
|
||
/**
|
||
* Convert a template node to a DocumentFragment.
|
||
*
|
||
* @param {Node} node
|
||
* @return {DocumentFragment}
|
||
*/
|
||
|
||
function nodeToFragment(node) {
|
||
// if its a template tag and the browser supports it,
|
||
// its content is already a document fragment.
|
||
if (isRealTemplate(node)) {
|
||
trimNode(node.content);
|
||
return node.content;
|
||
}
|
||
// script template
|
||
if (node.tagName === 'SCRIPT') {
|
||
return stringToFragment(node.textContent);
|
||
}
|
||
// normal node, clone it to avoid mutating the original
|
||
var clonedNode = cloneNode(node);
|
||
var frag = document.createDocumentFragment();
|
||
var child;
|
||
/* eslint-disable no-cond-assign */
|
||
while (child = clonedNode.firstChild) {
|
||
/* eslint-enable no-cond-assign */
|
||
frag.appendChild(child);
|
||
}
|
||
trimNode(frag);
|
||
return frag;
|
||
}
|
||
|
||
// Test for the presence of the Safari template cloning bug
|
||
// https://bugs.webkit.org/showug.cgi?id=137755
|
||
var hasBrokenTemplate = (function () {
|
||
/* istanbul ignore else */
|
||
if (inBrowser) {
|
||
var a = document.createElement('div');
|
||
a.innerHTML = '<template>1</template>';
|
||
return !a.cloneNode(true).firstChild.innerHTML;
|
||
} else {
|
||
return false;
|
||
}
|
||
})();
|
||
|
||
// Test for IE10/11 textarea placeholder clone bug
|
||
var hasTextareaCloneBug = (function () {
|
||
/* istanbul ignore else */
|
||
if (inBrowser) {
|
||
var t = document.createElement('textarea');
|
||
t.placeholder = 't';
|
||
return t.cloneNode(true).value === 't';
|
||
} else {
|
||
return false;
|
||
}
|
||
})();
|
||
|
||
/**
|
||
* 1. Deal with Safari cloning nested <template> bug by
|
||
* manually cloning all template instances.
|
||
* 2. Deal with IE10/11 textarea placeholder bug by setting
|
||
* the correct value after cloning.
|
||
*
|
||
* @param {Element|DocumentFragment} node
|
||
* @return {Element|DocumentFragment}
|
||
*/
|
||
|
||
function cloneNode(node) {
|
||
if (!node.querySelectorAll) {
|
||
return node.cloneNode();
|
||
}
|
||
var res = node.cloneNode(true);
|
||
var i, original, cloned;
|
||
/* istanbul ignore if */
|
||
if (hasBrokenTemplate) {
|
||
var tempClone = res;
|
||
if (isRealTemplate(node)) {
|
||
node = node.content;
|
||
tempClone = res.content;
|
||
}
|
||
original = node.querySelectorAll('template');
|
||
if (original.length) {
|
||
cloned = tempClone.querySelectorAll('template');
|
||
i = cloned.length;
|
||
while (i--) {
|
||
cloned[i].parentNode.replaceChild(cloneNode(original[i]), cloned[i]);
|
||
}
|
||
}
|
||
}
|
||
/* istanbul ignore if */
|
||
if (hasTextareaCloneBug) {
|
||
if (node.tagName === 'TEXTAREA') {
|
||
res.value = node.value;
|
||
} else {
|
||
original = node.querySelectorAll('textarea');
|
||
if (original.length) {
|
||
cloned = res.querySelectorAll('textarea');
|
||
i = cloned.length;
|
||
while (i--) {
|
||
cloned[i].value = original[i].value;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
|
||
/**
|
||
* Process the template option and normalizes it into a
|
||
* a DocumentFragment that can be used as a partial or a
|
||
* instance template.
|
||
*
|
||
* @param {*} template
|
||
* Possible values include:
|
||
* - DocumentFragment object
|
||
* - Node object of type Template
|
||
* - id selector: '#some-template-id'
|
||
* - template string: '<div><span>{{msg}}</span></div>'
|
||
* @param {Boolean} shouldClone
|
||
* @param {Boolean} raw
|
||
* inline HTML interpolation. Do not check for id
|
||
* selector and keep whitespace in the string.
|
||
* @return {DocumentFragment|undefined}
|
||
*/
|
||
|
||
function parseTemplate(template, shouldClone, raw) {
|
||
var node, frag;
|
||
|
||
// if the template is already a document fragment,
|
||
// do nothing
|
||
if (isFragment(template)) {
|
||
trimNode(template);
|
||
return shouldClone ? cloneNode(template) : template;
|
||
}
|
||
|
||
if (typeof template === 'string') {
|
||
// id selector
|
||
if (!raw && template.charAt(0) === '#') {
|
||
// id selector can be cached too
|
||
frag = idSelectorCache.get(template);
|
||
if (!frag) {
|
||
node = document.getElementById(template.slice(1));
|
||
if (node) {
|
||
frag = nodeToFragment(node);
|
||
// save selector to cache
|
||
idSelectorCache.put(template, frag);
|
||
}
|
||
}
|
||
} else {
|
||
// normal string template
|
||
frag = stringToFragment(template, raw);
|
||
}
|
||
} else if (template.nodeType) {
|
||
// a direct node
|
||
frag = nodeToFragment(template);
|
||
}
|
||
|
||
return frag && shouldClone ? cloneNode(frag) : frag;
|
||
}
|
||
|
||
var template = Object.freeze({
|
||
cloneNode: cloneNode,
|
||
parseTemplate: parseTemplate
|
||
});
|
||
|
||
var html = {
|
||
|
||
bind: function bind() {
|
||
// a comment node means this is a binding for
|
||
// {{{ inline unescaped html }}}
|
||
if (this.el.nodeType === 8) {
|
||
// hold nodes
|
||
this.nodes = [];
|
||
// replace the placeholder with proper anchor
|
||
this.anchor = createAnchor('v-html');
|
||
replace(this.el, this.anchor);
|
||
}
|
||
},
|
||
|
||
update: function update(value) {
|
||
value = _toString(value);
|
||
if (this.nodes) {
|
||
this.swap(value);
|
||
} else {
|
||
this.el.innerHTML = value;
|
||
}
|
||
},
|
||
|
||
swap: function swap(value) {
|
||
// remove old nodes
|
||
var i = this.nodes.length;
|
||
while (i--) {
|
||
remove(this.nodes[i]);
|
||
}
|
||
// convert new value to a fragment
|
||
// do not attempt to retrieve from id selector
|
||
var frag = parseTemplate(value, true, true);
|
||
// save a reference to these nodes so we can remove later
|
||
this.nodes = toArray(frag.childNodes);
|
||
before(frag, this.anchor);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Abstraction for a partially-compiled fragment.
|
||
* Can optionally compile content with a child scope.
|
||
*
|
||
* @param {Function} linker
|
||
* @param {Vue} vm
|
||
* @param {DocumentFragment} frag
|
||
* @param {Vue} [host]
|
||
* @param {Object} [scope]
|
||
*/
|
||
function Fragment(linker, vm, frag, host, scope, parentFrag) {
|
||
this.children = [];
|
||
this.childFrags = [];
|
||
this.vm = vm;
|
||
this.scope = scope;
|
||
this.inserted = false;
|
||
this.parentFrag = parentFrag;
|
||
if (parentFrag) {
|
||
parentFrag.childFrags.push(this);
|
||
}
|
||
this.unlink = linker(vm, frag, host, scope, this);
|
||
var single = this.single = frag.childNodes.length === 1 &&
|
||
// do not go single mode if the only node is an anchor
|
||
!frag.childNodes[0].__v_anchor;
|
||
if (single) {
|
||
this.node = frag.childNodes[0];
|
||
this.before = singleBefore;
|
||
this.remove = singleRemove;
|
||
} else {
|
||
this.node = createAnchor('fragment-start');
|
||
this.end = createAnchor('fragment-end');
|
||
this.frag = frag;
|
||
prepend(this.node, frag);
|
||
frag.appendChild(this.end);
|
||
this.before = multiBefore;
|
||
this.remove = multiRemove;
|
||
}
|
||
this.node.__v_frag = this;
|
||
}
|
||
|
||
/**
|
||
* Call attach/detach for all components contained within
|
||
* this fragment. Also do so recursively for all child
|
||
* fragments.
|
||
*
|
||
* @param {Function} hook
|
||
*/
|
||
|
||
Fragment.prototype.callHook = function (hook) {
|
||
var i, l;
|
||
for (i = 0, l = this.childFrags.length; i < l; i++) {
|
||
this.childFrags[i].callHook(hook);
|
||
}
|
||
for (i = 0, l = this.children.length; i < l; i++) {
|
||
hook(this.children[i]);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Insert fragment before target, single node version
|
||
*
|
||
* @param {Node} target
|
||
* @param {Boolean} withTransition
|
||
*/
|
||
|
||
function singleBefore(target, withTransition) {
|
||
this.inserted = true;
|
||
var method = withTransition !== false ? beforeWithTransition : before;
|
||
method(this.node, target, this.vm);
|
||
if (inDoc(this.node)) {
|
||
this.callHook(attach);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Remove fragment, single node version
|
||
*/
|
||
|
||
function singleRemove() {
|
||
this.inserted = false;
|
||
var shouldCallRemove = inDoc(this.node);
|
||
var self = this;
|
||
this.beforeRemove();
|
||
removeWithTransition(this.node, this.vm, function () {
|
||
if (shouldCallRemove) {
|
||
self.callHook(detach);
|
||
}
|
||
self.destroy();
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Insert fragment before target, multi-nodes version
|
||
*
|
||
* @param {Node} target
|
||
* @param {Boolean} withTransition
|
||
*/
|
||
|
||
function multiBefore(target, withTransition) {
|
||
this.inserted = true;
|
||
var vm = this.vm;
|
||
var method = withTransition !== false ? beforeWithTransition : before;
|
||
mapNodeRange(this.node, this.end, function (node) {
|
||
method(node, target, vm);
|
||
});
|
||
if (inDoc(this.node)) {
|
||
this.callHook(attach);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Remove fragment, multi-nodes version
|
||
*/
|
||
|
||
function multiRemove() {
|
||
this.inserted = false;
|
||
var self = this;
|
||
var shouldCallRemove = inDoc(this.node);
|
||
this.beforeRemove();
|
||
removeNodeRange(this.node, this.end, this.vm, this.frag, function () {
|
||
if (shouldCallRemove) {
|
||
self.callHook(detach);
|
||
}
|
||
self.destroy();
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Prepare the fragment for removal.
|
||
*/
|
||
|
||
Fragment.prototype.beforeRemove = function () {
|
||
var i, l;
|
||
for (i = 0, l = this.childFrags.length; i < l; i++) {
|
||
// call the same method recursively on child
|
||
// fragments, depth-first
|
||
this.childFrags[i].beforeRemove(false);
|
||
}
|
||
for (i = 0, l = this.children.length; i < l; i++) {
|
||
// Call destroy for all contained instances,
|
||
// with remove:false and defer:true.
|
||
// Defer is necessary because we need to
|
||
// keep the children to call detach hooks
|
||
// on them.
|
||
this.children[i].$destroy(false, true);
|
||
}
|
||
var dirs = this.unlink.dirs;
|
||
for (i = 0, l = dirs.length; i < l; i++) {
|
||
// disable the watchers on all the directives
|
||
// so that the rendered content stays the same
|
||
// during removal.
|
||
dirs[i]._watcher && dirs[i]._watcher.teardown();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Destroy the fragment.
|
||
*/
|
||
|
||
Fragment.prototype.destroy = function () {
|
||
if (this.parentFrag) {
|
||
this.parentFrag.childFrags.$remove(this);
|
||
}
|
||
this.node.__v_frag = null;
|
||
this.unlink();
|
||
};
|
||
|
||
/**
|
||
* Call attach hook for a Vue instance.
|
||
*
|
||
* @param {Vue} child
|
||
*/
|
||
|
||
function attach(child) {
|
||
if (!child._isAttached) {
|
||
child._callHook('attached');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Call detach hook for a Vue instance.
|
||
*
|
||
* @param {Vue} child
|
||
*/
|
||
|
||
function detach(child) {
|
||
if (child._isAttached) {
|
||
child._callHook('detached');
|
||
}
|
||
}
|
||
|
||
var linkerCache = new Cache(5000);
|
||
|
||
/**
|
||
* A factory that can be used to create instances of a
|
||
* fragment. Caches the compiled linker if possible.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {Element|String} el
|
||
*/
|
||
function FragmentFactory(vm, el) {
|
||
this.vm = vm;
|
||
var template;
|
||
var isString = typeof el === 'string';
|
||
if (isString || isTemplate(el)) {
|
||
template = parseTemplate(el, true);
|
||
} else {
|
||
template = document.createDocumentFragment();
|
||
template.appendChild(el);
|
||
}
|
||
this.template = template;
|
||
// linker can be cached, but only for components
|
||
var linker;
|
||
var cid = vm.constructor.cid;
|
||
if (cid > 0) {
|
||
var cacheId = cid + (isString ? el : getOuterHTML(el));
|
||
linker = linkerCache.get(cacheId);
|
||
if (!linker) {
|
||
linker = compile(template, vm.$options, true);
|
||
linkerCache.put(cacheId, linker);
|
||
}
|
||
} else {
|
||
linker = compile(template, vm.$options, true);
|
||
}
|
||
this.linker = linker;
|
||
}
|
||
|
||
/**
|
||
* Create a fragment instance with given host and scope.
|
||
*
|
||
* @param {Vue} host
|
||
* @param {Object} scope
|
||
* @param {Fragment} parentFrag
|
||
*/
|
||
|
||
FragmentFactory.prototype.create = function (host, scope, parentFrag) {
|
||
var frag = cloneNode(this.template);
|
||
return new Fragment(this.linker, this.vm, frag, host, scope, parentFrag);
|
||
};
|
||
|
||
var ON = 700;
|
||
var MODEL = 800;
|
||
var BIND = 850;
|
||
var TRANSITION = 1100;
|
||
var EL = 1500;
|
||
var COMPONENT = 1500;
|
||
var PARTIAL = 1750;
|
||
var FOR = 2000;
|
||
var IF = 2000;
|
||
var SLOT = 2100;
|
||
|
||
var uid$3 = 0;
|
||
|
||
var vFor = {
|
||
|
||
priority: FOR,
|
||
|
||
params: ['track-by', 'stagger', 'enter-stagger', 'leave-stagger'],
|
||
|
||
bind: function bind() {
|
||
// support "item in/of items" syntax
|
||
var inMatch = this.expression.match(/(.*) (?:in|of) (.*)/);
|
||
if (inMatch) {
|
||
var itMatch = inMatch[1].match(/\((.*),(.*)\)/);
|
||
if (itMatch) {
|
||
this.iterator = itMatch[1].trim();
|
||
this.alias = itMatch[2].trim();
|
||
} else {
|
||
this.alias = inMatch[1].trim();
|
||
}
|
||
this.expression = inMatch[2];
|
||
}
|
||
|
||
if (!this.alias) {
|
||
process.env.NODE_ENV !== 'production' && warn('Alias is required in v-for.');
|
||
return;
|
||
}
|
||
|
||
// uid as a cache identifier
|
||
this.id = '__v-for__' + ++uid$3;
|
||
|
||
// check if this is an option list,
|
||
// so that we know if we need to update the <select>'s
|
||
// v-model when the option list has changed.
|
||
// because v-model has a lower priority than v-for,
|
||
// the v-model is not bound here yet, so we have to
|
||
// retrive it in the actual updateModel() function.
|
||
var tag = this.el.tagName;
|
||
this.isOption = (tag === 'OPTION' || tag === 'OPTGROUP') && this.el.parentNode.tagName === 'SELECT';
|
||
|
||
// setup anchor nodes
|
||
this.start = createAnchor('v-for-start');
|
||
this.end = createAnchor('v-for-end');
|
||
replace(this.el, this.end);
|
||
before(this.start, this.end);
|
||
|
||
// cache
|
||
this.cache = Object.create(null);
|
||
|
||
// fragment factory
|
||
this.factory = new FragmentFactory(this.vm, this.el);
|
||
},
|
||
|
||
update: function update(data) {
|
||
this.diff(data);
|
||
this.updateRef();
|
||
this.updateModel();
|
||
},
|
||
|
||
/**
|
||
* Diff, based on new data and old data, determine the
|
||
* minimum amount of DOM manipulations needed to make the
|
||
* DOM reflect the new data Array.
|
||
*
|
||
* The algorithm diffs the new data Array by storing a
|
||
* hidden reference to an owner vm instance on previously
|
||
* seen data. This allows us to achieve O(n) which is
|
||
* better than a levenshtein distance based algorithm,
|
||
* which is O(m * n).
|
||
*
|
||
* @param {Array} data
|
||
*/
|
||
|
||
diff: function diff(data) {
|
||
// check if the Array was converted from an Object
|
||
var item = data[0];
|
||
var convertedFromObject = this.fromObject = isObject(item) && hasOwn(item, '$key') && hasOwn(item, '$value');
|
||
|
||
var trackByKey = this.params.trackBy;
|
||
var oldFrags = this.frags;
|
||
var frags = this.frags = new Array(data.length);
|
||
var alias = this.alias;
|
||
var iterator = this.iterator;
|
||
var start = this.start;
|
||
var end = this.end;
|
||
var inDocument = inDoc(start);
|
||
var init = !oldFrags;
|
||
var i, l, frag, key, value, primitive;
|
||
|
||
// First pass, go through the new Array and fill up
|
||
// the new frags array. If a piece of data has a cached
|
||
// instance for it, we reuse it. Otherwise build a new
|
||
// instance.
|
||
for (i = 0, l = data.length; i < l; i++) {
|
||
item = data[i];
|
||
key = convertedFromObject ? item.$key : null;
|
||
value = convertedFromObject ? item.$value : item;
|
||
primitive = !isObject(value);
|
||
frag = !init && this.getCachedFrag(value, i, key);
|
||
if (frag) {
|
||
// reusable fragment
|
||
frag.reused = true;
|
||
// update $index
|
||
frag.scope.$index = i;
|
||
// update $key
|
||
if (key) {
|
||
frag.scope.$key = key;
|
||
}
|
||
// update iterator
|
||
if (iterator) {
|
||
frag.scope[iterator] = key !== null ? key : i;
|
||
}
|
||
// update data for track-by, object repeat &
|
||
// primitive values.
|
||
if (trackByKey || convertedFromObject || primitive) {
|
||
frag.scope[alias] = value;
|
||
}
|
||
} else {
|
||
// new isntance
|
||
frag = this.create(value, alias, i, key);
|
||
frag.fresh = !init;
|
||
}
|
||
frags[i] = frag;
|
||
if (init) {
|
||
frag.before(end);
|
||
}
|
||
}
|
||
|
||
// we're done for the initial render.
|
||
if (init) {
|
||
return;
|
||
}
|
||
|
||
// Second pass, go through the old fragments and
|
||
// destroy those who are not reused (and remove them
|
||
// from cache)
|
||
var removalIndex = 0;
|
||
var totalRemoved = oldFrags.length - frags.length;
|
||
// when removing a large number of fragments, watcher removal
|
||
// turns out to be a perf bottleneck, so we batch the watcher
|
||
// removals into a single filter call!
|
||
this.vm._vForRemoving = true;
|
||
for (i = 0, l = oldFrags.length; i < l; i++) {
|
||
frag = oldFrags[i];
|
||
if (!frag.reused) {
|
||
this.deleteCachedFrag(frag);
|
||
this.remove(frag, removalIndex++, totalRemoved, inDocument);
|
||
}
|
||
}
|
||
this.vm._vForRemoving = false;
|
||
if (removalIndex) {
|
||
this.vm._watchers = this.vm._watchers.filter(function (w) {
|
||
return w.active;
|
||
});
|
||
}
|
||
|
||
// Final pass, move/insert new fragments into the
|
||
// right place.
|
||
var targetPrev, prevEl, currentPrev;
|
||
var insertionIndex = 0;
|
||
for (i = 0, l = frags.length; i < l; i++) {
|
||
frag = frags[i];
|
||
// this is the frag that we should be after
|
||
targetPrev = frags[i - 1];
|
||
prevEl = targetPrev ? targetPrev.staggerCb ? targetPrev.staggerAnchor : targetPrev.end || targetPrev.node : start;
|
||
if (frag.reused && !frag.staggerCb) {
|
||
currentPrev = findPrevFrag(frag, start, this.id);
|
||
if (currentPrev !== targetPrev && (!currentPrev ||
|
||
// optimization for moving a single item.
|
||
// thanks to suggestions by @livoras in #1807
|
||
findPrevFrag(currentPrev, start, this.id) !== targetPrev)) {
|
||
this.move(frag, prevEl);
|
||
}
|
||
} else {
|
||
// new instance, or still in stagger.
|
||
// insert with updated stagger index.
|
||
this.insert(frag, insertionIndex++, prevEl, inDocument);
|
||
}
|
||
frag.reused = frag.fresh = false;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Create a new fragment instance.
|
||
*
|
||
* @param {*} value
|
||
* @param {String} alias
|
||
* @param {Number} index
|
||
* @param {String} [key]
|
||
* @return {Fragment}
|
||
*/
|
||
|
||
create: function create(value, alias, index, key) {
|
||
var host = this._host;
|
||
// create iteration scope
|
||
var parentScope = this._scope || this.vm;
|
||
var scope = Object.create(parentScope);
|
||
// ref holder for the scope
|
||
scope.$refs = Object.create(parentScope.$refs);
|
||
scope.$els = Object.create(parentScope.$els);
|
||
// make sure point $parent to parent scope
|
||
scope.$parent = parentScope;
|
||
// for two-way binding on alias
|
||
scope.$forContext = this;
|
||
// define scope properties
|
||
defineReactive(scope, alias, value);
|
||
defineReactive(scope, '$index', index);
|
||
if (key) {
|
||
defineReactive(scope, '$key', key);
|
||
} else if (scope.$key) {
|
||
// avoid accidental fallback
|
||
def(scope, '$key', null);
|
||
}
|
||
if (this.iterator) {
|
||
defineReactive(scope, this.iterator, key !== null ? key : index);
|
||
}
|
||
var frag = this.factory.create(host, scope, this._frag);
|
||
frag.forId = this.id;
|
||
this.cacheFrag(value, frag, index, key);
|
||
return frag;
|
||
},
|
||
|
||
/**
|
||
* Update the v-ref on owner vm.
|
||
*/
|
||
|
||
updateRef: function updateRef() {
|
||
var ref = this.descriptor.ref;
|
||
if (!ref) return;
|
||
var hash = (this._scope || this.vm).$refs;
|
||
var refs;
|
||
if (!this.fromObject) {
|
||
refs = this.frags.map(findVmFromFrag);
|
||
} else {
|
||
refs = {};
|
||
this.frags.forEach(function (frag) {
|
||
refs[frag.scope.$key] = findVmFromFrag(frag);
|
||
});
|
||
}
|
||
hash[ref] = refs;
|
||
},
|
||
|
||
/**
|
||
* For option lists, update the containing v-model on
|
||
* parent <select>.
|
||
*/
|
||
|
||
updateModel: function updateModel() {
|
||
if (this.isOption) {
|
||
var parent = this.start.parentNode;
|
||
var model = parent && parent.__v_model;
|
||
if (model) {
|
||
model.forceUpdate();
|
||
}
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Insert a fragment. Handles staggering.
|
||
*
|
||
* @param {Fragment} frag
|
||
* @param {Number} index
|
||
* @param {Node} prevEl
|
||
* @param {Boolean} inDocument
|
||
*/
|
||
|
||
insert: function insert(frag, index, prevEl, inDocument) {
|
||
if (frag.staggerCb) {
|
||
frag.staggerCb.cancel();
|
||
frag.staggerCb = null;
|
||
}
|
||
var staggerAmount = this.getStagger(frag, index, null, 'enter');
|
||
if (inDocument && staggerAmount) {
|
||
// create an anchor and insert it synchronously,
|
||
// so that we can resolve the correct order without
|
||
// worrying about some elements not inserted yet
|
||
var anchor = frag.staggerAnchor;
|
||
if (!anchor) {
|
||
anchor = frag.staggerAnchor = createAnchor('stagger-anchor');
|
||
anchor.__v_frag = frag;
|
||
}
|
||
after(anchor, prevEl);
|
||
var op = frag.staggerCb = cancellable(function () {
|
||
frag.staggerCb = null;
|
||
frag.before(anchor);
|
||
remove(anchor);
|
||
});
|
||
setTimeout(op, staggerAmount);
|
||
} else {
|
||
frag.before(prevEl.nextSibling);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Remove a fragment. Handles staggering.
|
||
*
|
||
* @param {Fragment} frag
|
||
* @param {Number} index
|
||
* @param {Number} total
|
||
* @param {Boolean} inDocument
|
||
*/
|
||
|
||
remove: function remove(frag, index, total, inDocument) {
|
||
if (frag.staggerCb) {
|
||
frag.staggerCb.cancel();
|
||
frag.staggerCb = null;
|
||
// it's not possible for the same frag to be removed
|
||
// twice, so if we have a pending stagger callback,
|
||
// it means this frag is queued for enter but removed
|
||
// before its transition started. Since it is already
|
||
// destroyed, we can just leave it in detached state.
|
||
return;
|
||
}
|
||
var staggerAmount = this.getStagger(frag, index, total, 'leave');
|
||
if (inDocument && staggerAmount) {
|
||
var op = frag.staggerCb = cancellable(function () {
|
||
frag.staggerCb = null;
|
||
frag.remove();
|
||
});
|
||
setTimeout(op, staggerAmount);
|
||
} else {
|
||
frag.remove();
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Move a fragment to a new position.
|
||
* Force no transition.
|
||
*
|
||
* @param {Fragment} frag
|
||
* @param {Node} prevEl
|
||
*/
|
||
|
||
move: function move(frag, prevEl) {
|
||
// fix a common issue with Sortable:
|
||
// if prevEl doesn't have nextSibling, this means it's
|
||
// been dragged after the end anchor. Just re-position
|
||
// the end anchor to the end of the container.
|
||
/* istanbul ignore if */
|
||
if (!prevEl.nextSibling) {
|
||
this.end.parentNode.appendChild(this.end);
|
||
}
|
||
frag.before(prevEl.nextSibling, false);
|
||
},
|
||
|
||
/**
|
||
* Cache a fragment using track-by or the object key.
|
||
*
|
||
* @param {*} value
|
||
* @param {Fragment} frag
|
||
* @param {Number} index
|
||
* @param {String} [key]
|
||
*/
|
||
|
||
cacheFrag: function cacheFrag(value, frag, index, key) {
|
||
var trackByKey = this.params.trackBy;
|
||
var cache = this.cache;
|
||
var primitive = !isObject(value);
|
||
var id;
|
||
if (key || trackByKey || primitive) {
|
||
id = trackByKey ? trackByKey === '$index' ? index : value[trackByKey] : key || value;
|
||
if (!cache[id]) {
|
||
cache[id] = frag;
|
||
} else if (trackByKey !== '$index') {
|
||
process.env.NODE_ENV !== 'production' && this.warnDuplicate(value);
|
||
}
|
||
} else {
|
||
id = this.id;
|
||
if (hasOwn(value, id)) {
|
||
if (value[id] === null) {
|
||
value[id] = frag;
|
||
} else {
|
||
process.env.NODE_ENV !== 'production' && this.warnDuplicate(value);
|
||
}
|
||
} else {
|
||
def(value, id, frag);
|
||
}
|
||
}
|
||
frag.raw = value;
|
||
},
|
||
|
||
/**
|
||
* Get a cached fragment from the value/index/key
|
||
*
|
||
* @param {*} value
|
||
* @param {Number} index
|
||
* @param {String} key
|
||
* @return {Fragment}
|
||
*/
|
||
|
||
getCachedFrag: function getCachedFrag(value, index, key) {
|
||
var trackByKey = this.params.trackBy;
|
||
var primitive = !isObject(value);
|
||
var frag;
|
||
if (key || trackByKey || primitive) {
|
||
var id = trackByKey ? trackByKey === '$index' ? index : value[trackByKey] : key || value;
|
||
frag = this.cache[id];
|
||
} else {
|
||
frag = value[this.id];
|
||
}
|
||
if (frag && (frag.reused || frag.fresh)) {
|
||
process.env.NODE_ENV !== 'production' && this.warnDuplicate(value);
|
||
}
|
||
return frag;
|
||
},
|
||
|
||
/**
|
||
* Delete a fragment from cache.
|
||
*
|
||
* @param {Fragment} frag
|
||
*/
|
||
|
||
deleteCachedFrag: function deleteCachedFrag(frag) {
|
||
var value = frag.raw;
|
||
var trackByKey = this.params.trackBy;
|
||
var scope = frag.scope;
|
||
var index = scope.$index;
|
||
// fix #948: avoid accidentally fall through to
|
||
// a parent repeater which happens to have $key.
|
||
var key = hasOwn(scope, '$key') && scope.$key;
|
||
var primitive = !isObject(value);
|
||
if (trackByKey || key || primitive) {
|
||
var id = trackByKey ? trackByKey === '$index' ? index : value[trackByKey] : key || value;
|
||
this.cache[id] = null;
|
||
} else {
|
||
value[this.id] = null;
|
||
frag.raw = null;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Get the stagger amount for an insertion/removal.
|
||
*
|
||
* @param {Fragment} frag
|
||
* @param {Number} index
|
||
* @param {Number} total
|
||
* @param {String} type
|
||
*/
|
||
|
||
getStagger: function getStagger(frag, index, total, type) {
|
||
type = type + 'Stagger';
|
||
var trans = frag.node.__v_trans;
|
||
var hooks = trans && trans.hooks;
|
||
var hook = hooks && (hooks[type] || hooks.stagger);
|
||
return hook ? hook.call(frag, index, total) : index * parseInt(this.params[type] || this.params.stagger, 10);
|
||
},
|
||
|
||
/**
|
||
* Pre-process the value before piping it through the
|
||
* filters. This is passed to and called by the watcher.
|
||
*/
|
||
|
||
_preProcess: function _preProcess(value) {
|
||
// regardless of type, store the un-filtered raw value.
|
||
this.rawValue = value;
|
||
return value;
|
||
},
|
||
|
||
/**
|
||
* Post-process the value after it has been piped through
|
||
* the filters. This is passed to and called by the watcher.
|
||
*
|
||
* It is necessary for this to be called during the
|
||
* wathcer's dependency collection phase because we want
|
||
* the v-for to update when the source Object is mutated.
|
||
*/
|
||
|
||
_postProcess: function _postProcess(value) {
|
||
if (isArray(value)) {
|
||
return value;
|
||
} else if (isPlainObject(value)) {
|
||
// convert plain object to array.
|
||
var keys = Object.keys(value);
|
||
var i = keys.length;
|
||
var res = new Array(i);
|
||
var key;
|
||
while (i--) {
|
||
key = keys[i];
|
||
res[i] = {
|
||
$key: key,
|
||
$value: value[key]
|
||
};
|
||
}
|
||
return res;
|
||
} else {
|
||
if (typeof value === 'number' && !isNaN(value)) {
|
||
value = range(value);
|
||
}
|
||
return value || [];
|
||
}
|
||
},
|
||
|
||
unbind: function unbind() {
|
||
if (this.descriptor.ref) {
|
||
(this._scope || this.vm).$refs[this.descriptor.ref] = null;
|
||
}
|
||
if (this.frags) {
|
||
var i = this.frags.length;
|
||
var frag;
|
||
while (i--) {
|
||
frag = this.frags[i];
|
||
this.deleteCachedFrag(frag);
|
||
frag.destroy();
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Helper to find the previous element that is a fragment
|
||
* anchor. This is necessary because a destroyed frag's
|
||
* element could still be lingering in the DOM before its
|
||
* leaving transition finishes, but its inserted flag
|
||
* should have been set to false so we can skip them.
|
||
*
|
||
* If this is a block repeat, we want to make sure we only
|
||
* return frag that is bound to this v-for. (see #929)
|
||
*
|
||
* @param {Fragment} frag
|
||
* @param {Comment|Text} anchor
|
||
* @param {String} id
|
||
* @return {Fragment}
|
||
*/
|
||
|
||
function findPrevFrag(frag, anchor, id) {
|
||
var el = frag.node.previousSibling;
|
||
/* istanbul ignore if */
|
||
if (!el) return;
|
||
frag = el.__v_frag;
|
||
while ((!frag || frag.forId !== id || !frag.inserted) && el !== anchor) {
|
||
el = el.previousSibling;
|
||
/* istanbul ignore if */
|
||
if (!el) return;
|
||
frag = el.__v_frag;
|
||
}
|
||
return frag;
|
||
}
|
||
|
||
/**
|
||
* Find a vm from a fragment.
|
||
*
|
||
* @param {Fragment} frag
|
||
* @return {Vue|undefined}
|
||
*/
|
||
|
||
function findVmFromFrag(frag) {
|
||
var node = frag.node;
|
||
// handle multi-node frag
|
||
if (frag.end) {
|
||
while (!node.__vue__ && node !== frag.end && node.nextSibling) {
|
||
node = node.nextSibling;
|
||
}
|
||
}
|
||
return node.__vue__;
|
||
}
|
||
|
||
/**
|
||
* Create a range array from given number.
|
||
*
|
||
* @param {Number} n
|
||
* @return {Array}
|
||
*/
|
||
|
||
function range(n) {
|
||
var i = -1;
|
||
var ret = new Array(Math.floor(n));
|
||
while (++i < n) {
|
||
ret[i] = i;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
vFor.warnDuplicate = function (value) {
|
||
warn('Duplicate value found in v-for="' + this.descriptor.raw + '": ' + JSON.stringify(value) + '. Use track-by="$index" if ' + 'you are expecting duplicate values.');
|
||
};
|
||
}
|
||
|
||
var vIf = {
|
||
|
||
priority: IF,
|
||
|
||
bind: function bind() {
|
||
var el = this.el;
|
||
if (!el.__vue__) {
|
||
// check else block
|
||
var next = el.nextElementSibling;
|
||
if (next && getAttr(next, 'v-else') !== null) {
|
||
remove(next);
|
||
this.elseFactory = new FragmentFactory(next._context || this.vm, next);
|
||
}
|
||
// check main block
|
||
this.anchor = createAnchor('v-if');
|
||
replace(el, this.anchor);
|
||
this.factory = new FragmentFactory(this.vm, el);
|
||
} else {
|
||
process.env.NODE_ENV !== 'production' && warn('v-if="' + this.expression + '" cannot be ' + 'used on an instance root element.');
|
||
this.invalid = true;
|
||
}
|
||
},
|
||
|
||
update: function update(value) {
|
||
if (this.invalid) return;
|
||
if (value) {
|
||
if (!this.frag) {
|
||
this.insert();
|
||
}
|
||
} else {
|
||
this.remove();
|
||
}
|
||
},
|
||
|
||
insert: function insert() {
|
||
if (this.elseFrag) {
|
||
this.elseFrag.remove();
|
||
this.elseFrag = null;
|
||
}
|
||
this.frag = this.factory.create(this._host, this._scope, this._frag);
|
||
this.frag.before(this.anchor);
|
||
},
|
||
|
||
remove: function remove() {
|
||
if (this.frag) {
|
||
this.frag.remove();
|
||
this.frag = null;
|
||
}
|
||
if (this.elseFactory && !this.elseFrag) {
|
||
this.elseFrag = this.elseFactory.create(this._host, this._scope, this._frag);
|
||
this.elseFrag.before(this.anchor);
|
||
}
|
||
},
|
||
|
||
unbind: function unbind() {
|
||
if (this.frag) {
|
||
this.frag.destroy();
|
||
}
|
||
if (this.elseFrag) {
|
||
this.elseFrag.destroy();
|
||
}
|
||
}
|
||
};
|
||
|
||
var show = {
|
||
|
||
bind: function bind() {
|
||
// check else block
|
||
var next = this.el.nextElementSibling;
|
||
if (next && getAttr(next, 'v-else') !== null) {
|
||
this.elseEl = next;
|
||
}
|
||
},
|
||
|
||
update: function update(value) {
|
||
this.apply(this.el, value);
|
||
if (this.elseEl) {
|
||
this.apply(this.elseEl, !value);
|
||
}
|
||
},
|
||
|
||
apply: function apply(el, value) {
|
||
if (inDoc(el)) {
|
||
applyTransition(el, value ? 1 : -1, toggle, this.vm);
|
||
} else {
|
||
toggle();
|
||
}
|
||
function toggle() {
|
||
el.style.display = value ? '' : 'none';
|
||
}
|
||
}
|
||
};
|
||
|
||
var text$2 = {
|
||
|
||
bind: function bind() {
|
||
var self = this;
|
||
var el = this.el;
|
||
var isRange = el.type === 'range';
|
||
var lazy = this.params.lazy;
|
||
var number = this.params.number;
|
||
var debounce = this.params.debounce;
|
||
|
||
// handle composition events.
|
||
// http://blog.evanyou.me/2014/01/03/composition-event/
|
||
// skip this for Android because it handles composition
|
||
// events quite differently. Android doesn't trigger
|
||
// composition events for language input methods e.g.
|
||
// Chinese, but instead triggers them for spelling
|
||
// suggestions... (see Discussion/#162)
|
||
var composing = false;
|
||
if (!isAndroid && !isRange) {
|
||
this.on('compositionstart', function () {
|
||
composing = true;
|
||
});
|
||
this.on('compositionend', function () {
|
||
composing = false;
|
||
// in IE11 the "compositionend" event fires AFTER
|
||
// the "input" event, so the input handler is blocked
|
||
// at the end... have to call it here.
|
||
//
|
||
// #1327: in lazy mode this is unecessary.
|
||
if (!lazy) {
|
||
self.listener();
|
||
}
|
||
});
|
||
}
|
||
|
||
// prevent messing with the input when user is typing,
|
||
// and force update on blur.
|
||
this.focused = false;
|
||
if (!isRange && !lazy) {
|
||
this.on('focus', function () {
|
||
self.focused = true;
|
||
});
|
||
this.on('blur', function () {
|
||
self.focused = false;
|
||
});
|
||
}
|
||
|
||
// Now attach the main listener
|
||
this.listener = this.rawListener = function () {
|
||
if (composing || !self._bound) {
|
||
return;
|
||
}
|
||
var val = number || isRange ? toNumber(el.value) : el.value;
|
||
self.set(val);
|
||
// force update on next tick to avoid lock & same value
|
||
// also only update when user is not typing
|
||
nextTick(function () {
|
||
if (self._bound && !self.focused) {
|
||
self.update(self._watcher.value);
|
||
}
|
||
});
|
||
};
|
||
|
||
// apply debounce
|
||
if (debounce) {
|
||
this.listener = _debounce(this.listener, debounce);
|
||
}
|
||
|
||
// Support jQuery events, since jQuery.trigger() doesn't
|
||
// trigger native events in some cases and some plugins
|
||
// rely on $.trigger()
|
||
//
|
||
// We want to make sure if a listener is attached using
|
||
// jQuery, it is also removed with jQuery, that's why
|
||
// we do the check for each directive instance and
|
||
// store that check result on itself. This also allows
|
||
// easier test coverage control by unsetting the global
|
||
// jQuery variable in tests.
|
||
this.hasjQuery = typeof jQuery === 'function';
|
||
if (this.hasjQuery) {
|
||
var method = jQuery.fn.on ? 'on' : 'bind';
|
||
jQuery(el)[method]('change', this.rawListener);
|
||
if (!lazy) {
|
||
jQuery(el)[method]('input', this.listener);
|
||
}
|
||
} else {
|
||
this.on('change', this.rawListener);
|
||
if (!lazy) {
|
||
this.on('input', this.listener);
|
||
}
|
||
}
|
||
|
||
// IE9 doesn't fire input event on backspace/del/cut
|
||
if (!lazy && isIE9) {
|
||
this.on('cut', function () {
|
||
nextTick(self.listener);
|
||
});
|
||
this.on('keyup', function (e) {
|
||
if (e.keyCode === 46 || e.keyCode === 8) {
|
||
self.listener();
|
||
}
|
||
});
|
||
}
|
||
|
||
// set initial value if present
|
||
if (el.hasAttribute('value') || el.tagName === 'TEXTAREA' && el.value.trim()) {
|
||
this.afterBind = this.listener;
|
||
}
|
||
},
|
||
|
||
update: function update(value) {
|
||
this.el.value = _toString(value);
|
||
},
|
||
|
||
unbind: function unbind() {
|
||
var el = this.el;
|
||
if (this.hasjQuery) {
|
||
var method = jQuery.fn.off ? 'off' : 'unbind';
|
||
jQuery(el)[method]('change', this.listener);
|
||
jQuery(el)[method]('input', this.listener);
|
||
}
|
||
}
|
||
};
|
||
|
||
var radio = {
|
||
|
||
bind: function bind() {
|
||
var self = this;
|
||
var el = this.el;
|
||
|
||
this.getValue = function () {
|
||
// value overwrite via v-bind:value
|
||
if (el.hasOwnProperty('_value')) {
|
||
return el._value;
|
||
}
|
||
var val = el.value;
|
||
if (self.params.number) {
|
||
val = toNumber(val);
|
||
}
|
||
return val;
|
||
};
|
||
|
||
this.listener = function () {
|
||
self.set(self.getValue());
|
||
};
|
||
this.on('change', this.listener);
|
||
|
||
if (el.hasAttribute('checked')) {
|
||
this.afterBind = this.listener;
|
||
}
|
||
},
|
||
|
||
update: function update(value) {
|
||
this.el.checked = looseEqual(value, this.getValue());
|
||
}
|
||
};
|
||
|
||
var select = {
|
||
|
||
bind: function bind() {
|
||
var self = this;
|
||
var el = this.el;
|
||
|
||
// method to force update DOM using latest value.
|
||
this.forceUpdate = function () {
|
||
if (self._watcher) {
|
||
self.update(self._watcher.get());
|
||
}
|
||
};
|
||
|
||
// check if this is a multiple select
|
||
var multiple = this.multiple = el.hasAttribute('multiple');
|
||
|
||
// attach listener
|
||
this.listener = function () {
|
||
var value = getValue(el, multiple);
|
||
value = self.params.number ? isArray(value) ? value.map(toNumber) : toNumber(value) : value;
|
||
self.set(value);
|
||
};
|
||
this.on('change', this.listener);
|
||
|
||
// if has initial value, set afterBind
|
||
var initValue = getValue(el, multiple, true);
|
||
if (multiple && initValue.length || !multiple && initValue !== null) {
|
||
this.afterBind = this.listener;
|
||
}
|
||
|
||
// All major browsers except Firefox resets
|
||
// selectedIndex with value -1 to 0 when the element
|
||
// is appended to a new parent, therefore we have to
|
||
// force a DOM update whenever that happens...
|
||
this.vm.$on('hook:attached', this.forceUpdate);
|
||
},
|
||
|
||
update: function update(value) {
|
||
var el = this.el;
|
||
el.selectedIndex = -1;
|
||
var multi = this.multiple && isArray(value);
|
||
var options = el.options;
|
||
var i = options.length;
|
||
var op, val;
|
||
while (i--) {
|
||
op = options[i];
|
||
val = op.hasOwnProperty('_value') ? op._value : op.value;
|
||
/* eslint-disable eqeqeq */
|
||
op.selected = multi ? indexOf$1(value, val) > -1 : looseEqual(value, val);
|
||
/* eslint-enable eqeqeq */
|
||
}
|
||
},
|
||
|
||
unbind: function unbind() {
|
||
/* istanbul ignore next */
|
||
this.vm.$off('hook:attached', this.forceUpdate);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Get select value
|
||
*
|
||
* @param {SelectElement} el
|
||
* @param {Boolean} multi
|
||
* @param {Boolean} init
|
||
* @return {Array|*}
|
||
*/
|
||
|
||
function getValue(el, multi, init) {
|
||
var res = multi ? [] : null;
|
||
var op, val, selected;
|
||
for (var i = 0, l = el.options.length; i < l; i++) {
|
||
op = el.options[i];
|
||
selected = init ? op.hasAttribute('selected') : op.selected;
|
||
if (selected) {
|
||
val = op.hasOwnProperty('_value') ? op._value : op.value;
|
||
if (multi) {
|
||
res.push(val);
|
||
} else {
|
||
return val;
|
||
}
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
|
||
/**
|
||
* Native Array.indexOf uses strict equal, but in this
|
||
* case we need to match string/numbers with custom equal.
|
||
*
|
||
* @param {Array} arr
|
||
* @param {*} val
|
||
*/
|
||
|
||
function indexOf$1(arr, val) {
|
||
var i = arr.length;
|
||
while (i--) {
|
||
if (looseEqual(arr[i], val)) {
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
var checkbox = {
|
||
|
||
bind: function bind() {
|
||
var self = this;
|
||
var el = this.el;
|
||
|
||
this.getValue = function () {
|
||
return el.hasOwnProperty('_value') ? el._value : self.params.number ? toNumber(el.value) : el.value;
|
||
};
|
||
|
||
function getBooleanValue() {
|
||
var val = el.checked;
|
||
if (val && el.hasOwnProperty('_trueValue')) {
|
||
return el._trueValue;
|
||
}
|
||
if (!val && el.hasOwnProperty('_falseValue')) {
|
||
return el._falseValue;
|
||
}
|
||
return val;
|
||
}
|
||
|
||
this.listener = function () {
|
||
var model = self._watcher.value;
|
||
if (isArray(model)) {
|
||
var val = self.getValue();
|
||
if (el.checked) {
|
||
if (indexOf(model, val) < 0) {
|
||
model.push(val);
|
||
}
|
||
} else {
|
||
model.$remove(val);
|
||
}
|
||
} else {
|
||
self.set(getBooleanValue());
|
||
}
|
||
};
|
||
|
||
this.on('change', this.listener);
|
||
if (el.hasAttribute('checked')) {
|
||
this.afterBind = this.listener;
|
||
}
|
||
},
|
||
|
||
update: function update(value) {
|
||
var el = this.el;
|
||
if (isArray(value)) {
|
||
el.checked = indexOf(value, this.getValue()) > -1;
|
||
} else {
|
||
if (el.hasOwnProperty('_trueValue')) {
|
||
el.checked = looseEqual(value, el._trueValue);
|
||
} else {
|
||
el.checked = !!value;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
var handlers = {
|
||
text: text$2,
|
||
radio: radio,
|
||
select: select,
|
||
checkbox: checkbox
|
||
};
|
||
|
||
var model = {
|
||
|
||
priority: MODEL,
|
||
twoWay: true,
|
||
handlers: handlers,
|
||
params: ['lazy', 'number', 'debounce'],
|
||
|
||
/**
|
||
* Possible elements:
|
||
* <select>
|
||
* <textarea>
|
||
* <input type="*">
|
||
* - text
|
||
* - checkbox
|
||
* - radio
|
||
* - number
|
||
*/
|
||
|
||
bind: function bind() {
|
||
// friendly warning...
|
||
this.checkFilters();
|
||
if (this.hasRead && !this.hasWrite) {
|
||
process.env.NODE_ENV !== 'production' && warn('It seems you are using a read-only filter with ' + 'v-model. You might want to use a two-way filter ' + 'to ensure correct behavior.');
|
||
}
|
||
var el = this.el;
|
||
var tag = el.tagName;
|
||
var handler;
|
||
if (tag === 'INPUT') {
|
||
handler = handlers[el.type] || handlers.text;
|
||
} else if (tag === 'SELECT') {
|
||
handler = handlers.select;
|
||
} else if (tag === 'TEXTAREA') {
|
||
handler = handlers.text;
|
||
} else {
|
||
process.env.NODE_ENV !== 'production' && warn('v-model does not support element type: ' + tag);
|
||
return;
|
||
}
|
||
el.__v_model = this;
|
||
handler.bind.call(this);
|
||
this.update = handler.update;
|
||
this._unbind = handler.unbind;
|
||
},
|
||
|
||
/**
|
||
* Check read/write filter stats.
|
||
*/
|
||
|
||
checkFilters: function checkFilters() {
|
||
var filters = this.filters;
|
||
if (!filters) return;
|
||
var i = filters.length;
|
||
while (i--) {
|
||
var filter = resolveAsset(this.vm.$options, 'filters', filters[i].name);
|
||
if (typeof filter === 'function' || filter.read) {
|
||
this.hasRead = true;
|
||
}
|
||
if (filter.write) {
|
||
this.hasWrite = true;
|
||
}
|
||
}
|
||
},
|
||
|
||
unbind: function unbind() {
|
||
this.el.__v_model = null;
|
||
this._unbind && this._unbind();
|
||
}
|
||
};
|
||
|
||
// keyCode aliases
|
||
var keyCodes = {
|
||
esc: 27,
|
||
tab: 9,
|
||
enter: 13,
|
||
space: 32,
|
||
'delete': [8, 46],
|
||
up: 38,
|
||
left: 37,
|
||
right: 39,
|
||
down: 40
|
||
};
|
||
|
||
function keyFilter(handler, keys) {
|
||
var codes = keys.map(function (key) {
|
||
var charCode = key.charCodeAt(0);
|
||
if (charCode > 47 && charCode < 58) {
|
||
return parseInt(key, 10);
|
||
}
|
||
if (key.length === 1) {
|
||
charCode = key.toUpperCase().charCodeAt(0);
|
||
if (charCode > 64 && charCode < 91) {
|
||
return charCode;
|
||
}
|
||
}
|
||
return keyCodes[key];
|
||
});
|
||
codes = [].concat.apply([], codes);
|
||
return function keyHandler(e) {
|
||
if (codes.indexOf(e.keyCode) > -1) {
|
||
return handler.call(this, e);
|
||
}
|
||
};
|
||
}
|
||
|
||
function stopFilter(handler) {
|
||
return function stopHandler(e) {
|
||
e.stopPropagation();
|
||
return handler.call(this, e);
|
||
};
|
||
}
|
||
|
||
function preventFilter(handler) {
|
||
return function preventHandler(e) {
|
||
e.preventDefault();
|
||
return handler.call(this, e);
|
||
};
|
||
}
|
||
|
||
function selfFilter(handler) {
|
||
return function selfHandler(e) {
|
||
if (e.target === e.currentTarget) {
|
||
return handler.call(this, e);
|
||
}
|
||
};
|
||
}
|
||
|
||
var on$1 = {
|
||
|
||
priority: ON,
|
||
acceptStatement: true,
|
||
keyCodes: keyCodes,
|
||
|
||
bind: function bind() {
|
||
// deal with iframes
|
||
if (this.el.tagName === 'IFRAME' && this.arg !== 'load') {
|
||
var self = this;
|
||
this.iframeBind = function () {
|
||
on(self.el.contentWindow, self.arg, self.handler, self.modifiers.capture);
|
||
};
|
||
this.on('load', this.iframeBind);
|
||
}
|
||
},
|
||
|
||
update: function update(handler) {
|
||
// stub a noop for v-on with no value,
|
||
// e.g. @mousedown.prevent
|
||
if (!this.descriptor.raw) {
|
||
handler = function () {};
|
||
}
|
||
|
||
if (typeof handler !== 'function') {
|
||
process.env.NODE_ENV !== 'production' && warn('v-on:' + this.arg + '="' + this.expression + '" expects a function value, ' + 'got ' + handler);
|
||
return;
|
||
}
|
||
|
||
// apply modifiers
|
||
if (this.modifiers.stop) {
|
||
handler = stopFilter(handler);
|
||
}
|
||
if (this.modifiers.prevent) {
|
||
handler = preventFilter(handler);
|
||
}
|
||
if (this.modifiers.self) {
|
||
handler = selfFilter(handler);
|
||
}
|
||
// key filter
|
||
var keys = Object.keys(this.modifiers).filter(function (key) {
|
||
return key !== 'stop' && key !== 'prevent';
|
||
});
|
||
if (keys.length) {
|
||
handler = keyFilter(handler, keys);
|
||
}
|
||
|
||
this.reset();
|
||
this.handler = handler;
|
||
|
||
if (this.iframeBind) {
|
||
this.iframeBind();
|
||
} else {
|
||
on(this.el, this.arg, this.handler, this.modifiers.capture);
|
||
}
|
||
},
|
||
|
||
reset: function reset() {
|
||
var el = this.iframeBind ? this.el.contentWindow : this.el;
|
||
if (this.handler) {
|
||
off(el, this.arg, this.handler);
|
||
}
|
||
},
|
||
|
||
unbind: function unbind() {
|
||
this.reset();
|
||
}
|
||
};
|
||
|
||
var prefixes = ['-webkit-', '-moz-', '-ms-'];
|
||
var camelPrefixes = ['Webkit', 'Moz', 'ms'];
|
||
var importantRE = /!important;?$/;
|
||
var propCache = Object.create(null);
|
||
|
||
var testEl = null;
|
||
|
||
var style = {
|
||
|
||
deep: true,
|
||
|
||
update: function update(value) {
|
||
if (typeof value === 'string') {
|
||
this.el.style.cssText = value;
|
||
} else if (isArray(value)) {
|
||
this.handleObject(value.reduce(extend, {}));
|
||
} else {
|
||
this.handleObject(value || {});
|
||
}
|
||
},
|
||
|
||
handleObject: function handleObject(value) {
|
||
// cache object styles so that only changed props
|
||
// are actually updated.
|
||
var cache = this.cache || (this.cache = {});
|
||
var name, val;
|
||
for (name in cache) {
|
||
if (!(name in value)) {
|
||
this.handleSingle(name, null);
|
||
delete cache[name];
|
||
}
|
||
}
|
||
for (name in value) {
|
||
val = value[name];
|
||
if (val !== cache[name]) {
|
||
cache[name] = val;
|
||
this.handleSingle(name, val);
|
||
}
|
||
}
|
||
},
|
||
|
||
handleSingle: function handleSingle(prop, value) {
|
||
prop = normalize(prop);
|
||
if (!prop) return; // unsupported prop
|
||
// cast possible numbers/booleans into strings
|
||
if (value != null) value += '';
|
||
if (value) {
|
||
var isImportant = importantRE.test(value) ? 'important' : '';
|
||
if (isImportant) {
|
||
value = value.replace(importantRE, '').trim();
|
||
}
|
||
this.el.style.setProperty(prop, value, isImportant);
|
||
} else {
|
||
this.el.style.removeProperty(prop);
|
||
}
|
||
}
|
||
|
||
};
|
||
|
||
/**
|
||
* Normalize a CSS property name.
|
||
* - cache result
|
||
* - auto prefix
|
||
* - camelCase -> dash-case
|
||
*
|
||
* @param {String} prop
|
||
* @return {String}
|
||
*/
|
||
|
||
function normalize(prop) {
|
||
if (propCache[prop]) {
|
||
return propCache[prop];
|
||
}
|
||
var res = prefix(prop);
|
||
propCache[prop] = propCache[res] = res;
|
||
return res;
|
||
}
|
||
|
||
/**
|
||
* Auto detect the appropriate prefix for a CSS property.
|
||
* https://gist.github.com/paulirish/523692
|
||
*
|
||
* @param {String} prop
|
||
* @return {String}
|
||
*/
|
||
|
||
function prefix(prop) {
|
||
prop = hyphenate(prop);
|
||
var camel = camelize(prop);
|
||
var upper = camel.charAt(0).toUpperCase() + camel.slice(1);
|
||
if (!testEl) {
|
||
testEl = document.createElement('div');
|
||
}
|
||
var i = prefixes.length;
|
||
var prefixed;
|
||
while (i--) {
|
||
prefixed = camelPrefixes[i] + upper;
|
||
if (prefixed in testEl.style) {
|
||
return prefixes[i] + prop;
|
||
}
|
||
}
|
||
if (camel in testEl.style) {
|
||
return prop;
|
||
}
|
||
}
|
||
|
||
// xlink
|
||
var xlinkNS = 'http://www.w3.org/1999/xlink';
|
||
var xlinkRE = /^xlink:/;
|
||
|
||
// check for attributes that prohibit interpolations
|
||
var disallowedInterpAttrRE = /^v-|^:|^@|^(?:is|transition|transition-mode|debounce|track-by|stagger|enter-stagger|leave-stagger)$/;
|
||
// these attributes should also set their corresponding properties
|
||
// because they only affect the initial state of the element
|
||
var attrWithPropsRE = /^(?:value|checked|selected|muted)$/;
|
||
// these attributes expect enumrated values of "true" or "false"
|
||
// but are not boolean attributes
|
||
var enumeratedAttrRE = /^(?:draggable|contenteditable|spellcheck)$/;
|
||
|
||
// these attributes should set a hidden property for
|
||
// binding v-model to object values
|
||
var modelProps = {
|
||
value: '_value',
|
||
'true-value': '_trueValue',
|
||
'false-value': '_falseValue'
|
||
};
|
||
|
||
var bind$1 = {
|
||
|
||
priority: BIND,
|
||
|
||
bind: function bind() {
|
||
var attr = this.arg;
|
||
var tag = this.el.tagName;
|
||
// should be deep watch on object mode
|
||
if (!attr) {
|
||
this.deep = true;
|
||
}
|
||
// handle interpolation bindings
|
||
var descriptor = this.descriptor;
|
||
var tokens = descriptor.interp;
|
||
if (tokens) {
|
||
// handle interpolations with one-time tokens
|
||
if (descriptor.hasOneTime) {
|
||
this.expression = tokensToExp(tokens, this._scope || this.vm);
|
||
}
|
||
|
||
// only allow binding on native attributes
|
||
if (disallowedInterpAttrRE.test(attr) || attr === 'name' && (tag === 'PARTIAL' || tag === 'SLOT')) {
|
||
process.env.NODE_ENV !== 'production' && warn(attr + '="' + descriptor.raw + '": ' + 'attribute interpolation is not allowed in Vue.js ' + 'directives and special attributes.');
|
||
this.el.removeAttribute(attr);
|
||
this.invalid = true;
|
||
}
|
||
|
||
/* istanbul ignore if */
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
var raw = attr + '="' + descriptor.raw + '": ';
|
||
// warn src
|
||
if (attr === 'src') {
|
||
warn(raw + 'interpolation in "src" attribute will cause ' + 'a 404 request. Use v-bind:src instead.');
|
||
}
|
||
|
||
// warn style
|
||
if (attr === 'style') {
|
||
warn(raw + 'interpolation in "style" attribute will cause ' + 'the attribute to be discarded in Internet Explorer. ' + 'Use v-bind:style instead.');
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
update: function update(value) {
|
||
if (this.invalid) {
|
||
return;
|
||
}
|
||
var attr = this.arg;
|
||
if (this.arg) {
|
||
this.handleSingle(attr, value);
|
||
} else {
|
||
this.handleObject(value || {});
|
||
}
|
||
},
|
||
|
||
// share object handler with v-bind:class
|
||
handleObject: style.handleObject,
|
||
|
||
handleSingle: function handleSingle(attr, value) {
|
||
var el = this.el;
|
||
var interp = this.descriptor.interp;
|
||
if (this.modifiers.camel) {
|
||
attr = camelize(attr);
|
||
}
|
||
if (!interp && attrWithPropsRE.test(attr) && attr in el) {
|
||
el[attr] = attr === 'value' ? value == null // IE9 will set input.value to "null" for null...
|
||
? '' : value : value;
|
||
}
|
||
// set model props
|
||
var modelProp = modelProps[attr];
|
||
if (!interp && modelProp) {
|
||
el[modelProp] = value;
|
||
// update v-model if present
|
||
var model = el.__v_model;
|
||
if (model) {
|
||
model.listener();
|
||
}
|
||
}
|
||
// do not set value attribute for textarea
|
||
if (attr === 'value' && el.tagName === 'TEXTAREA') {
|
||
el.removeAttribute(attr);
|
||
return;
|
||
}
|
||
// update attribute
|
||
if (enumeratedAttrRE.test(attr)) {
|
||
el.setAttribute(attr, value ? 'true' : 'false');
|
||
} else if (value != null && value !== false) {
|
||
if (attr === 'class') {
|
||
// handle edge case #1960:
|
||
// class interpolation should not overwrite Vue transition class
|
||
if (el.__v_trans) {
|
||
value += ' ' + el.__v_trans.id + '-transition';
|
||
}
|
||
setClass(el, value);
|
||
} else if (xlinkRE.test(attr)) {
|
||
el.setAttributeNS(xlinkNS, attr, value === true ? '' : value);
|
||
} else {
|
||
el.setAttribute(attr, value === true ? '' : value);
|
||
}
|
||
} else {
|
||
el.removeAttribute(attr);
|
||
}
|
||
}
|
||
};
|
||
|
||
var el = {
|
||
|
||
priority: EL,
|
||
|
||
bind: function bind() {
|
||
/* istanbul ignore if */
|
||
if (!this.arg) {
|
||
return;
|
||
}
|
||
var id = this.id = camelize(this.arg);
|
||
var refs = (this._scope || this.vm).$els;
|
||
if (hasOwn(refs, id)) {
|
||
refs[id] = this.el;
|
||
} else {
|
||
defineReactive(refs, id, this.el);
|
||
}
|
||
},
|
||
|
||
unbind: function unbind() {
|
||
var refs = (this._scope || this.vm).$els;
|
||
if (refs[this.id] === this.el) {
|
||
refs[this.id] = null;
|
||
}
|
||
}
|
||
};
|
||
|
||
var ref = {
|
||
bind: function bind() {
|
||
process.env.NODE_ENV !== 'production' && warn('v-ref:' + this.arg + ' must be used on a child ' + 'component. Found on <' + this.el.tagName.toLowerCase() + '>.');
|
||
}
|
||
};
|
||
|
||
var cloak = {
|
||
bind: function bind() {
|
||
var el = this.el;
|
||
this.vm.$once('pre-hook:compiled', function () {
|
||
el.removeAttribute('v-cloak');
|
||
});
|
||
}
|
||
};
|
||
|
||
// must export plain object
|
||
var directives = {
|
||
text: text$1,
|
||
html: html,
|
||
'for': vFor,
|
||
'if': vIf,
|
||
show: show,
|
||
model: model,
|
||
on: on$1,
|
||
bind: bind$1,
|
||
el: el,
|
||
ref: ref,
|
||
cloak: cloak
|
||
};
|
||
|
||
var vClass = {
|
||
|
||
deep: true,
|
||
|
||
update: function update(value) {
|
||
if (value && typeof value === 'string') {
|
||
this.handleObject(stringToObject(value));
|
||
} else if (isPlainObject(value)) {
|
||
this.handleObject(value);
|
||
} else if (isArray(value)) {
|
||
this.handleArray(value);
|
||
} else {
|
||
this.cleanup();
|
||
}
|
||
},
|
||
|
||
handleObject: function handleObject(value) {
|
||
this.cleanup(value);
|
||
var keys = this.prevKeys = Object.keys(value);
|
||
for (var i = 0, l = keys.length; i < l; i++) {
|
||
var key = keys[i];
|
||
if (value[key]) {
|
||
addClass(this.el, key);
|
||
} else {
|
||
removeClass(this.el, key);
|
||
}
|
||
}
|
||
},
|
||
|
||
handleArray: function handleArray(value) {
|
||
this.cleanup(value);
|
||
for (var i = 0, l = value.length; i < l; i++) {
|
||
if (value[i]) {
|
||
addClass(this.el, value[i]);
|
||
}
|
||
}
|
||
this.prevKeys = value.slice();
|
||
},
|
||
|
||
cleanup: function cleanup(value) {
|
||
if (this.prevKeys) {
|
||
var i = this.prevKeys.length;
|
||
while (i--) {
|
||
var key = this.prevKeys[i];
|
||
if (key && (!value || !contains(value, key))) {
|
||
removeClass(this.el, key);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
function stringToObject(value) {
|
||
var res = {};
|
||
var keys = value.trim().split(/\s+/);
|
||
var i = keys.length;
|
||
while (i--) {
|
||
res[keys[i]] = true;
|
||
}
|
||
return res;
|
||
}
|
||
|
||
function contains(value, key) {
|
||
return isArray(value) ? value.indexOf(key) > -1 : hasOwn(value, key);
|
||
}
|
||
|
||
var component = {
|
||
|
||
priority: COMPONENT,
|
||
|
||
params: ['keep-alive', 'transition-mode', 'inline-template'],
|
||
|
||
/**
|
||
* Setup. Two possible usages:
|
||
*
|
||
* - static:
|
||
* <comp> or <div v-component="comp">
|
||
*
|
||
* - dynamic:
|
||
* <component :is="view">
|
||
*/
|
||
|
||
bind: function bind() {
|
||
if (!this.el.__vue__) {
|
||
// keep-alive cache
|
||
this.keepAlive = this.params.keepAlive;
|
||
if (this.keepAlive) {
|
||
this.cache = {};
|
||
}
|
||
// check inline-template
|
||
if (this.params.inlineTemplate) {
|
||
// extract inline template as a DocumentFragment
|
||
this.inlineTemplate = extractContent(this.el, true);
|
||
}
|
||
// component resolution related state
|
||
this.pendingComponentCb = this.Component = null;
|
||
// transition related state
|
||
this.pendingRemovals = 0;
|
||
this.pendingRemovalCb = null;
|
||
// create a ref anchor
|
||
this.anchor = createAnchor('v-component');
|
||
replace(this.el, this.anchor);
|
||
// remove is attribute.
|
||
// this is removed during compilation, but because compilation is
|
||
// cached, when the component is used elsewhere this attribute
|
||
// will remain at link time.
|
||
this.el.removeAttribute('is');
|
||
// remove ref, same as above
|
||
if (this.descriptor.ref) {
|
||
this.el.removeAttribute('v-ref:' + hyphenate(this.descriptor.ref));
|
||
}
|
||
// if static, build right now.
|
||
if (this.literal) {
|
||
this.setComponent(this.expression);
|
||
}
|
||
} else {
|
||
process.env.NODE_ENV !== 'production' && warn('cannot mount component "' + this.expression + '" ' + 'on already mounted element: ' + this.el);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Public update, called by the watcher in the dynamic
|
||
* literal scenario, e.g. <component :is="view">
|
||
*/
|
||
|
||
update: function update(value) {
|
||
if (!this.literal) {
|
||
this.setComponent(value);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Switch dynamic components. May resolve the component
|
||
* asynchronously, and perform transition based on
|
||
* specified transition mode. Accepts a few additional
|
||
* arguments specifically for vue-router.
|
||
*
|
||
* The callback is called when the full transition is
|
||
* finished.
|
||
*
|
||
* @param {String} value
|
||
* @param {Function} [cb]
|
||
*/
|
||
|
||
setComponent: function setComponent(value, cb) {
|
||
this.invalidatePending();
|
||
if (!value) {
|
||
// just remove current
|
||
this.unbuild(true);
|
||
this.remove(this.childVM, cb);
|
||
this.childVM = null;
|
||
} else {
|
||
var self = this;
|
||
this.resolveComponent(value, function () {
|
||
self.mountComponent(cb);
|
||
});
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Resolve the component constructor to use when creating
|
||
* the child vm.
|
||
*/
|
||
|
||
resolveComponent: function resolveComponent(id, cb) {
|
||
var self = this;
|
||
this.pendingComponentCb = cancellable(function (Component) {
|
||
self.ComponentName = Component.options.name || id;
|
||
self.Component = Component;
|
||
cb();
|
||
});
|
||
this.vm._resolveComponent(id, this.pendingComponentCb);
|
||
},
|
||
|
||
/**
|
||
* Create a new instance using the current constructor and
|
||
* replace the existing instance. This method doesn't care
|
||
* whether the new component and the old one are actually
|
||
* the same.
|
||
*
|
||
* @param {Function} [cb]
|
||
*/
|
||
|
||
mountComponent: function mountComponent(cb) {
|
||
// actual mount
|
||
this.unbuild(true);
|
||
var self = this;
|
||
var activateHooks = this.Component.options.activate;
|
||
var cached = this.getCached();
|
||
var newComponent = this.build();
|
||
if (activateHooks && !cached) {
|
||
this.waitingFor = newComponent;
|
||
callActivateHooks(activateHooks, newComponent, function () {
|
||
if (self.waitingFor !== newComponent) {
|
||
return;
|
||
}
|
||
self.waitingFor = null;
|
||
self.transition(newComponent, cb);
|
||
});
|
||
} else {
|
||
// update ref for kept-alive component
|
||
if (cached) {
|
||
newComponent._updateRef();
|
||
}
|
||
this.transition(newComponent, cb);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* When the component changes or unbinds before an async
|
||
* constructor is resolved, we need to invalidate its
|
||
* pending callback.
|
||
*/
|
||
|
||
invalidatePending: function invalidatePending() {
|
||
if (this.pendingComponentCb) {
|
||
this.pendingComponentCb.cancel();
|
||
this.pendingComponentCb = null;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Instantiate/insert a new child vm.
|
||
* If keep alive and has cached instance, insert that
|
||
* instance; otherwise build a new one and cache it.
|
||
*
|
||
* @param {Object} [extraOptions]
|
||
* @return {Vue} - the created instance
|
||
*/
|
||
|
||
build: function build(extraOptions) {
|
||
var cached = this.getCached();
|
||
if (cached) {
|
||
return cached;
|
||
}
|
||
if (this.Component) {
|
||
// default options
|
||
var options = {
|
||
name: this.ComponentName,
|
||
el: cloneNode(this.el),
|
||
template: this.inlineTemplate,
|
||
// make sure to add the child with correct parent
|
||
// if this is a transcluded component, its parent
|
||
// should be the transclusion host.
|
||
parent: this._host || this.vm,
|
||
// if no inline-template, then the compiled
|
||
// linker can be cached for better performance.
|
||
_linkerCachable: !this.inlineTemplate,
|
||
_ref: this.descriptor.ref,
|
||
_asComponent: true,
|
||
_isRouterView: this._isRouterView,
|
||
// if this is a transcluded component, context
|
||
// will be the common parent vm of this instance
|
||
// and its host.
|
||
_context: this.vm,
|
||
// if this is inside an inline v-for, the scope
|
||
// will be the intermediate scope created for this
|
||
// repeat fragment. this is used for linking props
|
||
// and container directives.
|
||
_scope: this._scope,
|
||
// pass in the owner fragment of this component.
|
||
// this is necessary so that the fragment can keep
|
||
// track of its contained components in order to
|
||
// call attach/detach hooks for them.
|
||
_frag: this._frag
|
||
};
|
||
// extra options
|
||
// in 1.0.0 this is used by vue-router only
|
||
/* istanbul ignore if */
|
||
if (extraOptions) {
|
||
extend(options, extraOptions);
|
||
}
|
||
var child = new this.Component(options);
|
||
if (this.keepAlive) {
|
||
this.cache[this.Component.cid] = child;
|
||
}
|
||
/* istanbul ignore if */
|
||
if (process.env.NODE_ENV !== 'production' && this.el.hasAttribute('transition') && child._isFragment) {
|
||
warn('Transitions will not work on a fragment instance. ' + 'Template: ' + child.$options.template);
|
||
}
|
||
return child;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Try to get a cached instance of the current component.
|
||
*
|
||
* @return {Vue|undefined}
|
||
*/
|
||
|
||
getCached: function getCached() {
|
||
return this.keepAlive && this.cache[this.Component.cid];
|
||
},
|
||
|
||
/**
|
||
* Teardown the current child, but defers cleanup so
|
||
* that we can separate the destroy and removal steps.
|
||
*
|
||
* @param {Boolean} defer
|
||
*/
|
||
|
||
unbuild: function unbuild(defer) {
|
||
if (this.waitingFor) {
|
||
this.waitingFor.$destroy();
|
||
this.waitingFor = null;
|
||
}
|
||
var child = this.childVM;
|
||
if (!child || this.keepAlive) {
|
||
if (child) {
|
||
// remove ref
|
||
child._updateRef(true);
|
||
}
|
||
return;
|
||
}
|
||
// the sole purpose of `deferCleanup` is so that we can
|
||
// "deactivate" the vm right now and perform DOM removal
|
||
// later.
|
||
child.$destroy(false, defer);
|
||
},
|
||
|
||
/**
|
||
* Remove current destroyed child and manually do
|
||
* the cleanup after removal.
|
||
*
|
||
* @param {Function} cb
|
||
*/
|
||
|
||
remove: function remove(child, cb) {
|
||
var keepAlive = this.keepAlive;
|
||
if (child) {
|
||
// we may have a component switch when a previous
|
||
// component is still being transitioned out.
|
||
// we want to trigger only one lastest insertion cb
|
||
// when the existing transition finishes. (#1119)
|
||
this.pendingRemovals++;
|
||
this.pendingRemovalCb = cb;
|
||
var self = this;
|
||
child.$remove(function () {
|
||
self.pendingRemovals--;
|
||
if (!keepAlive) child._cleanup();
|
||
if (!self.pendingRemovals && self.pendingRemovalCb) {
|
||
self.pendingRemovalCb();
|
||
self.pendingRemovalCb = null;
|
||
}
|
||
});
|
||
} else if (cb) {
|
||
cb();
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Actually swap the components, depending on the
|
||
* transition mode. Defaults to simultaneous.
|
||
*
|
||
* @param {Vue} target
|
||
* @param {Function} [cb]
|
||
*/
|
||
|
||
transition: function transition(target, cb) {
|
||
var self = this;
|
||
var current = this.childVM;
|
||
// for devtool inspection
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
if (current) current._inactive = true;
|
||
target._inactive = false;
|
||
}
|
||
this.childVM = target;
|
||
switch (self.params.transitionMode) {
|
||
case 'in-out':
|
||
target.$before(self.anchor, function () {
|
||
self.remove(current, cb);
|
||
});
|
||
break;
|
||
case 'out-in':
|
||
self.remove(current, function () {
|
||
target.$before(self.anchor, cb);
|
||
});
|
||
break;
|
||
default:
|
||
self.remove(current);
|
||
target.$before(self.anchor, cb);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* Unbind.
|
||
*/
|
||
|
||
unbind: function unbind() {
|
||
this.invalidatePending();
|
||
// Do not defer cleanup when unbinding
|
||
this.unbuild();
|
||
// destroy all keep-alive cached instances
|
||
if (this.cache) {
|
||
for (var key in this.cache) {
|
||
this.cache[key].$destroy();
|
||
}
|
||
this.cache = null;
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Call activate hooks in order (asynchronous)
|
||
*
|
||
* @param {Array} hooks
|
||
* @param {Vue} vm
|
||
* @param {Function} cb
|
||
*/
|
||
|
||
function callActivateHooks(hooks, vm, cb) {
|
||
var total = hooks.length;
|
||
var called = 0;
|
||
hooks[0].call(vm, next);
|
||
function next() {
|
||
if (++called >= total) {
|
||
cb();
|
||
} else {
|
||
hooks[called].call(vm, next);
|
||
}
|
||
}
|
||
}
|
||
|
||
var bindingModes = config._propBindingModes;
|
||
|
||
var propDef = {
|
||
|
||
bind: function bind() {
|
||
var child = this.vm;
|
||
var parent = child._context;
|
||
// passed in from compiler directly
|
||
var prop = this.descriptor.prop;
|
||
var childKey = prop.path;
|
||
var parentKey = prop.parentPath;
|
||
var twoWay = prop.mode === bindingModes.TWO_WAY;
|
||
|
||
var parentWatcher = this.parentWatcher = new Watcher(parent, parentKey, function (val) {
|
||
val = coerceProp(prop, val);
|
||
if (assertProp(prop, val)) {
|
||
child[childKey] = val;
|
||
}
|
||
}, {
|
||
twoWay: twoWay,
|
||
filters: prop.filters,
|
||
// important: props need to be observed on the
|
||
// v-for scope if present
|
||
scope: this._scope
|
||
});
|
||
|
||
// set the child initial value.
|
||
initProp(child, prop, parentWatcher.value);
|
||
|
||
// setup two-way binding
|
||
if (twoWay) {
|
||
// important: defer the child watcher creation until
|
||
// the created hook (after data observation)
|
||
var self = this;
|
||
child.$once('pre-hook:created', function () {
|
||
self.childWatcher = new Watcher(child, childKey, function (val) {
|
||
parentWatcher.set(val);
|
||
}, {
|
||
// ensure sync upward before parent sync down.
|
||
// this is necessary in cases e.g. the child
|
||
// mutates a prop array, then replaces it. (#1683)
|
||
sync: true
|
||
});
|
||
});
|
||
}
|
||
},
|
||
|
||
unbind: function unbind() {
|
||
this.parentWatcher.teardown();
|
||
if (this.childWatcher) {
|
||
this.childWatcher.teardown();
|
||
}
|
||
}
|
||
};
|
||
|
||
var queue$1 = [];
|
||
var queued = false;
|
||
|
||
/**
|
||
* Push a job into the queue.
|
||
*
|
||
* @param {Function} job
|
||
*/
|
||
|
||
function pushJob(job) {
|
||
queue$1.push(job);
|
||
if (!queued) {
|
||
queued = true;
|
||
nextTick(flush);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Flush the queue, and do one forced reflow before
|
||
* triggering transitions.
|
||
*/
|
||
|
||
function flush() {
|
||
// Force layout
|
||
var f = document.documentElement.offsetHeight;
|
||
for (var i = 0; i < queue$1.length; i++) {
|
||
queue$1[i]();
|
||
}
|
||
queue$1 = [];
|
||
queued = false;
|
||
// dummy return, so js linters don't complain about
|
||
// unused variable f
|
||
return f;
|
||
}
|
||
|
||
var TYPE_TRANSITION = 'transition';
|
||
var TYPE_ANIMATION = 'animation';
|
||
var transDurationProp = transitionProp + 'Duration';
|
||
var animDurationProp = animationProp + 'Duration';
|
||
|
||
/**
|
||
* A Transition object that encapsulates the state and logic
|
||
* of the transition.
|
||
*
|
||
* @param {Element} el
|
||
* @param {String} id
|
||
* @param {Object} hooks
|
||
* @param {Vue} vm
|
||
*/
|
||
function Transition(el, id, hooks, vm) {
|
||
this.id = id;
|
||
this.el = el;
|
||
this.enterClass = hooks && hooks.enterClass || id + '-enter';
|
||
this.leaveClass = hooks && hooks.leaveClass || id + '-leave';
|
||
this.hooks = hooks;
|
||
this.vm = vm;
|
||
// async state
|
||
this.pendingCssEvent = this.pendingCssCb = this.cancel = this.pendingJsCb = this.op = this.cb = null;
|
||
this.justEntered = false;
|
||
this.entered = this.left = false;
|
||
this.typeCache = {};
|
||
// check css transition type
|
||
this.type = hooks && hooks.type;
|
||
/* istanbul ignore if */
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
if (this.type && this.type !== TYPE_TRANSITION && this.type !== TYPE_ANIMATION) {
|
||
warn('invalid CSS transition type for transition="' + this.id + '": ' + this.type);
|
||
}
|
||
}
|
||
// bind
|
||
var self = this;['enterNextTick', 'enterDone', 'leaveNextTick', 'leaveDone'].forEach(function (m) {
|
||
self[m] = bind(self[m], self);
|
||
});
|
||
}
|
||
|
||
var p$1 = Transition.prototype;
|
||
|
||
/**
|
||
* Start an entering transition.
|
||
*
|
||
* 1. enter transition triggered
|
||
* 2. call beforeEnter hook
|
||
* 3. add enter class
|
||
* 4. insert/show element
|
||
* 5. call enter hook (with possible explicit js callback)
|
||
* 6. reflow
|
||
* 7. based on transition type:
|
||
* - transition:
|
||
* remove class now, wait for transitionend,
|
||
* then done if there's no explicit js callback.
|
||
* - animation:
|
||
* wait for animationend, remove class,
|
||
* then done if there's no explicit js callback.
|
||
* - no css transition:
|
||
* done now if there's no explicit js callback.
|
||
* 8. wait for either done or js callback, then call
|
||
* afterEnter hook.
|
||
*
|
||
* @param {Function} op - insert/show the element
|
||
* @param {Function} [cb]
|
||
*/
|
||
|
||
p$1.enter = function (op, cb) {
|
||
this.cancelPending();
|
||
this.callHook('beforeEnter');
|
||
this.cb = cb;
|
||
addClass(this.el, this.enterClass);
|
||
op();
|
||
this.entered = false;
|
||
this.callHookWithCb('enter');
|
||
if (this.entered) {
|
||
return; // user called done synchronously.
|
||
}
|
||
this.cancel = this.hooks && this.hooks.enterCancelled;
|
||
pushJob(this.enterNextTick);
|
||
};
|
||
|
||
/**
|
||
* The "nextTick" phase of an entering transition, which is
|
||
* to be pushed into a queue and executed after a reflow so
|
||
* that removing the class can trigger a CSS transition.
|
||
*/
|
||
|
||
p$1.enterNextTick = function () {
|
||
// Important hack:
|
||
// in Chrome, if a just-entered element is applied the
|
||
// leave class while its interpolated property still has
|
||
// a very small value (within one frame), Chrome will
|
||
// skip the leave transition entirely and not firing the
|
||
// transtionend event. Therefore we need to protected
|
||
// against such cases using a one-frame timeout.
|
||
this.justEntered = true;
|
||
var self = this;
|
||
setTimeout(function () {
|
||
self.justEntered = false;
|
||
}, 17);
|
||
|
||
var enterDone = this.enterDone;
|
||
var type = this.getCssTransitionType(this.enterClass);
|
||
if (!this.pendingJsCb) {
|
||
if (type === TYPE_TRANSITION) {
|
||
// trigger transition by removing enter class now
|
||
removeClass(this.el, this.enterClass);
|
||
this.setupCssCb(transitionEndEvent, enterDone);
|
||
} else if (type === TYPE_ANIMATION) {
|
||
this.setupCssCb(animationEndEvent, enterDone);
|
||
} else {
|
||
enterDone();
|
||
}
|
||
} else if (type === TYPE_TRANSITION) {
|
||
removeClass(this.el, this.enterClass);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* The "cleanup" phase of an entering transition.
|
||
*/
|
||
|
||
p$1.enterDone = function () {
|
||
this.entered = true;
|
||
this.cancel = this.pendingJsCb = null;
|
||
removeClass(this.el, this.enterClass);
|
||
this.callHook('afterEnter');
|
||
if (this.cb) this.cb();
|
||
};
|
||
|
||
/**
|
||
* Start a leaving transition.
|
||
*
|
||
* 1. leave transition triggered.
|
||
* 2. call beforeLeave hook
|
||
* 3. add leave class (trigger css transition)
|
||
* 4. call leave hook (with possible explicit js callback)
|
||
* 5. reflow if no explicit js callback is provided
|
||
* 6. based on transition type:
|
||
* - transition or animation:
|
||
* wait for end event, remove class, then done if
|
||
* there's no explicit js callback.
|
||
* - no css transition:
|
||
* done if there's no explicit js callback.
|
||
* 7. wait for either done or js callback, then call
|
||
* afterLeave hook.
|
||
*
|
||
* @param {Function} op - remove/hide the element
|
||
* @param {Function} [cb]
|
||
*/
|
||
|
||
p$1.leave = function (op, cb) {
|
||
this.cancelPending();
|
||
this.callHook('beforeLeave');
|
||
this.op = op;
|
||
this.cb = cb;
|
||
addClass(this.el, this.leaveClass);
|
||
this.left = false;
|
||
this.callHookWithCb('leave');
|
||
if (this.left) {
|
||
return; // user called done synchronously.
|
||
}
|
||
this.cancel = this.hooks && this.hooks.leaveCancelled;
|
||
// only need to handle leaveDone if
|
||
// 1. the transition is already done (synchronously called
|
||
// by the user, which causes this.op set to null)
|
||
// 2. there's no explicit js callback
|
||
if (this.op && !this.pendingJsCb) {
|
||
// if a CSS transition leaves immediately after enter,
|
||
// the transitionend event never fires. therefore we
|
||
// detect such cases and end the leave immediately.
|
||
if (this.justEntered) {
|
||
this.leaveDone();
|
||
} else {
|
||
pushJob(this.leaveNextTick);
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* The "nextTick" phase of a leaving transition.
|
||
*/
|
||
|
||
p$1.leaveNextTick = function () {
|
||
var type = this.getCssTransitionType(this.leaveClass);
|
||
if (type) {
|
||
var event = type === TYPE_TRANSITION ? transitionEndEvent : animationEndEvent;
|
||
this.setupCssCb(event, this.leaveDone);
|
||
} else {
|
||
this.leaveDone();
|
||
}
|
||
};
|
||
|
||
/**
|
||
* The "cleanup" phase of a leaving transition.
|
||
*/
|
||
|
||
p$1.leaveDone = function () {
|
||
this.left = true;
|
||
this.cancel = this.pendingJsCb = null;
|
||
this.op();
|
||
removeClass(this.el, this.leaveClass);
|
||
this.callHook('afterLeave');
|
||
if (this.cb) this.cb();
|
||
this.op = null;
|
||
};
|
||
|
||
/**
|
||
* Cancel any pending callbacks from a previously running
|
||
* but not finished transition.
|
||
*/
|
||
|
||
p$1.cancelPending = function () {
|
||
this.op = this.cb = null;
|
||
var hasPending = false;
|
||
if (this.pendingCssCb) {
|
||
hasPending = true;
|
||
off(this.el, this.pendingCssEvent, this.pendingCssCb);
|
||
this.pendingCssEvent = this.pendingCssCb = null;
|
||
}
|
||
if (this.pendingJsCb) {
|
||
hasPending = true;
|
||
this.pendingJsCb.cancel();
|
||
this.pendingJsCb = null;
|
||
}
|
||
if (hasPending) {
|
||
removeClass(this.el, this.enterClass);
|
||
removeClass(this.el, this.leaveClass);
|
||
}
|
||
if (this.cancel) {
|
||
this.cancel.call(this.vm, this.el);
|
||
this.cancel = null;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Call a user-provided synchronous hook function.
|
||
*
|
||
* @param {String} type
|
||
*/
|
||
|
||
p$1.callHook = function (type) {
|
||
if (this.hooks && this.hooks[type]) {
|
||
this.hooks[type].call(this.vm, this.el);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Call a user-provided, potentially-async hook function.
|
||
* We check for the length of arguments to see if the hook
|
||
* expects a `done` callback. If true, the transition's end
|
||
* will be determined by when the user calls that callback;
|
||
* otherwise, the end is determined by the CSS transition or
|
||
* animation.
|
||
*
|
||
* @param {String} type
|
||
*/
|
||
|
||
p$1.callHookWithCb = function (type) {
|
||
var hook = this.hooks && this.hooks[type];
|
||
if (hook) {
|
||
if (hook.length > 1) {
|
||
this.pendingJsCb = cancellable(this[type + 'Done']);
|
||
}
|
||
hook.call(this.vm, this.el, this.pendingJsCb);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Get an element's transition type based on the
|
||
* calculated styles.
|
||
*
|
||
* @param {String} className
|
||
* @return {Number}
|
||
*/
|
||
|
||
p$1.getCssTransitionType = function (className) {
|
||
/* istanbul ignore if */
|
||
if (!transitionEndEvent ||
|
||
// skip CSS transitions if page is not visible -
|
||
// this solves the issue of transitionend events not
|
||
// firing until the page is visible again.
|
||
// pageVisibility API is supported in IE10+, same as
|
||
// CSS transitions.
|
||
document.hidden ||
|
||
// explicit js-only transition
|
||
this.hooks && this.hooks.css === false ||
|
||
// element is hidden
|
||
isHidden(this.el)) {
|
||
return;
|
||
}
|
||
var type = this.type || this.typeCache[className];
|
||
if (type) return type;
|
||
var inlineStyles = this.el.style;
|
||
var computedStyles = window.getComputedStyle(this.el);
|
||
var transDuration = inlineStyles[transDurationProp] || computedStyles[transDurationProp];
|
||
if (transDuration && transDuration !== '0s') {
|
||
type = TYPE_TRANSITION;
|
||
} else {
|
||
var animDuration = inlineStyles[animDurationProp] || computedStyles[animDurationProp];
|
||
if (animDuration && animDuration !== '0s') {
|
||
type = TYPE_ANIMATION;
|
||
}
|
||
}
|
||
if (type) {
|
||
this.typeCache[className] = type;
|
||
}
|
||
return type;
|
||
};
|
||
|
||
/**
|
||
* Setup a CSS transitionend/animationend callback.
|
||
*
|
||
* @param {String} event
|
||
* @param {Function} cb
|
||
*/
|
||
|
||
p$1.setupCssCb = function (event, cb) {
|
||
this.pendingCssEvent = event;
|
||
var self = this;
|
||
var el = this.el;
|
||
var onEnd = this.pendingCssCb = function (e) {
|
||
if (e.target === el) {
|
||
off(el, event, onEnd);
|
||
self.pendingCssEvent = self.pendingCssCb = null;
|
||
if (!self.pendingJsCb && cb) {
|
||
cb();
|
||
}
|
||
}
|
||
};
|
||
on(el, event, onEnd);
|
||
};
|
||
|
||
/**
|
||
* Check if an element is hidden - in that case we can just
|
||
* skip the transition alltogether.
|
||
*
|
||
* @param {Element} el
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
function isHidden(el) {
|
||
if (/svg$/.test(el.namespaceURI)) {
|
||
// SVG elements do not have offset(Width|Height)
|
||
// so we need to check the client rect
|
||
var rect = el.getBoundingClientRect();
|
||
return !(rect.width || rect.height);
|
||
} else {
|
||
return !(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
|
||
}
|
||
}
|
||
|
||
var transition$1 = {
|
||
|
||
priority: TRANSITION,
|
||
|
||
update: function update(id, oldId) {
|
||
var el = this.el;
|
||
// resolve on owner vm
|
||
var hooks = resolveAsset(this.vm.$options, 'transitions', id);
|
||
id = id || 'v';
|
||
el.__v_trans = new Transition(el, id, hooks, this.vm);
|
||
if (oldId) {
|
||
removeClass(el, oldId + '-transition');
|
||
}
|
||
addClass(el, id + '-transition');
|
||
}
|
||
};
|
||
|
||
var internalDirectives = {
|
||
style: style,
|
||
'class': vClass,
|
||
component: component,
|
||
prop: propDef,
|
||
transition: transition$1
|
||
};
|
||
|
||
var propBindingModes = config._propBindingModes;
|
||
var empty = {};
|
||
|
||
// regexes
|
||
var identRE$1 = /^[$_a-zA-Z]+[\w$]*$/;
|
||
var settablePathRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[[^\[\]]+\])*$/;
|
||
|
||
/**
|
||
* Compile props on a root element and return
|
||
* a props link function.
|
||
*
|
||
* @param {Element|DocumentFragment} el
|
||
* @param {Array} propOptions
|
||
* @return {Function} propsLinkFn
|
||
*/
|
||
|
||
function compileProps(el, propOptions) {
|
||
var props = [];
|
||
var names = Object.keys(propOptions);
|
||
var i = names.length;
|
||
var options, name, attr, value, path, parsed, prop;
|
||
while (i--) {
|
||
name = names[i];
|
||
options = propOptions[name] || empty;
|
||
|
||
if (process.env.NODE_ENV !== 'production' && name === '$data') {
|
||
warn('Do not use $data as prop.');
|
||
continue;
|
||
}
|
||
|
||
// props could contain dashes, which will be
|
||
// interpreted as minus calculations by the parser
|
||
// so we need to camelize the path here
|
||
path = camelize(name);
|
||
if (!identRE$1.test(path)) {
|
||
process.env.NODE_ENV !== 'production' && warn('Invalid prop key: "' + name + '". Prop keys ' + 'must be valid identifiers.');
|
||
continue;
|
||
}
|
||
|
||
prop = {
|
||
name: name,
|
||
path: path,
|
||
options: options,
|
||
mode: propBindingModes.ONE_WAY,
|
||
raw: null
|
||
};
|
||
|
||
attr = hyphenate(name);
|
||
// first check dynamic version
|
||
if ((value = getBindAttr(el, attr)) === null) {
|
||
if ((value = getBindAttr(el, attr + '.sync')) !== null) {
|
||
prop.mode = propBindingModes.TWO_WAY;
|
||
} else if ((value = getBindAttr(el, attr + '.once')) !== null) {
|
||
prop.mode = propBindingModes.ONE_TIME;
|
||
}
|
||
}
|
||
if (value !== null) {
|
||
// has dynamic binding!
|
||
prop.raw = value;
|
||
parsed = parseDirective(value);
|
||
value = parsed.expression;
|
||
prop.filters = parsed.filters;
|
||
// check binding type
|
||
if (isLiteral(value) && !parsed.filters) {
|
||
// for expressions containing literal numbers and
|
||
// booleans, there's no need to setup a prop binding,
|
||
// so we can optimize them as a one-time set.
|
||
prop.optimizedLiteral = true;
|
||
} else {
|
||
prop.dynamic = true;
|
||
// check non-settable path for two-way bindings
|
||
if (process.env.NODE_ENV !== 'production' && prop.mode === propBindingModes.TWO_WAY && !settablePathRE.test(value)) {
|
||
prop.mode = propBindingModes.ONE_WAY;
|
||
warn('Cannot bind two-way prop with non-settable ' + 'parent path: ' + value);
|
||
}
|
||
}
|
||
prop.parentPath = value;
|
||
|
||
// warn required two-way
|
||
if (process.env.NODE_ENV !== 'production' && options.twoWay && prop.mode !== propBindingModes.TWO_WAY) {
|
||
warn('Prop "' + name + '" expects a two-way binding type.');
|
||
}
|
||
} else if ((value = getAttr(el, attr)) !== null) {
|
||
// has literal binding!
|
||
prop.raw = value;
|
||
} else if (process.env.NODE_ENV !== 'production') {
|
||
// check possible camelCase prop usage
|
||
var lowerCaseName = path.toLowerCase();
|
||
value = /[A-Z\-]/.test(name) && (el.getAttribute(lowerCaseName) || el.getAttribute(':' + lowerCaseName) || el.getAttribute('v-bind:' + lowerCaseName) || el.getAttribute(':' + lowerCaseName + '.once') || el.getAttribute('v-bind:' + lowerCaseName + '.once') || el.getAttribute(':' + lowerCaseName + '.sync') || el.getAttribute('v-bind:' + lowerCaseName + '.sync'));
|
||
if (value) {
|
||
warn('Possible usage error for prop `' + lowerCaseName + '` - ' + 'did you mean `' + attr + '`? HTML is case-insensitive, remember to use ' + 'kebab-case for props in templates.');
|
||
} else if (options.required) {
|
||
// warn missing required
|
||
warn('Missing required prop: ' + name);
|
||
}
|
||
}
|
||
// push prop
|
||
props.push(prop);
|
||
}
|
||
return makePropsLinkFn(props);
|
||
}
|
||
|
||
/**
|
||
* Build a function that applies props to a vm.
|
||
*
|
||
* @param {Array} props
|
||
* @return {Function} propsLinkFn
|
||
*/
|
||
|
||
function makePropsLinkFn(props) {
|
||
return function propsLinkFn(vm, scope) {
|
||
// store resolved props info
|
||
vm._props = {};
|
||
var i = props.length;
|
||
var prop, path, options, value, raw;
|
||
while (i--) {
|
||
prop = props[i];
|
||
raw = prop.raw;
|
||
path = prop.path;
|
||
options = prop.options;
|
||
vm._props[path] = prop;
|
||
if (raw === null) {
|
||
// initialize absent prop
|
||
initProp(vm, prop, getDefault(vm, options));
|
||
} else if (prop.dynamic) {
|
||
// dynamic prop
|
||
if (prop.mode === propBindingModes.ONE_TIME) {
|
||
// one time binding
|
||
value = (scope || vm._context || vm).$get(prop.parentPath);
|
||
initProp(vm, prop, value);
|
||
} else {
|
||
if (vm._context) {
|
||
// dynamic binding
|
||
vm._bindDir({
|
||
name: 'prop',
|
||
def: propDef,
|
||
prop: prop
|
||
}, null, null, scope); // el, host, scope
|
||
} else {
|
||
// root instance
|
||
initProp(vm, prop, vm.$get(prop.parentPath));
|
||
}
|
||
}
|
||
} else if (prop.optimizedLiteral) {
|
||
// optimized literal, cast it and just set once
|
||
var stripped = stripQuotes(raw);
|
||
value = stripped === raw ? toBoolean(toNumber(raw)) : stripped;
|
||
initProp(vm, prop, value);
|
||
} else {
|
||
// string literal, but we need to cater for
|
||
// Boolean props with no value
|
||
value = options.type === Boolean && raw === '' ? true : raw;
|
||
initProp(vm, prop, value);
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Get the default value of a prop.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {Object} options
|
||
* @return {*}
|
||
*/
|
||
|
||
function getDefault(vm, options) {
|
||
// no default, return undefined
|
||
if (!hasOwn(options, 'default')) {
|
||
// absent boolean value defaults to false
|
||
return options.type === Boolean ? false : undefined;
|
||
}
|
||
var def = options['default'];
|
||
// warn against non-factory defaults for Object & Array
|
||
if (isObject(def)) {
|
||
process.env.NODE_ENV !== 'production' && warn('Object/Array as default prop values will be shared ' + 'across multiple instances. Use a factory function ' + 'to return the default value instead.');
|
||
}
|
||
// call factory function for non-Function types
|
||
return typeof def === 'function' && options.type !== Function ? def.call(vm) : def;
|
||
}
|
||
|
||
// special binding prefixes
|
||
var bindRE = /^v-bind:|^:/;
|
||
var onRE = /^v-on:|^@/;
|
||
var dirAttrRE = /^v-([^:]+)(?:$|:(.*)$)/;
|
||
var modifierRE = /\.[^\.]+/g;
|
||
var transitionRE = /^(v-bind:|:)?transition$/;
|
||
|
||
// terminal directives
|
||
var terminalDirectives = ['for', 'if'];
|
||
|
||
// default directive priority
|
||
var DEFAULT_PRIORITY = 1000;
|
||
|
||
/**
|
||
* Compile a template and return a reusable composite link
|
||
* function, which recursively contains more link functions
|
||
* inside. This top level compile function would normally
|
||
* be called on instance root nodes, but can also be used
|
||
* for partial compilation if the partial argument is true.
|
||
*
|
||
* The returned composite link function, when called, will
|
||
* return an unlink function that tearsdown all directives
|
||
* created during the linking phase.
|
||
*
|
||
* @param {Element|DocumentFragment} el
|
||
* @param {Object} options
|
||
* @param {Boolean} partial
|
||
* @return {Function}
|
||
*/
|
||
|
||
function compile(el, options, partial) {
|
||
// link function for the node itself.
|
||
var nodeLinkFn = partial || !options._asComponent ? compileNode(el, options) : null;
|
||
// link function for the childNodes
|
||
var childLinkFn = !(nodeLinkFn && nodeLinkFn.terminal) && el.tagName !== 'SCRIPT' && el.hasChildNodes() ? compileNodeList(el.childNodes, options) : null;
|
||
|
||
/**
|
||
* A composite linker function to be called on a already
|
||
* compiled piece of DOM, which instantiates all directive
|
||
* instances.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {Element|DocumentFragment} el
|
||
* @param {Vue} [host] - host vm of transcluded content
|
||
* @param {Object} [scope] - v-for scope
|
||
* @param {Fragment} [frag] - link context fragment
|
||
* @return {Function|undefined}
|
||
*/
|
||
|
||
return function compositeLinkFn(vm, el, host, scope, frag) {
|
||
// cache childNodes before linking parent, fix #657
|
||
var childNodes = toArray(el.childNodes);
|
||
// link
|
||
var dirs = linkAndCapture(function compositeLinkCapturer() {
|
||
if (nodeLinkFn) nodeLinkFn(vm, el, host, scope, frag);
|
||
if (childLinkFn) childLinkFn(vm, childNodes, host, scope, frag);
|
||
}, vm);
|
||
return makeUnlinkFn(vm, dirs);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Apply a linker to a vm/element pair and capture the
|
||
* directives created during the process.
|
||
*
|
||
* @param {Function} linker
|
||
* @param {Vue} vm
|
||
*/
|
||
|
||
function linkAndCapture(linker, vm) {
|
||
/* istanbul ignore if */
|
||
if (process.env.NODE_ENV === 'production') {
|
||
// reset directives before every capture in production
|
||
// mode, so that when unlinking we don't need to splice
|
||
// them out (which turns out to be a perf hit).
|
||
// they are kept in development mode because they are
|
||
// useful for Vue's own tests.
|
||
vm._directives = [];
|
||
}
|
||
var originalDirCount = vm._directives.length;
|
||
linker();
|
||
var dirs = vm._directives.slice(originalDirCount);
|
||
dirs.sort(directiveComparator);
|
||
for (var i = 0, l = dirs.length; i < l; i++) {
|
||
dirs[i]._bind();
|
||
}
|
||
return dirs;
|
||
}
|
||
|
||
/**
|
||
* Directive priority sort comparator
|
||
*
|
||
* @param {Object} a
|
||
* @param {Object} b
|
||
*/
|
||
|
||
function directiveComparator(a, b) {
|
||
a = a.descriptor.def.priority || DEFAULT_PRIORITY;
|
||
b = b.descriptor.def.priority || DEFAULT_PRIORITY;
|
||
return a > b ? -1 : a === b ? 0 : 1;
|
||
}
|
||
|
||
/**
|
||
* Linker functions return an unlink function that
|
||
* tearsdown all directives instances generated during
|
||
* the process.
|
||
*
|
||
* We create unlink functions with only the necessary
|
||
* information to avoid retaining additional closures.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {Array} dirs
|
||
* @param {Vue} [context]
|
||
* @param {Array} [contextDirs]
|
||
* @return {Function}
|
||
*/
|
||
|
||
function makeUnlinkFn(vm, dirs, context, contextDirs) {
|
||
function unlink(destroying) {
|
||
teardownDirs(vm, dirs, destroying);
|
||
if (context && contextDirs) {
|
||
teardownDirs(context, contextDirs);
|
||
}
|
||
}
|
||
// expose linked directives
|
||
unlink.dirs = dirs;
|
||
return unlink;
|
||
}
|
||
|
||
/**
|
||
* Teardown partial linked directives.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {Array} dirs
|
||
* @param {Boolean} destroying
|
||
*/
|
||
|
||
function teardownDirs(vm, dirs, destroying) {
|
||
var i = dirs.length;
|
||
while (i--) {
|
||
dirs[i]._teardown();
|
||
if (process.env.NODE_ENV !== 'production' && !destroying) {
|
||
vm._directives.$remove(dirs[i]);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Compile link props on an instance.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {Element} el
|
||
* @param {Object} props
|
||
* @param {Object} [scope]
|
||
* @return {Function}
|
||
*/
|
||
|
||
function compileAndLinkProps(vm, el, props, scope) {
|
||
var propsLinkFn = compileProps(el, props);
|
||
var propDirs = linkAndCapture(function () {
|
||
propsLinkFn(vm, scope);
|
||
}, vm);
|
||
return makeUnlinkFn(vm, propDirs);
|
||
}
|
||
|
||
/**
|
||
* Compile the root element of an instance.
|
||
*
|
||
* 1. attrs on context container (context scope)
|
||
* 2. attrs on the component template root node, if
|
||
* replace:true (child scope)
|
||
*
|
||
* If this is a fragment instance, we only need to compile 1.
|
||
*
|
||
* @param {Element} el
|
||
* @param {Object} options
|
||
* @param {Object} contextOptions
|
||
* @return {Function}
|
||
*/
|
||
|
||
function compileRoot(el, options, contextOptions) {
|
||
var containerAttrs = options._containerAttrs;
|
||
var replacerAttrs = options._replacerAttrs;
|
||
var contextLinkFn, replacerLinkFn;
|
||
|
||
// only need to compile other attributes for
|
||
// non-fragment instances
|
||
if (el.nodeType !== 11) {
|
||
// for components, container and replacer need to be
|
||
// compiled separately and linked in different scopes.
|
||
if (options._asComponent) {
|
||
// 2. container attributes
|
||
if (containerAttrs && contextOptions) {
|
||
contextLinkFn = compileDirectives(containerAttrs, contextOptions);
|
||
}
|
||
if (replacerAttrs) {
|
||
// 3. replacer attributes
|
||
replacerLinkFn = compileDirectives(replacerAttrs, options);
|
||
}
|
||
} else {
|
||
// non-component, just compile as a normal element.
|
||
replacerLinkFn = compileDirectives(el.attributes, options);
|
||
}
|
||
} else if (process.env.NODE_ENV !== 'production' && containerAttrs) {
|
||
// warn container directives for fragment instances
|
||
var names = containerAttrs.filter(function (attr) {
|
||
// allow vue-loader/vueify scoped css attributes
|
||
return attr.name.indexOf('_v-') < 0 &&
|
||
// allow event listeners
|
||
!onRE.test(attr.name) &&
|
||
// allow slots
|
||
attr.name !== 'slot';
|
||
}).map(function (attr) {
|
||
return '"' + attr.name + '"';
|
||
});
|
||
if (names.length) {
|
||
var plural = names.length > 1;
|
||
warn('Attribute' + (plural ? 's ' : ' ') + names.join(', ') + (plural ? ' are' : ' is') + ' ignored on component ' + '<' + options.el.tagName.toLowerCase() + '> because ' + 'the component is a fragment instance: ' + 'http://vuejs.org/guide/components.html#Fragment_Instance');
|
||
}
|
||
}
|
||
|
||
options._containerAttrs = options._replacerAttrs = null;
|
||
return function rootLinkFn(vm, el, scope) {
|
||
// link context scope dirs
|
||
var context = vm._context;
|
||
var contextDirs;
|
||
if (context && contextLinkFn) {
|
||
contextDirs = linkAndCapture(function () {
|
||
contextLinkFn(context, el, null, scope);
|
||
}, context);
|
||
}
|
||
|
||
// link self
|
||
var selfDirs = linkAndCapture(function () {
|
||
if (replacerLinkFn) replacerLinkFn(vm, el);
|
||
}, vm);
|
||
|
||
// return the unlink function that tearsdown context
|
||
// container directives.
|
||
return makeUnlinkFn(vm, selfDirs, context, contextDirs);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Compile a node and return a nodeLinkFn based on the
|
||
* node type.
|
||
*
|
||
* @param {Node} node
|
||
* @param {Object} options
|
||
* @return {Function|null}
|
||
*/
|
||
|
||
function compileNode(node, options) {
|
||
var type = node.nodeType;
|
||
if (type === 1 && node.tagName !== 'SCRIPT') {
|
||
return compileElement(node, options);
|
||
} else if (type === 3 && node.data.trim()) {
|
||
return compileTextNode(node, options);
|
||
} else {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Compile an element and return a nodeLinkFn.
|
||
*
|
||
* @param {Element} el
|
||
* @param {Object} options
|
||
* @return {Function|null}
|
||
*/
|
||
|
||
function compileElement(el, options) {
|
||
// preprocess textareas.
|
||
// textarea treats its text content as the initial value.
|
||
// just bind it as an attr directive for value.
|
||
if (el.tagName === 'TEXTAREA') {
|
||
var tokens = parseText(el.value);
|
||
if (tokens) {
|
||
el.setAttribute(':value', tokensToExp(tokens));
|
||
el.value = '';
|
||
}
|
||
}
|
||
var linkFn;
|
||
var hasAttrs = el.hasAttributes();
|
||
// check terminal directives (for & if)
|
||
if (hasAttrs) {
|
||
linkFn = checkTerminalDirectives(el, options);
|
||
}
|
||
// check element directives
|
||
if (!linkFn) {
|
||
linkFn = checkElementDirectives(el, options);
|
||
}
|
||
// check component
|
||
if (!linkFn) {
|
||
linkFn = checkComponent(el, options);
|
||
}
|
||
// normal directives
|
||
if (!linkFn && hasAttrs) {
|
||
linkFn = compileDirectives(el.attributes, options);
|
||
}
|
||
return linkFn;
|
||
}
|
||
|
||
/**
|
||
* Compile a textNode and return a nodeLinkFn.
|
||
*
|
||
* @param {TextNode} node
|
||
* @param {Object} options
|
||
* @return {Function|null} textNodeLinkFn
|
||
*/
|
||
|
||
function compileTextNode(node, options) {
|
||
// skip marked text nodes
|
||
if (node._skip) {
|
||
return removeText;
|
||
}
|
||
|
||
var tokens = parseText(node.wholeText);
|
||
if (!tokens) {
|
||
return null;
|
||
}
|
||
|
||
// mark adjacent text nodes as skipped,
|
||
// because we are using node.wholeText to compile
|
||
// all adjacent text nodes together. This fixes
|
||
// issues in IE where sometimes it splits up a single
|
||
// text node into multiple ones.
|
||
var next = node.nextSibling;
|
||
while (next && next.nodeType === 3) {
|
||
next._skip = true;
|
||
next = next.nextSibling;
|
||
}
|
||
|
||
var frag = document.createDocumentFragment();
|
||
var el, token;
|
||
for (var i = 0, l = tokens.length; i < l; i++) {
|
||
token = tokens[i];
|
||
el = token.tag ? processTextToken(token, options) : document.createTextNode(token.value);
|
||
frag.appendChild(el);
|
||
}
|
||
return makeTextNodeLinkFn(tokens, frag, options);
|
||
}
|
||
|
||
/**
|
||
* Linker for an skipped text node.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {Text} node
|
||
*/
|
||
|
||
function removeText(vm, node) {
|
||
remove(node);
|
||
}
|
||
|
||
/**
|
||
* Process a single text token.
|
||
*
|
||
* @param {Object} token
|
||
* @param {Object} options
|
||
* @return {Node}
|
||
*/
|
||
|
||
function processTextToken(token, options) {
|
||
var el;
|
||
if (token.oneTime) {
|
||
el = document.createTextNode(token.value);
|
||
} else {
|
||
if (token.html) {
|
||
el = document.createComment('v-html');
|
||
setTokenType('html');
|
||
} else {
|
||
// IE will clean up empty textNodes during
|
||
// frag.cloneNode(true), so we have to give it
|
||
// something here...
|
||
el = document.createTextNode(' ');
|
||
setTokenType('text');
|
||
}
|
||
}
|
||
function setTokenType(type) {
|
||
if (token.descriptor) return;
|
||
var parsed = parseDirective(token.value);
|
||
token.descriptor = {
|
||
name: type,
|
||
def: directives[type],
|
||
expression: parsed.expression,
|
||
filters: parsed.filters
|
||
};
|
||
}
|
||
return el;
|
||
}
|
||
|
||
/**
|
||
* Build a function that processes a textNode.
|
||
*
|
||
* @param {Array<Object>} tokens
|
||
* @param {DocumentFragment} frag
|
||
*/
|
||
|
||
function makeTextNodeLinkFn(tokens, frag) {
|
||
return function textNodeLinkFn(vm, el, host, scope) {
|
||
var fragClone = frag.cloneNode(true);
|
||
var childNodes = toArray(fragClone.childNodes);
|
||
var token, value, node;
|
||
for (var i = 0, l = tokens.length; i < l; i++) {
|
||
token = tokens[i];
|
||
value = token.value;
|
||
if (token.tag) {
|
||
node = childNodes[i];
|
||
if (token.oneTime) {
|
||
value = (scope || vm).$eval(value);
|
||
if (token.html) {
|
||
replace(node, parseTemplate(value, true));
|
||
} else {
|
||
node.data = value;
|
||
}
|
||
} else {
|
||
vm._bindDir(token.descriptor, node, host, scope);
|
||
}
|
||
}
|
||
}
|
||
replace(el, fragClone);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Compile a node list and return a childLinkFn.
|
||
*
|
||
* @param {NodeList} nodeList
|
||
* @param {Object} options
|
||
* @return {Function|undefined}
|
||
*/
|
||
|
||
function compileNodeList(nodeList, options) {
|
||
var linkFns = [];
|
||
var nodeLinkFn, childLinkFn, node;
|
||
for (var i = 0, l = nodeList.length; i < l; i++) {
|
||
node = nodeList[i];
|
||
nodeLinkFn = compileNode(node, options);
|
||
childLinkFn = !(nodeLinkFn && nodeLinkFn.terminal) && node.tagName !== 'SCRIPT' && node.hasChildNodes() ? compileNodeList(node.childNodes, options) : null;
|
||
linkFns.push(nodeLinkFn, childLinkFn);
|
||
}
|
||
return linkFns.length ? makeChildLinkFn(linkFns) : null;
|
||
}
|
||
|
||
/**
|
||
* Make a child link function for a node's childNodes.
|
||
*
|
||
* @param {Array<Function>} linkFns
|
||
* @return {Function} childLinkFn
|
||
*/
|
||
|
||
function makeChildLinkFn(linkFns) {
|
||
return function childLinkFn(vm, nodes, host, scope, frag) {
|
||
var node, nodeLinkFn, childrenLinkFn;
|
||
for (var i = 0, n = 0, l = linkFns.length; i < l; n++) {
|
||
node = nodes[n];
|
||
nodeLinkFn = linkFns[i++];
|
||
childrenLinkFn = linkFns[i++];
|
||
// cache childNodes before linking parent, fix #657
|
||
var childNodes = toArray(node.childNodes);
|
||
if (nodeLinkFn) {
|
||
nodeLinkFn(vm, node, host, scope, frag);
|
||
}
|
||
if (childrenLinkFn) {
|
||
childrenLinkFn(vm, childNodes, host, scope, frag);
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Check for element directives (custom elements that should
|
||
* be resovled as terminal directives).
|
||
*
|
||
* @param {Element} el
|
||
* @param {Object} options
|
||
*/
|
||
|
||
function checkElementDirectives(el, options) {
|
||
var tag = el.tagName.toLowerCase();
|
||
if (commonTagRE.test(tag)) {
|
||
return;
|
||
}
|
||
var def = resolveAsset(options, 'elementDirectives', tag);
|
||
if (def) {
|
||
return makeTerminalNodeLinkFn(el, tag, '', options, def);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check if an element is a component. If yes, return
|
||
* a component link function.
|
||
*
|
||
* @param {Element} el
|
||
* @param {Object} options
|
||
* @return {Function|undefined}
|
||
*/
|
||
|
||
function checkComponent(el, options) {
|
||
var component = checkComponentAttr(el, options);
|
||
if (component) {
|
||
var ref = findRef(el);
|
||
var descriptor = {
|
||
name: 'component',
|
||
ref: ref,
|
||
expression: component.id,
|
||
def: internalDirectives.component,
|
||
modifiers: {
|
||
literal: !component.dynamic
|
||
}
|
||
};
|
||
var componentLinkFn = function componentLinkFn(vm, el, host, scope, frag) {
|
||
if (ref) {
|
||
defineReactive((scope || vm).$refs, ref, null);
|
||
}
|
||
vm._bindDir(descriptor, el, host, scope, frag);
|
||
};
|
||
componentLinkFn.terminal = true;
|
||
return componentLinkFn;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Check an element for terminal directives in fixed order.
|
||
* If it finds one, return a terminal link function.
|
||
*
|
||
* @param {Element} el
|
||
* @param {Object} options
|
||
* @return {Function} terminalLinkFn
|
||
*/
|
||
|
||
function checkTerminalDirectives(el, options) {
|
||
// skip v-pre
|
||
if (getAttr(el, 'v-pre') !== null) {
|
||
return skip;
|
||
}
|
||
// skip v-else block, but only if following v-if
|
||
if (el.hasAttribute('v-else')) {
|
||
var prev = el.previousElementSibling;
|
||
if (prev && prev.hasAttribute('v-if')) {
|
||
return skip;
|
||
}
|
||
}
|
||
var value, dirName;
|
||
for (var i = 0, l = terminalDirectives.length; i < l; i++) {
|
||
dirName = terminalDirectives[i];
|
||
value = el.getAttribute('v-' + dirName);
|
||
if (value != null) {
|
||
return makeTerminalNodeLinkFn(el, dirName, value, options);
|
||
}
|
||
}
|
||
}
|
||
|
||
function skip() {}
|
||
skip.terminal = true;
|
||
|
||
/**
|
||
* Build a node link function for a terminal directive.
|
||
* A terminal link function terminates the current
|
||
* compilation recursion and handles compilation of the
|
||
* subtree in the directive.
|
||
*
|
||
* @param {Element} el
|
||
* @param {String} dirName
|
||
* @param {String} value
|
||
* @param {Object} options
|
||
* @param {Object} [def]
|
||
* @return {Function} terminalLinkFn
|
||
*/
|
||
|
||
function makeTerminalNodeLinkFn(el, dirName, value, options, def) {
|
||
var parsed = parseDirective(value);
|
||
var descriptor = {
|
||
name: dirName,
|
||
expression: parsed.expression,
|
||
filters: parsed.filters,
|
||
raw: value,
|
||
// either an element directive, or if/for
|
||
// #2366 or custom terminal directive
|
||
def: def || resolveAsset(options, 'directives', dirName)
|
||
};
|
||
// check ref for v-for and router-view
|
||
if (dirName === 'for' || dirName === 'router-view') {
|
||
descriptor.ref = findRef(el);
|
||
}
|
||
var fn = function terminalNodeLinkFn(vm, el, host, scope, frag) {
|
||
if (descriptor.ref) {
|
||
defineReactive((scope || vm).$refs, descriptor.ref, null);
|
||
}
|
||
vm._bindDir(descriptor, el, host, scope, frag);
|
||
};
|
||
fn.terminal = true;
|
||
return fn;
|
||
}
|
||
|
||
/**
|
||
* Compile the directives on an element and return a linker.
|
||
*
|
||
* @param {Array|NamedNodeMap} attrs
|
||
* @param {Object} options
|
||
* @return {Function}
|
||
*/
|
||
|
||
function compileDirectives(attrs, options) {
|
||
var i = attrs.length;
|
||
var dirs = [];
|
||
var attr, name, value, rawName, rawValue, dirName, arg, modifiers, dirDef, tokens, matched;
|
||
while (i--) {
|
||
attr = attrs[i];
|
||
name = rawName = attr.name;
|
||
value = rawValue = attr.value;
|
||
tokens = parseText(value);
|
||
// reset arg
|
||
arg = null;
|
||
// check modifiers
|
||
modifiers = parseModifiers(name);
|
||
name = name.replace(modifierRE, '');
|
||
|
||
// attribute interpolations
|
||
if (tokens) {
|
||
value = tokensToExp(tokens);
|
||
arg = name;
|
||
pushDir('bind', directives.bind, tokens);
|
||
// warn against mixing mustaches with v-bind
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
if (name === 'class' && Array.prototype.some.call(attrs, function (attr) {
|
||
return attr.name === ':class' || attr.name === 'v-bind:class';
|
||
})) {
|
||
warn('class="' + rawValue + '": Do not mix mustache interpolation ' + 'and v-bind for "class" on the same element. Use one or the other.');
|
||
}
|
||
}
|
||
} else
|
||
|
||
// special attribute: transition
|
||
if (transitionRE.test(name)) {
|
||
modifiers.literal = !bindRE.test(name);
|
||
pushDir('transition', internalDirectives.transition);
|
||
} else
|
||
|
||
// event handlers
|
||
if (onRE.test(name)) {
|
||
arg = name.replace(onRE, '');
|
||
pushDir('on', directives.on);
|
||
} else
|
||
|
||
// attribute bindings
|
||
if (bindRE.test(name)) {
|
||
dirName = name.replace(bindRE, '');
|
||
if (dirName === 'style' || dirName === 'class') {
|
||
pushDir(dirName, internalDirectives[dirName]);
|
||
} else {
|
||
arg = dirName;
|
||
pushDir('bind', directives.bind);
|
||
}
|
||
} else
|
||
|
||
// normal directives
|
||
if (matched = name.match(dirAttrRE)) {
|
||
dirName = matched[1];
|
||
arg = matched[2];
|
||
|
||
// skip v-else (when used with v-show)
|
||
if (dirName === 'else') {
|
||
continue;
|
||
}
|
||
|
||
dirDef = resolveAsset(options, 'directives', dirName);
|
||
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
assertAsset(dirDef, 'directive', dirName);
|
||
}
|
||
|
||
if (dirDef) {
|
||
pushDir(dirName, dirDef);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Push a directive.
|
||
*
|
||
* @param {String} dirName
|
||
* @param {Object|Function} def
|
||
* @param {Array} [interpTokens]
|
||
*/
|
||
|
||
function pushDir(dirName, def, interpTokens) {
|
||
var hasOneTimeToken = interpTokens && hasOneTime(interpTokens);
|
||
var parsed = !hasOneTimeToken && parseDirective(value);
|
||
dirs.push({
|
||
name: dirName,
|
||
attr: rawName,
|
||
raw: rawValue,
|
||
def: def,
|
||
arg: arg,
|
||
modifiers: modifiers,
|
||
// conversion from interpolation strings with one-time token
|
||
// to expression is differed until directive bind time so that we
|
||
// have access to the actual vm context for one-time bindings.
|
||
expression: parsed && parsed.expression,
|
||
filters: parsed && parsed.filters,
|
||
interp: interpTokens,
|
||
hasOneTime: hasOneTimeToken
|
||
});
|
||
}
|
||
|
||
if (dirs.length) {
|
||
return makeNodeLinkFn(dirs);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Parse modifiers from directive attribute name.
|
||
*
|
||
* @param {String} name
|
||
* @return {Object}
|
||
*/
|
||
|
||
function parseModifiers(name) {
|
||
var res = Object.create(null);
|
||
var match = name.match(modifierRE);
|
||
if (match) {
|
||
var i = match.length;
|
||
while (i--) {
|
||
res[match[i].slice(1)] = true;
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
|
||
/**
|
||
* Build a link function for all directives on a single node.
|
||
*
|
||
* @param {Array} directives
|
||
* @return {Function} directivesLinkFn
|
||
*/
|
||
|
||
function makeNodeLinkFn(directives) {
|
||
return function nodeLinkFn(vm, el, host, scope, frag) {
|
||
// reverse apply because it's sorted low to high
|
||
var i = directives.length;
|
||
while (i--) {
|
||
vm._bindDir(directives[i], el, host, scope, frag);
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Check if an interpolation string contains one-time tokens.
|
||
*
|
||
* @param {Array} tokens
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
function hasOneTime(tokens) {
|
||
var i = tokens.length;
|
||
while (i--) {
|
||
if (tokens[i].oneTime) return true;
|
||
}
|
||
}
|
||
|
||
var specialCharRE = /[^\w\-:\.]/;
|
||
|
||
/**
|
||
* Process an element or a DocumentFragment based on a
|
||
* instance option object. This allows us to transclude
|
||
* a template node/fragment before the instance is created,
|
||
* so the processed fragment can then be cloned and reused
|
||
* in v-for.
|
||
*
|
||
* @param {Element} el
|
||
* @param {Object} options
|
||
* @return {Element|DocumentFragment}
|
||
*/
|
||
|
||
function transclude(el, options) {
|
||
// extract container attributes to pass them down
|
||
// to compiler, because they need to be compiled in
|
||
// parent scope. we are mutating the options object here
|
||
// assuming the same object will be used for compile
|
||
// right after this.
|
||
if (options) {
|
||
options._containerAttrs = extractAttrs(el);
|
||
}
|
||
// for template tags, what we want is its content as
|
||
// a documentFragment (for fragment instances)
|
||
if (isTemplate(el)) {
|
||
el = parseTemplate(el);
|
||
}
|
||
if (options) {
|
||
if (options._asComponent && !options.template) {
|
||
options.template = '<slot></slot>';
|
||
}
|
||
if (options.template) {
|
||
options._content = extractContent(el);
|
||
el = transcludeTemplate(el, options);
|
||
}
|
||
}
|
||
if (isFragment(el)) {
|
||
// anchors for fragment instance
|
||
// passing in `persist: true` to avoid them being
|
||
// discarded by IE during template cloning
|
||
prepend(createAnchor('v-start', true), el);
|
||
el.appendChild(createAnchor('v-end', true));
|
||
}
|
||
return el;
|
||
}
|
||
|
||
/**
|
||
* Process the template option.
|
||
* If the replace option is true this will swap the $el.
|
||
*
|
||
* @param {Element} el
|
||
* @param {Object} options
|
||
* @return {Element|DocumentFragment}
|
||
*/
|
||
|
||
function transcludeTemplate(el, options) {
|
||
var template = options.template;
|
||
var frag = parseTemplate(template, true);
|
||
if (frag) {
|
||
var replacer = frag.firstChild;
|
||
var tag = replacer.tagName && replacer.tagName.toLowerCase();
|
||
if (options.replace) {
|
||
/* istanbul ignore if */
|
||
if (el === document.body) {
|
||
process.env.NODE_ENV !== 'production' && warn('You are mounting an instance with a template to ' + '<body>. This will replace <body> entirely. You ' + 'should probably use `replace: false` here.');
|
||
}
|
||
// there are many cases where the instance must
|
||
// become a fragment instance: basically anything that
|
||
// can create more than 1 root nodes.
|
||
if (
|
||
// multi-children template
|
||
frag.childNodes.length > 1 ||
|
||
// non-element template
|
||
replacer.nodeType !== 1 ||
|
||
// single nested component
|
||
tag === 'component' || resolveAsset(options, 'components', tag) || hasBindAttr(replacer, 'is') ||
|
||
// element directive
|
||
resolveAsset(options, 'elementDirectives', tag) ||
|
||
// for block
|
||
replacer.hasAttribute('v-for') ||
|
||
// if block
|
||
replacer.hasAttribute('v-if')) {
|
||
return frag;
|
||
} else {
|
||
options._replacerAttrs = extractAttrs(replacer);
|
||
mergeAttrs(el, replacer);
|
||
return replacer;
|
||
}
|
||
} else {
|
||
el.appendChild(frag);
|
||
return el;
|
||
}
|
||
} else {
|
||
process.env.NODE_ENV !== 'production' && warn('Invalid template option: ' + template);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Helper to extract a component container's attributes
|
||
* into a plain object array.
|
||
*
|
||
* @param {Element} el
|
||
* @return {Array}
|
||
*/
|
||
|
||
function extractAttrs(el) {
|
||
if (el.nodeType === 1 && el.hasAttributes()) {
|
||
return toArray(el.attributes);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Merge the attributes of two elements, and make sure
|
||
* the class names are merged properly.
|
||
*
|
||
* @param {Element} from
|
||
* @param {Element} to
|
||
*/
|
||
|
||
function mergeAttrs(from, to) {
|
||
var attrs = from.attributes;
|
||
var i = attrs.length;
|
||
var name, value;
|
||
while (i--) {
|
||
name = attrs[i].name;
|
||
value = attrs[i].value;
|
||
if (!to.hasAttribute(name) && !specialCharRE.test(name)) {
|
||
to.setAttribute(name, value);
|
||
} else if (name === 'class' && !parseText(value)) {
|
||
value.split(/\s+/).forEach(function (cls) {
|
||
addClass(to, cls);
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Scan and determine slot content distribution.
|
||
* We do this during transclusion instead at compile time so that
|
||
* the distribution is decoupled from the compilation order of
|
||
* the slots.
|
||
*
|
||
* @param {Element|DocumentFragment} template
|
||
* @param {Element} content
|
||
* @param {Vue} vm
|
||
*/
|
||
|
||
function scanSlots(template, content, vm) {
|
||
if (!content) {
|
||
return;
|
||
}
|
||
var contents = vm._slotContents = {};
|
||
var slots = template.querySelectorAll('slot');
|
||
if (slots.length) {
|
||
var hasDefault, slot, name;
|
||
for (var i = 0, l = slots.length; i < l; i++) {
|
||
slot = slots[i];
|
||
/* eslint-disable no-cond-assign */
|
||
if (name = slot.getAttribute('name')) {
|
||
select(slot, name);
|
||
} else if (process.env.NODE_ENV !== 'production' && (name = getBindAttr(slot, 'name'))) {
|
||
warn('<slot :name="' + name + '">: slot names cannot be dynamic.');
|
||
} else {
|
||
// default slot
|
||
hasDefault = true;
|
||
}
|
||
/* eslint-enable no-cond-assign */
|
||
}
|
||
if (hasDefault) {
|
||
contents['default'] = extractFragment(content.childNodes, content);
|
||
}
|
||
}
|
||
|
||
function select(slot, name) {
|
||
// named slot
|
||
var selector = '[slot="' + name + '"]';
|
||
var nodes = content.querySelectorAll(selector);
|
||
if (nodes.length) {
|
||
contents[name] = extractFragment(nodes, content);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Extract qualified content nodes from a node list.
|
||
*
|
||
* @param {NodeList} nodes
|
||
* @param {Element} parent
|
||
* @return {DocumentFragment}
|
||
*/
|
||
|
||
function extractFragment(nodes, parent) {
|
||
var frag = document.createDocumentFragment();
|
||
nodes = toArray(nodes);
|
||
for (var i = 0, l = nodes.length; i < l; i++) {
|
||
var node = nodes[i];
|
||
if (node.parentNode === parent) {
|
||
if (isTemplate(node) && !node.hasAttribute('v-if') && !node.hasAttribute('v-for')) {
|
||
parent.removeChild(node);
|
||
node = parseTemplate(node);
|
||
}
|
||
frag.appendChild(node);
|
||
}
|
||
}
|
||
return frag;
|
||
}
|
||
|
||
|
||
|
||
var compiler = Object.freeze({
|
||
compile: compile,
|
||
compileAndLinkProps: compileAndLinkProps,
|
||
compileRoot: compileRoot,
|
||
terminalDirectives: terminalDirectives,
|
||
transclude: transclude,
|
||
scanSlots: scanSlots
|
||
});
|
||
|
||
function stateMixin (Vue) {
|
||
/**
|
||
* Accessor for `$data` property, since setting $data
|
||
* requires observing the new object and updating
|
||
* proxied properties.
|
||
*/
|
||
|
||
Object.defineProperty(Vue.prototype, '$data', {
|
||
get: function get() {
|
||
return this._data;
|
||
},
|
||
set: function set(newData) {
|
||
if (newData !== this._data) {
|
||
this._setData(newData);
|
||
}
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Setup the scope of an instance, which contains:
|
||
* - observed data
|
||
* - computed properties
|
||
* - user methods
|
||
* - meta properties
|
||
*/
|
||
|
||
Vue.prototype._initState = function () {
|
||
this._initProps();
|
||
this._initMeta();
|
||
this._initMethods();
|
||
this._initData();
|
||
this._initComputed();
|
||
};
|
||
|
||
/**
|
||
* Initialize props.
|
||
*/
|
||
|
||
Vue.prototype._initProps = function () {
|
||
var options = this.$options;
|
||
var el = options.el;
|
||
var props = options.props;
|
||
if (props && !el) {
|
||
process.env.NODE_ENV !== 'production' && warn('Props will not be compiled if no `el` option is ' + 'provided at instantiation.');
|
||
}
|
||
// make sure to convert string selectors into element now
|
||
el = options.el = query(el);
|
||
this._propsUnlinkFn = el && el.nodeType === 1 && props
|
||
// props must be linked in proper scope if inside v-for
|
||
? compileAndLinkProps(this, el, props, this._scope) : null;
|
||
};
|
||
|
||
/**
|
||
* Initialize the data.
|
||
*/
|
||
|
||
Vue.prototype._initData = function () {
|
||
var propsData = this._data;
|
||
var optionsDataFn = this.$options.data;
|
||
var optionsData = optionsDataFn && optionsDataFn();
|
||
var runtimeData;
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
runtimeData = (typeof this._runtimeData === 'function' ? this._runtimeData() : this._runtimeData) || {};
|
||
this._runtimeData = null;
|
||
}
|
||
if (optionsData) {
|
||
this._data = optionsData;
|
||
for (var prop in propsData) {
|
||
if (process.env.NODE_ENV !== 'production' && hasOwn(optionsData, prop) && !hasOwn(runtimeData, prop)) {
|
||
warn('Data field "' + prop + '" is already defined ' + 'as a prop. Use prop default value instead.');
|
||
}
|
||
if (this._props[prop].raw !== null || !hasOwn(optionsData, prop)) {
|
||
set(optionsData, prop, propsData[prop]);
|
||
}
|
||
}
|
||
}
|
||
var data = this._data;
|
||
// proxy data on instance
|
||
var keys = Object.keys(data);
|
||
var i, key;
|
||
i = keys.length;
|
||
while (i--) {
|
||
key = keys[i];
|
||
this._proxy(key);
|
||
}
|
||
// observe data
|
||
observe(data, this);
|
||
};
|
||
|
||
/**
|
||
* Swap the instance's $data. Called in $data's setter.
|
||
*
|
||
* @param {Object} newData
|
||
*/
|
||
|
||
Vue.prototype._setData = function (newData) {
|
||
newData = newData || {};
|
||
var oldData = this._data;
|
||
this._data = newData;
|
||
var keys, key, i;
|
||
// unproxy keys not present in new data
|
||
keys = Object.keys(oldData);
|
||
i = keys.length;
|
||
while (i--) {
|
||
key = keys[i];
|
||
if (!(key in newData)) {
|
||
this._unproxy(key);
|
||
}
|
||
}
|
||
// proxy keys not already proxied,
|
||
// and trigger change for changed values
|
||
keys = Object.keys(newData);
|
||
i = keys.length;
|
||
while (i--) {
|
||
key = keys[i];
|
||
if (!hasOwn(this, key)) {
|
||
// new property
|
||
this._proxy(key);
|
||
}
|
||
}
|
||
oldData.__ob__.removeVm(this);
|
||
observe(newData, this);
|
||
this._digest();
|
||
};
|
||
|
||
/**
|
||
* Proxy a property, so that
|
||
* vm.prop === vm._data.prop
|
||
*
|
||
* @param {String} key
|
||
*/
|
||
|
||
Vue.prototype._proxy = function (key) {
|
||
if (!isReserved(key)) {
|
||
// need to store ref to self here
|
||
// because these getter/setters might
|
||
// be called by child scopes via
|
||
// prototype inheritance.
|
||
var self = this;
|
||
Object.defineProperty(self, key, {
|
||
configurable: true,
|
||
enumerable: true,
|
||
get: function proxyGetter() {
|
||
return self._data[key];
|
||
},
|
||
set: function proxySetter(val) {
|
||
self._data[key] = val;
|
||
}
|
||
});
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Unproxy a property.
|
||
*
|
||
* @param {String} key
|
||
*/
|
||
|
||
Vue.prototype._unproxy = function (key) {
|
||
if (!isReserved(key)) {
|
||
delete this[key];
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Force update on every watcher in scope.
|
||
*/
|
||
|
||
Vue.prototype._digest = function () {
|
||
for (var i = 0, l = this._watchers.length; i < l; i++) {
|
||
this._watchers[i].update(true); // shallow updates
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Setup computed properties. They are essentially
|
||
* special getter/setters
|
||
*/
|
||
|
||
function noop() {}
|
||
Vue.prototype._initComputed = function () {
|
||
var computed = this.$options.computed;
|
||
if (computed) {
|
||
for (var key in computed) {
|
||
var userDef = computed[key];
|
||
var def = {
|
||
enumerable: true,
|
||
configurable: true
|
||
};
|
||
if (typeof userDef === 'function') {
|
||
def.get = makeComputedGetter(userDef, this);
|
||
def.set = noop;
|
||
} else {
|
||
def.get = userDef.get ? userDef.cache !== false ? makeComputedGetter(userDef.get, this) : bind(userDef.get, this) : noop;
|
||
def.set = userDef.set ? bind(userDef.set, this) : noop;
|
||
}
|
||
Object.defineProperty(this, key, def);
|
||
}
|
||
}
|
||
};
|
||
|
||
function makeComputedGetter(getter, owner) {
|
||
var watcher = new Watcher(owner, getter, null, {
|
||
lazy: true
|
||
});
|
||
return function computedGetter() {
|
||
if (watcher.dirty) {
|
||
watcher.evaluate();
|
||
}
|
||
if (Dep.target) {
|
||
watcher.depend();
|
||
}
|
||
return watcher.value;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Setup instance methods. Methods must be bound to the
|
||
* instance since they might be passed down as a prop to
|
||
* child components.
|
||
*/
|
||
|
||
Vue.prototype._initMethods = function () {
|
||
var methods = this.$options.methods;
|
||
if (methods) {
|
||
for (var key in methods) {
|
||
this[key] = bind(methods[key], this);
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Initialize meta information like $index, $key & $value.
|
||
*/
|
||
|
||
Vue.prototype._initMeta = function () {
|
||
var metas = this.$options._meta;
|
||
if (metas) {
|
||
for (var key in metas) {
|
||
defineReactive(this, key, metas[key]);
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
var eventRE = /^v-on:|^@/;
|
||
|
||
function eventsMixin (Vue) {
|
||
/**
|
||
* Setup the instance's option events & watchers.
|
||
* If the value is a string, we pull it from the
|
||
* instance's methods by name.
|
||
*/
|
||
|
||
Vue.prototype._initEvents = function () {
|
||
var options = this.$options;
|
||
if (options._asComponent) {
|
||
registerComponentEvents(this, options.el);
|
||
}
|
||
registerCallbacks(this, '$on', options.events);
|
||
registerCallbacks(this, '$watch', options.watch);
|
||
};
|
||
|
||
/**
|
||
* Register v-on events on a child component
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {Element} el
|
||
*/
|
||
|
||
function registerComponentEvents(vm, el) {
|
||
var attrs = el.attributes;
|
||
var name, handler;
|
||
for (var i = 0, l = attrs.length; i < l; i++) {
|
||
name = attrs[i].name;
|
||
if (eventRE.test(name)) {
|
||
name = name.replace(eventRE, '');
|
||
handler = (vm._scope || vm._context).$eval(attrs[i].value, true);
|
||
if (typeof handler === 'function') {
|
||
handler._fromParent = true;
|
||
vm.$on(name.replace(eventRE), handler);
|
||
} else if (process.env.NODE_ENV !== 'production') {
|
||
warn('v-on:' + name + '="' + attrs[i].value + '"' + (vm.$options.name ? ' on component <' + vm.$options.name + '>' : '') + ' expects a function value, got ' + handler);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Register callbacks for option events and watchers.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {String} action
|
||
* @param {Object} hash
|
||
*/
|
||
|
||
function registerCallbacks(vm, action, hash) {
|
||
if (!hash) return;
|
||
var handlers, key, i, j;
|
||
for (key in hash) {
|
||
handlers = hash[key];
|
||
if (isArray(handlers)) {
|
||
for (i = 0, j = handlers.length; i < j; i++) {
|
||
register(vm, action, key, handlers[i]);
|
||
}
|
||
} else {
|
||
register(vm, action, key, handlers);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Helper to register an event/watch callback.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {String} action
|
||
* @param {String} key
|
||
* @param {Function|String|Object} handler
|
||
* @param {Object} [options]
|
||
*/
|
||
|
||
function register(vm, action, key, handler, options) {
|
||
var type = typeof handler;
|
||
if (type === 'function') {
|
||
vm[action](key, handler, options);
|
||
} else if (type === 'string') {
|
||
var methods = vm.$options.methods;
|
||
var method = methods && methods[handler];
|
||
if (method) {
|
||
vm[action](key, method, options);
|
||
} else {
|
||
process.env.NODE_ENV !== 'production' && warn('Unknown method: "' + handler + '" when ' + 'registering callback for ' + action + ': "' + key + '".');
|
||
}
|
||
} else if (handler && type === 'object') {
|
||
register(vm, action, key, handler.handler, handler);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Setup recursive attached/detached calls
|
||
*/
|
||
|
||
Vue.prototype._initDOMHooks = function () {
|
||
this.$on('hook:attached', onAttached);
|
||
this.$on('hook:detached', onDetached);
|
||
};
|
||
|
||
/**
|
||
* Callback to recursively call attached hook on children
|
||
*/
|
||
|
||
function onAttached() {
|
||
if (!this._isAttached) {
|
||
this._isAttached = true;
|
||
this.$children.forEach(callAttach);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Iterator to call attached hook
|
||
*
|
||
* @param {Vue} child
|
||
*/
|
||
|
||
function callAttach(child) {
|
||
if (!child._isAttached && inDoc(child.$el)) {
|
||
child._callHook('attached');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Callback to recursively call detached hook on children
|
||
*/
|
||
|
||
function onDetached() {
|
||
if (this._isAttached) {
|
||
this._isAttached = false;
|
||
this.$children.forEach(callDetach);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Iterator to call detached hook
|
||
*
|
||
* @param {Vue} child
|
||
*/
|
||
|
||
function callDetach(child) {
|
||
if (child._isAttached && !inDoc(child.$el)) {
|
||
child._callHook('detached');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Trigger all handlers for a hook
|
||
*
|
||
* @param {String} hook
|
||
*/
|
||
|
||
Vue.prototype._callHook = function (hook) {
|
||
this.$emit('pre-hook:' + hook);
|
||
var handlers = this.$options[hook];
|
||
if (handlers) {
|
||
for (var i = 0, j = handlers.length; i < j; i++) {
|
||
handlers[i].call(this);
|
||
}
|
||
}
|
||
this.$emit('hook:' + hook);
|
||
};
|
||
}
|
||
|
||
function noop() {}
|
||
|
||
/**
|
||
* A directive links a DOM element with a piece of data,
|
||
* which is the result of evaluating an expression.
|
||
* It registers a watcher with the expression and calls
|
||
* the DOM update function when a change is triggered.
|
||
*
|
||
* @param {String} name
|
||
* @param {Node} el
|
||
* @param {Vue} vm
|
||
* @param {Object} descriptor
|
||
* - {String} name
|
||
* - {Object} def
|
||
* - {String} expression
|
||
* - {Array<Object>} [filters]
|
||
* - {Boolean} literal
|
||
* - {String} attr
|
||
* - {String} raw
|
||
* @param {Object} def - directive definition object
|
||
* @param {Vue} [host] - transclusion host component
|
||
* @param {Object} [scope] - v-for scope
|
||
* @param {Fragment} [frag] - owner fragment
|
||
* @constructor
|
||
*/
|
||
function Directive(descriptor, vm, el, host, scope, frag) {
|
||
this.vm = vm;
|
||
this.el = el;
|
||
// copy descriptor properties
|
||
this.descriptor = descriptor;
|
||
this.name = descriptor.name;
|
||
this.expression = descriptor.expression;
|
||
this.arg = descriptor.arg;
|
||
this.modifiers = descriptor.modifiers;
|
||
this.filters = descriptor.filters;
|
||
this.literal = this.modifiers && this.modifiers.literal;
|
||
// private
|
||
this._locked = false;
|
||
this._bound = false;
|
||
this._listeners = null;
|
||
// link context
|
||
this._host = host;
|
||
this._scope = scope;
|
||
this._frag = frag;
|
||
// store directives on node in dev mode
|
||
if (process.env.NODE_ENV !== 'production' && this.el) {
|
||
this.el._vue_directives = this.el._vue_directives || [];
|
||
this.el._vue_directives.push(this);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Initialize the directive, mixin definition properties,
|
||
* setup the watcher, call definition bind() and update()
|
||
* if present.
|
||
*
|
||
* @param {Object} def
|
||
*/
|
||
|
||
Directive.prototype._bind = function () {
|
||
var name = this.name;
|
||
var descriptor = this.descriptor;
|
||
|
||
// remove attribute
|
||
if ((name !== 'cloak' || this.vm._isCompiled) && this.el && this.el.removeAttribute) {
|
||
var attr = descriptor.attr || 'v-' + name;
|
||
this.el.removeAttribute(attr);
|
||
}
|
||
|
||
// copy def properties
|
||
var def = descriptor.def;
|
||
if (typeof def === 'function') {
|
||
this.update = def;
|
||
} else {
|
||
extend(this, def);
|
||
}
|
||
|
||
// setup directive params
|
||
this._setupParams();
|
||
|
||
// initial bind
|
||
if (this.bind) {
|
||
this.bind();
|
||
}
|
||
this._bound = true;
|
||
|
||
if (this.literal) {
|
||
this.update && this.update(descriptor.raw);
|
||
} else if ((this.expression || this.modifiers) && (this.update || this.twoWay) && !this._checkStatement()) {
|
||
// wrapped updater for context
|
||
var dir = this;
|
||
if (this.update) {
|
||
this._update = function (val, oldVal) {
|
||
if (!dir._locked) {
|
||
dir.update(val, oldVal);
|
||
}
|
||
};
|
||
} else {
|
||
this._update = noop;
|
||
}
|
||
var preProcess = this._preProcess ? bind(this._preProcess, this) : null;
|
||
var postProcess = this._postProcess ? bind(this._postProcess, this) : null;
|
||
var watcher = this._watcher = new Watcher(this.vm, this.expression, this._update, // callback
|
||
{
|
||
filters: this.filters,
|
||
twoWay: this.twoWay,
|
||
deep: this.deep,
|
||
preProcess: preProcess,
|
||
postProcess: postProcess,
|
||
scope: this._scope
|
||
});
|
||
// v-model with inital inline value need to sync back to
|
||
// model instead of update to DOM on init. They would
|
||
// set the afterBind hook to indicate that.
|
||
if (this.afterBind) {
|
||
this.afterBind();
|
||
} else if (this.update) {
|
||
this.update(watcher.value);
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Setup all param attributes, e.g. track-by,
|
||
* transition-mode, etc...
|
||
*/
|
||
|
||
Directive.prototype._setupParams = function () {
|
||
if (!this.params) {
|
||
return;
|
||
}
|
||
var params = this.params;
|
||
// swap the params array with a fresh object.
|
||
this.params = Object.create(null);
|
||
var i = params.length;
|
||
var key, val, mappedKey;
|
||
while (i--) {
|
||
key = params[i];
|
||
mappedKey = camelize(key);
|
||
val = getBindAttr(this.el, key);
|
||
if (val != null) {
|
||
// dynamic
|
||
this._setupParamWatcher(mappedKey, val);
|
||
} else {
|
||
// static
|
||
val = getAttr(this.el, key);
|
||
if (val != null) {
|
||
this.params[mappedKey] = val === '' ? true : val;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Setup a watcher for a dynamic param.
|
||
*
|
||
* @param {String} key
|
||
* @param {String} expression
|
||
*/
|
||
|
||
Directive.prototype._setupParamWatcher = function (key, expression) {
|
||
var self = this;
|
||
var called = false;
|
||
var unwatch = (this._scope || this.vm).$watch(expression, function (val, oldVal) {
|
||
self.params[key] = val;
|
||
// since we are in immediate mode,
|
||
// only call the param change callbacks if this is not the first update.
|
||
if (called) {
|
||
var cb = self.paramWatchers && self.paramWatchers[key];
|
||
if (cb) {
|
||
cb.call(self, val, oldVal);
|
||
}
|
||
} else {
|
||
called = true;
|
||
}
|
||
}, {
|
||
immediate: true,
|
||
user: false
|
||
});(this._paramUnwatchFns || (this._paramUnwatchFns = [])).push(unwatch);
|
||
};
|
||
|
||
/**
|
||
* Check if the directive is a function caller
|
||
* and if the expression is a callable one. If both true,
|
||
* we wrap up the expression and use it as the event
|
||
* handler.
|
||
*
|
||
* e.g. on-click="a++"
|
||
*
|
||
* @return {Boolean}
|
||
*/
|
||
|
||
Directive.prototype._checkStatement = function () {
|
||
var expression = this.expression;
|
||
if (expression && this.acceptStatement && !isSimplePath(expression)) {
|
||
var fn = parseExpression(expression).get;
|
||
var scope = this._scope || this.vm;
|
||
var handler = function handler(e) {
|
||
scope.$event = e;
|
||
fn.call(scope, scope);
|
||
scope.$event = null;
|
||
};
|
||
if (this.filters) {
|
||
handler = scope._applyFilters(handler, null, this.filters);
|
||
}
|
||
this.update(handler);
|
||
return true;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Set the corresponding value with the setter.
|
||
* This should only be used in two-way directives
|
||
* e.g. v-model.
|
||
*
|
||
* @param {*} value
|
||
* @public
|
||
*/
|
||
|
||
Directive.prototype.set = function (value) {
|
||
/* istanbul ignore else */
|
||
if (this.twoWay) {
|
||
this._withLock(function () {
|
||
this._watcher.set(value);
|
||
});
|
||
} else if (process.env.NODE_ENV !== 'production') {
|
||
warn('Directive.set() can only be used inside twoWay' + 'directives.');
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Execute a function while preventing that function from
|
||
* triggering updates on this directive instance.
|
||
*
|
||
* @param {Function} fn
|
||
*/
|
||
|
||
Directive.prototype._withLock = function (fn) {
|
||
var self = this;
|
||
self._locked = true;
|
||
fn.call(self);
|
||
nextTick(function () {
|
||
self._locked = false;
|
||
});
|
||
};
|
||
|
||
/**
|
||
* Convenience method that attaches a DOM event listener
|
||
* to the directive element and autometically tears it down
|
||
* during unbind.
|
||
*
|
||
* @param {String} event
|
||
* @param {Function} handler
|
||
* @param {Boolean} [useCapture]
|
||
*/
|
||
|
||
Directive.prototype.on = function (event, handler, useCapture) {
|
||
on(this.el, event, handler, useCapture);(this._listeners || (this._listeners = [])).push([event, handler]);
|
||
};
|
||
|
||
/**
|
||
* Teardown the watcher and call unbind.
|
||
*/
|
||
|
||
Directive.prototype._teardown = function () {
|
||
if (this._bound) {
|
||
this._bound = false;
|
||
if (this.unbind) {
|
||
this.unbind();
|
||
}
|
||
if (this._watcher) {
|
||
this._watcher.teardown();
|
||
}
|
||
var listeners = this._listeners;
|
||
var i;
|
||
if (listeners) {
|
||
i = listeners.length;
|
||
while (i--) {
|
||
off(this.el, listeners[i][0], listeners[i][1]);
|
||
}
|
||
}
|
||
var unwatchFns = this._paramUnwatchFns;
|
||
if (unwatchFns) {
|
||
i = unwatchFns.length;
|
||
while (i--) {
|
||
unwatchFns[i]();
|
||
}
|
||
}
|
||
if (process.env.NODE_ENV !== 'production' && this.el) {
|
||
this.el._vue_directives.$remove(this);
|
||
}
|
||
this.vm = this.el = this._watcher = this._listeners = null;
|
||
}
|
||
};
|
||
|
||
function lifecycleMixin (Vue) {
|
||
/**
|
||
* Update v-ref for component.
|
||
*
|
||
* @param {Boolean} remove
|
||
*/
|
||
|
||
Vue.prototype._updateRef = function (remove) {
|
||
var ref = this.$options._ref;
|
||
if (ref) {
|
||
var refs = (this._scope || this._context).$refs;
|
||
if (remove) {
|
||
if (refs[ref] === this) {
|
||
refs[ref] = null;
|
||
}
|
||
} else {
|
||
refs[ref] = this;
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Transclude, compile and link element.
|
||
*
|
||
* If a pre-compiled linker is available, that means the
|
||
* passed in element will be pre-transcluded and compiled
|
||
* as well - all we need to do is to call the linker.
|
||
*
|
||
* Otherwise we need to call transclude/compile/link here.
|
||
*
|
||
* @param {Element} el
|
||
*/
|
||
|
||
Vue.prototype._compile = function (el) {
|
||
var options = this.$options;
|
||
|
||
// transclude and init element
|
||
// transclude can potentially replace original
|
||
// so we need to keep reference; this step also injects
|
||
// the template and caches the original attributes
|
||
// on the container node and replacer node.
|
||
var original = el;
|
||
el = transclude(el, options);
|
||
this._initElement(el);
|
||
|
||
// handle v-pre on root node (#2026)
|
||
if (el.nodeType === 1 && getAttr(el, 'v-pre') !== null) {
|
||
return;
|
||
}
|
||
|
||
// root is always compiled per-instance, because
|
||
// container attrs and props can be different every time.
|
||
var contextOptions = this._context && this._context.$options;
|
||
var rootLinker = compileRoot(el, options, contextOptions);
|
||
|
||
// scan for slot distribution before compiling the content
|
||
// so that it's decoupeld from slot/directive compilation order
|
||
scanSlots(el, options._content, this);
|
||
|
||
// compile and link the rest
|
||
var contentLinkFn;
|
||
var ctor = this.constructor;
|
||
// component compilation can be cached
|
||
// as long as it's not using inline-template
|
||
if (options._linkerCachable) {
|
||
contentLinkFn = ctor.linker;
|
||
if (!contentLinkFn) {
|
||
contentLinkFn = ctor.linker = compile(el, options);
|
||
}
|
||
}
|
||
|
||
// link phase
|
||
// make sure to link root with prop scope!
|
||
var rootUnlinkFn = rootLinker(this, el, this._scope);
|
||
var contentUnlinkFn = contentLinkFn ? contentLinkFn(this, el) : compile(el, options)(this, el);
|
||
|
||
// register composite unlink function
|
||
// to be called during instance destruction
|
||
this._unlinkFn = function () {
|
||
rootUnlinkFn();
|
||
// passing destroying: true to avoid searching and
|
||
// splicing the directives
|
||
contentUnlinkFn(true);
|
||
};
|
||
|
||
// finally replace original
|
||
if (options.replace) {
|
||
replace(original, el);
|
||
}
|
||
|
||
this._isCompiled = true;
|
||
this._callHook('compiled');
|
||
};
|
||
|
||
/**
|
||
* Initialize instance element. Called in the public
|
||
* $mount() method.
|
||
*
|
||
* @param {Element} el
|
||
*/
|
||
|
||
Vue.prototype._initElement = function (el) {
|
||
if (isFragment(el)) {
|
||
this._isFragment = true;
|
||
this.$el = this._fragmentStart = el.firstChild;
|
||
this._fragmentEnd = el.lastChild;
|
||
// set persisted text anchors to empty
|
||
if (this._fragmentStart.nodeType === 3) {
|
||
this._fragmentStart.data = this._fragmentEnd.data = '';
|
||
}
|
||
this._fragment = el;
|
||
} else {
|
||
this.$el = el;
|
||
}
|
||
this.$el.__vue__ = this;
|
||
this._callHook('beforeCompile');
|
||
};
|
||
|
||
/**
|
||
* Create and bind a directive to an element.
|
||
*
|
||
* @param {String} name - directive name
|
||
* @param {Node} node - target node
|
||
* @param {Object} desc - parsed directive descriptor
|
||
* @param {Object} def - directive definition object
|
||
* @param {Vue} [host] - transclusion host component
|
||
* @param {Object} [scope] - v-for scope
|
||
* @param {Fragment} [frag] - owner fragment
|
||
*/
|
||
|
||
Vue.prototype._bindDir = function (descriptor, node, host, scope, frag) {
|
||
this._directives.push(new Directive(descriptor, this, node, host, scope, frag));
|
||
};
|
||
|
||
/**
|
||
* Teardown an instance, unobserves the data, unbind all the
|
||
* directives, turn off all the event listeners, etc.
|
||
*
|
||
* @param {Boolean} remove - whether to remove the DOM node.
|
||
* @param {Boolean} deferCleanup - if true, defer cleanup to
|
||
* be called later
|
||
*/
|
||
|
||
Vue.prototype._destroy = function (remove, deferCleanup) {
|
||
if (this._isBeingDestroyed) {
|
||
if (!deferCleanup) {
|
||
this._cleanup();
|
||
}
|
||
return;
|
||
}
|
||
|
||
var destroyReady;
|
||
var pendingRemoval;
|
||
|
||
var self = this;
|
||
// Cleanup should be called either synchronously or asynchronoysly as
|
||
// callback of this.$remove(), or if remove and deferCleanup are false.
|
||
// In any case it should be called after all other removing, unbinding and
|
||
// turning of is done
|
||
var cleanupIfPossible = function cleanupIfPossible() {
|
||
if (destroyReady && !pendingRemoval && !deferCleanup) {
|
||
self._cleanup();
|
||
}
|
||
};
|
||
|
||
// remove DOM element
|
||
if (remove && this.$el) {
|
||
pendingRemoval = true;
|
||
this.$remove(function () {
|
||
pendingRemoval = false;
|
||
cleanupIfPossible();
|
||
});
|
||
}
|
||
|
||
this._callHook('beforeDestroy');
|
||
this._isBeingDestroyed = true;
|
||
var i;
|
||
// remove self from parent. only necessary
|
||
// if parent is not being destroyed as well.
|
||
var parent = this.$parent;
|
||
if (parent && !parent._isBeingDestroyed) {
|
||
parent.$children.$remove(this);
|
||
// unregister ref (remove: true)
|
||
this._updateRef(true);
|
||
}
|
||
// destroy all children.
|
||
i = this.$children.length;
|
||
while (i--) {
|
||
this.$children[i].$destroy();
|
||
}
|
||
// teardown props
|
||
if (this._propsUnlinkFn) {
|
||
this._propsUnlinkFn();
|
||
}
|
||
// teardown all directives. this also tearsdown all
|
||
// directive-owned watchers.
|
||
if (this._unlinkFn) {
|
||
this._unlinkFn();
|
||
}
|
||
i = this._watchers.length;
|
||
while (i--) {
|
||
this._watchers[i].teardown();
|
||
}
|
||
// remove reference to self on $el
|
||
if (this.$el) {
|
||
this.$el.__vue__ = null;
|
||
}
|
||
|
||
destroyReady = true;
|
||
cleanupIfPossible();
|
||
};
|
||
|
||
/**
|
||
* Clean up to ensure garbage collection.
|
||
* This is called after the leave transition if there
|
||
* is any.
|
||
*/
|
||
|
||
Vue.prototype._cleanup = function () {
|
||
if (this._isDestroyed) {
|
||
return;
|
||
}
|
||
// remove self from owner fragment
|
||
// do it in cleanup so that we can call $destroy with
|
||
// defer right when a fragment is about to be removed.
|
||
if (this._frag) {
|
||
this._frag.children.$remove(this);
|
||
}
|
||
// remove reference from data ob
|
||
// frozen object may not have observer.
|
||
if (this._data.__ob__) {
|
||
this._data.__ob__.removeVm(this);
|
||
}
|
||
// Clean up references to private properties and other
|
||
// instances. preserve reference to _data so that proxy
|
||
// accessors still work. The only potential side effect
|
||
// here is that mutating the instance after it's destroyed
|
||
// may affect the state of other components that are still
|
||
// observing the same object, but that seems to be a
|
||
// reasonable responsibility for the user rather than
|
||
// always throwing an error on them.
|
||
this.$el = this.$parent = this.$root = this.$children = this._watchers = this._context = this._scope = this._directives = null;
|
||
// call the last hook...
|
||
this._isDestroyed = true;
|
||
this._callHook('destroyed');
|
||
// turn off all instance listeners.
|
||
this.$off();
|
||
};
|
||
}
|
||
|
||
function miscMixin (Vue) {
|
||
/**
|
||
* Apply a list of filter (descriptors) to a value.
|
||
* Using plain for loops here because this will be called in
|
||
* the getter of any watcher with filters so it is very
|
||
* performance sensitive.
|
||
*
|
||
* @param {*} value
|
||
* @param {*} [oldValue]
|
||
* @param {Array} filters
|
||
* @param {Boolean} write
|
||
* @return {*}
|
||
*/
|
||
|
||
Vue.prototype._applyFilters = function (value, oldValue, filters, write) {
|
||
var filter, fn, args, arg, offset, i, l, j, k;
|
||
for (i = 0, l = filters.length; i < l; i++) {
|
||
filter = filters[i];
|
||
fn = resolveAsset(this.$options, 'filters', filter.name);
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
assertAsset(fn, 'filter', filter.name);
|
||
}
|
||
if (!fn) continue;
|
||
fn = write ? fn.write : fn.read || fn;
|
||
if (typeof fn !== 'function') continue;
|
||
args = write ? [value, oldValue] : [value];
|
||
offset = write ? 2 : 1;
|
||
if (filter.args) {
|
||
for (j = 0, k = filter.args.length; j < k; j++) {
|
||
arg = filter.args[j];
|
||
args[j + offset] = arg.dynamic ? this.$get(arg.value) : arg.value;
|
||
}
|
||
}
|
||
value = fn.apply(this, args);
|
||
}
|
||
return value;
|
||
};
|
||
|
||
/**
|
||
* Resolve a component, depending on whether the component
|
||
* is defined normally or using an async factory function.
|
||
* Resolves synchronously if already resolved, otherwise
|
||
* resolves asynchronously and caches the resolved
|
||
* constructor on the factory.
|
||
*
|
||
* @param {String} id
|
||
* @param {Function} cb
|
||
*/
|
||
|
||
Vue.prototype._resolveComponent = function (id, cb) {
|
||
var factory = resolveAsset(this.$options, 'components', id);
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
assertAsset(factory, 'component', id);
|
||
}
|
||
if (!factory) {
|
||
return;
|
||
}
|
||
// async component factory
|
||
if (!factory.options) {
|
||
if (factory.resolved) {
|
||
// cached
|
||
cb(factory.resolved);
|
||
} else if (factory.requested) {
|
||
// pool callbacks
|
||
factory.pendingCallbacks.push(cb);
|
||
} else {
|
||
factory.requested = true;
|
||
var cbs = factory.pendingCallbacks = [cb];
|
||
factory.call(this, function resolve(res) {
|
||
if (isPlainObject(res)) {
|
||
res = Vue.extend(res);
|
||
}
|
||
// cache resolved
|
||
factory.resolved = res;
|
||
// invoke callbacks
|
||
for (var i = 0, l = cbs.length; i < l; i++) {
|
||
cbs[i](res);
|
||
}
|
||
}, function reject(reason) {
|
||
process.env.NODE_ENV !== 'production' && warn('Failed to resolve async component: ' + id + '. ' + (reason ? '\nReason: ' + reason : ''));
|
||
});
|
||
}
|
||
} else {
|
||
// normal component
|
||
cb(factory);
|
||
}
|
||
};
|
||
}
|
||
|
||
var filterRE$1 = /[^|]\|[^|]/;
|
||
|
||
function dataAPI (Vue) {
|
||
/**
|
||
* Get the value from an expression on this vm.
|
||
*
|
||
* @param {String} exp
|
||
* @param {Boolean} [asStatement]
|
||
* @return {*}
|
||
*/
|
||
|
||
Vue.prototype.$get = function (exp, asStatement) {
|
||
var res = parseExpression(exp);
|
||
if (res) {
|
||
if (asStatement && !isSimplePath(exp)) {
|
||
var self = this;
|
||
return function statementHandler() {
|
||
self.$arguments = toArray(arguments);
|
||
var result = res.get.call(self, self);
|
||
self.$arguments = null;
|
||
return result;
|
||
};
|
||
} else {
|
||
try {
|
||
return res.get.call(this, this);
|
||
} catch (e) {}
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Set the value from an expression on this vm.
|
||
* The expression must be a valid left-hand
|
||
* expression in an assignment.
|
||
*
|
||
* @param {String} exp
|
||
* @param {*} val
|
||
*/
|
||
|
||
Vue.prototype.$set = function (exp, val) {
|
||
var res = parseExpression(exp, true);
|
||
if (res && res.set) {
|
||
res.set.call(this, this, val);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Delete a property on the VM
|
||
*
|
||
* @param {String} key
|
||
*/
|
||
|
||
Vue.prototype.$delete = function (key) {
|
||
del(this._data, key);
|
||
};
|
||
|
||
/**
|
||
* Watch an expression, trigger callback when its
|
||
* value changes.
|
||
*
|
||
* @param {String|Function} expOrFn
|
||
* @param {Function} cb
|
||
* @param {Object} [options]
|
||
* - {Boolean} deep
|
||
* - {Boolean} immediate
|
||
* @return {Function} - unwatchFn
|
||
*/
|
||
|
||
Vue.prototype.$watch = function (expOrFn, cb, options) {
|
||
var vm = this;
|
||
var parsed;
|
||
if (typeof expOrFn === 'string') {
|
||
parsed = parseDirective(expOrFn);
|
||
expOrFn = parsed.expression;
|
||
}
|
||
var watcher = new Watcher(vm, expOrFn, cb, {
|
||
deep: options && options.deep,
|
||
sync: options && options.sync,
|
||
filters: parsed && parsed.filters,
|
||
user: !options || options.user !== false
|
||
});
|
||
if (options && options.immediate) {
|
||
cb.call(vm, watcher.value);
|
||
}
|
||
return function unwatchFn() {
|
||
watcher.teardown();
|
||
};
|
||
};
|
||
|
||
/**
|
||
* Evaluate a text directive, including filters.
|
||
*
|
||
* @param {String} text
|
||
* @param {Boolean} [asStatement]
|
||
* @return {String}
|
||
*/
|
||
|
||
Vue.prototype.$eval = function (text, asStatement) {
|
||
// check for filters.
|
||
if (filterRE$1.test(text)) {
|
||
var dir = parseDirective(text);
|
||
// the filter regex check might give false positive
|
||
// for pipes inside strings, so it's possible that
|
||
// we don't get any filters here
|
||
var val = this.$get(dir.expression, asStatement);
|
||
return dir.filters ? this._applyFilters(val, null, dir.filters) : val;
|
||
} else {
|
||
// no filter
|
||
return this.$get(text, asStatement);
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Interpolate a piece of template text.
|
||
*
|
||
* @param {String} text
|
||
* @return {String}
|
||
*/
|
||
|
||
Vue.prototype.$interpolate = function (text) {
|
||
var tokens = parseText(text);
|
||
var vm = this;
|
||
if (tokens) {
|
||
if (tokens.length === 1) {
|
||
return vm.$eval(tokens[0].value) + '';
|
||
} else {
|
||
return tokens.map(function (token) {
|
||
return token.tag ? vm.$eval(token.value) : token.value;
|
||
}).join('');
|
||
}
|
||
} else {
|
||
return text;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Log instance data as a plain JS object
|
||
* so that it is easier to inspect in console.
|
||
* This method assumes console is available.
|
||
*
|
||
* @param {String} [path]
|
||
*/
|
||
|
||
Vue.prototype.$log = function (path) {
|
||
var data = path ? getPath(this._data, path) : this._data;
|
||
if (data) {
|
||
data = clean(data);
|
||
}
|
||
// include computed fields
|
||
if (!path) {
|
||
for (var key in this.$options.computed) {
|
||
data[key] = clean(this[key]);
|
||
}
|
||
}
|
||
console.log(data);
|
||
};
|
||
|
||
/**
|
||
* "clean" a getter/setter converted object into a plain
|
||
* object copy.
|
||
*
|
||
* @param {Object} - obj
|
||
* @return {Object}
|
||
*/
|
||
|
||
function clean(obj) {
|
||
return JSON.parse(JSON.stringify(obj));
|
||
}
|
||
}
|
||
|
||
function domAPI (Vue) {
|
||
/**
|
||
* Convenience on-instance nextTick. The callback is
|
||
* auto-bound to the instance, and this avoids component
|
||
* modules having to rely on the global Vue.
|
||
*
|
||
* @param {Function} fn
|
||
*/
|
||
|
||
Vue.prototype.$nextTick = function (fn) {
|
||
nextTick(fn, this);
|
||
};
|
||
|
||
/**
|
||
* Append instance to target
|
||
*
|
||
* @param {Node} target
|
||
* @param {Function} [cb]
|
||
* @param {Boolean} [withTransition] - defaults to true
|
||
*/
|
||
|
||
Vue.prototype.$appendTo = function (target, cb, withTransition) {
|
||
return insert(this, target, cb, withTransition, append, appendWithTransition);
|
||
};
|
||
|
||
/**
|
||
* Prepend instance to target
|
||
*
|
||
* @param {Node} target
|
||
* @param {Function} [cb]
|
||
* @param {Boolean} [withTransition] - defaults to true
|
||
*/
|
||
|
||
Vue.prototype.$prependTo = function (target, cb, withTransition) {
|
||
target = query(target);
|
||
if (target.hasChildNodes()) {
|
||
this.$before(target.firstChild, cb, withTransition);
|
||
} else {
|
||
this.$appendTo(target, cb, withTransition);
|
||
}
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Insert instance before target
|
||
*
|
||
* @param {Node} target
|
||
* @param {Function} [cb]
|
||
* @param {Boolean} [withTransition] - defaults to true
|
||
*/
|
||
|
||
Vue.prototype.$before = function (target, cb, withTransition) {
|
||
return insert(this, target, cb, withTransition, beforeWithCb, beforeWithTransition);
|
||
};
|
||
|
||
/**
|
||
* Insert instance after target
|
||
*
|
||
* @param {Node} target
|
||
* @param {Function} [cb]
|
||
* @param {Boolean} [withTransition] - defaults to true
|
||
*/
|
||
|
||
Vue.prototype.$after = function (target, cb, withTransition) {
|
||
target = query(target);
|
||
if (target.nextSibling) {
|
||
this.$before(target.nextSibling, cb, withTransition);
|
||
} else {
|
||
this.$appendTo(target.parentNode, cb, withTransition);
|
||
}
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Remove instance from DOM
|
||
*
|
||
* @param {Function} [cb]
|
||
* @param {Boolean} [withTransition] - defaults to true
|
||
*/
|
||
|
||
Vue.prototype.$remove = function (cb, withTransition) {
|
||
if (!this.$el.parentNode) {
|
||
return cb && cb();
|
||
}
|
||
var inDocument = this._isAttached && inDoc(this.$el);
|
||
// if we are not in document, no need to check
|
||
// for transitions
|
||
if (!inDocument) withTransition = false;
|
||
var self = this;
|
||
var realCb = function realCb() {
|
||
if (inDocument) self._callHook('detached');
|
||
if (cb) cb();
|
||
};
|
||
if (this._isFragment) {
|
||
removeNodeRange(this._fragmentStart, this._fragmentEnd, this, this._fragment, realCb);
|
||
} else {
|
||
var op = withTransition === false ? removeWithCb : removeWithTransition;
|
||
op(this.$el, this, realCb);
|
||
}
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Shared DOM insertion function.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {Element} target
|
||
* @param {Function} [cb]
|
||
* @param {Boolean} [withTransition]
|
||
* @param {Function} op1 - op for non-transition insert
|
||
* @param {Function} op2 - op for transition insert
|
||
* @return vm
|
||
*/
|
||
|
||
function insert(vm, target, cb, withTransition, op1, op2) {
|
||
target = query(target);
|
||
var targetIsDetached = !inDoc(target);
|
||
var op = withTransition === false || targetIsDetached ? op1 : op2;
|
||
var shouldCallHook = !targetIsDetached && !vm._isAttached && !inDoc(vm.$el);
|
||
if (vm._isFragment) {
|
||
mapNodeRange(vm._fragmentStart, vm._fragmentEnd, function (node) {
|
||
op(node, target, vm);
|
||
});
|
||
cb && cb();
|
||
} else {
|
||
op(vm.$el, target, vm, cb);
|
||
}
|
||
if (shouldCallHook) {
|
||
vm._callHook('attached');
|
||
}
|
||
return vm;
|
||
}
|
||
|
||
/**
|
||
* Check for selectors
|
||
*
|
||
* @param {String|Element} el
|
||
*/
|
||
|
||
function query(el) {
|
||
return typeof el === 'string' ? document.querySelector(el) : el;
|
||
}
|
||
|
||
/**
|
||
* Append operation that takes a callback.
|
||
*
|
||
* @param {Node} el
|
||
* @param {Node} target
|
||
* @param {Vue} vm - unused
|
||
* @param {Function} [cb]
|
||
*/
|
||
|
||
function append(el, target, vm, cb) {
|
||
target.appendChild(el);
|
||
if (cb) cb();
|
||
}
|
||
|
||
/**
|
||
* InsertBefore operation that takes a callback.
|
||
*
|
||
* @param {Node} el
|
||
* @param {Node} target
|
||
* @param {Vue} vm - unused
|
||
* @param {Function} [cb]
|
||
*/
|
||
|
||
function beforeWithCb(el, target, vm, cb) {
|
||
before(el, target);
|
||
if (cb) cb();
|
||
}
|
||
|
||
/**
|
||
* Remove operation that takes a callback.
|
||
*
|
||
* @param {Node} el
|
||
* @param {Vue} vm - unused
|
||
* @param {Function} [cb]
|
||
*/
|
||
|
||
function removeWithCb(el, vm, cb) {
|
||
remove(el);
|
||
if (cb) cb();
|
||
}
|
||
}
|
||
|
||
function eventsAPI (Vue) {
|
||
/**
|
||
* Listen on the given `event` with `fn`.
|
||
*
|
||
* @param {String} event
|
||
* @param {Function} fn
|
||
*/
|
||
|
||
Vue.prototype.$on = function (event, fn) {
|
||
(this._events[event] || (this._events[event] = [])).push(fn);
|
||
modifyListenerCount(this, event, 1);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Adds an `event` listener that will be invoked a single
|
||
* time then automatically removed.
|
||
*
|
||
* @param {String} event
|
||
* @param {Function} fn
|
||
*/
|
||
|
||
Vue.prototype.$once = function (event, fn) {
|
||
var self = this;
|
||
function on() {
|
||
self.$off(event, on);
|
||
fn.apply(this, arguments);
|
||
}
|
||
on.fn = fn;
|
||
this.$on(event, on);
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Remove the given callback for `event` or all
|
||
* registered callbacks.
|
||
*
|
||
* @param {String} event
|
||
* @param {Function} fn
|
||
*/
|
||
|
||
Vue.prototype.$off = function (event, fn) {
|
||
var cbs;
|
||
// all
|
||
if (!arguments.length) {
|
||
if (this.$parent) {
|
||
for (event in this._events) {
|
||
cbs = this._events[event];
|
||
if (cbs) {
|
||
modifyListenerCount(this, event, -cbs.length);
|
||
}
|
||
}
|
||
}
|
||
this._events = {};
|
||
return this;
|
||
}
|
||
// specific event
|
||
cbs = this._events[event];
|
||
if (!cbs) {
|
||
return this;
|
||
}
|
||
if (arguments.length === 1) {
|
||
modifyListenerCount(this, event, -cbs.length);
|
||
this._events[event] = null;
|
||
return this;
|
||
}
|
||
// specific handler
|
||
var cb;
|
||
var i = cbs.length;
|
||
while (i--) {
|
||
cb = cbs[i];
|
||
if (cb === fn || cb.fn === fn) {
|
||
modifyListenerCount(this, event, -1);
|
||
cbs.splice(i, 1);
|
||
break;
|
||
}
|
||
}
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Trigger an event on self.
|
||
*
|
||
* @param {String|Object} event
|
||
* @return {Boolean} shouldPropagate
|
||
*/
|
||
|
||
Vue.prototype.$emit = function (event) {
|
||
var isSource = typeof event === 'string';
|
||
event = isSource ? event : event.name;
|
||
var cbs = this._events[event];
|
||
var shouldPropagate = isSource || !cbs;
|
||
if (cbs) {
|
||
cbs = cbs.length > 1 ? toArray(cbs) : cbs;
|
||
// this is a somewhat hacky solution to the question raised
|
||
// in #2102: for an inline component listener like <comp @test="doThis">,
|
||
// the propagation handling is somewhat broken. Therefore we
|
||
// need to treat these inline callbacks differently.
|
||
var hasParentCbs = isSource && cbs.some(function (cb) {
|
||
return cb._fromParent;
|
||
});
|
||
if (hasParentCbs) {
|
||
shouldPropagate = false;
|
||
}
|
||
var args = toArray(arguments, 1);
|
||
for (var i = 0, l = cbs.length; i < l; i++) {
|
||
var cb = cbs[i];
|
||
var res = cb.apply(this, args);
|
||
if (res === true && (!hasParentCbs || cb._fromParent)) {
|
||
shouldPropagate = true;
|
||
}
|
||
}
|
||
}
|
||
return shouldPropagate;
|
||
};
|
||
|
||
/**
|
||
* Recursively broadcast an event to all children instances.
|
||
*
|
||
* @param {String|Object} event
|
||
* @param {...*} additional arguments
|
||
*/
|
||
|
||
Vue.prototype.$broadcast = function (event) {
|
||
var isSource = typeof event === 'string';
|
||
event = isSource ? event : event.name;
|
||
// if no child has registered for this event,
|
||
// then there's no need to broadcast.
|
||
if (!this._eventsCount[event]) return;
|
||
var children = this.$children;
|
||
var args = toArray(arguments);
|
||
if (isSource) {
|
||
// use object event to indicate non-source emit
|
||
// on children
|
||
args[0] = { name: event, source: this };
|
||
}
|
||
for (var i = 0, l = children.length; i < l; i++) {
|
||
var child = children[i];
|
||
var shouldPropagate = child.$emit.apply(child, args);
|
||
if (shouldPropagate) {
|
||
child.$broadcast.apply(child, args);
|
||
}
|
||
}
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Recursively propagate an event up the parent chain.
|
||
*
|
||
* @param {String} event
|
||
* @param {...*} additional arguments
|
||
*/
|
||
|
||
Vue.prototype.$dispatch = function (event) {
|
||
var shouldPropagate = this.$emit.apply(this, arguments);
|
||
if (!shouldPropagate) return;
|
||
var parent = this.$parent;
|
||
var args = toArray(arguments);
|
||
// use object event to indicate non-source emit
|
||
// on parents
|
||
args[0] = { name: event, source: this };
|
||
while (parent) {
|
||
shouldPropagate = parent.$emit.apply(parent, args);
|
||
parent = shouldPropagate ? parent.$parent : null;
|
||
}
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Modify the listener counts on all parents.
|
||
* This bookkeeping allows $broadcast to return early when
|
||
* no child has listened to a certain event.
|
||
*
|
||
* @param {Vue} vm
|
||
* @param {String} event
|
||
* @param {Number} count
|
||
*/
|
||
|
||
var hookRE = /^hook:/;
|
||
function modifyListenerCount(vm, event, count) {
|
||
var parent = vm.$parent;
|
||
// hooks do not get broadcasted so no need
|
||
// to do bookkeeping for them
|
||
if (!parent || !count || hookRE.test(event)) return;
|
||
while (parent) {
|
||
parent._eventsCount[event] = (parent._eventsCount[event] || 0) + count;
|
||
parent = parent.$parent;
|
||
}
|
||
}
|
||
}
|
||
|
||
function lifecycleAPI (Vue) {
|
||
/**
|
||
* Set instance target element and kick off the compilation
|
||
* process. The passed in `el` can be a selector string, an
|
||
* existing Element, or a DocumentFragment (for block
|
||
* instances).
|
||
*
|
||
* @param {Element|DocumentFragment|string} el
|
||
* @public
|
||
*/
|
||
|
||
Vue.prototype.$mount = function (el) {
|
||
if (this._isCompiled) {
|
||
process.env.NODE_ENV !== 'production' && warn('$mount() should be called only once.');
|
||
return;
|
||
}
|
||
el = query(el);
|
||
if (!el) {
|
||
el = document.createElement('div');
|
||
}
|
||
this._compile(el);
|
||
this._initDOMHooks();
|
||
if (inDoc(this.$el)) {
|
||
this._callHook('attached');
|
||
ready.call(this);
|
||
} else {
|
||
this.$once('hook:attached', ready);
|
||
}
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Mark an instance as ready.
|
||
*/
|
||
|
||
function ready() {
|
||
this._isAttached = true;
|
||
this._isReady = true;
|
||
this._callHook('ready');
|
||
}
|
||
|
||
/**
|
||
* Teardown the instance, simply delegate to the internal
|
||
* _destroy.
|
||
*/
|
||
|
||
Vue.prototype.$destroy = function (remove, deferCleanup) {
|
||
this._destroy(remove, deferCleanup);
|
||
};
|
||
|
||
/**
|
||
* Partially compile a piece of DOM and return a
|
||
* decompile function.
|
||
*
|
||
* @param {Element|DocumentFragment} el
|
||
* @param {Vue} [host]
|
||
* @return {Function}
|
||
*/
|
||
|
||
Vue.prototype.$compile = function (el, host, scope, frag) {
|
||
return compile(el, this.$options, true)(this, el, host, scope, frag);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* The exposed Vue constructor.
|
||
*
|
||
* API conventions:
|
||
* - public API methods/properties are prefixed with `$`
|
||
* - internal methods/properties are prefixed with `_`
|
||
* - non-prefixed properties are assumed to be proxied user
|
||
* data.
|
||
*
|
||
* @constructor
|
||
* @param {Object} [options]
|
||
* @public
|
||
*/
|
||
|
||
function Vue(options) {
|
||
this._init(options);
|
||
}
|
||
|
||
// install internals
|
||
initMixin(Vue);
|
||
stateMixin(Vue);
|
||
eventsMixin(Vue);
|
||
lifecycleMixin(Vue);
|
||
miscMixin(Vue);
|
||
|
||
// install instance APIs
|
||
dataAPI(Vue);
|
||
domAPI(Vue);
|
||
eventsAPI(Vue);
|
||
lifecycleAPI(Vue);
|
||
|
||
var slot = {
|
||
|
||
priority: SLOT,
|
||
params: ['name'],
|
||
|
||
bind: function bind() {
|
||
// this was resolved during component transclusion
|
||
var name = this.params.name || 'default';
|
||
var content = this.vm._slotContents && this.vm._slotContents[name];
|
||
if (!content || !content.hasChildNodes()) {
|
||
this.fallback();
|
||
} else {
|
||
this.compile(content.cloneNode(true), this.vm._context, this.vm);
|
||
}
|
||
},
|
||
|
||
compile: function compile(content, context, host) {
|
||
if (content && context) {
|
||
if (this.el.hasChildNodes() && content.childNodes.length === 1 && content.childNodes[0].nodeType === 1 && content.childNodes[0].hasAttribute('v-if')) {
|
||
// if the inserted slot has v-if
|
||
// inject fallback content as the v-else
|
||
var elseBlock = document.createElement('template');
|
||
elseBlock.setAttribute('v-else', '');
|
||
elseBlock.innerHTML = this.el.innerHTML;
|
||
// the else block should be compiled in child scope
|
||
elseBlock._context = this.vm;
|
||
content.appendChild(elseBlock);
|
||
}
|
||
var scope = host ? host._scope : this._scope;
|
||
this.unlink = context.$compile(content, host, scope, this._frag);
|
||
}
|
||
if (content) {
|
||
replace(this.el, content);
|
||
} else {
|
||
remove(this.el);
|
||
}
|
||
},
|
||
|
||
fallback: function fallback() {
|
||
this.compile(extractContent(this.el, true), this.vm);
|
||
},
|
||
|
||
unbind: function unbind() {
|
||
if (this.unlink) {
|
||
this.unlink();
|
||
}
|
||
}
|
||
};
|
||
|
||
var partial = {
|
||
|
||
priority: PARTIAL,
|
||
|
||
params: ['name'],
|
||
|
||
// watch changes to name for dynamic partials
|
||
paramWatchers: {
|
||
name: function name(value) {
|
||
vIf.remove.call(this);
|
||
if (value) {
|
||
this.insert(value);
|
||
}
|
||
}
|
||
},
|
||
|
||
bind: function bind() {
|
||
this.anchor = createAnchor('v-partial');
|
||
replace(this.el, this.anchor);
|
||
this.insert(this.params.name);
|
||
},
|
||
|
||
insert: function insert(id) {
|
||
var partial = resolveAsset(this.vm.$options, 'partials', id);
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
assertAsset(partial, 'partial', id);
|
||
}
|
||
if (partial) {
|
||
this.factory = new FragmentFactory(this.vm, partial);
|
||
vIf.insert.call(this);
|
||
}
|
||
},
|
||
|
||
unbind: function unbind() {
|
||
if (this.frag) {
|
||
this.frag.destroy();
|
||
}
|
||
}
|
||
};
|
||
|
||
var elementDirectives = {
|
||
slot: slot,
|
||
partial: partial
|
||
};
|
||
|
||
var convertArray = vFor._postProcess;
|
||
|
||
/**
|
||
* Limit filter for arrays
|
||
*
|
||
* @param {Number} n
|
||
* @param {Number} offset (Decimal expected)
|
||
*/
|
||
|
||
function limitBy(arr, n, offset) {
|
||
offset = offset ? parseInt(offset, 10) : 0;
|
||
n = toNumber(n);
|
||
return typeof n === 'number' ? arr.slice(offset, offset + n) : arr;
|
||
}
|
||
|
||
/**
|
||
* Filter filter for arrays
|
||
*
|
||
* @param {String} search
|
||
* @param {String} [delimiter]
|
||
* @param {String} ...dataKeys
|
||
*/
|
||
|
||
function filterBy(arr, search, delimiter) {
|
||
arr = convertArray(arr);
|
||
if (search == null) {
|
||
return arr;
|
||
}
|
||
if (typeof search === 'function') {
|
||
return arr.filter(search);
|
||
}
|
||
// cast to lowercase string
|
||
search = ('' + search).toLowerCase();
|
||
// allow optional `in` delimiter
|
||
// because why not
|
||
var n = delimiter === 'in' ? 3 : 2;
|
||
// extract and flatten keys
|
||
var keys = toArray(arguments, n).reduce(function (prev, cur) {
|
||
return prev.concat(cur);
|
||
}, []);
|
||
var res = [];
|
||
var item, key, val, j;
|
||
for (var i = 0, l = arr.length; i < l; i++) {
|
||
item = arr[i];
|
||
val = item && item.$value || item;
|
||
j = keys.length;
|
||
if (j) {
|
||
while (j--) {
|
||
key = keys[j];
|
||
if (key === '$key' && contains$1(item.$key, search) || contains$1(getPath(val, key), search)) {
|
||
res.push(item);
|
||
break;
|
||
}
|
||
}
|
||
} else if (contains$1(item, search)) {
|
||
res.push(item);
|
||
}
|
||
}
|
||
return res;
|
||
}
|
||
|
||
/**
|
||
* Filter filter for arrays
|
||
*
|
||
* @param {String} sortKey
|
||
* @param {String} reverse
|
||
*/
|
||
|
||
function orderBy(arr, sortKey, reverse) {
|
||
arr = convertArray(arr);
|
||
if (!sortKey) {
|
||
return arr;
|
||
}
|
||
var order = reverse && reverse < 0 ? -1 : 1;
|
||
// sort on a copy to avoid mutating original array
|
||
return arr.slice().sort(function (a, b) {
|
||
if (sortKey !== '$key') {
|
||
if (isObject(a) && '$value' in a) a = a.$value;
|
||
if (isObject(b) && '$value' in b) b = b.$value;
|
||
}
|
||
a = isObject(a) ? getPath(a, sortKey) : a;
|
||
b = isObject(b) ? getPath(b, sortKey) : b;
|
||
return a === b ? 0 : a > b ? order : -order;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* String contain helper
|
||
*
|
||
* @param {*} val
|
||
* @param {String} search
|
||
*/
|
||
|
||
function contains$1(val, search) {
|
||
var i;
|
||
if (isPlainObject(val)) {
|
||
var keys = Object.keys(val);
|
||
i = keys.length;
|
||
while (i--) {
|
||
if (contains$1(val[keys[i]], search)) {
|
||
return true;
|
||
}
|
||
}
|
||
} else if (isArray(val)) {
|
||
i = val.length;
|
||
while (i--) {
|
||
if (contains$1(val[i], search)) {
|
||
return true;
|
||
}
|
||
}
|
||
} else if (val != null) {
|
||
return val.toString().toLowerCase().indexOf(search) > -1;
|
||
}
|
||
}
|
||
|
||
var digitsRE = /(\d{3})(?=\d)/g;
|
||
|
||
// asset collections must be a plain object.
|
||
var filters = {
|
||
|
||
orderBy: orderBy,
|
||
filterBy: filterBy,
|
||
limitBy: limitBy,
|
||
|
||
/**
|
||
* Stringify value.
|
||
*
|
||
* @param {Number} indent
|
||
*/
|
||
|
||
json: {
|
||
read: function read(value, indent) {
|
||
return typeof value === 'string' ? value : JSON.stringify(value, null, Number(indent) || 2);
|
||
},
|
||
write: function write(value) {
|
||
try {
|
||
return JSON.parse(value);
|
||
} catch (e) {
|
||
return value;
|
||
}
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 'abc' => 'Abc'
|
||
*/
|
||
|
||
capitalize: function capitalize(value) {
|
||
if (!value && value !== 0) return '';
|
||
value = value.toString();
|
||
return value.charAt(0).toUpperCase() + value.slice(1);
|
||
},
|
||
|
||
/**
|
||
* 'abc' => 'ABC'
|
||
*/
|
||
|
||
uppercase: function uppercase(value) {
|
||
return value || value === 0 ? value.toString().toUpperCase() : '';
|
||
},
|
||
|
||
/**
|
||
* 'AbC' => 'abc'
|
||
*/
|
||
|
||
lowercase: function lowercase(value) {
|
||
return value || value === 0 ? value.toString().toLowerCase() : '';
|
||
},
|
||
|
||
/**
|
||
* 12345 => $12,345.00
|
||
*
|
||
* @param {String} sign
|
||
*/
|
||
|
||
currency: function currency(value, _currency) {
|
||
value = parseFloat(value);
|
||
if (!isFinite(value) || !value && value !== 0) return '';
|
||
_currency = _currency != null ? _currency : '$';
|
||
var stringified = Math.abs(value).toFixed(2);
|
||
var _int = stringified.slice(0, -3);
|
||
var i = _int.length % 3;
|
||
var head = i > 0 ? _int.slice(0, i) + (_int.length > 3 ? ',' : '') : '';
|
||
var _float = stringified.slice(-3);
|
||
var sign = value < 0 ? '-' : '';
|
||
return sign + _currency + head + _int.slice(i).replace(digitsRE, '$1,') + _float;
|
||
},
|
||
|
||
/**
|
||
* 'item' => 'items'
|
||
*
|
||
* @params
|
||
* an array of strings corresponding to
|
||
* the single, double, triple ... forms of the word to
|
||
* be pluralized. When the number to be pluralized
|
||
* exceeds the length of the args, it will use the last
|
||
* entry in the array.
|
||
*
|
||
* e.g. ['single', 'double', 'triple', 'multiple']
|
||
*/
|
||
|
||
pluralize: function pluralize(value) {
|
||
var args = toArray(arguments, 1);
|
||
return args.length > 1 ? args[value % 10 - 1] || args[args.length - 1] : args[0] + (value === 1 ? '' : 's');
|
||
},
|
||
|
||
/**
|
||
* Debounce a handler function.
|
||
*
|
||
* @param {Function} handler
|
||
* @param {Number} delay = 300
|
||
* @return {Function}
|
||
*/
|
||
|
||
debounce: function debounce(handler, delay) {
|
||
if (!handler) return;
|
||
if (!delay) {
|
||
delay = 300;
|
||
}
|
||
return _debounce(handler, delay);
|
||
}
|
||
};
|
||
|
||
function installGlobalAPI (Vue) {
|
||
/**
|
||
* Vue and every constructor that extends Vue has an
|
||
* associated options object, which can be accessed during
|
||
* compilation steps as `this.constructor.options`.
|
||
*
|
||
* These can be seen as the default options of every
|
||
* Vue instance.
|
||
*/
|
||
|
||
Vue.options = {
|
||
directives: directives,
|
||
elementDirectives: elementDirectives,
|
||
filters: filters,
|
||
transitions: {},
|
||
components: {},
|
||
partials: {},
|
||
replace: true
|
||
};
|
||
|
||
/**
|
||
* Expose useful internals
|
||
*/
|
||
|
||
Vue.util = util;
|
||
Vue.config = config;
|
||
Vue.set = set;
|
||
Vue['delete'] = del;
|
||
Vue.nextTick = nextTick;
|
||
|
||
/**
|
||
* The following are exposed for advanced usage / plugins
|
||
*/
|
||
|
||
Vue.compiler = compiler;
|
||
Vue.FragmentFactory = FragmentFactory;
|
||
Vue.internalDirectives = internalDirectives;
|
||
Vue.parsers = {
|
||
path: path,
|
||
text: text,
|
||
template: template,
|
||
directive: directive,
|
||
expression: expression
|
||
};
|
||
|
||
/**
|
||
* Each instance constructor, including Vue, has a unique
|
||
* cid. This enables us to create wrapped "child
|
||
* constructors" for prototypal inheritance and cache them.
|
||
*/
|
||
|
||
Vue.cid = 0;
|
||
var cid = 1;
|
||
|
||
/**
|
||
* Class inheritance
|
||
*
|
||
* @param {Object} extendOptions
|
||
*/
|
||
|
||
Vue.extend = function (extendOptions) {
|
||
extendOptions = extendOptions || {};
|
||
var Super = this;
|
||
var isFirstExtend = Super.cid === 0;
|
||
if (isFirstExtend && extendOptions._Ctor) {
|
||
return extendOptions._Ctor;
|
||
}
|
||
var name = extendOptions.name || Super.options.name;
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
if (!/^[a-zA-Z][\w-]*$/.test(name)) {
|
||
warn('Invalid component name: "' + name + '". Component names ' + 'can only contain alphanumeric characaters and the hyphen.');
|
||
name = null;
|
||
}
|
||
}
|
||
var Sub = createClass(name || 'VueComponent');
|
||
Sub.prototype = Object.create(Super.prototype);
|
||
Sub.prototype.constructor = Sub;
|
||
Sub.cid = cid++;
|
||
Sub.options = mergeOptions(Super.options, extendOptions);
|
||
Sub['super'] = Super;
|
||
// allow further extension
|
||
Sub.extend = Super.extend;
|
||
// create asset registers, so extended classes
|
||
// can have their private assets too.
|
||
config._assetTypes.forEach(function (type) {
|
||
Sub[type] = Super[type];
|
||
});
|
||
// enable recursive self-lookup
|
||
if (name) {
|
||
Sub.options.components[name] = Sub;
|
||
}
|
||
// cache constructor
|
||
if (isFirstExtend) {
|
||
extendOptions._Ctor = Sub;
|
||
}
|
||
return Sub;
|
||
};
|
||
|
||
/**
|
||
* A function that returns a sub-class constructor with the
|
||
* given name. This gives us much nicer output when
|
||
* logging instances in the console.
|
||
*
|
||
* @param {String} name
|
||
* @return {Function}
|
||
*/
|
||
|
||
function createClass(name) {
|
||
/* eslint-disable no-new-func */
|
||
return new Function('return function ' + classify(name) + ' (options) { this._init(options) }')();
|
||
/* eslint-enable no-new-func */
|
||
}
|
||
|
||
/**
|
||
* Plugin system
|
||
*
|
||
* @param {Object} plugin
|
||
*/
|
||
|
||
Vue.use = function (plugin) {
|
||
/* istanbul ignore if */
|
||
if (plugin.installed) {
|
||
return;
|
||
}
|
||
// additional parameters
|
||
var args = toArray(arguments, 1);
|
||
args.unshift(this);
|
||
if (typeof plugin.install === 'function') {
|
||
plugin.install.apply(plugin, args);
|
||
} else {
|
||
plugin.apply(null, args);
|
||
}
|
||
plugin.installed = true;
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Apply a global mixin by merging it into the default
|
||
* options.
|
||
*/
|
||
|
||
Vue.mixin = function (mixin) {
|
||
Vue.options = mergeOptions(Vue.options, mixin);
|
||
};
|
||
|
||
/**
|
||
* Create asset registration methods with the following
|
||
* signature:
|
||
*
|
||
* @param {String} id
|
||
* @param {*} definition
|
||
*/
|
||
|
||
config._assetTypes.forEach(function (type) {
|
||
Vue[type] = function (id, definition) {
|
||
if (!definition) {
|
||
return this.options[type + 's'][id];
|
||
} else {
|
||
/* istanbul ignore if */
|
||
if (process.env.NODE_ENV !== 'production') {
|
||
if (type === 'component' && (commonTagRE.test(id) || reservedTagRE.test(id))) {
|
||
warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + id);
|
||
}
|
||
}
|
||
if (type === 'component' && isPlainObject(definition)) {
|
||
definition.name = id;
|
||
definition = Vue.extend(definition);
|
||
}
|
||
this.options[type + 's'][id] = definition;
|
||
return definition;
|
||
}
|
||
};
|
||
});
|
||
|
||
// expose internal transition API
|
||
extend(Vue.transition, transition);
|
||
}
|
||
|
||
installGlobalAPI(Vue);
|
||
|
||
Vue.version = '1.0.17';
|
||
|
||
// devtools global hook
|
||
/* istanbul ignore next */
|
||
if (devtools) {
|
||
devtools.emit('init', Vue);
|
||
} else if (process.env.NODE_ENV !== 'production' && inBrowser && /Chrome\/\d+/.test(window.navigator.userAgent)) {
|
||
console.log('Download the Vue Devtools for a better development experience:\n' + 'https://github.com/vuejs/vue-devtools');
|
||
}
|
||
|
||
module.exports = Vue;
|
||
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"_process":137}],152:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/vueify-insert-css/index.js", module);
|
||
(function(){
|
||
var inserted = exports.cache = {}
|
||
|
||
exports.insert = function (css) {
|
||
if (inserted[css]) return
|
||
inserted[css] = true
|
||
|
||
var elem = document.createElement('style')
|
||
elem.setAttribute('type', 'text/css')
|
||
|
||
if ('textContent' in elem) {
|
||
elem.textContent = css
|
||
} else {
|
||
elem.styleSheet.cssText = css
|
||
}
|
||
|
||
document.getElementsByTagName('head')[0].appendChild(elem)
|
||
return elem
|
||
}
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],153:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/vuex/dist/vuex.js", module);
|
||
(function(){
|
||
/*!
|
||
* Vuex v0.6.2
|
||
* (c) 2016 Evan You
|
||
* Released under the MIT License.
|
||
*/
|
||
(function (global, factory) {
|
||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||
typeof define === 'function' && define.amd ? define(factory) :
|
||
(global.Vuex = factory());
|
||
}(this, function () { 'use strict';
|
||
|
||
var babelHelpers = {};
|
||
babelHelpers.typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
|
||
return typeof obj;
|
||
} : function (obj) {
|
||
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
||
};
|
||
|
||
babelHelpers.classCallCheck = function (instance, Constructor) {
|
||
if (!(instance instanceof Constructor)) {
|
||
throw new TypeError("Cannot call a class as a function");
|
||
}
|
||
};
|
||
|
||
babelHelpers.createClass = function () {
|
||
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);
|
||
}
|
||
}
|
||
|
||
return function (Constructor, protoProps, staticProps) {
|
||
if (protoProps) defineProperties(Constructor.prototype, protoProps);
|
||
if (staticProps) defineProperties(Constructor, staticProps);
|
||
return Constructor;
|
||
};
|
||
}();
|
||
|
||
babelHelpers.toConsumableArray = function (arr) {
|
||
if (Array.isArray(arr)) {
|
||
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
|
||
|
||
return arr2;
|
||
} else {
|
||
return Array.from(arr);
|
||
}
|
||
};
|
||
|
||
babelHelpers;
|
||
|
||
/**
|
||
* Merge an array of objects into one.
|
||
*
|
||
* @param {Array<Object>} arr
|
||
* @return {Object}
|
||
*/
|
||
|
||
function mergeObjects(arr) {
|
||
return arr.reduce(function (prev, obj) {
|
||
Object.keys(obj).forEach(function (key) {
|
||
var existing = prev[key];
|
||
if (existing) {
|
||
// allow multiple mutation objects to contain duplicate
|
||
// handlers for the same mutation type
|
||
if (Array.isArray(existing)) {
|
||
existing.push(obj[key]);
|
||
} else {
|
||
prev[key] = [prev[key], obj[key]];
|
||
}
|
||
} else {
|
||
prev[key] = obj[key];
|
||
}
|
||
});
|
||
return prev;
|
||
}, {});
|
||
}
|
||
|
||
/**
|
||
* Deep clone an object. Faster than JSON.parse(JSON.stringify()).
|
||
*
|
||
* @param {*} obj
|
||
* @return {*}
|
||
*/
|
||
|
||
function deepClone(obj) {
|
||
if (Array.isArray(obj)) {
|
||
return obj.map(deepClone);
|
||
} else if (obj && (typeof obj === 'undefined' ? 'undefined' : babelHelpers.typeof(obj)) === 'object') {
|
||
var cloned = {};
|
||
var keys = Object.keys(obj);
|
||
for (var i = 0, l = keys.length; i < l; i++) {
|
||
var key = keys[i];
|
||
cloned[key] = deepClone(obj[key]);
|
||
}
|
||
return cloned;
|
||
} else {
|
||
return obj;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Hacks to get access to Vue internals.
|
||
* Maybe we should expose these...
|
||
*/
|
||
|
||
var Watcher = void 0;
|
||
function getWatcher(vm) {
|
||
if (!Watcher) {
|
||
var unwatch = vm.$watch('__vuex__', function (a) {
|
||
return a;
|
||
});
|
||
Watcher = vm._watchers[0].constructor;
|
||
unwatch();
|
||
}
|
||
return Watcher;
|
||
}
|
||
|
||
var Dep = void 0;
|
||
function getDep(vm) {
|
||
if (!Dep) {
|
||
Dep = vm._data.__ob__.dep.constructor;
|
||
}
|
||
return Dep;
|
||
}
|
||
|
||
var hook = typeof window !== 'undefined' && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
|
||
|
||
var devtoolMiddleware = {
|
||
onInit: function onInit(state, store) {
|
||
if (!hook) return;
|
||
hook.emit('vuex:init', store);
|
||
hook.on('vuex:travel-to-state', function (targetState) {
|
||
var currentState = store._vm._data;
|
||
store._dispatching = true;
|
||
Object.keys(targetState).forEach(function (key) {
|
||
currentState[key] = targetState[key];
|
||
});
|
||
store._dispatching = false;
|
||
});
|
||
},
|
||
onMutation: function onMutation(mutation, state) {
|
||
if (!hook) return;
|
||
hook.emit('vuex:mutation', mutation, state);
|
||
}
|
||
};
|
||
|
||
function override (Vue) {
|
||
// override init and inject vuex init procedure
|
||
var _init = Vue.prototype._init;
|
||
Vue.prototype._init = function () {
|
||
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
||
|
||
options.init = options.init ? [vuexInit].concat(options.init) : vuexInit;
|
||
_init.call(this, options);
|
||
};
|
||
|
||
function vuexInit() {
|
||
var options = this.$options;
|
||
var store = options.store;
|
||
var vuex = options.vuex;
|
||
// store injection
|
||
|
||
if (store) {
|
||
this.$store = store;
|
||
} else if (options.parent && options.parent.$store) {
|
||
this.$store = options.parent.$store;
|
||
}
|
||
// vuex option handling
|
||
if (vuex) {
|
||
if (!this.$store) {
|
||
console.warn('[vuex] store not injected. make sure to ' + 'provide the store option in your root component.');
|
||
}
|
||
var state = vuex.state;
|
||
var getters = vuex.getters;
|
||
var actions = vuex.actions;
|
||
// handle deprecated state option
|
||
|
||
if (state && !getters) {
|
||
console.warn('[vuex] vuex.state option will been deprecated in 1.0. ' + 'Use vuex.getters instead.');
|
||
getters = state;
|
||
}
|
||
// getters
|
||
if (getters) {
|
||
options.computed = options.computed || {};
|
||
for (var key in getters) {
|
||
defineVuexGetter(this, key, getters[key]);
|
||
}
|
||
}
|
||
// actions
|
||
if (actions) {
|
||
options.methods = options.methods || {};
|
||
for (var _key in actions) {
|
||
options.methods[_key] = makeBoundAction(actions[_key], this.$store);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function setter() {
|
||
throw new Error('vuex getter properties are read-only.');
|
||
}
|
||
|
||
function defineVuexGetter(vm, key, getter) {
|
||
Object.defineProperty(vm, key, {
|
||
enumerable: true,
|
||
configurable: true,
|
||
get: makeComputedGetter(vm.$store, getter),
|
||
set: setter
|
||
});
|
||
}
|
||
|
||
function makeComputedGetter(store, getter) {
|
||
var id = store._getterCacheId;
|
||
// cached
|
||
if (getter[id]) {
|
||
return getter[id];
|
||
}
|
||
var vm = store._vm;
|
||
var Watcher = getWatcher(vm);
|
||
var Dep = getDep(vm);
|
||
var watcher = new Watcher(vm, function (state) {
|
||
return getter(state);
|
||
}, null, { lazy: true });
|
||
var computedGetter = function computedGetter() {
|
||
if (watcher.dirty) {
|
||
watcher.evaluate();
|
||
}
|
||
if (Dep.target) {
|
||
watcher.depend();
|
||
}
|
||
return watcher.value;
|
||
};
|
||
getter[id] = computedGetter;
|
||
return computedGetter;
|
||
}
|
||
|
||
function makeBoundAction(action, store) {
|
||
return function vuexBoundAction() {
|
||
for (var _len = arguments.length, args = Array(_len), _key2 = 0; _key2 < _len; _key2++) {
|
||
args[_key2] = arguments[_key2];
|
||
}
|
||
|
||
return action.call.apply(action, [this, store].concat(args));
|
||
};
|
||
}
|
||
|
||
// option merging
|
||
var merge = Vue.config.optionMergeStrategies.computed;
|
||
Vue.config.optionMergeStrategies.vuex = function (toVal, fromVal) {
|
||
if (!toVal) return fromVal;
|
||
if (!fromVal) return toVal;
|
||
return {
|
||
getters: merge(toVal.getters, fromVal.getters),
|
||
state: merge(toVal.state, fromVal.state),
|
||
actions: merge(toVal.actions, fromVal.actions)
|
||
};
|
||
};
|
||
}
|
||
|
||
var Vue = void 0;
|
||
var uid = 0;
|
||
|
||
var Store = function () {
|
||
|
||
/**
|
||
* @param {Object} options
|
||
* - {Object} state
|
||
* - {Object} actions
|
||
* - {Object} mutations
|
||
* - {Array} middlewares
|
||
* - {Boolean} strict
|
||
*/
|
||
|
||
function Store() {
|
||
var _this = this;
|
||
|
||
var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
||
|
||
var _ref$state = _ref.state;
|
||
var state = _ref$state === undefined ? {} : _ref$state;
|
||
var _ref$mutations = _ref.mutations;
|
||
var mutations = _ref$mutations === undefined ? {} : _ref$mutations;
|
||
var _ref$modules = _ref.modules;
|
||
var modules = _ref$modules === undefined ? {} : _ref$modules;
|
||
var _ref$middlewares = _ref.middlewares;
|
||
var middlewares = _ref$middlewares === undefined ? [] : _ref$middlewares;
|
||
var _ref$strict = _ref.strict;
|
||
var strict = _ref$strict === undefined ? false : _ref$strict;
|
||
babelHelpers.classCallCheck(this, Store);
|
||
|
||
this._getterCacheId = 'vuex_store_' + uid++;
|
||
this._dispatching = false;
|
||
this._rootMutations = this._mutations = mutations;
|
||
this._modules = modules;
|
||
// bind dispatch to self
|
||
var dispatch = this.dispatch;
|
||
this.dispatch = function () {
|
||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
||
args[_key] = arguments[_key];
|
||
}
|
||
|
||
dispatch.apply(_this, args);
|
||
};
|
||
// use a Vue instance to store the state tree
|
||
// suppress warnings just in case the user has added
|
||
// some funky global mixins
|
||
if (!Vue) {
|
||
throw new Error('[vuex] must call Vue.use(Vuex) before creating a store instance.');
|
||
}
|
||
var silent = Vue.config.silent;
|
||
Vue.config.silent = true;
|
||
this._vm = new Vue({
|
||
data: state
|
||
});
|
||
Vue.config.silent = silent;
|
||
this._setupModuleState(state, modules);
|
||
this._setupModuleMutations(modules);
|
||
this._setupMiddlewares(middlewares, state);
|
||
// add extra warnings in strict mode
|
||
if (strict) {
|
||
this._setupMutationCheck();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Getter for the entire state tree.
|
||
* Read only.
|
||
*
|
||
* @return {Object}
|
||
*/
|
||
|
||
babelHelpers.createClass(Store, [{
|
||
key: 'dispatch',
|
||
|
||
|
||
/**
|
||
* Dispatch an action.
|
||
*
|
||
* @param {String} type
|
||
*/
|
||
|
||
value: function dispatch(type) {
|
||
var _this2 = this;
|
||
|
||
for (var _len2 = arguments.length, payload = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
||
payload[_key2 - 1] = arguments[_key2];
|
||
}
|
||
|
||
// compatibility for object actions, e.g. FSA
|
||
if ((typeof type === 'undefined' ? 'undefined' : babelHelpers.typeof(type)) === 'object' && type.type && arguments.length === 1) {
|
||
payload = [type];
|
||
type = type.type;
|
||
}
|
||
var mutation = this._mutations[type];
|
||
var prevSnapshot = this._prevSnapshot;
|
||
var state = this.state;
|
||
var snapshot = void 0,
|
||
clonedPayload = void 0;
|
||
if (mutation) {
|
||
this._dispatching = true;
|
||
// apply the mutation
|
||
if (Array.isArray(mutation)) {
|
||
mutation.forEach(function (m) {
|
||
return m.apply(undefined, [state].concat(babelHelpers.toConsumableArray(payload)));
|
||
});
|
||
} else {
|
||
mutation.apply(undefined, [state].concat(babelHelpers.toConsumableArray(payload)));
|
||
}
|
||
this._dispatching = false;
|
||
// invoke middlewares
|
||
if (this._needSnapshots) {
|
||
snapshot = this._prevSnapshot = deepClone(state);
|
||
clonedPayload = deepClone(payload);
|
||
}
|
||
this._middlewares.forEach(function (m) {
|
||
if (m.onMutation) {
|
||
if (m.snapshot) {
|
||
m.onMutation({ type: type, payload: clonedPayload }, snapshot, prevSnapshot, _this2);
|
||
} else {
|
||
m.onMutation({ type: type, payload: payload }, state, _this2);
|
||
}
|
||
}
|
||
});
|
||
} else {
|
||
console.warn('[vuex] Unknown mutation: ' + type);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Watch state changes on the store.
|
||
* Same API as Vue's $watch, except when watching a function,
|
||
* the function gets the state as the first argument.
|
||
*
|
||
* @param {String|Function} expOrFn
|
||
* @param {Function} cb
|
||
* @param {Object} [options]
|
||
*/
|
||
|
||
}, {
|
||
key: 'watch',
|
||
value: function watch(expOrFn, cb, options) {
|
||
var _this3 = this;
|
||
|
||
return this._vm.$watch(function () {
|
||
return typeof expOrFn === 'function' ? expOrFn(_this3.state) : _this3._vm.$get(expOrFn);
|
||
}, cb, options);
|
||
}
|
||
|
||
/**
|
||
* Hot update mutations & modules.
|
||
*
|
||
* @param {Object} options
|
||
* - {Object} [mutations]
|
||
* - {Object} [modules]
|
||
*/
|
||
|
||
}, {
|
||
key: 'hotUpdate',
|
||
value: function hotUpdate() {
|
||
var _ref2 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
||
|
||
var mutations = _ref2.mutations;
|
||
var modules = _ref2.modules;
|
||
|
||
this._rootMutations = this._mutations = mutations || this._rootMutations;
|
||
this._setupModuleMutations(modules || this._modules);
|
||
}
|
||
|
||
/**
|
||
* Attach sub state tree of each module to the root tree.
|
||
*
|
||
* @param {Object} state
|
||
* @param {Object} modules
|
||
*/
|
||
|
||
}, {
|
||
key: '_setupModuleState',
|
||
value: function _setupModuleState(state, modules) {
|
||
var setPath = Vue.parsers.path.setPath;
|
||
|
||
Object.keys(modules).forEach(function (key) {
|
||
setPath(state, key, modules[key].state || {});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Bind mutations for each module to its sub tree and
|
||
* merge them all into one final mutations map.
|
||
*
|
||
* @param {Object} updatedModules
|
||
*/
|
||
|
||
}, {
|
||
key: '_setupModuleMutations',
|
||
value: function _setupModuleMutations(updatedModules) {
|
||
var modules = this._modules;
|
||
var getPath = Vue.parsers.path.getPath;
|
||
|
||
var allMutations = [this._rootMutations];
|
||
Object.keys(updatedModules).forEach(function (key) {
|
||
modules[key] = updatedModules[key];
|
||
});
|
||
Object.keys(modules).forEach(function (key) {
|
||
var module = modules[key];
|
||
if (!module || !module.mutations) return;
|
||
// bind mutations to sub state tree
|
||
var mutations = {};
|
||
Object.keys(module.mutations).forEach(function (name) {
|
||
var original = module.mutations[name];
|
||
mutations[name] = function (state) {
|
||
for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
|
||
args[_key3 - 1] = arguments[_key3];
|
||
}
|
||
|
||
original.apply(undefined, [getPath(state, key)].concat(args));
|
||
};
|
||
});
|
||
allMutations.push(mutations);
|
||
});
|
||
this._mutations = mergeObjects(allMutations);
|
||
}
|
||
|
||
/**
|
||
* Setup mutation check: if the vuex instance's state is mutated
|
||
* outside of a mutation handler, we throw en error. This effectively
|
||
* enforces all mutations to the state to be trackable and hot-reloadble.
|
||
* However, this comes at a run time cost since we are doing a deep
|
||
* watch on the entire state tree, so it is only enalbed with the
|
||
* strict option is set to true.
|
||
*/
|
||
|
||
}, {
|
||
key: '_setupMutationCheck',
|
||
value: function _setupMutationCheck() {
|
||
var _this4 = this;
|
||
|
||
var Watcher = getWatcher(this._vm);
|
||
/* eslint-disable no-new */
|
||
new Watcher(this._vm, '$data', function () {
|
||
if (!_this4._dispatching) {
|
||
throw new Error('[vuex] Do not mutate vuex store state outside mutation handlers.');
|
||
}
|
||
}, { deep: true, sync: true });
|
||
/* eslint-enable no-new */
|
||
}
|
||
|
||
/**
|
||
* Setup the middlewares. The devtools middleware is always
|
||
* included, since it does nothing if no devtool is detected.
|
||
*
|
||
* A middleware can demand the state it receives to be
|
||
* "snapshots", i.e. deep clones of the actual state tree.
|
||
*
|
||
* @param {Array} middlewares
|
||
* @param {Object} state
|
||
*/
|
||
|
||
}, {
|
||
key: '_setupMiddlewares',
|
||
value: function _setupMiddlewares(middlewares, state) {
|
||
var _this5 = this;
|
||
|
||
this._middlewares = [devtoolMiddleware].concat(middlewares);
|
||
this._needSnapshots = middlewares.some(function (m) {
|
||
return m.snapshot;
|
||
});
|
||
if (this._needSnapshots) {
|
||
console.log('[vuex] One or more of your middlewares are taking state snapshots ' + 'for each mutation. Make sure to use them only during development.');
|
||
}
|
||
var initialSnapshot = this._prevSnapshot = this._needSnapshots ? deepClone(state) : null;
|
||
// call init hooks
|
||
this._middlewares.forEach(function (m) {
|
||
if (m.onInit) {
|
||
m.onInit(m.snapshot ? initialSnapshot : state, _this5);
|
||
}
|
||
});
|
||
}
|
||
}, {
|
||
key: 'state',
|
||
get: function get() {
|
||
return this._vm._data;
|
||
},
|
||
set: function set(v) {
|
||
throw new Error('[vuex] Vuex root state is read only.');
|
||
}
|
||
}]);
|
||
return Store;
|
||
}();
|
||
|
||
function install(_Vue) {
|
||
Vue = _Vue;
|
||
override(Vue);
|
||
}
|
||
|
||
// auto install in dist mode
|
||
if (typeof window !== 'undefined' && window.Vue) {
|
||
install(window.Vue);
|
||
}
|
||
|
||
function createLogger() {
|
||
console.warn('[vuex] Vuex.createLogger has been deprecated.' + 'Use `import createLogger from \'vuex/logger\' instead.');
|
||
}
|
||
|
||
var index = {
|
||
Store: Store,
|
||
install: install,
|
||
createLogger: createLogger
|
||
};
|
||
|
||
return index;
|
||
|
||
}));
|
||
}).apply(this, arguments);
|
||
|
||
},{}],154:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("node_modules/yeast/index.js", module);
|
||
(function(){
|
||
'use strict';
|
||
|
||
var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split('')
|
||
, length = 64
|
||
, map = {}
|
||
, seed = 0
|
||
, i = 0
|
||
, prev;
|
||
|
||
/**
|
||
* Return a string representing the specified number.
|
||
*
|
||
* @param {Number} num The number to convert.
|
||
* @returns {String} The string representation of the number.
|
||
* @api public
|
||
*/
|
||
function encode(num) {
|
||
var encoded = '';
|
||
|
||
do {
|
||
encoded = alphabet[num % length] + encoded;
|
||
num = Math.floor(num / length);
|
||
} while (num > 0);
|
||
|
||
return encoded;
|
||
}
|
||
|
||
/**
|
||
* Return the integer value specified by the given string.
|
||
*
|
||
* @param {String} str The string to convert.
|
||
* @returns {Number} The integer value represented by the string.
|
||
* @api public
|
||
*/
|
||
function decode(str) {
|
||
var decoded = 0;
|
||
|
||
for (i = 0; i < str.length; i++) {
|
||
decoded = decoded * length + map[str.charAt(i)];
|
||
}
|
||
|
||
return decoded;
|
||
}
|
||
|
||
/**
|
||
* Yeast: A tiny growing id generator.
|
||
*
|
||
* @returns {String} A unique id.
|
||
* @api public
|
||
*/
|
||
function yeast() {
|
||
var now = encode(+new Date());
|
||
|
||
if (now !== prev) return seed = 0, prev = now;
|
||
return now +'.'+ encode(seed++);
|
||
}
|
||
|
||
//
|
||
// Map each character to its index.
|
||
//
|
||
for (; i < length; i++) map[alphabet[i]] = i;
|
||
|
||
//
|
||
// Expose the `yeast`, `encode` and `decode` functions.
|
||
//
|
||
yeast.encode = encode;
|
||
yeast.decode = decode;
|
||
module.exports = yeast;
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],155:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("src/App.vue", module);
|
||
(function(){
|
||
var __vueify_style__ = require("vueify-insert-css").insert("\n\n/* #F16745 #FFC65D #7BC8A4 #4CC3D9 #93648D #404040 */\n\n body {\n color: #404040;\n }\n\n .jumbotron-top {\n color: #fff;\n background: #4CC3D9;\n margin-bottom: 0;\n }\n\n .btn-custom {\n color: #fff;\n background: #F16745;\n }\n\n .jumbotron.jumbotron-green {\n padding: 75px 0;\n /*background: #404040;*/\n /*color: #fff;*/\n }\n\n #v-select .dropdown-toggle {\n /*border-color:#fff;*/\n background: #fff;\n }\n\n #v-select .dropdown-toggle:after {\n color: #404040;\n }\n\n /* Cyan theme */\n #v-select .selected-tag {\n color: #147688;\n background-color: #d7f3f9;\n border-color: #91ddec;\n }\n\n #v-select.dropdown.open .dropdown-toggle,\n #v-select.dropdown.open .dropdown-menu {\n border-color: #4CC3D9;\n }\n\n #v-select .active a {\n background: rgba(50,50,50,.1);\n color: #333;\n }\n\n #v-select.dropdown .highlight a,\n #v-select.dropdown li:hover a {\n background: #4CC3D9;\n color: #fff;\n }\n\n #output {\n height: 200px;\n border: none;\n color: #404040;\n }\n")
|
||
'use strict';
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
|
||
var _Jumbotron = require('./components/Jumbotron.vue');
|
||
|
||
var _Jumbotron2 = _interopRequireDefault(_Jumbotron);
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
||
exports.default = {
|
||
components: { Jumbotron: _Jumbotron2.default }
|
||
};
|
||
if (module.exports.__esModule) module.exports = module.exports.default
|
||
;(typeof module.exports === "function"? module.exports.options: module.exports).template = "\n<div class=\"jumbotron jumbotron-top\">\n <div class=\"container\">\n <h1>Vue Select</h1>\n <p class=\"lead\">A simple component that provides similar functionality to Select2 without the overhead of jQuery.</p>\n <a class=\"btn btn-custom\" href=\"https://github.com/sagalbot/vue-select\">View on GitHub</a>\n </div>\n</div>\n\n <jumbotron></jumbotron>\n\n <div id=\"app\" class=\"container\">\n <h2 class=\"page-header\">Live Edit <small>play around with the above vue-select</small></h2>\n\n <div class=\"row\">\n <div class=\"col-md-6\">\n <label class=\"control-label\">Options</label><br>\n <div class=\"radio\">\n <label for=\"advanced\">\n <input id=\"advanced\" type=\"radio\" v-model=\"optionType\" value=\"advanced\"> Objects\n <pre><code class=\"language-javascript\">[{value: 'foo', label: 'Foo'}]</code></pre>\n </label>\n <br>\n <label for=\"simple\">\n <input id=\"simple\" type=\"radio\" v-model=\"optionType\" value=\"simple\"> Strings\n <pre><code class=\"language-javascript\">['foo', 'bar']</code></pre>\n </label>\n <span class=\"help-block\">The <code>options</code> property is watched for changes, and the value is reset anytime the options change. This is useful if you have multiple selection boxes that depend on its ancestors values.</span>\n </div>\n </div>\n\n <div class=\"col-md-6\">\n\n <div class=\"form-group\">\n <label class=\"control-label\">Allow Multiple</label>\n <div class=\"checkbox\">\n <label class=\"control-label\">\n <input v-model=\"multiple\" type=\"checkbox\"> True\n </label>\n <span class=\"help-block\">Equivalent to the <code>multiple</code> attribute to a <code><select></code>. You'll want to clear any selections you have made before changing this option. It's not one that should be changed after render.</span>\n </div>\n </div>\n\n <div class=\"form-group\">\n <label class=\"control-label\">Max Height</label>\n <input type=\"text\" v-model=\"maxHeight\" class=\"form-control\">\n <span class=\"help-block\">Limit the height of the dropdown menu.</span>\n </div>\n\n <div class=\"form-group\">\n <label class=\"control-label\">Placeholder</label>\n <input type=\"text\" v-model=\"placeholder\" class=\"form-control\">\n <span class=\"help-block\">Equivalent to the <code>placeholder</code> attribute.</span>\n </div>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6\">\n <h2 class=\"page-header\">Install & Usage</h2>\n <h5>Install from GitHub using NPM</h5>\n <pre><code class=\"language-c-like\">$ npm install sagalbot/vue-select</code></pre>\n\n <pre v-pre=\"\"> <code class=\"language-markup\"><template>\n <div id=\"myApp\">\n <v-select :value.sync=\"selected\" :options=\"options\"></v-select>\n </div>\n </template></code>\n\n <code class=\"language-markup\"><script></code>\n <code class=\"language-javascript\">import vSelect from 'vue-select'\n export default {\n components: {vSelect},\n\n data() {\n return {\n selected: null,\n options: ['foo','bar','baz']\n }\n }\n }</code>\n <code class=\"language-markup\"></script></code>\n </pre>\n </div>\n <div class=\"col-md-6\">\n <h2 class=\"page-header\">Parameters</h2>\n <ul>\n <li>\n <code>value</code> Represents the currently selected value(s)\n <ul>\n <li>type: String</li>\n <li>required: true </li>\n </ul>\n </li>\n\n <li>\n <code>options</code> An array of strings or objects to be used as dropdown choices. Supports <code>['foo','bar']</code> & <code>[{label: 'Foo', value: 'foo'}]</code>. When using the <code>[{}]</code> syntax, the objects in the array can have as many properties as you need, as long as the object contains <code>value</code> and <code>label</code> keys.\n <ul>\n <li>type: Array</li>\n <li>default: []</li>\n </ul>\n </li>\n\n <li>\n <code>maxHeight</code> Limit the height of the dropdown menu\n <ul>\n <li>type: String</li>\n <li>default: '400px'</li>\n </ul>\n </li>\n\n <li>\n <code>searchable</code> Toggle filtering of options\n <ul>\n <li>type: Boolean</li>\n <li>default: true</li>\n </ul>\n </li>\n\n <li>\n <code>multiple</code> Equivalent to <code>multiple</code> attribute on a <code><select></code>\n <ul>\n <li>type: Boolean</li>\n <li>default: true</li>\n </ul>\n </li>\n\n <li>\n <code>placeholder</code> Equivalent to <code>placeholder</code> attribute on an <code><input></code>\n <ul>\n <li>type: String</li>\n <li>default: ''</li>\n </ul>\n </li>\n\n <li>\n <code>transition</code> Vue <code>transition</code> prop applied to the <code>.dropdown-menu</code>\n <ul>\n <li>type: Boolean</li>\n <li>default: true</li>\n </ul>\n </li>\n </ul>\n\n </div>\n </div>\n\n</div>\n"
|
||
if (module.hot) {(function () { module.hot.accept()
|
||
var hotAPI = require("vue-hot-reload-api")
|
||
hotAPI.install(require("vue"), true)
|
||
if (!hotAPI.compatible) return
|
||
var id = "/Volumes/Documents/Dropbox/htdocs/vue-select/src/App.vue"
|
||
module.hot.dispose(function () {
|
||
require("vueify-insert-css").cache["\n\n/* #F16745 #FFC65D #7BC8A4 #4CC3D9 #93648D #404040 */\n\n body {\n color: #404040;\n }\n\n .jumbotron-top {\n color: #fff;\n background: #4CC3D9;\n margin-bottom: 0;\n }\n\n .btn-custom {\n color: #fff;\n background: #F16745;\n }\n\n .jumbotron.jumbotron-green {\n padding: 75px 0;\n /*background: #404040;*/\n /*color: #fff;*/\n }\n\n #v-select .dropdown-toggle {\n /*border-color:#fff;*/\n background: #fff;\n }\n\n #v-select .dropdown-toggle:after {\n color: #404040;\n }\n\n /* Cyan theme */\n #v-select .selected-tag {\n color: #147688;\n background-color: #d7f3f9;\n border-color: #91ddec;\n }\n\n #v-select.dropdown.open .dropdown-toggle,\n #v-select.dropdown.open .dropdown-menu {\n border-color: #4CC3D9;\n }\n\n #v-select .active a {\n background: rgba(50,50,50,.1);\n color: #333;\n }\n\n #v-select.dropdown .highlight a,\n #v-select.dropdown li:hover a {\n background: #4CC3D9;\n color: #fff;\n }\n\n #output {\n height: 200px;\n border: none;\n color: #404040;\n }\n"] = false
|
||
document.head.removeChild(__vueify_style__)
|
||
})
|
||
if (!module.hot.data) {
|
||
hotAPI.createRecord(id, module.exports)
|
||
} else {
|
||
hotAPI.update(id, module.exports, (typeof module.exports === "function" ? module.exports.options : module.exports).template)
|
||
}
|
||
})()}
|
||
}).apply(this, arguments);
|
||
|
||
},{"./components/Jumbotron.vue":156,"vue":151,"vue-hot-reload-api":150,"vueify-insert-css":152}],156:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("src/components/Jumbotron.vue", module);
|
||
(function(){
|
||
'use strict';
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
|
||
var _Select = require('./Select.vue');
|
||
|
||
var _Select2 = _interopRequireDefault(_Select);
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
||
exports.default = {
|
||
components: { vSelect: _Select2.default },
|
||
|
||
data: function data() {
|
||
return {
|
||
select: null,
|
||
placeholder: 'Choose a Country',
|
||
multiple: true,
|
||
maxHeight: '400px',
|
||
options: {
|
||
advanced: require('../countries/countries.js'),
|
||
simple: require('../countries/simpleCountries.js'),
|
||
simpler: [{ label: 'This is Foo', value: 'foo' }, { label: 'This is Bar', value: 'bar' }, { label: 'This is Baz', value: 'baz' }]
|
||
},
|
||
optionType: 'simple'
|
||
};
|
||
}
|
||
};
|
||
if (module.exports.__esModule) module.exports = module.exports.default
|
||
;(typeof module.exports === "function"? module.exports.options: module.exports).template = "\n<div class=\"jumbotron jumbotron-green\">\n <div class=\"container\">\n <div class=\"row\">\n <div class=\"col-md-6 col-md-offset-1\">\n\n <v-select id=\"v-select\" :placeholder=\"placeholder\" :value.sync=\"select\" :options=\"options[optionType]\" :multiple=\"multiple\">\n </v-select>\n\n </div>\n\n <pre id=\"output\" class=\"col-md-4\">{{ select | json }}</pre>\n </div>\n </div>\n</div>\n"
|
||
if (module.hot) {(function () { module.hot.accept()
|
||
var hotAPI = require("vue-hot-reload-api")
|
||
hotAPI.install(require("vue"), true)
|
||
if (!hotAPI.compatible) return
|
||
var id = "/Volumes/Documents/Dropbox/htdocs/vue-select/src/components/Jumbotron.vue"
|
||
if (!module.hot.data) {
|
||
hotAPI.createRecord(id, module.exports)
|
||
} else {
|
||
hotAPI.update(id, module.exports, (typeof module.exports === "function" ? module.exports.options : module.exports).template)
|
||
}
|
||
})()}
|
||
}).apply(this, arguments);
|
||
|
||
},{"../countries/countries.js":158,"../countries/simpleCountries.js":159,"./Select.vue":157,"vue":151,"vue-hot-reload-api":150}],157:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("src/components/Select.vue", module);
|
||
(function(){
|
||
var __vueify_style__ = require("vueify-insert-css").insert("\n.dropdown[_v-3d450ab6] {\n position: relative;\n}\n\n.open .dropdown-toggle[_v-3d450ab6],\n.open .dropdown-menu[_v-3d450ab6] {\n border-color: rgba(60,60,60,.26);\n}\n\n.open-indicator[_v-3d450ab6] {\n position: absolute;\n top: 10px;\n right: 10px;\n display: inline-block;\n cursor: pointer;\n pointer-events: all;\n -webkit-transition: all 150ms cubic-bezier(1.000, -0.115, 0.975, 0.855);\n transition: all 150ms cubic-bezier(1.000, -0.115, 0.975, 0.855);\n -webkit-transition-timing-function: cubic-bezier(1.000, -0.115, 0.975, 0.855);\n transition-timing-function: cubic-bezier(1.000, -0.115, 0.975, 0.855);\n}\n\n.open .open-indicator[_v-3d450ab6] {\n -webkit-transform: rotate(180deg);\n transform: rotate(180deg);\n}\n\n.dropdown-toggle[_v-3d450ab6] {\n display: block;\n padding: 0;\n background: none;\n border: 1px solid rgba(60,60,60,.26);\n border-radius: 4px;\n white-space: normal;\n}\n.searchable .dropdown-toggle[_v-3d450ab6] {\n cursor: text;\n}\n\n.open .dropdown-toggle[_v-3d450ab6] {\n border-bottom: none;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.dropdown-menu[_v-3d450ab6] {\n margin: 0;\n width: 100%;\n overflow-y: scroll;\n border-top: none;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.selected-tag[_v-3d450ab6] {\n color: #333;\n background-color: #f0f0f0;\n border: 1px solid #ccc;\n border-radius: 4px;\n height: 26px;\n margin: 4px 1px 0px 3px;\n padding: 0 0.25em;\n float: left;\n line-height: 1.7em;\n}\n\n.selected-tag .close[_v-3d450ab6] {\n float: none;\n margin-right: 0;\n font-size: 20px;\n}\n\ninput[type=search][_v-3d450ab6],\ninput[type=search][_v-3d450ab6]:focus {\n display: inline-block;\n border: none;\n outline: none;\n margin: 0;\n width: 10em;\n max-width: 100%;\n background: none;\n position: relative;\n box-shadow: none;\n float: left;\n clear: none;\n}\n\ninput[type=search][_v-3d450ab6]:disabled {\n cursor: pointer;\n}\n\nli a[_v-3d450ab6] {\n cursor: pointer;\n}\n\n.active a[_v-3d450ab6] {\n background: rgba(50,50,50,.1);\n color: #333;\n}\n\n.highlight a[_v-3d450ab6],\nli:hover a[_v-3d450ab6] {\n background: #f0f0f0;\n color: #333;\n}\n")
|
||
'use strict';
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
|
||
var _typeof2 = require('babel-runtime/helpers/typeof');
|
||
|
||
var _typeof3 = _interopRequireDefault(_typeof2);
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
||
exports.default = {
|
||
props: {
|
||
value: {
|
||
twoway: true,
|
||
required: true
|
||
},
|
||
options: {
|
||
type: Array,
|
||
default: function _default() {
|
||
return [];
|
||
}
|
||
},
|
||
maxHeight: {
|
||
type: String,
|
||
default: '400px'
|
||
},
|
||
searchable: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
multiple: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
placeholder: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
transition: {
|
||
type: String,
|
||
default: 'expand'
|
||
},
|
||
clearSearchOnSelect: {
|
||
type: Boolean,
|
||
default: true
|
||
}
|
||
},
|
||
|
||
data: function data() {
|
||
return {
|
||
search: '',
|
||
open: false,
|
||
typeAheadPointer: -1
|
||
};
|
||
},
|
||
|
||
|
||
watch: {
|
||
options: function options() {
|
||
this.$set('value', this.multiple ? [] : null);
|
||
},
|
||
multiple: function multiple(val) {
|
||
this.$set('value', val ? [] : null);
|
||
},
|
||
filteredOptions: function filteredOptions() {
|
||
this.typeAheadPointer = 0;
|
||
}
|
||
},
|
||
|
||
methods: {
|
||
select: function select(option) {
|
||
if (!this.isOptionSelected(option)) {
|
||
if (this.multiple) {
|
||
|
||
if (!this.value) {
|
||
this.$set('value', [option]);
|
||
} else {
|
||
this.value.push(option);
|
||
}
|
||
} else {
|
||
this.value = option;
|
||
}
|
||
} else {
|
||
if (this.multiple) {
|
||
this.value.$remove(option);
|
||
}
|
||
}
|
||
|
||
if (!this.multiple) {
|
||
this.open = !this.open;
|
||
}
|
||
|
||
if (this.clearSearchOnSelect) {
|
||
this.search = '';
|
||
}
|
||
},
|
||
toggleDropdown: function toggleDropdown(e) {
|
||
if (e.target === this.$els.openIndicator || e.target === this.$els.search || e.target === this.$els.toggle || e.target === this.$el) {
|
||
if (this.open) {
|
||
this.$els.search.blur(); // dropdown will close on blur
|
||
} else {
|
||
this.open = true;
|
||
this.$els.search.focus();
|
||
}
|
||
}
|
||
},
|
||
isOptionSelected: function isOptionSelected(option) {
|
||
if (this.multiple && this.value) {
|
||
return this.value.indexOf(option) !== -1;
|
||
}
|
||
|
||
return this.value === option;
|
||
},
|
||
getOptionValue: function getOptionValue(option) {
|
||
if ((typeof option === 'undefined' ? 'undefined' : (0, _typeof3.default)(option)) === 'object' && option.value) {
|
||
return option.value;
|
||
}
|
||
|
||
return option;
|
||
},
|
||
getOptionLabel: function getOptionLabel(option) {
|
||
if ((typeof option === 'undefined' ? 'undefined' : (0, _typeof3.default)(option)) === 'object' && option.label) {
|
||
return option.label;
|
||
}
|
||
|
||
return option;
|
||
},
|
||
typeAheadUp: function typeAheadUp() {
|
||
if (this.typeAheadPointer > 0) this.typeAheadPointer--;
|
||
},
|
||
typeAheadDown: function typeAheadDown() {
|
||
if (this.typeAheadPointer < this.filteredOptions.length - 1) this.typeAheadPointer++;
|
||
},
|
||
typeAheadSelect: function typeAheadSelect() {
|
||
if (this.filteredOptions[this.typeAheadPointer]) {
|
||
this.select(this.filteredOptions[this.typeAheadPointer]);
|
||
}
|
||
|
||
if (this.clearSearchOnSelect) {
|
||
this.search = "";
|
||
}
|
||
},
|
||
onEscape: function onEscape() {
|
||
if (!this.search.length) {
|
||
this.$els.search.blur();
|
||
} else {
|
||
this.$set('search', '');
|
||
}
|
||
},
|
||
maybeDeleteValue: function maybeDeleteValue() {
|
||
if (!this.$els.search.value.length && this.value) {
|
||
return this.multiple ? this.value.pop() : this.$set('value', null);
|
||
}
|
||
}
|
||
},
|
||
|
||
computed: {
|
||
cssClasses: function cssClasses() {
|
||
return {
|
||
open: this.open,
|
||
searchable: this.searchable
|
||
};
|
||
},
|
||
searchPlaceholder: function searchPlaceholder() {
|
||
if (this.isValueEmpty && this.placeholder) {
|
||
return this.placeholder;
|
||
}
|
||
},
|
||
filteredOptions: function filteredOptions() {
|
||
return this.$options.filters.filterBy(this.options, this.search);
|
||
},
|
||
isValueEmpty: function isValueEmpty() {
|
||
if (this.value) {
|
||
return !this.value.length;
|
||
}
|
||
|
||
return true;
|
||
},
|
||
valueAsArray: function valueAsArray() {
|
||
if (this.multiple) {
|
||
return this.value;
|
||
} else if (this.value) {
|
||
return [this.value];
|
||
}
|
||
|
||
return [];
|
||
}
|
||
}
|
||
|
||
};
|
||
if (module.exports.__esModule) module.exports = module.exports.default
|
||
;(typeof module.exports === "function"? module.exports.options: module.exports).template = "\n<div class=\"dropdown\" :class=\"cssClasses\" _v-3d450ab6=\"\">\n <div v-el:toggle=\"\" @mousedown.prevent=\"toggleDropdown\" class=\"dropdown-toggle clearfix\" type=\"button\" _v-3d450ab6=\"\">\n <span class=\"form-control\" v-if=\"!searchable && isValueEmpty\" _v-3d450ab6=\"\">\n {{ placeholder }}\n </span>\n\n <span class=\"selected-tag\" v-for=\"option in valueAsArray\" _v-3d450ab6=\"\">\n {{ getOptionLabel(option) }}\n <button v-if=\"multiple\" @click=\"select(option)\" type=\"button\" class=\"close\" _v-3d450ab6=\"\">\n <span aria-hidden=\"true\" _v-3d450ab6=\"\">×</span>\n </button>\n </span>\n\n <input v-el:search=\"\" v-show=\"searchable\" v-model=\"search\" @keydown.delete=\"maybeDeleteValue\" @keydown.esc=\"onEscape\" @keydown.up.prevent=\"typeAheadUp\" @keydown.down.prevent=\"typeAheadDown\" @keydown.enter.prevent=\"typeAheadSelect\" @blur=\"open = false\" @focus=\"open = true\" type=\"search\" class=\"form-control\" :placeholder=\"searchPlaceholder\" _v-3d450ab6=\"\">\n\n <i v-el:open-indicator=\"\" role=\"presentation\" class=\"open-indicator glyphicon-chevron-down glyphicon\" _v-3d450ab6=\"\"></i>\n </div>\n\n <ul v-show=\"open\" v-el:dropdown-menu=\"\" :transition=\"transition\" :style=\"{ 'max-height': maxHeight }\" class=\"dropdown-menu animated\" _v-3d450ab6=\"\">\n <li v-for=\"option in filteredOptions\" :class=\"{ active: isOptionSelected(option), highlight: $index === typeAheadPointer }\" @mouseover=\"typeAheadPointer = $index\" _v-3d450ab6=\"\">\n <a @mousedown.prevent=\"select(option)\" _v-3d450ab6=\"\">\n {{ getOptionLabel(option) }}\n </a>\n </li>\n <li transition=\"fade\" v-if=\"!filteredOptions.length\" class=\"divider\" _v-3d450ab6=\"\"></li>\n <li transition=\"fade\" v-if=\"!filteredOptions.length\" class=\"text-center\" _v-3d450ab6=\"\">Sorry, no matching options.</li>\n </ul>\n</div>\n"
|
||
if (module.hot) {(function () { module.hot.accept()
|
||
var hotAPI = require("vue-hot-reload-api")
|
||
hotAPI.install(require("vue"), true)
|
||
if (!hotAPI.compatible) return
|
||
var id = "/Volumes/Documents/Dropbox/htdocs/vue-select/src/components/Select.vue"
|
||
module.hot.dispose(function () {
|
||
require("vueify-insert-css").cache["\n.dropdown[_v-3d450ab6] {\n position: relative;\n}\n\n.open .dropdown-toggle[_v-3d450ab6],\n.open .dropdown-menu[_v-3d450ab6] {\n border-color: rgba(60,60,60,.26);\n}\n\n.open-indicator[_v-3d450ab6] {\n position: absolute;\n top: 10px;\n right: 10px;\n display: inline-block;\n cursor: pointer;\n pointer-events: all;\n -webkit-transition: all 150ms cubic-bezier(1.000, -0.115, 0.975, 0.855);\n transition: all 150ms cubic-bezier(1.000, -0.115, 0.975, 0.855);\n -webkit-transition-timing-function: cubic-bezier(1.000, -0.115, 0.975, 0.855);\n transition-timing-function: cubic-bezier(1.000, -0.115, 0.975, 0.855);\n}\n\n.open .open-indicator[_v-3d450ab6] {\n -webkit-transform: rotate(180deg);\n transform: rotate(180deg);\n}\n\n.dropdown-toggle[_v-3d450ab6] {\n display: block;\n padding: 0;\n background: none;\n border: 1px solid rgba(60,60,60,.26);\n border-radius: 4px;\n white-space: normal;\n}\n.searchable .dropdown-toggle[_v-3d450ab6] {\n cursor: text;\n}\n\n.open .dropdown-toggle[_v-3d450ab6] {\n border-bottom: none;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n}\n\n.dropdown-menu[_v-3d450ab6] {\n margin: 0;\n width: 100%;\n overflow-y: scroll;\n border-top: none;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.selected-tag[_v-3d450ab6] {\n color: #333;\n background-color: #f0f0f0;\n border: 1px solid #ccc;\n border-radius: 4px;\n height: 26px;\n margin: 4px 1px 0px 3px;\n padding: 0 0.25em;\n float: left;\n line-height: 1.7em;\n}\n\n.selected-tag .close[_v-3d450ab6] {\n float: none;\n margin-right: 0;\n font-size: 20px;\n}\n\ninput[type=search][_v-3d450ab6],\ninput[type=search][_v-3d450ab6]:focus {\n display: inline-block;\n border: none;\n outline: none;\n margin: 0;\n width: 10em;\n max-width: 100%;\n background: none;\n position: relative;\n box-shadow: none;\n float: left;\n clear: none;\n}\n\ninput[type=search][_v-3d450ab6]:disabled {\n cursor: pointer;\n}\n\nli a[_v-3d450ab6] {\n cursor: pointer;\n}\n\n.active a[_v-3d450ab6] {\n background: rgba(50,50,50,.1);\n color: #333;\n}\n\n.highlight a[_v-3d450ab6],\nli:hover a[_v-3d450ab6] {\n background: #f0f0f0;\n color: #333;\n}\n"] = false
|
||
document.head.removeChild(__vueify_style__)
|
||
})
|
||
if (!module.hot.data) {
|
||
hotAPI.createRecord(id, module.exports)
|
||
} else {
|
||
hotAPI.update(id, module.exports, (typeof module.exports === "function" ? module.exports.options : module.exports).template)
|
||
}
|
||
})()}
|
||
}).apply(this, arguments);
|
||
|
||
},{"babel-runtime/helpers/typeof":5,"vue":151,"vue-hot-reload-api":150,"vueify-insert-css":152}],158:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("src/countries/countries.js", module);
|
||
(function(){
|
||
"use strict";
|
||
|
||
module.exports = [{ value: "AF", label: "Afghanistan" }, { value: "AX", label: "Åland Islands" }, { value: "AL", label: "Albania" }, { value: "DZ", label: "Algeria" }, { value: "AS", label: "American Samoa" }, { value: "AD", label: "Andorra" }, { value: "AO", label: "Angola" }, { value: "AI", label: "Anguilla" }, { value: "AQ", label: "Antarctica" }, { value: "AG", label: "Antigua and Barbuda" }, { value: "AR", label: "Argentina" }, { value: "AM", label: "Armenia" }, { value: "AW", label: "Aruba" }, { value: "AU", label: "Australia" }, { value: "AT", label: "Austria" }, { value: "AZ", label: "Azerbaijan" }, { value: "BS", label: "Bahamas" }, { value: "BH", label: "Bahrain" }, { value: "BD", label: "Bangladesh" }, { value: "BB", label: "Barbados" }, { value: "BY", label: "Belarus" }, { value: "BE", label: "Belgium" }, { value: "BZ", label: "Belize" }, { value: "BJ", label: "Benin" }, { value: "BM", label: "Bermuda" }, { value: "BT", label: "Bhutan" }, { value: "BO", label: "Bolivia" }, { value: "BA", label: "Bosnia and Herzegovina" }, { value: "BW", label: "Botswana" }, { value: "BV", label: "Bouvet Island" }, { value: "BR", label: "Brazil" }, { value: "IO", label: "British Indian Ocean Territory" }, { value: "BN", label: "Brunei Darussalam" }, { value: "BG", label: "Bulgaria" }, { value: "BF", label: "Burkina Faso" }, { value: "BI", label: "Burundi" }, { value: "KH", label: "Cambodia" }, { value: "CM", label: "Cameroon" }, { value: "CA", label: "Canada" }, { value: "CV", label: "Cape Verde" }, { value: "KY", label: "Cayman Islands" }, { value: "CF", label: "Central African Republic" }, { value: "TD", label: "Chad" }, { value: "CL", label: "Chile" }, { value: "CN", label: "China" }, { value: "CX", label: "Christmas Island" }, { value: "CC", label: "Cocos (Keeling) Islands" }, { value: "CO", label: "Colombia" }, { value: "KM", label: "Comoros" }, { value: "CG", label: "Congo" }, { value: "CD", label: "Congo, The Democratic Republic of The" }, { value: "CK", label: "Cook Islands" }, { value: "CR", label: "Costa Rica" }, { value: "CI", label: "Cote D'ivoire" }, { value: "HR", label: "Croatia" }, { value: "CU", label: "Cuba" }, { value: "CY", label: "Cyprus" }, { value: "CZ", label: "Czech Republic" }, { value: "DK", label: "Denmark" }, { value: "DJ", label: "Djibouti" }, { value: "DM", label: "Dominica" }, { value: "DO", label: "Dominican Republic" }, { value: "EC", label: "Ecuador" }, { value: "EG", label: "Egypt" }, { value: "SV", label: "El Salvador" }, { value: "GQ", label: "Equatorial Guinea" }, { value: "ER", label: "Eritrea" }, { value: "EE", label: "Estonia" }, { value: "ET", label: "Ethiopia" }, { value: "FK", label: "Falkland Islands (Malvinas)" }, { value: "FO", label: "Faroe Islands" }, { value: "FJ", label: "Fiji" }, { value: "FI", label: "Finland" }, { value: "FR", label: "France" }, { value: "GF", label: "French Guiana" }, { value: "PF", label: "French Polynesia" }, { value: "TF", label: "French Southern Territories" }, { value: "GA", label: "Gabon" }, { value: "GM", label: "Gambia" }, { value: "GE", label: "Georgia" }, { value: "DE", label: "Germany" }, { value: "GH", label: "Ghana" }, { value: "GI", label: "Gibraltar" }, { value: "GR", label: "Greece" }, { value: "GL", label: "Greenland" }, { value: "GD", label: "Grenada" }, { value: "GP", label: "Guadeloupe" }, { value: "GU", label: "Guam" }, { value: "GT", label: "Guatemala" }, { value: "GG", label: "Guernsey" }, { value: "GN", label: "Guinea" }, { value: "GW", label: "Guinea-bissau" }, { value: "GY", label: "Guyana" }, { value: "HT", label: "Haiti" }, { value: "HM", label: "Heard Island and Mcdonald Islands" }, { value: "VA", label: "Holy See (Vatican City State)" }, { value: "HN", label: "Honduras" }, { value: "HK", label: "Hong Kong" }, { value: "HU", label: "Hungary" }, { value: "IS", label: "Iceland" }, { value: "IN", label: "India" }, { value: "ID", label: "Indonesia" }, { value: "IR", label: "Iran, Islamic Republic of" }, { value: "IQ", label: "Iraq" }, { value: "IE", label: "Ireland" }, { value: "IM", label: "Isle of Man" }, { value: "IL", label: "Israel" }, { value: "IT", label: "Italy" }, { value: "JM", label: "Jamaica" }, { value: "JP", label: "Japan" }, { value: "JE", label: "Jersey" }, { value: "JO", label: "Jordan" }, { value: "KZ", label: "Kazakhstan" }, { value: "KE", label: "Kenya" }, { value: "KI", label: "Kiribati" }, { value: "KP", label: "Korea, Democratic People's Republic of" }, { value: "KR", label: "Korea, Republic of" }, { value: "KW", label: "Kuwait" }, { value: "KG", label: "Kyrgyzstan" }, { value: "LA", label: "Lao People's Democratic Republic" }, { value: "LV", label: "Latvia" }, { value: "LB", label: "Lebanon" }, { value: "LS", label: "Lesotho" }, { value: "LR", label: "Liberia" }, { value: "LY", label: "Libyan Arab Jamahiriya" }, { value: "LI", label: "Liechtenstein" }, { value: "LT", label: "Lithuania" }, { value: "LU", label: "Luxembourg" }, { value: "MO", label: "Macao" }, { value: "MK", label: "Macedonia, The Former Yugoslav Republic of" }, { value: "MG", label: "Madagascar" }, { value: "MW", label: "Malawi" }, { value: "MY", label: "Malaysia" }, { value: "MV", label: "Maldives" }, { value: "ML", label: "Mali" }, { value: "MT", label: "Malta" }, { value: "MH", label: "Marshall Islands" }, { value: "MQ", label: "Martinique" }, { value: "MR", label: "Mauritania" }, { value: "MU", label: "Mauritius" }, { value: "YT", label: "Mayotte" }, { value: "MX", label: "Mexico" }, { value: "FM", label: "Micronesia, Federated States of" }, { value: "MD", label: "Moldova, Republic of" }, { value: "MC", label: "Monaco" }, { value: "MN", label: "Mongolia" }, { value: "ME", label: "Montenegro" }, { value: "MS", label: "Montserrat" }, { value: "MA", label: "Morocco" }, { value: "MZ", label: "Mozambique" }, { value: "MM", label: "Myanmar" }, { value: "NA", label: "Namibia" }, { value: "NR", label: "Nauru" }, { value: "NP", label: "Nepal" }, { value: "NL", label: "Netherlands" }, { value: "AN", label: "Netherlands Antilles" }, { value: "NC", label: "New Caledonia" }, { value: "NZ", label: "New Zealand" }, { value: "NI", label: "Nicaragua" }, { value: "NE", label: "Niger" }, { value: "NG", label: "Nigeria" }, { value: "NU", label: "Niue" }, { value: "NF", label: "Norfolk Island" }, { value: "MP", label: "Northern Mariana Islands" }, { value: "NO", label: "Norway" }, { value: "OM", label: "Oman" }, { value: "PK", label: "Pakistan" }, { value: "PW", label: "Palau" }, { value: "PS", label: "Palestinian Territory, Occupied" }, { value: "PA", label: "Panama" }, { value: "PG", label: "Papua New Guinea" }, { value: "PY", label: "Paraguay" }, { value: "PE", label: "Peru" }, { value: "PH", label: "Philippines" }, { value: "PN", label: "Pitcairn" }, { value: "PL", label: "Poland" }, { value: "PT", label: "Portugal" }, { value: "PR", label: "Puerto Rico" }, { value: "QA", label: "Qatar" }, { value: "RE", label: "Reunion" }, { value: "RO", label: "Romania" }, { value: "RU", label: "Russian Federation" }, { value: "RW", label: "Rwanda" }, { value: "SH", label: "Saint Helena" }, { value: "KN", label: "Saint Kitts and Nevis" }, { value: "LC", label: "Saint Lucia" }, { value: "PM", label: "Saint Pierre and Miquelon" }, { value: "VC", label: "Saint Vincent and The Grenadines" }, { value: "WS", label: "Samoa" }, { value: "SM", label: "San Marino" }, { value: "ST", label: "Sao Tome and Principe" }, { value: "SA", label: "Saudi Arabia" }, { value: "SN", label: "Senegal" }, { value: "RS", label: "Serbia" }, { value: "SC", label: "Seychelles" }, { value: "SL", label: "Sierra Leone" }, { value: "SG", label: "Singapore" }, { value: "SK", label: "Slovakia" }, { value: "SI", label: "Slovenia" }, { value: "SB", label: "Solomon Islands" }, { value: "SO", label: "Somalia" }, { value: "ZA", label: "South Africa" }, { value: "GS", label: "South Georgia and The South Sandwich Islands" }, { value: "ES", label: "Spain" }, { value: "LK", label: "Sri Lanka" }, { value: "SD", label: "Sudan" }, { value: "SR", label: "Suriname" }, { value: "SJ", label: "Svalbard and Jan Mayen" }, { value: "SZ", label: "Swaziland" }, { value: "SE", label: "Sweden" }, { value: "CH", label: "Switzerland" }, { value: "SY", label: "Syrian Arab Republic" }, { value: "TW", label: "Taiwan, Province of China" }, { value: "TJ", label: "Tajikistan" }, { value: "TZ", label: "Tanzania, United Republic of" }, { value: "TH", label: "Thailand" }, { value: "TL", label: "Timor-leste" }, { value: "TG", label: "Togo" }, { value: "TK", label: "Tokelau" }, { value: "TO", label: "Tonga" }, { value: "TT", label: "Trinidad and Tobago" }, { value: "TN", label: "Tunisia" }, { value: "TR", label: "Turkey" }, { value: "TM", label: "Turkmenistan" }, { value: "TC", label: "Turks and Caicos Islands" }, { value: "TV", label: "Tuvalu" }, { value: "UG", label: "Uganda" }, { value: "UA", label: "Ukraine" }, { value: "AE", label: "United Arab Emirates" }, { value: "GB", label: "United Kingdom" }, { value: "US", label: "United States" }, { value: "UM", label: "United States Minor Outlying Islands" }, { value: "UY", label: "Uruguay" }, { value: "UZ", label: "Uzbekistan" }, { value: "VU", label: "Vanuatu" }, { value: "VE", label: "Venezuela" }, { value: "VN", label: "Viet Nam" }, { value: "VG", label: "Virgin Islands, British" }, { value: "VI", label: "Virgin Islands, U.S." }, { value: "WF", label: "Wallis and Futuna" }, { value: "EH", label: "Western Sahara" }, { value: "YE", label: "Yemen" }, { value: "ZM", label: "Zambia" }, { value: "ZW", label: "Zimbabwe" }];
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],159:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("src/countries/simpleCountries.js", module);
|
||
(function(){
|
||
"use strict";
|
||
|
||
module.exports = ["Afghanistan", "Åland Islands", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory", "Brunei Darussalam", "Bulgaria", "Burkina Faso", "Burundi", "Cambodia", "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo", "Congo, The Democratic Republic of The", "Cook Islands", "Costa Rica", "Cote D'ivoire", "Croatia", "Cuba", "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia", "Falkland Islands (Malvinas)", "Faroe Islands", "Fiji", "Finland", "France", "French Guiana", "French Polynesia", "French Southern Territories", "Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guernsey", "Guinea", "Guinea-bissau", "Guyana", "Haiti", "Heard Island and Mcdonald Islands", "Holy See (Vatican City State)", "Honduras", "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iran, Islamic Republic of", "Iraq", "Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Korea, Democratic People's Republic of", "Korea, Republic of", "Kuwait", "Kyrgyzstan", "Lao People's Democratic Republic", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libyan Arab Jamahiriya", "Liechtenstein", "Lithuania", "Luxembourg", "Macao", "Macedonia, The Former Yugoslav Republic of", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia, Federated States of", "Moldova, Republic of", "Monaco", "Mongolia", "Montenegro", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia", "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau", "Palestinian Territory, Occupied", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Pitcairn", "Poland", "Portugal", "Puerto Rico", "Qatar", "Reunion", "Romania", "Russian Federation", "Rwanda", "Saint Helena", "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon", "Saint Vincent and The Grenadines", "Samoa", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Senegal", "Serbia", "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa", "South Georgia and The South Sandwich Islands", "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden", "Switzerland", "Syrian Arab Republic", "Taiwan, Province of China", "Tajikistan", "Tanzania, United Republic of", "Thailand", "Timor-leste", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan", "Vanuatu", "Venezuela", "Viet Nam", "Virgin Islands, British", "Virgin Islands, U.S.", "Wallis and Futuna", "Western Sahara", "Yemen", "Zambia", "Zimbabwe"];
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{}],160:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("src/main.js", module);
|
||
(function(){
|
||
'use strict';
|
||
|
||
var _vue = require('vue');
|
||
|
||
var _vue2 = _interopRequireDefault(_vue);
|
||
|
||
var _App = require('./App.vue');
|
||
|
||
var _App2 = _interopRequireDefault(_App);
|
||
|
||
var _store = require('./vuex/store');
|
||
|
||
var _store2 = _interopRequireDefault(_store);
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
||
/* eslint-disable no-new */
|
||
new _vue2.default({
|
||
el: 'body',
|
||
store: _store2.default,
|
||
components: { App: _App2.default }
|
||
});
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"./App.vue":155,"./vuex/store":161,"vue":151}],161:[function(require,module,exports){
|
||
_hmr["websocket:null"].initModule("src/vuex/store.js", module);
|
||
(function(){
|
||
'use strict';
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
|
||
var _vue = require('vue');
|
||
|
||
var _vue2 = _interopRequireDefault(_vue);
|
||
|
||
var _vuex = require('vuex');
|
||
|
||
var _vuex2 = _interopRequireDefault(_vuex);
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
||
_vue2.default.use(_vuex2.default);
|
||
_vue2.default.config.debug = true;
|
||
|
||
var state = {
|
||
count: 0
|
||
};
|
||
|
||
var mutations = {
|
||
INCREMENT: function INCREMENT(state) {
|
||
state.count++;
|
||
},
|
||
DECREMENT: function DECREMENT(state) {
|
||
state.count--;
|
||
}
|
||
};
|
||
|
||
exports.default = new _vuex2.default.Store({
|
||
state: state,
|
||
mutations: mutations
|
||
});
|
||
|
||
}).apply(this, arguments);
|
||
|
||
},{"vue":151,"vuex":153}],1:[function(require,module,exports){
|
||
(function(global, _main, moduleDefs, cachedModules, _entries) {
|
||
'use strict';
|
||
|
||
var moduleMeta = {"node_modules/browserify-hmr/lib/has.js":{"index":11,"hash":"Hky4QYVrU1+kFHIEuxPy","parents":["node_modules/browserify-hmr/lib/str-set.js","node_modules/browserify-hmr/inc/index.js"]},"node_modules/process/browser.js":{"index":137,"hash":"d/Dio43QDX3Xt7NYvbr6","parents":["node_modules/vue/dist/vue.common.js"]},"node_modules/vue/dist/vue.common.js":{"index":151,"hash":"1Vqz8fxmKHSuo/7YEUpo","parents":["src/components/Select.vue","src/components/Jumbotron.vue","src/App.vue","src/vuex/store.js","src/main.js"]},"node_modules/parseuri/index.js":{"index":136,"hash":"c/c7XftSI6ClFc9h2jOh","parents":["node_modules/socket.io-client/lib/url.js","node_modules/engine.io-client/lib/socket.js"]},"node_modules/socket.io-client/lib/url.js":{"index":142,"hash":"eA2ffpU7mjSLlYTvz6k0","parents":["node_modules/socket.io-client/lib/index.js"]},"node_modules/debug/browser.js":{"index":46,"hash":"S76q28f1VPJIcCtJn1eq","parents":["node_modules/socket.io-client/lib/url.js","node_modules/socket.io-client/lib/socket.js","node_modules/socket.io-parser/index.js","node_modules/engine.io-client/lib/transports/websocket.js","node_modules/engine.io-client/lib/transports/polling.js","node_modules/engine.io-client/lib/transports/polling-xhr.js","node_modules/engine.io-client/lib/socket.js","node_modules/socket.io-client/lib/manager.js","node_modules/socket.io-client/lib/index.js"]},"node_modules/socket.io-client/lib/on.js":{"index":140,"hash":"y5MOoFpTKKBHwE8q8jae","parents":["node_modules/socket.io-client/lib/socket.js","node_modules/socket.io-client/lib/manager.js"]},"node_modules/socket.io-client/node_modules/component-emitter/index.js":{"index":143,"hash":"asxNeKKEYmnxnAxICTS6","parents":["node_modules/socket.io-client/lib/socket.js","node_modules/socket.io-client/lib/manager.js"]},"node_modules/component-bind/index.js":{"index":13,"hash":"4yIcVw+afwUsnTQyI0a3","parents":["node_modules/socket.io-client/lib/socket.js","node_modules/socket.io-client/lib/manager.js"]},"node_modules/to-array/index.js":{"index":148,"hash":"2EoggafxX+GLXkXiaGjm","parents":["node_modules/socket.io-client/lib/socket.js"]},"node_modules/socket.io-parser/is-buffer.js":{"index":146,"hash":"F42/EWSzWcL1IvKh+yw4","parents":["node_modules/socket.io-parser/binary.js","node_modules/socket.io-parser/index.js"]},"node_modules/isarray/index.js":{"index":64,"hash":"dKtews1S4sHvaZhZ+ceq","parents":["node_modules/has-binary/index.js","node_modules/socket.io-parser/binary.js","node_modules/socket.io-parser/index.js","node_modules/engine.io-parser/node_modules/has-binary/index.js"]},"node_modules/component-emitter/index.js":{"index":14,"hash":"0uL1LSa/mOj+Llu+HTZ7","parents":["node_modules/socket.io-parser/index.js","node_modules/engine.io-client/lib/transport.js","node_modules/engine.io-client/lib/transports/polling-xhr.js","node_modules/engine.io-client/lib/socket.js"]},"node_modules/socket.io-parser/node_modules/json3/lib/json3.js":{"index":147,"hash":"nN5GuS/Ch9onUpX4WT08","parents":["node_modules/socket.io-parser/index.js"]},"node_modules/backo2/index.js":{"index":6,"hash":"L5ry3mfVEw1wgmx9Sa+q","parents":["node_modules/socket.io-client/lib/manager.js"]},"node_modules/indexof/index.js":{"index":63,"hash":"8zMGV0j0ID5bUIeT7r+M","parents":["node_modules/engine.io-client/lib/socket.js","node_modules/socket.io-client/lib/manager.js"]},"node_modules/browserify-hmr/lib/str-set.js":{"index":12,"hash":"lcrDmQK4uaqOqN+FV4/9","parents":["node_modules/browserify-hmr/inc/index.js"]},"node_modules/lodash/internal/arrayFilter.js":{"index":73,"hash":"BGunz0w1QzJXyqQSOdZb","parents":["node_modules/lodash/collection/filter.js"]},"node_modules/lodash/internal/arraySome.js":{"index":75,"hash":"GxeJPxJj2jUg5TzV5gLv","parents":["node_modules/lodash/collection/some.js","node_modules/lodash/internal/equalArrays.js"]},"node_modules/lodash/internal/arrayEach.js":{"index":72,"hash":"eLxUBVsb8vpFbu0VN4KL","parents":["node_modules/lodash/collection/forEach.js"]},"node_modules/lodash/internal/arrayMap.js":{"index":74,"hash":"xdr8c0JsUFapIHTuM5VE","parents":["node_modules/lodash/collection/map.js"]},"node_modules/vueify-insert-css/index.js":{"index":152,"hash":"fvTUijA6yyBpp68H+JX2","parents":["src/components/Select.vue","src/App.vue"]},"node_modules/vue-hot-reload-api/index.js":{"index":150,"hash":"f1FdC0AX0Gv6zyDU4qOs","parents":["src/components/Select.vue","src/components/Jumbotron.vue","src/App.vue"]},"node_modules/ms/index.js":{"index":133,"hash":"HanVKm5AkV6MOdHRAMCT","parents":["node_modules/debug/debug.js"]},"node_modules/debug/debug.js":{"index":47,"hash":"yqdR7nJc7wxIHzFDNzG+","parents":["node_modules/debug/browser.js"]},"node_modules/has-binary/index.js":{"index":61,"hash":"ghM6s7JwI5VY2IMMbY1o","parents":["node_modules/socket.io-client/lib/socket.js"]},"node_modules/socket.io-client/lib/socket.js":{"index":141,"hash":"dZhwrF36uFIGbDZMhss6","parents":["node_modules/socket.io-client/lib/manager.js","node_modules/socket.io-client/lib/index.js"]},"node_modules/socket.io-parser/index.js":{"index":145,"hash":"7PrgORY9faIa3QvXeHjU","parents":["node_modules/socket.io-client/lib/socket.js","node_modules/socket.io-client/lib/manager.js","node_modules/socket.io-client/lib/index.js"]},"node_modules/socket.io-parser/binary.js":{"index":144,"hash":"8I5NRA1rlGtsqsBVMpry","parents":["node_modules/socket.io-parser/index.js"]},"node_modules/lodash/internal/isLength.js":{"index":113,"hash":"DFIKI121VzeE+pBbx1Oa","parents":["node_modules/lodash/internal/createBaseEach.js","node_modules/lodash/internal/isArrayLike.js","node_modules/lodash/lang/isArray.js","node_modules/lodash/object/keysIn.js","node_modules/lodash/internal/shimKeys.js","node_modules/lodash/lang/isTypedArray.js"]},"node_modules/lodash/internal/isObjectLike.js":{"index":114,"hash":"qEGnAWJNoAetOIJ7YKiV","parents":["node_modules/lodash/lang/isNative.js","node_modules/lodash/lang/isArray.js","node_modules/lodash/lang/isArguments.js","node_modules/lodash/lang/isTypedArray.js","node_modules/lodash/internal/baseIsEqual.js"]},"node_modules/lodash/internal/createObjectMapper.js":{"index":102,"hash":"cp8s+Z6khiKdK5QCQ+Ms","parents":["node_modules/lodash/object/mapValues.js"]},"node_modules/lodash/internal/baseCallback.js":{"index":78,"hash":"FDEmxoh1cXY/hddgPNGW","parents":["node_modules/lodash/internal/createObjectMapper.js","node_modules/lodash/collection/map.js","node_modules/lodash/collection/some.js","node_modules/lodash/collection/filter.js"]},"node_modules/lodash/internal/baseForOwn.js":{"index":83,"hash":"sOLmHH2OosmeW92YaLK/","parents":["node_modules/lodash/internal/createObjectMapper.js","node_modules/lodash/internal/baseEach.js","node_modules/lodash/object/forOwn.js"]},"node_modules/lodash/object/mapValues.js":{"index":129,"hash":"2HfAmVuaVGfc8pd5zIaC","parents":["node_modules/browserify-hmr/inc/index.js"]},"node_modules/lodash/utility/identity.js":{"index":131,"hash":"A/cz5O4nnho2x2e5KIWS","parents":["node_modules/lodash/internal/bindCallback.js","node_modules/lodash/internal/baseCallback.js"]},"node_modules/lodash/internal/baseFilter.js":{"index":81,"hash":"yyvQag4hw8sItBFf3/9T","parents":["node_modules/lodash/collection/filter.js"]},"node_modules/lodash/internal/baseEach.js":{"index":80,"hash":"Ji7NLCJhdzSBlpDI+qC3","parents":["node_modules/lodash/internal/baseFilter.js","node_modules/lodash/internal/baseSome.js","node_modules/lodash/internal/baseMap.js","node_modules/lodash/collection/forEach.js"]},"node_modules/lodash/internal/baseSome.js":{"index":94,"hash":"lCW5AtHn9X2vSuPgS8pk","parents":["node_modules/lodash/collection/some.js"]},"node_modules/lodash/internal/isIndex.js":{"index":110,"hash":"I8y5AsjL/lwDlORDOqqM","parents":["node_modules/lodash/internal/isIterateeCall.js","node_modules/lodash/object/keysIn.js","node_modules/lodash/internal/shimKeys.js"]},"node_modules/lodash/lang/isObject.js":{"index":123,"hash":"Go+dTLFqO1KJN+uQLb8s","parents":["node_modules/lodash/internal/toObject.js","node_modules/lodash/internal/isStrictComparable.js","node_modules/lodash/internal/isIterateeCall.js","node_modules/lodash/lang/isFunction.js","node_modules/lodash/object/keysIn.js","node_modules/lodash/object/keys.js","node_modules/lodash/internal/baseIsEqual.js"]},"node_modules/lodash/internal/createForEach.js":{"index":100,"hash":"iJtWBCzx+bzzSLwlaaRv","parents":["node_modules/lodash/collection/forEach.js"]},"node_modules/lodash/lang/isArray.js":{"index":120,"hash":"rpMiE1Z199/XZCjno4KN","parents":["node_modules/lodash/internal/createForEach.js","node_modules/lodash/collection/map.js","node_modules/lodash/internal/isKey.js","node_modules/lodash/internal/toPath.js","node_modules/lodash/collection/some.js","node_modules/lodash/array/zipObject.js","node_modules/lodash/object/keysIn.js","node_modules/lodash/internal/shimKeys.js","node_modules/lodash/internal/baseIsEqualDeep.js","node_modules/lodash/internal/baseMatchesProperty.js","node_modules/lodash/collection/filter.js"]},"node_modules/lodash/internal/bindCallback.js":{"index":96,"hash":"S6iy1I+53IEzDLSGuW0j","parents":["node_modules/lodash/internal/createForEach.js","node_modules/lodash/internal/createForOwn.js","node_modules/lodash/internal/createAssigner.js","node_modules/lodash/internal/baseCallback.js"]},"node_modules/lodash/internal/createForOwn.js":{"index":101,"hash":"KJqijjvJO7d1nU17Sz3c","parents":["node_modules/lodash/object/forOwn.js"]},"node_modules/lodash/function/restParam.js":{"index":71,"hash":"/RRH9MCtjArr1p3Qeh63","parents":["node_modules/lodash/internal/createAssigner.js"]},"node_modules/lodash/internal/createAssigner.js":{"index":97,"hash":"X8R81jvRCofY1BnG+A/L","parents":["node_modules/lodash/object/assign.js"]},"node_modules/lodash/internal/isIterateeCall.js":{"index":111,"hash":"dXMnNRevAizOBisKCEes","parents":["node_modules/lodash/internal/createAssigner.js","node_modules/lodash/collection/some.js"]},"node_modules/lodash/internal/assignWith.js":{"index":76,"hash":"aKBKyfIKqZsNOHAbJTAI","parents":["node_modules/lodash/object/assign.js"]},"node_modules/lodash/object/keys.js":{"index":127,"hash":"BbXGNIcfatSp32uWOBAV","parents":["node_modules/lodash/internal/assignWith.js","node_modules/lodash/internal/baseAssign.js","node_modules/lodash/object/pairs.js","node_modules/lodash/internal/baseForOwn.js","node_modules/lodash/internal/equalObjects.js"]},"node_modules/lodash/internal/baseCopy.js":{"index":79,"hash":"WvGi8IywM6u7ZNXvztwg","parents":["node_modules/lodash/internal/baseAssign.js"]},"node_modules/lodash/internal/baseAssign.js":{"index":77,"hash":"6VX87YoeNgDvMUyiAc/7","parents":["node_modules/lodash/object/assign.js"]},"node_modules/lodash/object/assign.js":{"index":125,"hash":"9WOhJBREl8AO9Hs6Cr+Q","parents":["node_modules/browserify-hmr/inc/index.js"]},"node_modules/lodash/internal/baseMap.js":{"index":88,"hash":"ofv2jCE5QlahpynG4rkN","parents":["node_modules/lodash/collection/map.js"]},"node_modules/lodash/internal/isArrayLike.js":{"index":109,"hash":"76Awthz8ChTgjGk0JZ6Y","parents":["node_modules/lodash/internal/baseMap.js","node_modules/lodash/internal/isIterateeCall.js","node_modules/lodash/lang/isArguments.js","node_modules/lodash/object/keys.js"]},"node_modules/lodash/collection/map.js":{"index":69,"hash":"63n5x8GTiWPuxiZzm9TM","parents":["node_modules/browserify-hmr/inc/index.js"]},"src/countries/simpleCountries.js":{"index":159,"hash":"hLYWkCZR5WGzTBCM7Si4","parents":["src/components/Jumbotron.vue"]},"src/countries/countries.js":{"index":158,"hash":"X8uY48ZCe9q8spDOiZgi","parents":["src/components/Jumbotron.vue"]},"node_modules/lodash/internal/baseProperty.js":{"index":91,"hash":"Yuk2tpof21q0Xl2sQg89","parents":["node_modules/lodash/utility/property.js","node_modules/lodash/internal/getLength.js"]},"node_modules/lodash/internal/baseSlice.js":{"index":93,"hash":"OLgw9XVic1W0AKjehzHB","parents":["node_modules/lodash/internal/baseMatchesProperty.js"]},"node_modules/lodash/array/last.js":{"index":65,"hash":"3oXXa2idWbKySVLcq3os","parents":["node_modules/lodash/internal/baseMatchesProperty.js"]},"node_modules/lodash/internal/createBaseEach.js":{"index":98,"hash":"+5X3Ztm78NNPr9vQZ7fB","parents":["node_modules/lodash/internal/baseEach.js"]},"node_modules/lodash/internal/getLength.js":{"index":106,"hash":"UiZ6F0+nXZ0fiKckTqnM","parents":["node_modules/lodash/internal/createBaseEach.js","node_modules/lodash/internal/isArrayLike.js"]},"node_modules/lodash/internal/toObject.js":{"index":117,"hash":"8f3eulB97DddBRdcU+7v","parents":["node_modules/lodash/internal/createBaseEach.js","node_modules/lodash/internal/isKey.js","node_modules/lodash/internal/baseIsMatch.js","node_modules/lodash/internal/baseGet.js","node_modules/lodash/internal/createBaseFor.js","node_modules/lodash/object/pairs.js","node_modules/lodash/internal/baseMatches.js","node_modules/lodash/internal/baseMatchesProperty.js"]},"node_modules/lodash/collection/forEach.js":{"index":68,"hash":"0Lo1RNt18PMo/HAKbHEu","parents":["node_modules/browserify-hmr/inc/index.js"]},"node_modules/engine.io-parser/lib/keys.js":{"index":59,"hash":"oFyKNTA0twlyQVhVzp9n","parents":["node_modules/engine.io-parser/lib/browser.js"]},"node_modules/arraybuffer.slice/index.js":{"index":3,"hash":"RSb5Zx9CgX3adjzbvf/k","parents":["node_modules/engine.io-parser/lib/browser.js"]},"node_modules/blob/index.js":{"index":8,"hash":"oJwgFCPr7Au6OHJnm0nr","parents":["node_modules/engine.io-parser/lib/browser.js"]},"node_modules/utf8/utf8.js":{"index":149,"hash":"Hbc0UH3rEqjp72mfznNr","parents":["node_modules/engine.io-parser/lib/browser.js"]},"node_modules/after/index.js":{"index":2,"hash":"NzPfXWECmM8rW/6fdkcj","parents":["node_modules/engine.io-parser/lib/browser.js"]},"node_modules/base64-arraybuffer/lib/base64-arraybuffer.js":{"index":7,"hash":"dW6cnktjBIyZ6bv9vRp2","parents":["node_modules/engine.io-parser/lib/browser.js"]},"node_modules/parseqs/index.js":{"index":135,"hash":"FI4tRELwI5Itz+ckwR+m","parents":["node_modules/engine.io-client/lib/transports/websocket.js","node_modules/engine.io-client/lib/transports/polling.js","node_modules/engine.io-client/lib/socket.js"]},"node_modules/parsejson/index.js":{"index":134,"hash":"t92555Kfo3kvbKzdtU/P","parents":["node_modules/engine.io-client/lib/socket.js"]},"node_modules/lodash/internal/isKey.js":{"index":112,"hash":"lDpw5crcRmTRExTLVTKc","parents":["node_modules/lodash/utility/property.js","node_modules/lodash/internal/baseMatchesProperty.js"]},"node_modules/lodash/internal/basePropertyDeep.js":{"index":92,"hash":"mqX1OyYdndJ183lyl/sn","parents":["node_modules/lodash/utility/property.js"]},"node_modules/lodash/internal/baseGet.js":{"index":84,"hash":"H9EiMd3ullQpRkvooLgz","parents":["node_modules/lodash/internal/basePropertyDeep.js","node_modules/lodash/internal/baseMatchesProperty.js"]},"node_modules/lodash/internal/toPath.js":{"index":118,"hash":"faVQvsb+LSLI4uaMgtrQ","parents":["node_modules/lodash/internal/basePropertyDeep.js","node_modules/lodash/internal/baseMatchesProperty.js"]},"node_modules/lodash/utility/property.js":{"index":132,"hash":"7IoOI/uGZCxbcY23uQDK","parents":["node_modules/lodash/internal/baseCallback.js"]},"node_modules/lodash/internal/baseIsMatch.js":{"index":87,"hash":"EpuJzlg204aR35T4QKcS","parents":["node_modules/lodash/internal/baseMatches.js"]},"node_modules/lodash/internal/baseIsEqual.js":{"index":85,"hash":"dBgoFXnhj9KH6oX3dQwa","parents":["node_modules/lodash/internal/baseIsMatch.js","node_modules/lodash/internal/baseMatchesProperty.js"]},"node_modules/lodash/internal/isStrictComparable.js":{"index":115,"hash":"ofNP4/nFrz5Rkb3kGOhn","parents":["node_modules/lodash/internal/getMatchData.js","node_modules/lodash/internal/baseMatchesProperty.js"]},"node_modules/lodash/internal/baseToString.js":{"index":95,"hash":"ABFQFf14pRECi3sw8oKV","parents":["node_modules/lodash/internal/toPath.js"]},"node_modules/lodash/collection/some.js":{"index":70,"hash":"9JyJFfdCx56pmR6fwM9q","parents":["node_modules/browserify-hmr/inc/index.js"]},"node_modules/lodash/internal/createBaseFor.js":{"index":99,"hash":"9RWlFaBOuelvwgkhYgPG","parents":["node_modules/lodash/internal/baseFor.js"]},"node_modules/lodash/internal/baseFor.js":{"index":82,"hash":"NGxcZ0n01+w2G1PzyBlY","parents":["node_modules/lodash/internal/baseForOwn.js"]},"node_modules/engine.io-parser/node_modules/has-binary/index.js":{"index":60,"hash":"aWcciZgvEP4tdxYE2Lfd","parents":["node_modules/engine.io-parser/lib/browser.js"]},"node_modules/engine.io-parser/lib/browser.js":{"index":58,"hash":"X3Q3m2C/zJbJqzepYCjy","parents":["node_modules/engine.io-client/lib/transport.js","node_modules/engine.io-client/lib/transports/websocket.js","node_modules/engine.io-client/lib/transports/polling.js","node_modules/engine.io-client/lib/socket.js","node_modules/engine.io-client/lib/index.js"]},"node_modules/engine.io-client/lib/transport.js":{"index":51,"hash":"qAS1jC8gVTG4yb/AanoB","parents":["node_modules/engine.io-client/lib/transports/websocket.js","node_modules/engine.io-client/lib/transports/polling.js","node_modules/engine.io-client/lib/socket.js"]},"node_modules/browser-resolve/empty.js":{"index":9,"hash":"47DEQpj8HBSa+/TImW+5","parents":["node_modules/engine.io-client/lib/transports/websocket.js"]},"node_modules/lodash/lang/isFunction.js":{"index":121,"hash":"xkfzrZNZPGGOIf0kE8Y9","parents":["node_modules/lodash/lang/isNative.js"]},"node_modules/lodash/lang/isNative.js":{"index":122,"hash":"2rstaALy1DW0JSDdijps","parents":["node_modules/lodash/internal/getNative.js"]},"node_modules/lodash/internal/getNative.js":{"index":108,"hash":"7GRZ7115BSuoc/1bdaBK","parents":["node_modules/lodash/lang/isArray.js","node_modules/lodash/object/keys.js"]},"node_modules/lodash/array/zipObject.js":{"index":66,"hash":"fKfSwIzPo5SUx9d0DkgN","parents":["node_modules/browserify-hmr/inc/index.js"]},"node_modules/lodash/object/pairs.js":{"index":130,"hash":"x6Ilwx8encvg/BW5API2","parents":["node_modules/lodash/internal/getMatchData.js"]},"node_modules/lodash/internal/getMatchData.js":{"index":107,"hash":"n0PHWhNs6YZ+DzgYMHPx","parents":["node_modules/lodash/internal/baseMatches.js"]},"node_modules/lodash/internal/baseMatches.js":{"index":89,"hash":"Cwj5GSiQv9/E8nSFBoX2","parents":["node_modules/lodash/internal/baseCallback.js"]},"node_modules/lodash/internal/equalByTag.js":{"index":104,"hash":"+y++gesJpPvyM+2E8aNB","parents":["node_modules/lodash/internal/baseIsEqualDeep.js"]},"node_modules/lodash/lang/isArguments.js":{"index":119,"hash":"xQ4mqbsKQMCmtsPbfQc6","parents":["node_modules/lodash/object/keysIn.js","node_modules/lodash/internal/shimKeys.js"]},"node_modules/lodash/object/keysIn.js":{"index":128,"hash":"8POZiGR1fRHso579G46Z","parents":["node_modules/lodash/internal/shimKeys.js"]},"node_modules/lodash/internal/shimKeys.js":{"index":116,"hash":"oO4aKopmxRfPxyKgRX9F","parents":["node_modules/lodash/object/keys.js"]},"node_modules/lodash/object/forOwn.js":{"index":126,"hash":"LZ77PzuJW/wlgVPdvlGc","parents":["node_modules/browserify-hmr/inc/index.js"]},"node_modules/has-cors/index.js":{"index":62,"hash":"HwTb4UF/S089ZYA8hrRl","parents":["node_modules/engine.io-client/lib/xmlhttprequest.js"]},"node_modules/engine.io-client/lib/xmlhttprequest.js":{"index":57,"hash":"us0FsN5s7hiT3hqVV5lx","parents":["node_modules/engine.io-client/lib/transports/polling.js","node_modules/engine.io-client/lib/transports/polling-xhr.js","node_modules/engine.io-client/lib/transports/index.js"]},"node_modules/yeast/index.js":{"index":154,"hash":"ZM3+5w4l/D2f6x7svySF","parents":["node_modules/engine.io-client/lib/transports/websocket.js","node_modules/engine.io-client/lib/transports/polling.js"]},"node_modules/component-inherit/index.js":{"index":15,"hash":"T0Fqch4d4akvlr8bh7lc","parents":["node_modules/engine.io-client/lib/transports/websocket.js","node_modules/engine.io-client/lib/transports/polling-jsonp.js","node_modules/engine.io-client/lib/transports/polling.js","node_modules/engine.io-client/lib/transports/polling-xhr.js"]},"node_modules/engine.io-client/lib/transports/websocket.js":{"index":56,"hash":"ZRSUX1iAUU5kMC9oN9hc","parents":["node_modules/engine.io-client/lib/transports/index.js"]},"node_modules/engine.io-client/lib/transports/polling-jsonp.js":{"index":53,"hash":"cw0j0n9JiZAG/Al34gBk","parents":["node_modules/engine.io-client/lib/transports/index.js"]},"node_modules/engine.io-client/lib/transports/polling.js":{"index":55,"hash":"vdgStJPJzZrXTQesqN8z","parents":["node_modules/engine.io-client/lib/transports/polling-jsonp.js","node_modules/engine.io-client/lib/transports/polling-xhr.js"]},"node_modules/lodash/internal/equalArrays.js":{"index":103,"hash":"OBJL6vuaOotu5flUeCnv","parents":["node_modules/lodash/internal/baseIsEqualDeep.js"]},"node_modules/lodash/internal/equalObjects.js":{"index":105,"hash":"44Iy49kDcaAZsykEdaH3","parents":["node_modules/lodash/internal/baseIsEqualDeep.js"]},"node_modules/lodash/lang/isTypedArray.js":{"index":124,"hash":"aVeZyIFGadrEh7EsaDRu","parents":["node_modules/lodash/internal/baseIsEqualDeep.js"]},"node_modules/lodash/internal/baseIsEqualDeep.js":{"index":86,"hash":"ltZZaMHmzp6d9jBltV3Y","parents":["node_modules/lodash/internal/baseIsEqual.js"]},"node_modules/lodash/internal/baseMatchesProperty.js":{"index":90,"hash":"OudnSoeq2A4ql5lg51kc","parents":["node_modules/lodash/internal/baseCallback.js"]},"node_modules/lodash/collection/filter.js":{"index":67,"hash":"XtU5zjCqSDlYcwOLUC13","parents":["node_modules/browserify-hmr/inc/index.js"]},"node_modules/browserify-hmr/inc/index.js":{"index":10,"hash":"azyGnExX2uVlPI7oM92b","parents":[]},"node_modules/core-js/library/modules/$.core.js":{"index":20,"hash":"jO6z5PVz8f6aTUjm5Hrx","parents":["node_modules/core-js/library/modules/$.export.js","node_modules/core-js/library/fn/symbol/index.js"]},"node_modules/core-js/library/modules/es6.object.to-string.js":{"index":44,"hash":"47DEQpj8HBSa+/TImW+5","parents":["node_modules/core-js/library/fn/symbol/index.js"]},"node_modules/engine.io-client/lib/transports/polling-xhr.js":{"index":54,"hash":"idg/D5BOlsKB6+2V6pPe","parents":["node_modules/engine.io-client/lib/transports/index.js"]},"node_modules/engine.io-client/lib/transports/index.js":{"index":52,"hash":"T2DiP0RY+tM6z+OQNF75","parents":["node_modules/engine.io-client/lib/socket.js"]},"node_modules/engine.io-client/lib/socket.js":{"index":50,"hash":"XSGlEwnfJ+YGqRI033+d","parents":["node_modules/engine.io-client/lib/index.js"]},"node_modules/engine.io-client/lib/index.js":{"index":49,"hash":"G6QYuSNu0EcS+G5tR9NE","parents":["node_modules/engine.io-client/index.js"]},"node_modules/engine.io-client/index.js":{"index":48,"hash":"HQau4MkD4lAynB9tt0Wl","parents":["node_modules/socket.io-client/lib/manager.js"]},"node_modules/socket.io-client/lib/manager.js":{"index":139,"hash":"ycazfyz0LQGPtd/P1Ih9","parents":["node_modules/socket.io-client/lib/index.js"]},"node_modules/socket.io-client/lib/index.js":{"index":138,"hash":"6O21Z/SJToLoAyfVkS1+","parents":[]},"node_modules/core-js/library/modules/$.has.js":{"index":29,"hash":"y4idiH2Sj/rmZqd39CHH","parents":["node_modules/core-js/library/modules/$.set-to-string-tag.js","node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.js":{"index":34,"hash":"UI1ymRgurU07soRpiobz","parents":["node_modules/core-js/library/modules/$.set-to-string-tag.js","node_modules/core-js/library/modules/$.keyof.js","node_modules/core-js/library/modules/$.enum-keys.js","node_modules/core-js/library/modules/$.get-names.js","node_modules/core-js/library/modules/$.hide.js","node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.fails.js":{"index":26,"hash":"6G4+YXaRghTGQQnkm/qp","parents":["node_modules/core-js/library/modules/$.descriptors.js","node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.global.js":{"index":28,"hash":"t7QKkyeVEU+gGSy/l5Cc","parents":["node_modules/core-js/library/modules/$.shared.js","node_modules/core-js/library/modules/$.wks.js","node_modules/core-js/library/modules/$.export.js","node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.uid.js":{"index":42,"hash":"auy0a5KBxuU7QAdJ7we/","parents":["node_modules/core-js/library/modules/$.wks.js","node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.property-desc.js":{"index":37,"hash":"iSs9jpAw1JT2ZWWLScSH","parents":["node_modules/core-js/library/modules/$.hide.js","node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.library.js":{"index":36,"hash":"Bhgn5RpO7pDcQnSVaI5C","parents":["node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.descriptors.js":{"index":23,"hash":"NJqnAOVs55bKea+gKIGt","parents":["node_modules/core-js/library/modules/$.hide.js","node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.shared.js":{"index":40,"hash":"ZK+Tn2LANbB4OqkscM3N","parents":["node_modules/core-js/library/modules/$.wks.js","node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.set-to-string-tag.js":{"index":39,"hash":"3G0pjz42ePfLP++caEH3","parents":["node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.wks.js":{"index":43,"hash":"qMliszffX6kySHptJTIp","parents":["node_modules/core-js/library/modules/$.set-to-string-tag.js","node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.keyof.js":{"index":35,"hash":"QAkD89X3k/nEd4vAmyCz","parents":["node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.to-iobject.js":{"index":41,"hash":"yp4UOuCLRVO1tqlgppw5","parents":["node_modules/core-js/library/modules/$.keyof.js","node_modules/core-js/library/modules/$.get-names.js","node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.enum-keys.js":{"index":24,"hash":"d/Ib2kcvofwv5M39O14Y","parents":["node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.get-names.js":{"index":27,"hash":"YHazxvllS2UBE+8VU/uH","parents":["node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.is-object.js":{"index":33,"hash":"FkaOOMIm0uw4T/qUEXed","parents":["node_modules/core-js/library/modules/$.an-object.js"]},"node_modules/core-js/library/modules/$.an-object.js":{"index":18,"hash":"d7pCynXJhKpK2u1S0fph","parents":["node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.cof.js":{"index":19,"hash":"FY6tg0ymdCS/rEwpAa7R","parents":["node_modules/core-js/library/modules/$.is-array.js","node_modules/core-js/library/modules/$.iobject.js"]},"node_modules/core-js/library/modules/$.is-array.js":{"index":32,"hash":"xN9Fwd6YjBUWmVzBxcVm","parents":["node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.defined.js":{"index":22,"hash":"RZr8uFl+WrrjvGzPSz3c","parents":["node_modules/core-js/library/modules/$.to-iobject.js"]},"node_modules/core-js/library/modules/$.iobject.js":{"index":31,"hash":"HvETp5p0zMBjh+wvjxSm","parents":["node_modules/core-js/library/modules/$.to-iobject.js"]},"node_modules/core-js/library/modules/$.hide.js":{"index":30,"hash":"2HBwvxEtbt4UpskOWy62","parents":["node_modules/core-js/library/modules/$.redefine.js"]},"node_modules/core-js/library/modules/$.redefine.js":{"index":38,"hash":"v4z59Kie6WPVO1h+8oJP","parents":["node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/$.a-function.js":{"index":17,"hash":"vI7NBVNoKizw/T7ablYt","parents":["node_modules/core-js/library/modules/$.ctx.js"]},"node_modules/core-js/library/modules/$.ctx.js":{"index":21,"hash":"IBAqoysxf6uGe4qIslFW","parents":["node_modules/core-js/library/modules/$.export.js"]},"node_modules/core-js/library/modules/$.export.js":{"index":25,"hash":"tF6TuwqA3fLdeFKqSI9n","parents":["node_modules/core-js/library/modules/es6.symbol.js"]},"node_modules/core-js/library/modules/es6.symbol.js":{"index":45,"hash":"RB3U/3ZSwfWuCvaaW2A4","parents":["node_modules/core-js/library/fn/symbol/index.js"]},"node_modules/core-js/library/fn/symbol/index.js":{"index":16,"hash":"2EnyuJY8T+YSjL7XPyTs","parents":["node_modules/babel-runtime/core-js/symbol.js"]},"node_modules/babel-runtime/core-js/symbol.js":{"index":4,"hash":"aiWeZ2ndRLi+VSl8A+j6","parents":["node_modules/babel-runtime/helpers/typeof.js"]},"node_modules/babel-runtime/helpers/typeof.js":{"index":5,"hash":"EmXNwlygan5mvsdVpEzI","parents":["src/components/Select.vue"]},"src/components/Select.vue":{"index":157,"hash":"wlg8anPzo8gxDM6p0Cs7","parents":["src/components/Jumbotron.vue"]},"src/components/Jumbotron.vue":{"index":156,"hash":"XTffrFkQCRxXIb0VJWLn","parents":["src/App.vue"]},"src/App.vue":{"index":155,"hash":"CamSgByskedxduMbol7z","parents":["src/main.js"]},"node_modules/vuex/dist/vuex.js":{"index":153,"hash":"gX//W6yHs/IFY/kkM/lI","parents":["src/vuex/store.js"]},"src/vuex/store.js":{"index":161,"hash":"hwHd4AxvLYr1C+NBOgh/","parents":["src/main.js"]},"src/main.js":{"index":160,"hash":"z2sdYiItshBNRWvsUwFd","parents":[]}};
|
||
var originalEntries = ["/Volumes/Documents/Dropbox/htdocs/vue-select/src/main.js"];
|
||
var updateUrl = null;
|
||
var updateMode = "websocket";
|
||
var supportModes = ["none","websocket"];
|
||
var ignoreUnaccepted = true;
|
||
var updateCacheBust = false;
|
||
var bundleKey = "websocket:null";
|
||
var sioPath = "./node_modules/socket.io-client/lib/index.js";
|
||
var incPath = "./node_modules/browserify-hmr/inc/index.js";
|
||
|
||
if (!global._hmr) {
|
||
try {
|
||
Object.defineProperty(global, '_hmr', {value: {}});
|
||
} catch(e) {
|
||
global._hmr = {};
|
||
}
|
||
}
|
||
|
||
if (!Object.prototype.hasOwnProperty.call(global._hmr, bundleKey)) {
|
||
// Temporary hack so requiring modules works before the _hmr values are
|
||
// correctly initialized.
|
||
global._hmr[bundleKey] = {initModule: function(){}};
|
||
}
|
||
|
||
var main = require(incPath);
|
||
var isFirstRun = main(
|
||
moduleDefs, cachedModules, moduleMeta, updateUrl,
|
||
updateMode, supportModes, ignoreUnaccepted, updateCacheBust, bundleKey,
|
||
sioPath ? require(sioPath) : null,
|
||
typeof __filename !== 'undefined' && __filename,
|
||
typeof __dirname !== 'undefined' && __dirname
|
||
);
|
||
if (isFirstRun) {
|
||
for (var i=0, len=originalEntries.length; i<len; i++) {
|
||
require(originalEntries[i]);
|
||
}
|
||
}
|
||
}).call(
|
||
this,
|
||
typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},
|
||
arguments[3], arguments[4], arguments[5], arguments[6]
|
||
);
|
||
|
||
},{"./node_modules/browserify-hmr/inc/index.js":10,"./node_modules/socket.io-client/lib/index.js":138,"/Volumes/Documents/Dropbox/htdocs/vue-select/src/main.js":160}]},{},[1])
|
||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvYWZ0ZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYXJyYXlidWZmZXIuc2xpY2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYmFiZWwtcnVudGltZS9jb3JlLWpzL3N5bWJvbC5qcyIsIm5vZGVfbW9kdWxlcy9iYWJlbC1ydW50aW1lL2hlbHBlcnMvdHlwZW9mLmpzIiwibm9kZV9tb2R1bGVzL2JhY2tvMi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9iYXNlNjQtYXJyYXlidWZmZXIvbGliL2Jhc2U2NC1hcnJheWJ1ZmZlci5qcyIsIm5vZGVfbW9kdWxlcy9ibG9iL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXItcmVzb2x2ZS9lbXB0eS5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWhtci9pbmMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1obXIvbGliL2hhcy5qcyIsIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWhtci9saWIvc3RyLXNldC5qcyIsIm5vZGVfbW9kdWxlcy9jb21wb25lbnQtYmluZC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9jb21wb25lbnQtZW1pdHRlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9jb21wb25lbnQtaW5oZXJpdC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvZm4vc3ltYm9sL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuYS1mdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmFuLW9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmNvZi5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmNvcmUuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5jdHguanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5kZWZpbmVkLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuZGVzY3JpcHRvcnMuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5lbnVtLWtleXMuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5leHBvcnQuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5mYWlscy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmdldC1uYW1lcy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmdsb2JhbC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmhhcy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmhpZGUuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5pb2JqZWN0LmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuaXMtYXJyYXkuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5pcy1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmtleW9mLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQubGlicmFyeS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnByb3BlcnR5LWRlc2MuanMiLCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5yZWRlZmluZS5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnNldC10by1zdHJpbmctdGFnLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuc2hhcmVkLmpzIiwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQudG8taW9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnVpZC5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLndrcy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYuc3ltYm9sLmpzIiwibm9kZV9tb2R1bGVzL2RlYnVnL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvZGVidWcvZGVidWcuanMiLCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi9zb2NrZXQuanMiLCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLWpzb25wLmpzIiwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvcG9sbGluZy14aHIuanMiLCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLmpzIiwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvd2Vic29ja2V0LmpzIiwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3htbGh0dHByZXF1ZXN0LmpzIiwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbGliL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIva2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tcGFyc2VyL25vZGVfbW9kdWxlcy9oYXMtYmluYXJ5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2hhcy1iaW5hcnkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaGFzLWNvcnMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvaW5kZXhvZi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9hcnJheS9sYXN0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9hcnJheS96aXBPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2NvbGxlY3Rpb24vZmlsdGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9jb2xsZWN0aW9uL2ZvckVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2NvbGxlY3Rpb24vbWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9jb2xsZWN0aW9uL3NvbWUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2Z1bmN0aW9uL3Jlc3RQYXJhbS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYXJyYXlFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9hcnJheUZpbHRlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYXJyYXlNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2FycmF5U29tZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYXNzaWduV2l0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUFzc2lnbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUNhbGxiYWNrLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlQ29weS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VGaWx0ZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VGb3JPd24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VHZXQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VJc0VxdWFsLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlSXNFcXVhbERlZXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VJc01hdGNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlTWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlTWF0Y2hlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZU1hdGNoZXNQcm9wZXJ0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlUHJvcGVydHlEZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlU2xpY2UuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VTb21lLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlVG9TdHJpbmcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2JpbmRDYWxsYmFjay5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvY3JlYXRlQXNzaWduZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2NyZWF0ZUJhc2VFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVCYXNlRm9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVGb3JPd24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2NyZWF0ZU9iamVjdE1hcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvZXF1YWxBcnJheXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2VxdWFsQnlUYWcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2VxdWFsT2JqZWN0cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvZ2V0TGVuZ3RoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9nZXRNYXRjaERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2dldE5hdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvaXNBcnJheUxpa2UuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2lzSW5kZXguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2lzSXRlcmF0ZWVDYWxsLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9pc0tleS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvaXNMZW5ndGguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2lzT2JqZWN0TGlrZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvaXNTdHJpY3RDb21wYXJhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9zaGltS2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvdG9PYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL3RvUGF0aC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvbGFuZy9pc0FyZ3VtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvbGFuZy9pc0FycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9sYW5nL2lzRnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2xhbmcvaXNOYXRpdmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2xhbmcvaXNPYmplY3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2xhbmcvaXNUeXBlZEFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9vYmplY3QvYXNzaWduLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9vYmplY3QvZm9yT3duLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9vYmplY3Qva2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L2tleXNJbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L21hcFZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L3BhaXJzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC91dGlsaXR5L2lkZW50aXR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC91dGlsaXR5L3Byb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL21zL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3BhcnNlanNvbi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9wYXJzZXFzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3BhcnNldXJpL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi9tYW5hZ2VyLmpzIiwibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL29uLmpzIiwibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL3NvY2tldC5qcyIsIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi91cmwuanMiLCJub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9iaW5hcnkuanMiLCJub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tcGFyc2VyL2lzLWJ1ZmZlci5qcyIsIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tcGFyc2VyL25vZGVfbW9kdWxlcy9qc29uMy9saWIvanNvbjMuanMiLCJub2RlX21vZHVsZXMvdG8tYXJyYXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvdXRmOC91dGY4LmpzIiwibm9kZV9tb2R1bGVzL3Z1ZS1ob3QtcmVsb2FkLWFwaS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy92dWUvZGlzdC92dWUuY29tbW9uLmpzIiwibm9kZV9tb2R1bGVzL3Z1ZWlmeS1pbnNlcnQtY3NzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3Z1ZXgvZGlzdC92dWV4LmpzIiwibm9kZV9tb2R1bGVzL3llYXN0L2luZGV4LmpzIiwic3JjL0FwcC52dWUiLCJzcmMvY29tcG9uZW50cy9KdW1ib3Ryb24udnVlIiwic3JjL2NvbXBvbmVudHMvU2VsZWN0LnZ1ZSIsInNyYy9jb3VudHJpZXMvY291bnRyaWVzLmpzIiwic3JjL2NvdW50cmllcy9zaW1wbGVDb3VudHJpZXMuanMiLCJzcmMvbWFpbi5qcyIsInNyYy92dWV4L3N0b3JlLmpzIiwiX19obXJfbWFuYWdlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQzVCQSx1Rjs7Ozs7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCOzs7Ozs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7OztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0FDaEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUNscEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQzFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNuS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRTs7Ozs7O0FDTkE7QUFDQTtBQUNBLHdEOzs7Ozs7QUNGQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7OztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRTs7Ozs7O0FDSkE7QUFDQSxxRTs7Ozs7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNKQTtBQUNBO0FBQ0E7QUFDQSxHOzs7Ozs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7OztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCOzs7Ozs7QUM3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRTs7Ozs7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNuQkE7QUFDQTtBQUNBO0FBQ0EsdUU7Ozs7OztBQ0hBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7OztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRTs7Ozs7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7OztBQ0pBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNUQSxzQjs7Ozs7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNQQSxxQzs7Ozs7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRTs7Ozs7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7OztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFOzs7Ozs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7OztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEU7Ozs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQzs7Ozs7O0FDbE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3ZLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDcE1BO0FBQ0E7Ozs7Ozs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDeHRCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7OztBQzFKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7OztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7QUM5T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUM1WkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDdFBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7OztBQ2hTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7OztBQ2xsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7OztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRTs7Ozs7O0FDVEE7QUFDQTtBQUNBOzs7Ozs7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNyR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNuREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ2xEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDNUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7O0FDM0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUM1aUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUMzWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUM1RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUNoS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDN0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7OztBQy9ZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDdDRCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7OztBQ3BQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7QUN6U0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7O0FDMTlTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEk7Ozs7OztBQy9qQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7OztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSzs7Ozs7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEs7Ozs7OztBQzFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSzs7Ozs7Ozs7QUNqTkEsT0FBTyxPQUFQLEdBQWlCLENBQ0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGFBQVAsRUFEWCxFQUVILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxlQUFQLEVBRlgsRUFHSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQUhYLEVBSUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUFKWCxFQUtILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxnQkFBUCxFQUxYLEVBTUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUFOWCxFQU9ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxRQUFQLEVBUFgsRUFRSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sVUFBUCxFQVJYLEVBU0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFlBQVAsRUFUWCxFQVVILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxxQkFBUCxFQVZYLEVBV0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFdBQVAsRUFYWCxFQVlILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxTQUFQLEVBWlgsRUFhSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sT0FBUCxFQWJYLEVBY0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFdBQVAsRUFkWCxFQWVILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxTQUFQLEVBZlgsRUFnQkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFlBQVAsRUFoQlgsRUFpQkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUFqQlgsRUFrQkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUFsQlgsRUFtQkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFlBQVAsRUFuQlgsRUFvQkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFVBQVAsRUFwQlgsRUFxQkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUFyQlgsRUFzQkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUF0QlgsRUF1QkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFFBQVAsRUF2QlgsRUF3QkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLE9BQVAsRUF4QlgsRUF5QkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUF6QlgsRUEwQkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFFBQVAsRUExQlgsRUEyQkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUEzQlgsRUE0QkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLHdCQUFQLEVBNUJYLEVBNkJILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxVQUFQLEVBN0JYLEVBOEJILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxlQUFQLEVBOUJYLEVBK0JILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxRQUFQLEVBL0JYLEVBZ0NILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxnQ0FBUCxFQWhDWCxFQWlDSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sbUJBQVAsRUFqQ1gsRUFrQ0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFVBQVAsRUFsQ1gsRUFtQ0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGNBQVAsRUFuQ1gsRUFvQ0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUFwQ1gsRUFxQ0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFVBQVAsRUFyQ1gsRUFzQ0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFVBQVAsRUF0Q1gsRUF1Q0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFFBQVAsRUF2Q1gsRUF3Q0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFlBQVAsRUF4Q1gsRUF5Q0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGdCQUFQLEVBekNYLEVBMENILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTywwQkFBUCxFQTFDWCxFQTJDSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sTUFBUCxFQTNDWCxFQTRDSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sT0FBUCxFQTVDWCxFQTZDSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sT0FBUCxFQTdDWCxFQThDSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sa0JBQVAsRUE5Q1gsRUErQ0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLHlCQUFQLEVBL0NYLEVBZ0RILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxVQUFQLEVBaERYLEVBaURILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxTQUFQLEVBakRYLEVBa0RILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxPQUFQLEVBbERYLEVBbURILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyx1Q0FBUCxFQW5EWCxFQW9ESCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sY0FBUCxFQXBEWCxFQXFESCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sWUFBUCxFQXJEWCxFQXNESCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sZUFBUCxFQXREWCxFQXVESCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQXZEWCxFQXdESCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sTUFBUCxFQXhEWCxFQXlESCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQXpEWCxFQTBESCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sZ0JBQVAsRUExRFgsRUEyREgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUEzRFgsRUE0REgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFVBQVAsRUE1RFgsRUE2REgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFVBQVAsRUE3RFgsRUE4REgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLG9CQUFQLEVBOURYLEVBK0RILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxTQUFQLEVBL0RYLEVBZ0VILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxPQUFQLEVBaEVYLEVBaUVILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxhQUFQLEVBakVYLEVBa0VILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxtQkFBUCxFQWxFWCxFQW1FSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQW5FWCxFQW9FSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQXBFWCxFQXFFSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sVUFBUCxFQXJFWCxFQXNFSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sNkJBQVAsRUF0RVgsRUF1RUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGVBQVAsRUF2RVgsRUF3RUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLE1BQVAsRUF4RVgsRUF5RUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUF6RVgsRUEwRUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFFBQVAsRUExRVgsRUEyRUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGVBQVAsRUEzRVgsRUE0RUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGtCQUFQLEVBNUVYLEVBNkVILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyw2QkFBUCxFQTdFWCxFQThFSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sT0FBUCxFQTlFWCxFQStFSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQS9FWCxFQWdGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQWhGWCxFQWlGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQWpGWCxFQWtGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sT0FBUCxFQWxGWCxFQW1GSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sV0FBUCxFQW5GWCxFQW9GSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQXBGWCxFQXFGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sV0FBUCxFQXJGWCxFQXNGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQXRGWCxFQXVGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sWUFBUCxFQXZGWCxFQXdGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sTUFBUCxFQXhGWCxFQXlGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sV0FBUCxFQXpGWCxFQTBGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sVUFBUCxFQTFGWCxFQTJGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQTNGWCxFQTRGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sZUFBUCxFQTVGWCxFQTZGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQTdGWCxFQThGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sT0FBUCxFQTlGWCxFQStGSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sbUNBQVAsRUEvRlgsRUFnR0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLCtCQUFQLEVBaEdYLEVBaUdILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxVQUFQLEVBakdYLEVBa0dILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxXQUFQLEVBbEdYLEVBbUdILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxTQUFQLEVBbkdYLEVBb0dILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxTQUFQLEVBcEdYLEVBcUdILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxPQUFQLEVBckdYLEVBc0dILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxXQUFQLEVBdEdYLEVBdUdILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTywyQkFBUCxFQXZHWCxFQXdHSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sTUFBUCxFQXhHWCxFQXlHSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQXpHWCxFQTBHSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sYUFBUCxFQTFHWCxFQTJHSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQTNHWCxFQTRHSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sT0FBUCxFQTVHWCxFQTZHSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQTdHWCxFQThHSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sT0FBUCxFQTlHWCxFQStHSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQS9HWCxFQWdISCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQWhIWCxFQWlISCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sWUFBUCxFQWpIWCxFQWtISCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sT0FBUCxFQWxIWCxFQW1ISCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sVUFBUCxFQW5IWCxFQW9ISCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sd0NBQVAsRUFwSFgsRUFxSEgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLG9CQUFQLEVBckhYLEVBc0hILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxRQUFQLEVBdEhYLEVBdUhILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxZQUFQLEVBdkhYLEVBd0hILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxrQ0FBUCxFQXhIWCxFQXlISCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQXpIWCxFQTBISCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQTFIWCxFQTJISCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQTNIWCxFQTRISCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQTVIWCxFQTZISCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sd0JBQVAsRUE3SFgsRUE4SEgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGVBQVAsRUE5SFgsRUErSEgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFdBQVAsRUEvSFgsRUFnSUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFlBQVAsRUFoSVgsRUFpSUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLE9BQVAsRUFqSVgsRUFrSUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLDRDQUFQLEVBbElYLEVBbUlILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxZQUFQLEVBbklYLEVBb0lILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxRQUFQLEVBcElYLEVBcUlILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxVQUFQLEVBcklYLEVBc0lILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxVQUFQLEVBdElYLEVBdUlILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxNQUFQLEVBdklYLEVBd0lILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxPQUFQLEVBeElYLEVBeUlILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxrQkFBUCxFQXpJWCxFQTBJSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sWUFBUCxFQTFJWCxFQTJJSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sWUFBUCxFQTNJWCxFQTRJSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sV0FBUCxFQTVJWCxFQTZJSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQTdJWCxFQThJSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQTlJWCxFQStJSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8saUNBQVAsRUEvSVgsRUFnSkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLHNCQUFQLEVBaEpYLEVBaUpILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxRQUFQLEVBakpYLEVBa0pILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxVQUFQLEVBbEpYLEVBbUpILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxZQUFQLEVBbkpYLEVBb0pILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxZQUFQLEVBcEpYLEVBcUpILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxTQUFQLEVBckpYLEVBc0pILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxZQUFQLEVBdEpYLEVBdUpILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxTQUFQLEVBdkpYLEVBd0pILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxTQUFQLEVBeEpYLEVBeUpILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxPQUFQLEVBekpYLEVBMEpILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxPQUFQLEVBMUpYLEVBMkpILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxhQUFQLEVBM0pYLEVBNEpILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxzQkFBUCxFQTVKWCxFQTZKSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sZUFBUCxFQTdKWCxFQThKSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sYUFBUCxFQTlKWCxFQStKSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sV0FBUCxFQS9KWCxFQWdLSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sT0FBUCxFQWhLWCxFQWlLSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQWpLWCxFQWtLSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sTUFBUCxFQWxLWCxFQW1LSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sZ0JBQVAsRUFuS1gsRUFvS0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLDBCQUFQLEVBcEtYLEVBcUtILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxRQUFQLEVBcktYLEVBc0tILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxNQUFQLEVBdEtYLEVBdUtILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxVQUFQLEVBdktYLEVBd0tILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxPQUFQLEVBeEtYLEVBeUtILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxpQ0FBUCxFQXpLWCxFQTBLSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQTFLWCxFQTJLSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sa0JBQVAsRUEzS1gsRUE0S0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFVBQVAsRUE1S1gsRUE2S0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLE1BQVAsRUE3S1gsRUE4S0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGFBQVAsRUE5S1gsRUErS0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFVBQVAsRUEvS1gsRUFnTEgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFFBQVAsRUFoTFgsRUFpTEgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFVBQVAsRUFqTFgsRUFrTEgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGFBQVAsRUFsTFgsRUFtTEgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLE9BQVAsRUFuTFgsRUFvTEgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUFwTFgsRUFxTEgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUFyTFgsRUFzTEgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLG9CQUFQLEVBdExYLEVBdUxILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxRQUFQLEVBdkxYLEVBd0xILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxjQUFQLEVBeExYLEVBeUxILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyx1QkFBUCxFQXpMWCxFQTBMSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sYUFBUCxFQTFMWCxFQTJMSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sMkJBQVAsRUEzTFgsRUE0TEgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGtDQUFQLEVBNUxYLEVBNkxILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxPQUFQLEVBN0xYLEVBOExILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxZQUFQLEVBOUxYLEVBK0xILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyx1QkFBUCxFQS9MWCxFQWdNSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sY0FBUCxFQWhNWCxFQWlNSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQWpNWCxFQWtNSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQWxNWCxFQW1NSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sWUFBUCxFQW5NWCxFQW9NSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sY0FBUCxFQXBNWCxFQXFNSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sV0FBUCxFQXJNWCxFQXNNSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sVUFBUCxFQXRNWCxFQXVNSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sVUFBUCxFQXZNWCxFQXdNSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8saUJBQVAsRUF4TVgsRUF5TUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUF6TVgsRUEwTUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGNBQVAsRUExTVgsRUEyTUgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLDhDQUFQLEVBM01YLEVBNE1ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxPQUFQLEVBNU1YLEVBNk1ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxXQUFQLEVBN01YLEVBOE1ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxPQUFQLEVBOU1YLEVBK01ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxVQUFQLEVBL01YLEVBZ05ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyx3QkFBUCxFQWhOWCxFQWlOSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sV0FBUCxFQWpOWCxFQWtOSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQWxOWCxFQW1OSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sYUFBUCxFQW5OWCxFQW9OSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sc0JBQVAsRUFwTlgsRUFxTkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLDJCQUFQLEVBck5YLEVBc05ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxZQUFQLEVBdE5YLEVBdU5ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyw4QkFBUCxFQXZOWCxFQXdOSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sVUFBUCxFQXhOWCxFQXlOSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sYUFBUCxFQXpOWCxFQTBOSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sTUFBUCxFQTFOWCxFQTJOSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sU0FBUCxFQTNOWCxFQTROSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sT0FBUCxFQTVOWCxFQTZOSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8scUJBQVAsRUE3TlgsRUE4TkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFNBQVAsRUE5TlgsRUErTkgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLFFBQVAsRUEvTlgsRUFnT0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGNBQVAsRUFoT1gsRUFpT0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLDBCQUFQLEVBak9YLEVBa09ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxRQUFQLEVBbE9YLEVBbU9ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxRQUFQLEVBbk9YLEVBb09ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxTQUFQLEVBcE9YLEVBcU9ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxzQkFBUCxFQXJPWCxFQXNPSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sZ0JBQVAsRUF0T1gsRUF1T0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLGVBQVAsRUF2T1gsRUF3T0gsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLHNDQUFQLEVBeE9YLEVBeU9ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxTQUFQLEVBek9YLEVBME9ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxZQUFQLEVBMU9YLEVBMk9ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxTQUFQLEVBM09YLEVBNE9ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxXQUFQLEVBNU9YLEVBNk9ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxVQUFQLEVBN09YLEVBOE9ILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyx5QkFBUCxFQTlPWCxFQStPSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sc0JBQVAsRUEvT1gsRUFnUEgsRUFBQyxPQUFPLElBQVAsRUFBYSxPQUFPLG1CQUFQLEVBaFBYLEVBaVBILEVBQUMsT0FBTyxJQUFQLEVBQWEsT0FBTyxnQkFBUCxFQWpQWCxFQWtQSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sT0FBUCxFQWxQWCxFQW1QSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sUUFBUCxFQW5QWCxFQW9QSCxFQUFDLE9BQU8sSUFBUCxFQUFhLE9BQU8sVUFBUCxFQXBQWCxDQUFqQjs7Ozs7Ozs7O0FDQUEsT0FBTyxPQUFQLEdBQWlCLENBQUMsYUFBRCxFQUFlLGVBQWYsRUFBK0IsU0FBL0IsRUFBeUMsU0FBekMsRUFBbUQsZ0JBQW5ELEVBQW9FLFNBQXBFLEVBQThFLFFBQTlFLEVBQXVGLFVBQXZGLEVBQWtHLFlBQWxHLEVBQStHLHFCQUEvRyxFQUFxSSxXQUFySSxFQUFpSixTQUFqSixFQUEySixPQUEzSixFQUFtSyxXQUFuSyxFQUErSyxTQUEvSyxFQUF5TCxZQUF6TCxFQUFzTSxTQUF0TSxFQUFnTixTQUFoTixFQUEwTixZQUExTixFQUF1TyxVQUF2TyxFQUFrUCxTQUFsUCxFQUE0UCxTQUE1UCxFQUFzUSxRQUF0USxFQUErUSxPQUEvUSxFQUF1UixTQUF2UixFQUFpUyxRQUFqUyxFQUEwUyxTQUExUyxFQUFvVCx3QkFBcFQsRUFBNlUsVUFBN1UsRUFBd1YsZUFBeFYsRUFBd1csUUFBeFcsRUFBaVgsZ0NBQWpYLEVBQWtaLG1CQUFsWixFQUFzYSxVQUF0YSxFQUFpYixjQUFqYixFQUFnYyxTQUFoYyxFQUEwYyxVQUExYyxFQUFxZCxVQUFyZCxFQUFnZSxRQUFoZSxFQUF5ZSxZQUF6ZSxFQUFzZixnQkFBdGYsRUFBdWdCLDBCQUF2Z0IsRUFBa2lCLE1BQWxpQixFQUF5aUIsT0FBemlCLEVBQWlqQixPQUFqakIsRUFBeWpCLGtCQUF6akIsRUFBNGtCLHlCQUE1a0IsRUFBc21CLFVBQXRtQixFQUFpbkIsU0FBam5CLEVBQTJuQixPQUEzbkIsRUFBbW9CLHVDQUFub0IsRUFBMnFCLGNBQTNxQixFQUEwckIsWUFBMXJCLEVBQXVzQixlQUF2c0IsRUFBdXRCLFNBQXZ0QixFQUFpdUIsTUFBanVCLEVBQXd1QixRQUF4dUIsRUFBaXZCLGdCQUFqdkIsRUFBa3dCLFNBQWx3QixFQUE0d0IsVUFBNXdCLEVBQXV4QixVQUF2eEIsRUFBa3lCLG9CQUFseUIsRUFBdXpCLFNBQXZ6QixFQUFpMEIsT0FBajBCLEVBQXkwQixhQUF6MEIsRUFBdTFCLG1CQUF2MUIsRUFBMjJCLFNBQTMyQixFQUFxM0IsU0FBcjNCLEVBQSszQixVQUEvM0IsRUFBMDRCLDZCQUExNEIsRUFBdzZCLGVBQXg2QixFQUF3N0IsTUFBeDdCLEVBQSs3QixTQUEvN0IsRUFBeThCLFFBQXo4QixFQUFrOUIsZUFBbDlCLEVBQWsrQixrQkFBbCtCLEVBQXEvQiw2QkFBci9CLEVBQW1oQyxPQUFuaEMsRUFBMmhDLFFBQTNoQyxFQUFvaUMsU0FBcGlDLEVBQThpQyxTQUE5aUMsRUFBd2pDLE9BQXhqQyxFQUFna0MsV0FBaGtDLEVBQTRrQyxRQUE1a0MsRUFBcWxDLFdBQXJsQyxFQUFpbUMsU0FBam1DLEVBQTJtQyxZQUEzbUMsRUFBd25DLE1BQXhuQyxFQUErbkMsV0FBL25DLEVBQTJvQyxVQUEzb0MsRUFBc3BDLFFBQXRwQyxFQUErcEMsZUFBL3BDLEVBQStxQyxRQUEvcUMsRUFBd3JDLE9BQXhyQyxFQUFnc0MsbUNBQWhzQyxFQUFvdUMsK0JBQXB1QyxFQUFvd0MsVUFBcHdDLEVBQSt3QyxXQUEvd0MsRUFBMnhDLFNBQTN4QyxFQUFxeUMsU0FBcnlDLEVBQSt5QyxPQUEveUMsRUFBdXpDLFdBQXZ6QyxFQUFtMEMsMkJBQW4wQyxFQUErMUMsTUFBLzFDLEVBQXMyQyxTQUF0MkMsRUFBZzNDLGFBQWgzQyxFQUE4M0MsUUFBOTNDLEVBQXU0QyxPQUF2NEMsRUFBKzRDLFNBQS80QyxFQUF5NUMsT0FBejVDLEVBQWk2QyxRQUFqNkMsRUFBMDZDLFFBQTE2QyxFQUFtN0MsWUFBbjdDLEVBQWc4QyxPQUFoOEMsRUFBdzhDLFVBQXg4QyxFQUFtOUMsd0NBQW45QyxFQUE0L0Msb0JBQTUvQyxFQUFpaEQsUUFBamhELEVBQTBoRCxZQUExaEQsRUFBdWlELGtDQUF2aUQsRUFBMGtELFFBQTFrRCxFQUFtbEQsU0FBbmxELEVBQTZsRCxTQUE3bEQsRUFBdW1ELFNBQXZtRCxFQUFpbkQsd0JBQWpuRCxFQUEwb0QsZUFBMW9ELEVBQTBwRCxXQUExcEQsRUFBc3FELFlBQXRxRCxFQUFtckQsT0FBbnJELEVBQTJyRCw0Q0FBM3JELEVBQXd1RCxZQUF4dUQsRUFBcXZELFFBQXJ2RCxFQUE4dkQsVUFBOXZELEVBQXl3RCxVQUF6d0QsRUFBb3hELE1BQXB4RCxFQUEyeEQsT0FBM3hELEVBQW15RCxrQkFBbnlELEVBQXN6RCxZQUF0ekQsRUFBbTBELFlBQW4wRCxFQUFnMUQsV0FBaDFELEVBQTQxRCxTQUE1MUQsRUFBczJELFFBQXQyRCxFQUErMkQsaUNBQS8yRCxFQUFpNUQsc0JBQWo1RCxFQUF3NkQsUUFBeDZELEVBQWk3RCxVQUFqN0QsRUFBNDdELFlBQTU3RCxFQUF5OEQsWUFBejhELEVBQXM5RCxTQUF0OUQsRUFBZytELFlBQWgrRCxFQUE2K0QsU0FBNytELEVBQXUvRCxTQUF2L0QsRUFBaWdFLE9BQWpnRSxFQUF5Z0UsT0FBemdFLEVBQWloRSxhQUFqaEUsRUFBK2hFLHNCQUEvaEUsRUFBc2pFLGVBQXRqRSxFQUFza0UsYUFBdGtFLEVBQW9sRSxXQUFwbEUsRUFBZ21FLE9BQWhtRSxFQUF3bUUsU0FBeG1FLEVBQWtuRSxNQUFsbkUsRUFBeW5FLGdCQUF6bkUsRUFBMG9FLDBCQUExb0UsRUFBcXFFLFFBQXJxRSxFQUE4cUUsTUFBOXFFLEVBQXFyRSxVQUFyckUsRUFBZ3NFLE9BQWhzRSxFQUF3c0UsaUNBQXhzRSxFQUEwdUUsUUFBMXVFLEVBQW12RSxrQkFBbnZFLEVBQXN3RSxVQUF0d0UsRUFBaXhFLE1BQWp4RSxFQUF3eEUsYUFBeHhFLEVBQXN5RSxVQUF0eUUsRUFBaXpFLFFBQWp6RSxFQUEwekUsVUFBMXpFLEVBQXEwRSxhQUFyMEUsRUFBbTFFLE9BQW4xRSxFQUEyMUUsU0FBMzFFLEVBQXEyRSxTQUFyMkUsRUFBKzJFLG9CQUEvMkUsRUFBbzRFLFFBQXA0RSxFQUE2NEUsY0FBNzRFLEVBQTQ1RSx1QkFBNTVFLEVBQW83RSxhQUFwN0UsRUFBazhFLDJCQUFsOEUsRUFBODlFLGtDQUE5OUUsRUFBaWdGLE9BQWpnRixFQUF5Z0YsWUFBemdGLEVBQXNoRix1QkFBdGhGLEVBQThpRixjQUE5aUYsRUFBNmpGLFNBQTdqRixFQUF1a0YsUUFBdmtGLEVBQWdsRixZQUFobEYsRUFBNmxGLGNBQTdsRixFQUE0bUYsV0FBNW1GLEVBQXduRixVQUF4bkYsRUFBbW9GLFVBQW5vRixFQUE4b0YsaUJBQTlvRixFQUFncUYsU0FBaHFGLEVBQTBxRixjQUExcUYsRUFBeXJGLDhDQUF6ckYsRUFBd3VGLE9BQXh1RixFQUFndkYsV0FBaHZGLEVBQTR2RixPQUE1dkYsRUFBb3dGLFVBQXB3RixFQUErd0Ysd0JBQS93RixFQUF3eUYsV0FBeHlGLEVBQW96RixRQUFwekYsRUFBNnpGLGFBQTd6RixFQUEyMEYsc0JBQTMwRixFQUFrMkYsMkJBQWwyRixFQUE4M0YsWUFBOTNGLEVBQTI0Riw4QkFBMzRGLEVBQTA2RixVQUExNkYsRUFBcTdGLGFBQXI3RixFQUFtOEYsTUFBbjhGLEVBQTA4RixTQUExOEYsRUFBbzlGLE9BQXA5RixFQUE0OUYscUJBQTU5RixFQUFrL0YsU0FBbC9GLEVBQTQvRixRQUE1L0YsRUFBcWdHLGNBQXJnRyxFQUFvaEcsMEJBQXBoRyxFQUEraUcsUUFBL2lHLEVBQXdqRyxRQUF4akcsRUFBaWtHLFNBQWprRyxFQUEya0csc0JBQTNrRyxFQUFrbUcsZ0JBQWxtRyxFQUFtbkcsZUFBbm5HLEVBQW1vRyxzQ0FBbm9HLEVBQTBxRyxTQUExcUcsRUFBb3JHLFlBQXByRyxFQUFpc0csU0FBanNHLEVBQTJzRyxXQUEzc0csRUFBdXRHLFVBQXZ0RyxFQUFrdUcseUJBQWx1RyxFQUE0dkcsc0JBQTV2RyxFQUFteEcsbUJBQW54RyxFQUF1eUcsZ0JBQXZ5RyxFQUF3ekcsT0FBeHpHLEVBQWcwRyxRQUFoMEcsRUFBeTBHLFVBQXowRyxDQUFqQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDS0Esa0JBQVE7QUFDTixNQUFJLE1BQUo7QUFDQSx3QkFGTTtBQUdOLGNBQVksRUFBRSxrQkFBRixFQUFaO0NBSEY7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDRkEsY0FBSSxHQUFKO0FBQ0EsY0FBSSxNQUFKLENBQVcsS0FBWCxHQUFtQixJQUFuQjs7QUFFQSxJQUFNLFFBQVE7QUFDWixTQUFPLENBQVA7Q0FESTs7QUFJTixJQUFNLFlBQVk7QUFDaEIsZ0NBQVcsT0FBTztBQUNoQixVQUFNLEtBQU4sR0FEZ0I7R0FERjtBQUloQixnQ0FBVyxPQUFPO0FBQ2hCLFVBQU0sS0FBTixHQURnQjtHQUpGO0NBQVo7O2tCQVNTLElBQUksZUFBSyxLQUFMLENBQVc7QUFDNUIsY0FENEI7QUFFNUIsc0JBRjRCO0NBQWY7Ozs7O0FDbkJmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwibW9kdWxlLmV4cG9ydHMgPSBhZnRlclxuXG5mdW5jdGlvbiBhZnRlcihjb3VudCwgY2FsbGJhY2ssIGVycl9jYikge1xuICAgIHZhciBiYWlsID0gZmFsc2VcbiAgICBlcnJfY2IgPSBlcnJfY2IgfHwgbm9vcFxuICAgIHByb3h5LmNvdW50ID0gY291bnRcblxuICAgIHJldHVybiAoY291bnQgPT09IDApID8gY2FsbGJhY2soKSA6IHByb3h5XG5cbiAgICBmdW5jdGlvbiBwcm94eShlcnIsIHJlc3VsdCkge1xuICAgICAgICBpZiAocHJveHkuY291bnQgPD0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhZnRlciBjYWxsZWQgdG9vIG1hbnkgdGltZXMnKVxuICAgICAgICB9XG4gICAgICAgIC0tcHJveHkuY291bnRcblxuICAgICAgICAvLyBhZnRlciBmaXJzdCBlcnJvciwgcmVzdCBhcmUgcGFzc2VkIHRvIGVycl9jYlxuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICBiYWlsID0gdHJ1ZVxuICAgICAgICAgICAgY2FsbGJhY2soZXJyKVxuICAgICAgICAgICAgLy8gZnV0dXJlIGVycm9yIGNhbGxiYWNrcyB3aWxsIGdvIHRvIGVycm9yIGhhbmRsZXJcbiAgICAgICAgICAgIGNhbGxiYWNrID0gZXJyX2NiXG4gICAgICAgIH0gZWxzZSBpZiAocHJveHkuY291bnQgPT09IDAgJiYgIWJhaWwpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHJlc3VsdClcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gbm9vcCgpIHt9XG4iLCIvKipcbiAqIEFuIGFic3RyYWN0aW9uIGZvciBzbGljaW5nIGFuIGFycmF5YnVmZmVyIGV2ZW4gd2hlblxuICogQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlIGlzIG5vdCBzdXBwb3J0ZWRcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYXJyYXlidWZmZXIsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gYXJyYXlidWZmZXIuYnl0ZUxlbmd0aDtcbiAgc3RhcnQgPSBzdGFydCB8fCAwO1xuICBlbmQgPSBlbmQgfHwgYnl0ZXM7XG5cbiAgaWYgKGFycmF5YnVmZmVyLnNsaWNlKSB7IHJldHVybiBhcnJheWJ1ZmZlci5zbGljZShzdGFydCwgZW5kKTsgfVxuXG4gIGlmIChzdGFydCA8IDApIHsgc3RhcnQgKz0gYnl0ZXM7IH1cbiAgaWYgKGVuZCA8IDApIHsgZW5kICs9IGJ5dGVzOyB9XG4gIGlmIChlbmQgPiBieXRlcykgeyBlbmQgPSBieXRlczsgfVxuXG4gIGlmIChzdGFydCA+PSBieXRlcyB8fCBzdGFydCA+PSBlbmQgfHwgYnl0ZXMgPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xuICB9XG5cbiAgdmFyIGFidiA9IG5ldyBVaW50OEFycmF5KGFycmF5YnVmZmVyKTtcbiAgdmFyIHJlc3VsdCA9IG5ldyBVaW50OEFycmF5KGVuZCAtIHN0YXJ0KTtcbiAgZm9yICh2YXIgaSA9IHN0YXJ0LCBpaSA9IDA7IGkgPCBlbmQ7IGkrKywgaWkrKykge1xuICAgIHJlc3VsdFtpaV0gPSBhYnZbaV07XG4gIH1cbiAgcmV0dXJuIHJlc3VsdC5idWZmZXI7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7IFwiZGVmYXVsdFwiOiByZXF1aXJlKFwiY29yZS1qcy9saWJyYXJ5L2ZuL3N5bWJvbFwiKSwgX19lc01vZHVsZTogdHJ1ZSB9OyIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX1N5bWJvbCA9IHJlcXVpcmUoXCJiYWJlbC1ydW50aW1lL2NvcmUtanMvc3ltYm9sXCIpW1wiZGVmYXVsdFwiXTtcblxuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBmdW5jdGlvbiAob2JqKSB7XG4gIHJldHVybiBvYmogJiYgb2JqLmNvbnN0cnVjdG9yID09PSBfU3ltYm9sID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7XG59O1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlOyIsIlxuLyoqXG4gKiBFeHBvc2UgYEJhY2tvZmZgLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gQmFja29mZjtcblxuLyoqXG4gKiBJbml0aWFsaXplIGJhY2tvZmYgdGltZXIgd2l0aCBgb3B0c2AuXG4gKlxuICogLSBgbWluYCBpbml0aWFsIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIFsxMDBdXG4gKiAtIGBtYXhgIG1heCB0aW1lb3V0IFsxMDAwMF1cbiAqIC0gYGppdHRlcmAgWzBdXG4gKiAtIGBmYWN0b3JgIFsyXVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIEJhY2tvZmYob3B0cykge1xuICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgdGhpcy5tcyA9IG9wdHMubWluIHx8IDEwMDtcbiAgdGhpcy5tYXggPSBvcHRzLm1heCB8fCAxMDAwMDtcbiAgdGhpcy5mYWN0b3IgPSBvcHRzLmZhY3RvciB8fCAyO1xuICB0aGlzLmppdHRlciA9IG9wdHMuaml0dGVyID4gMCAmJiBvcHRzLmppdHRlciA8PSAxID8gb3B0cy5qaXR0ZXIgOiAwO1xuICB0aGlzLmF0dGVtcHRzID0gMDtcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGJhY2tvZmYgZHVyYXRpb24uXG4gKlxuICogQHJldHVybiB7TnVtYmVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5CYWNrb2ZmLnByb3RvdHlwZS5kdXJhdGlvbiA9IGZ1bmN0aW9uKCl7XG4gIHZhciBtcyA9IHRoaXMubXMgKiBNYXRoLnBvdyh0aGlzLmZhY3RvciwgdGhpcy5hdHRlbXB0cysrKTtcbiAgaWYgKHRoaXMuaml0dGVyKSB7XG4gICAgdmFyIHJhbmQgPSAgTWF0aC5yYW5kb20oKTtcbiAgICB2YXIgZGV2aWF0aW9uID0gTWF0aC5mbG9vcihyYW5kICogdGhpcy5qaXR0ZXIgKiBtcyk7XG4gICAgbXMgPSAoTWF0aC5mbG9vcihyYW5kICogMTApICYgMSkgPT0gMCAgPyBtcyAtIGRldmlhdGlvbiA6IG1zICsgZGV2aWF0aW9uO1xuICB9XG4gIHJldHVybiBNYXRoLm1pbihtcywgdGhpcy5tYXgpIHwgMDtcbn07XG5cbi8qKlxuICogUmVzZXQgdGhlIG51bWJlciBvZiBhdHRlbXB0cy5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkJhY2tvZmYucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5hdHRlbXB0cyA9IDA7XG59O1xuXG4vKipcbiAqIFNldCB0aGUgbWluaW11bSBkdXJhdGlvblxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuQmFja29mZi5wcm90b3R5cGUuc2V0TWluID0gZnVuY3Rpb24obWluKXtcbiAgdGhpcy5tcyA9IG1pbjtcbn07XG5cbi8qKlxuICogU2V0IHRoZSBtYXhpbXVtIGR1cmF0aW9uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5CYWNrb2ZmLnByb3RvdHlwZS5zZXRNYXggPSBmdW5jdGlvbihtYXgpe1xuICB0aGlzLm1heCA9IG1heDtcbn07XG5cbi8qKlxuICogU2V0IHRoZSBqaXR0ZXJcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkJhY2tvZmYucHJvdG90eXBlLnNldEppdHRlciA9IGZ1bmN0aW9uKGppdHRlcil7XG4gIHRoaXMuaml0dGVyID0gaml0dGVyO1xufTtcblxuIiwiLypcbiAqIGJhc2U2NC1hcnJheWJ1ZmZlclxuICogaHR0cHM6Ly9naXRodWIuY29tL25pa2xhc3ZoL2Jhc2U2NC1hcnJheWJ1ZmZlclxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMiBOaWtsYXMgdm9uIEhlcnR6ZW5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cbiAqL1xuKGZ1bmN0aW9uKGNoYXJzKXtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgZXhwb3J0cy5lbmNvZGUgPSBmdW5jdGlvbihhcnJheWJ1ZmZlcikge1xuICAgIHZhciBieXRlcyA9IG5ldyBVaW50OEFycmF5KGFycmF5YnVmZmVyKSxcbiAgICBpLCBsZW4gPSBieXRlcy5sZW5ndGgsIGJhc2U2NCA9IFwiXCI7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKz0zKSB7XG4gICAgICBiYXNlNjQgKz0gY2hhcnNbYnl0ZXNbaV0gPj4gMl07XG4gICAgICBiYXNlNjQgKz0gY2hhcnNbKChieXRlc1tpXSAmIDMpIDw8IDQpIHwgKGJ5dGVzW2kgKyAxXSA+PiA0KV07XG4gICAgICBiYXNlNjQgKz0gY2hhcnNbKChieXRlc1tpICsgMV0gJiAxNSkgPDwgMikgfCAoYnl0ZXNbaSArIDJdID4+IDYpXTtcbiAgICAgIGJhc2U2NCArPSBjaGFyc1tieXRlc1tpICsgMl0gJiA2M107XG4gICAgfVxuXG4gICAgaWYgKChsZW4gJSAzKSA9PT0gMikge1xuICAgICAgYmFzZTY0ID0gYmFzZTY0LnN1YnN0cmluZygwLCBiYXNlNjQubGVuZ3RoIC0gMSkgKyBcIj1cIjtcbiAgICB9IGVsc2UgaWYgKGxlbiAlIDMgPT09IDEpIHtcbiAgICAgIGJhc2U2NCA9IGJhc2U2NC5zdWJzdHJpbmcoMCwgYmFzZTY0Lmxlbmd0aCAtIDIpICsgXCI9PVwiO1xuICAgIH1cblxuICAgIHJldHVybiBiYXNlNjQ7XG4gIH07XG5cbiAgZXhwb3J0cy5kZWNvZGUgPSAgZnVuY3Rpb24oYmFzZTY0KSB7XG4gICAgdmFyIGJ1ZmZlckxlbmd0aCA9IGJhc2U2NC5sZW5ndGggKiAwLjc1LFxuICAgIGxlbiA9IGJhc2U2NC5sZW5ndGgsIGksIHAgPSAwLFxuICAgIGVuY29kZWQxLCBlbmNvZGVkMiwgZW5jb2RlZDMsIGVuY29kZWQ0O1xuXG4gICAgaWYgKGJhc2U2NFtiYXNlNjQubGVuZ3RoIC0gMV0gPT09IFwiPVwiKSB7XG4gICAgICBidWZmZXJMZW5ndGgtLTtcbiAgICAgIGlmIChiYXNlNjRbYmFzZTY0Lmxlbmd0aCAtIDJdID09PSBcIj1cIikge1xuICAgICAgICBidWZmZXJMZW5ndGgtLTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgYXJyYXlidWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoYnVmZmVyTGVuZ3RoKSxcbiAgICBieXRlcyA9IG5ldyBVaW50OEFycmF5KGFycmF5YnVmZmVyKTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrPTQpIHtcbiAgICAgIGVuY29kZWQxID0gY2hhcnMuaW5kZXhPZihiYXNlNjRbaV0pO1xuICAgICAgZW5jb2RlZDIgPSBjaGFycy5pbmRleE9mKGJhc2U2NFtpKzFdKTtcbiAgICAgIGVuY29kZWQzID0gY2hhcnMuaW5kZXhPZihiYXNlNjRbaSsyXSk7XG4gICAgICBlbmNvZGVkNCA9IGNoYXJzLmluZGV4T2YoYmFzZTY0W2krM10pO1xuXG4gICAgICBieXRlc1twKytdID0gKGVuY29kZWQxIDw8IDIpIHwgKGVuY29kZWQyID4+IDQpO1xuICAgICAgYnl0ZXNbcCsrXSA9ICgoZW5jb2RlZDIgJiAxNSkgPDwgNCkgfCAoZW5jb2RlZDMgPj4gMik7XG4gICAgICBieXRlc1twKytdID0gKChlbmNvZGVkMyAmIDMpIDw8IDYpIHwgKGVuY29kZWQ0ICYgNjMpO1xuICAgIH1cblxuICAgIHJldHVybiBhcnJheWJ1ZmZlcjtcbiAgfTtcbn0pKFwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrL1wiKTtcbiIsIi8qKlxuICogQ3JlYXRlIGEgYmxvYiBidWlsZGVyIGV2ZW4gd2hlbiB2ZW5kb3IgcHJlZml4ZXMgZXhpc3RcbiAqL1xuXG52YXIgQmxvYkJ1aWxkZXIgPSBnbG9iYWwuQmxvYkJ1aWxkZXJcbiAgfHwgZ2xvYmFsLldlYktpdEJsb2JCdWlsZGVyXG4gIHx8IGdsb2JhbC5NU0Jsb2JCdWlsZGVyXG4gIHx8IGdsb2JhbC5Nb3pCbG9iQnVpbGRlcjtcblxuLyoqXG4gKiBDaGVjayBpZiBCbG9iIGNvbnN0cnVjdG9yIGlzIHN1cHBvcnRlZFxuICovXG5cbnZhciBibG9iU3VwcG9ydGVkID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIHZhciBhID0gbmV3IEJsb2IoWydoaSddKTtcbiAgICByZXR1cm4gYS5zaXplID09PSAyO1xuICB9IGNhdGNoKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pKCk7XG5cbi8qKlxuICogQ2hlY2sgaWYgQmxvYiBjb25zdHJ1Y3RvciBzdXBwb3J0cyBBcnJheUJ1ZmZlclZpZXdzXG4gKiBGYWlscyBpbiBTYWZhcmkgNiwgc28gd2UgbmVlZCB0byBtYXAgdG8gQXJyYXlCdWZmZXJzIHRoZXJlLlxuICovXG5cbnZhciBibG9iU3VwcG9ydHNBcnJheUJ1ZmZlclZpZXcgPSBibG9iU3VwcG9ydGVkICYmIChmdW5jdGlvbigpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYiA9IG5ldyBCbG9iKFtuZXcgVWludDhBcnJheShbMSwyXSldKTtcbiAgICByZXR1cm4gYi5zaXplID09PSAyO1xuICB9IGNhdGNoKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pKCk7XG5cbi8qKlxuICogQ2hlY2sgaWYgQmxvYkJ1aWxkZXIgaXMgc3VwcG9ydGVkXG4gKi9cblxudmFyIGJsb2JCdWlsZGVyU3VwcG9ydGVkID0gQmxvYkJ1aWxkZXJcbiAgJiYgQmxvYkJ1aWxkZXIucHJvdG90eXBlLmFwcGVuZFxuICAmJiBCbG9iQnVpbGRlci5wcm90b3R5cGUuZ2V0QmxvYjtcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBtYXBzIEFycmF5QnVmZmVyVmlld3MgdG8gQXJyYXlCdWZmZXJzXG4gKiBVc2VkIGJ5IEJsb2JCdWlsZGVyIGNvbnN0cnVjdG9yIGFuZCBvbGQgYnJvd3NlcnMgdGhhdCBkaWRuJ3RcbiAqIHN1cHBvcnQgaXQgaW4gdGhlIEJsb2IgY29uc3RydWN0b3IuXG4gKi9cblxuZnVuY3Rpb24gbWFwQXJyYXlCdWZmZXJWaWV3cyhhcnkpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnkubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgY2h1bmsgPSBhcnlbaV07XG4gICAgaWYgKGNodW5rLmJ1ZmZlciBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgICB2YXIgYnVmID0gY2h1bmsuYnVmZmVyO1xuXG4gICAgICAvLyBpZiB0aGlzIGlzIGEgc3ViYXJyYXksIG1ha2UgYSBjb3B5IHNvIHdlIG9ubHlcbiAgICAgIC8vIGluY2x1ZGUgdGhlIHN1YmFycmF5IHJlZ2lvbiBmcm9tIHRoZSB1bmRlcmx5aW5nIGJ1ZmZlclxuICAgICAgaWYgKGNodW5rLmJ5dGVMZW5ndGggIT09IGJ1Zi5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHZhciBjb3B5ID0gbmV3IFVpbnQ4QXJyYXkoY2h1bmsuYnl0ZUxlbmd0aCk7XG4gICAgICAgIGNvcHkuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZiwgY2h1bmsuYnl0ZU9mZnNldCwgY2h1bmsuYnl0ZUxlbmd0aCkpO1xuICAgICAgICBidWYgPSBjb3B5LmJ1ZmZlcjtcbiAgICAgIH1cblxuICAgICAgYXJ5W2ldID0gYnVmO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBCbG9iQnVpbGRlckNvbnN0cnVjdG9yKGFyeSwgb3B0aW9ucykge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgYmIgPSBuZXcgQmxvYkJ1aWxkZXIoKTtcbiAgbWFwQXJyYXlCdWZmZXJWaWV3cyhhcnkpO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgYmIuYXBwZW5kKGFyeVtpXSk7XG4gIH1cblxuICByZXR1cm4gKG9wdGlvbnMudHlwZSkgPyBiYi5nZXRCbG9iKG9wdGlvbnMudHlwZSkgOiBiYi5nZXRCbG9iKCk7XG59O1xuXG5mdW5jdGlvbiBCbG9iQ29uc3RydWN0b3IoYXJ5LCBvcHRpb25zKSB7XG4gIG1hcEFycmF5QnVmZmVyVmlld3MoYXJ5KTtcbiAgcmV0dXJuIG5ldyBCbG9iKGFyeSwgb3B0aW9ucyB8fCB7fSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IChmdW5jdGlvbigpIHtcbiAgaWYgKGJsb2JTdXBwb3J0ZWQpIHtcbiAgICByZXR1cm4gYmxvYlN1cHBvcnRzQXJyYXlCdWZmZXJWaWV3ID8gZ2xvYmFsLkJsb2IgOiBCbG9iQ29uc3RydWN0b3I7XG4gIH0gZWxzZSBpZiAoYmxvYkJ1aWxkZXJTdXBwb3J0ZWQpIHtcbiAgICByZXR1cm4gQmxvYkJ1aWxkZXJDb25zdHJ1Y3RvcjtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59KSgpO1xuIiwiX2htcltcIndlYnNvY2tldDpudWxsXCJdLmluaXRNb2R1bGUoXCJub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzXCIsIG1vZHVsZSk7XG4oZnVuY3Rpb24oKXtcblxufSkuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJYU3dpYm1GdFpYTWlPbHRkTENKdFlYQndhVzVuY3lJNklpSXNJbk52ZFhKalpYTkRiMjUwWlc1MElqcGJYWDA9IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnLi4vbGliL2hhcycpO1xudmFyIFN0clNldCA9IHJlcXVpcmUoJy4uL2xpYi9zdHItc2V0Jyk7XG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9jb2xsZWN0aW9uL2ZvckVhY2gnKTtcbnZhciBzb21lID0gcmVxdWlyZSgnbG9kYXNoL2NvbGxlY3Rpb24vc29tZScpO1xudmFyIG1hcCA9IHJlcXVpcmUoJ2xvZGFzaC9jb2xsZWN0aW9uL21hcCcpO1xudmFyIGZpbHRlciA9IHJlcXVpcmUoJ2xvZGFzaC9jb2xsZWN0aW9uL2ZpbHRlcicpO1xudmFyIHppcE9iamVjdCA9IHJlcXVpcmUoJ2xvZGFzaC9hcnJheS96aXBPYmplY3QnKTtcbnZhciBmb3JPd24gPSByZXF1aXJlKCdsb2Rhc2gvb2JqZWN0L2Zvck93bicpO1xudmFyIG1hcFZhbHVlcyA9IHJlcXVpcmUoJ2xvZGFzaC9vYmplY3QvbWFwVmFsdWVzJyk7XG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL29iamVjdC9hc3NpZ24nKTtcblxuZnVuY3Rpb24gZW1pdEVycm9yKGVycikge1xuICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgIHRocm93IGVycjtcbiAgfSwgMCk7XG59XG5cbmZ1bmN0aW9uIG1ha2VNb2R1bGVJbmRleGVzVG9OYW1lcyhtb2R1bGVNZXRhKSB7XG4gIHZhciBtb2R1bGVJbmRleGVzVG9OYW1lcyA9IHt9O1xuICBmb3JPd24obW9kdWxlTWV0YSwgZnVuY3Rpb24odmFsdWUsIG5hbWUpIHtcbiAgICBtb2R1bGVJbmRleGVzVG9OYW1lc1t2YWx1ZS5pbmRleF0gPSBuYW1lO1xuICB9KTtcbiAgcmV0dXJuIG1vZHVsZUluZGV4ZXNUb05hbWVzO1xufVxuXG52YXIgY29uc29sZSA9IGdsb2JhbC5jb25zb2xlID8gZ2xvYmFsLmNvbnNvbGUgOiB7XG4gIGVycm9yOiBmdW5jdGlvbigpe30sIGxvZzogZnVuY3Rpb24oKSB7fVxufTtcblxuZnVuY3Rpb24gbWFpbihcbiAgbW9kdWxlRGVmcywgY2FjaGVkTW9kdWxlcywgbW9kdWxlTWV0YSwgdXBkYXRlVXJsLFxuICB1cGRhdGVNb2RlLCBzdXBwb3J0TW9kZXMsIGlnbm9yZVVuYWNjZXB0ZWQsIHVwZGF0ZUNhY2hlQnVzdCwgYnVuZGxlS2V5LFxuICBzb2NrZXRpbyxcbiAgYnVuZGxlX19maWxlbmFtZSwgYnVuZGxlX19kaXJuYW1lXG4pIHtcbiAgdmFyIG1vZHVsZUluZGV4ZXNUb05hbWVzID0gbWFrZU1vZHVsZUluZGV4ZXNUb05hbWVzKG1vZHVsZU1ldGEpO1xuXG4gIHZhciBzb2NrZXQ7XG4gIHZhciBuYW1lLCBpLCBsZW47XG5cbiAgaWYgKCFnbG9iYWwuX2htcltidW5kbGVLZXldLnNldFN0YXR1cykge1xuICAgIHZhciBydW50aW1lTW9kdWxlSW5mbyA9IHt9O1xuICAgIHZhciBjcmVhdGVJbmZvRW50cnkgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICBydW50aW1lTW9kdWxlSW5mb1tuYW1lXSA9IHtcbiAgICAgICAgaW5kZXg6IG1vZHVsZU1ldGFbbmFtZV0uaW5kZXgsXG4gICAgICAgIGhhc2g6IG1vZHVsZU1ldGFbbmFtZV0uaGFzaCxcbiAgICAgICAgcGFyZW50czogbmV3IFN0clNldChtb2R1bGVNZXRhW25hbWVdLnBhcmVudHMpLFxuICAgICAgICBtb2R1bGU6IG51bGwsXG4gICAgICAgIGRpc3Bvc2VEYXRhOiBudWxsLFxuICAgICAgICBhY2NlcHRlcnM6IG5ldyBTdHJTZXQoKSxcbiAgICAgICAgYWNjZXB0aW5nOiBuZXcgU3RyU2V0KCksXG4gICAgICAgIGRlY2xpbmVyczogbmV3IFN0clNldCgpLFxuICAgICAgICBkZWNsaW5pbmc6IG5ldyBTdHJTZXQoKSxcbiAgICAgICAgc2VsZkFjY2VwdENiczogW10sIC8vIG1heSBjb250YWluIG51bGwuIG5vbnplcm8gbGVuZ3RoIG1lYW5zIG1vZHVsZSBpcyBzZWxmLWFjY2VwdGluZ1xuICAgICAgICBkaXNwb3NlSGFuZGxlcnM6IFtdXG4gICAgICB9O1xuICAgIH07XG4gICAgZm9yIChuYW1lIGluIG1vZHVsZU1ldGEpIHtcbiAgICAgIGlmIChoYXMobW9kdWxlTWV0YSwgbmFtZSkpIHtcbiAgICAgICAgY3JlYXRlSW5mb0VudHJ5KG5hbWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGxvYWRlcnMgdGFrZSBhIGNhbGxiYWNrKGVyciwgZGF0YSkuIFRoZXkgbWF5IGdpdmUgbnVsbCBmb3IgZGF0YSBpZiB0aGV5XG4gICAgLy8ga25vdyB0aGVyZSBoYXNuJ3QgYmVlbiBhbiB1cGRhdGUuXG4gICAgdmFyIGZpbGVSZWxvYWRlcnMgPSB7XG4gICAgICBmczogZnVuY3Rpb24oY2IpIHtcbiAgICAgICAgdmFyIGZzO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGZzID0gcmVxdWlyZSgnZicrJ3MnKTtcbiAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgY2IoZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGZzLnJlYWRGaWxlKGxvY2FsSG1yLnVwZGF0ZVVybCB8fCBidW5kbGVfX2ZpbGVuYW1lLCAndXRmOCcsIGNiKTtcbiAgICAgIH0sXG4gICAgICBhamF4OiBmdW5jdGlvbihjYikge1xuICAgICAgICB2YXIgeGhyO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICBjYihlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgICAgICAgICBjYihudWxsLCB4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGNiKG5ldyBFcnJvcihcIlJlcXVlc3QgaGFkIHJlc3BvbnNlIFwiK3hoci5zdGF0dXMpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHZhciB1cmwgPSBsb2NhbEhtci51cGRhdGVVcmwgKyAodXBkYXRlQ2FjaGVCdXN0Pyc/X3Y9JysoK25ldyBEYXRlKCkpOicnKTtcbiAgICAgICAgeGhyLm9wZW4oJ0dFVCcsIHVybCwgdHJ1ZSk7XG4gICAgICAgIHhoci5zZW5kKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHZhciBsYXN0U2NyaXB0RGF0YSA9IG51bGw7XG5cbiAgICAvLyBjYihlcnIsIGV4cGVjdFVwZGF0ZSlcbiAgICB2YXIgcmVsb2FkQW5kUnVuU2NyaXB0ID0gZnVuY3Rpb24oY2IpIHtcbiAgICAgIGlmICghaGFzKGZpbGVSZWxvYWRlcnMsIGxvY2FsSG1yLnVwZGF0ZU1vZGUpKSB7XG4gICAgICAgIGNiKG5ldyBFcnJvcihcInVwZGF0ZU1vZGUgXCIrbG9jYWxIbXIudXBkYXRlTW9kZStcIiBub3QgaW1wbGVtZW50ZWRcIikpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgcmVsb2FkZXIgPSBmaWxlUmVsb2FkZXJzW2xvY2FsSG1yLnVwZGF0ZU1vZGVdO1xuICAgICAgcmVsb2FkZXIoZnVuY3Rpb24oZXJyLCBkYXRhKSB7XG4gICAgICAgIGlmIChlcnIgfHwgIWRhdGEgfHwgbGFzdFNjcmlwdERhdGEgPT09IGRhdGEpIHtcbiAgICAgICAgICBjYihlcnIsIGZhbHNlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbGFzdFNjcmlwdERhdGEgPSBkYXRhO1xuICAgICAgICBsb2NhbEhtci5uZXdMb2FkID0gbnVsbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvL2pzaGludCBldmlsOnRydWVcbiAgICAgICAgICBpZiAoYnVuZGxlX19maWxlbmFtZSB8fCBidW5kbGVfX2Rpcm5hbWUpIHtcbiAgICAgICAgICAgIG5ldyBGdW5jdGlvbigncmVxdWlyZScsICdfX2ZpbGVuYW1lJywgJ19fZGlybmFtZScsIGRhdGEpKHJlcXVpcmUsIGJ1bmRsZV9fZmlsZW5hbWUsIGJ1bmRsZV9fZGlybmFtZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG5ldyBGdW5jdGlvbigncmVxdWlyZScsIGRhdGEpKHJlcXVpcmUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBydW5uaW5nIHRoZSBmaWxlIHNldHMgX2htci5uZXdMb2FkXG4gICAgICAgIH0gY2F0Y2ggKGVycjIpIHtcbiAgICAgICAgICBsb2NhbEhtci5uZXdMb2FkID0gbnVsbDtcbiAgICAgICAgICBjYihlcnIyKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFsb2NhbEhtci5uZXdMb2FkKSB7XG4gICAgICAgICAgY2IobmV3IEVycm9yKFwiUmVsb2FkZWQgc2NyaXB0IGRpZCBub3Qgc2V0IGhvdCBtb2R1bGUgcmVsb2FkIGRhdGFcIikpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjYihudWxsLCB0cnVlKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICB2YXIgZ2V0T3V0ZGF0ZWRNb2R1bGVzID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgb3V0ZGF0ZWQgPSBbXTtcbiAgICAgIHZhciBuYW1lO1xuICAgICAgLy8gYWRkIGNoYW5nZWQgYW5kIGRlbGV0ZWQgbW9kdWxlc1xuICAgICAgZm9yIChuYW1lIGluIHJ1bnRpbWVNb2R1bGVJbmZvKSB7XG4gICAgICAgIGlmIChoYXMocnVudGltZU1vZHVsZUluZm8sIG5hbWUpKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIWhhcyhsb2NhbEhtci5uZXdMb2FkLm1vZHVsZU1ldGEsIG5hbWUpIHx8XG4gICAgICAgICAgICBydW50aW1lTW9kdWxlSW5mb1tuYW1lXS5oYXNoICE9PSBsb2NhbEhtci5uZXdMb2FkLm1vZHVsZU1ldGFbbmFtZV0uaGFzaFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgb3V0ZGF0ZWQucHVzaChuYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIGFkZCBicmFuZCBuZXcgbW9kdWxlc1xuICAgICAgZm9yIChuYW1lIGluIGxvY2FsSG1yLm5ld0xvYWQubW9kdWxlTWV0YSkge1xuICAgICAgICBpZiAoaGFzKGxvY2FsSG1yLm5ld0xvYWQubW9kdWxlTWV0YSwgbmFtZSkpIHtcbiAgICAgICAgICBpZiAoIWhhcyhydW50aW1lTW9kdWxlSW5mbywgbmFtZSkpIHtcbiAgICAgICAgICAgIG91dGRhdGVkLnB1c2gobmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBhZGQgbW9kdWxlcyB0aGF0IGFyZSBub24tYWNjZXB0aW5nL2RlY2xpbmluZyBwYXJlbnRzIG9mIG91dGRhdGVkIG1vZHVsZXMuXG4gICAgICAvLyBpbXBvcnRhbnQ6IGlmIG91dGRhdGVkIGhhcyBuZXcgZWxlbWVudHMgYWRkZWQgZHVyaW5nIHRoZSBsb29wLFxuICAgICAgLy8gdGhlbiB3ZSBpdGVyYXRlIG92ZXIgdGhlbSB0b28uXG4gICAgICBmb3IgKHZhciBpPTA7IGk8b3V0ZGF0ZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbmFtZSA9IG91dGRhdGVkW2ldO1xuICAgICAgICAvL2pzaGludCAtVzA4M1xuICAgICAgICBpZiAoaGFzKHJ1bnRpbWVNb2R1bGVJbmZvLCBuYW1lKSkge1xuICAgICAgICAgIHJ1bnRpbWVNb2R1bGVJbmZvW25hbWVdLnBhcmVudHMuZm9yRWFjaChmdW5jdGlvbihwYXJlbnROYW1lKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIHJ1bnRpbWVNb2R1bGVJbmZvW25hbWVdLnNlbGZBY2NlcHRDYnMubGVuZ3RoID09PSAwICYmXG4gICAgICAgICAgICAgICFydW50aW1lTW9kdWxlSW5mb1tuYW1lXS5hY2NlcHRlcnMuaGFzKHBhcmVudE5hbWUpICYmXG4gICAgICAgICAgICAgICFydW50aW1lTW9kdWxlSW5mb1tuYW1lXS5kZWNsaW5lcnMuaGFzKHBhcmVudE5hbWUpICYmXG4gICAgICAgICAgICAgIG91dGRhdGVkLmluZGV4T2YocGFyZW50TmFtZSkgPT09IC0xXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgb3V0ZGF0ZWQucHVzaChwYXJlbnROYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG91dGRhdGVkO1xuICAgIH07XG5cbiAgICB2YXIgbW9kdWxlSG90Q2hlY2sgPSBmdW5jdGlvbihhdXRvQXBwbHksIGNiKSB7XG4gICAgICBpZiAodHlwZW9mIGF1dG9BcHBseSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBjYiA9IGF1dG9BcHBseTtcbiAgICAgICAgYXV0b0FwcGx5ID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoIWNiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1vZHVsZS5ob3QuY2hlY2sgY2FsbGJhY2sgcGFyYW1ldGVyIHJlcXVpcmVkXCIpO1xuICAgICAgfVxuICAgICAgaWYgKGxvY2FsSG1yLnN0YXR1cyAhPT0gJ2lkbGUnKSB7XG4gICAgICAgIGNiKG5ldyBFcnJvcihcIm1vZHVsZS5ob3QuY2hlY2sgY2FuIG9ubHkgYmUgY2FsbGVkIHdoaWxlIHN0YXR1cyBpcyBpZGxlXCIpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHVwZGF0ZU1vZGUgPT09ICd3ZWJzb2NrZXQnKSB7XG4gICAgICAgIGNiKG5ldyBFcnJvcihcIm1vZHVsZS5ob3QuY2hlY2sgY2FuJ3QgYmUgdXNlZCB3aGVuIHVwZGF0ZSBtb2RlIGlzIHdlYnNvY2tldFwiKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbG9jYWxIbXIuc2V0U3RhdHVzKCdjaGVjaycpO1xuICAgICAgcmVsb2FkQW5kUnVuU2NyaXB0KGZ1bmN0aW9uKGVyciwgZXhwZWN0VXBkYXRlKSB7XG4gICAgICAgIGlmIChlcnIgfHwgIWV4cGVjdFVwZGF0ZSkge1xuICAgICAgICAgIGxvY2FsSG1yLnNldFN0YXR1cygnaWRsZScpO1xuICAgICAgICAgIGNiKGVyciwgbnVsbCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBvdXRkYXRlZE1vZHVsZXMgPSBnZXRPdXRkYXRlZE1vZHVsZXMoKTtcbiAgICAgICAgaWYgKG91dGRhdGVkTW9kdWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICBsb2NhbEhtci5zZXRTdGF0dXMoJ2lkbGUnKTtcbiAgICAgICAgICBjYihudWxsLCBudWxsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsb2NhbEhtci5zZXRTdGF0dXMoJ3JlYWR5Jyk7XG4gICAgICAgICAgaWYgKGF1dG9BcHBseSkge1xuICAgICAgICAgICAgbW9kdWxlSG90QXBwbHkoYXV0b0FwcGx5LCBjYik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNiKG51bGwsIG91dGRhdGVkTW9kdWxlcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgdmFyIG1vZHVsZUhvdEFwcGx5ID0gZnVuY3Rpb24ob3B0aW9ucywgY2IpIHtcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBjYiA9IG9wdGlvbnM7XG4gICAgICAgIG9wdGlvbnMgPSBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKCFjYikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJtb2R1bGUuaG90LmFwcGx5IGNhbGxiYWNrIHBhcmFtZXRlciByZXF1aXJlZFwiKTtcbiAgICAgIH1cbiAgICAgIHZhciBpZ25vcmVVbmFjY2VwdGVkID0gISEob3B0aW9ucyAmJiBvcHRpb25zLmlnbm9yZVVuYWNjZXB0ZWQpO1xuICAgICAgaWYgKGxvY2FsSG1yLnN0YXR1cyAhPT0gJ3JlYWR5Jykge1xuICAgICAgICBjYihuZXcgRXJyb3IoXCJtb2R1bGUuaG90LmFwcGx5IGNhbiBvbmx5IGJlIGNhbGxlZCB3aGlsZSBzdGF0dXMgaXMgcmVhZHlcIikpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBvdXRkYXRlZE1vZHVsZXMgPSBnZXRPdXRkYXRlZE1vZHVsZXMoKTtcbiAgICAgIHZhciBpc1ZhbHVlTm90SW5PdXRkYXRlZE1vZHVsZXMgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICByZXR1cm4gb3V0ZGF0ZWRNb2R1bGVzLmluZGV4T2YodmFsdWUpID09PSAtMTtcbiAgICAgIH07XG4gICAgICB2YXIgaSwgbGVuO1xuICAgICAgdmFyIGFjY2VwdGVkVXBkYXRlcyA9IGZpbHRlcihvdXRkYXRlZE1vZHVsZXMsIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgaWYgKGhhcyhydW50aW1lTW9kdWxlSW5mbywgbmFtZSkpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBydW50aW1lTW9kdWxlSW5mb1tuYW1lXS5kZWNsaW5lcnMuc29tZShpc1ZhbHVlTm90SW5PdXRkYXRlZE1vZHVsZXMpIHx8XG4gICAgICAgICAgICAoXG4gICAgICAgICAgICAgIHJ1bnRpbWVNb2R1bGVJbmZvW25hbWVdLmFjY2VwdGVycy5zaXplKCkgPT09IDAgJiZcbiAgICAgICAgICAgICAgcnVudGltZU1vZHVsZUluZm9bbmFtZV0uc2VsZkFjY2VwdENicy5sZW5ndGggPT09IDAgJiZcbiAgICAgICAgICAgICAgcnVudGltZU1vZHVsZUluZm9bbmFtZV0ucGFyZW50cy5zb21lKGlzVmFsdWVOb3RJbk91dGRhdGVkTW9kdWxlcylcbiAgICAgICAgICAgIClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9KTtcbiAgICAgIGlmICghaWdub3JlVW5hY2NlcHRlZCAmJiBvdXRkYXRlZE1vZHVsZXMubGVuZ3RoICE9PSBhY2NlcHRlZFVwZGF0ZXMubGVuZ3RoKSB7XG4gICAgICAgIGxvY2FsSG1yLnNldFN0YXR1cygnaWRsZScpO1xuICAgICAgICBjYihuZXcgRXJyb3IoXCJTb21lIHVwZGF0ZXMgd2VyZSBkZWNsaW5lZFwiKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZhciBhbjtcbiAgICAgIGZvciAoaT0wLCBsZW49YWNjZXB0ZWRVcGRhdGVzLmxlbmd0aDsgaTxsZW47IGkrKykge1xuICAgICAgICBhbiA9IGFjY2VwdGVkVXBkYXRlc1tpXTtcbiAgICAgICAgaWYgKGhhcyhydW50aW1lTW9kdWxlSW5mbywgYW4pKSB7XG4gICAgICAgICAgcnVudGltZU1vZHVsZUluZm9bYW5dLmRpc3Bvc2VEYXRhID0ge307XG4gICAgICAgICAgZm9yICh2YXIgaj0wOyBqPHJ1bnRpbWVNb2R1bGVJbmZvW2FuXS5kaXNwb3NlSGFuZGxlcnMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHJ1bnRpbWVNb2R1bGVJbmZvW2FuXS5kaXNwb3NlSGFuZGxlcnNbal0uY2FsbChudWxsLCBydW50aW1lTW9kdWxlSW5mb1thbl0uZGlzcG9zZURhdGEpO1xuICAgICAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgICAgIGxvY2FsSG1yLnNldFN0YXR1cygnaWRsZScpO1xuICAgICAgICAgICAgICBjYihlIHx8IG5ldyBFcnJvcihcIlVua25vd24gZGlzcG9zZSBjYWxsYmFjayBlcnJvclwiKSk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciBzZWxmQWNjZXB0ZXJzID0gW107XG4gICAgICBmb3IgKGk9MCwgbGVuPWFjY2VwdGVkVXBkYXRlcy5sZW5ndGg7IGk8bGVuOyBpKyspIHtcbiAgICAgICAgYW4gPSBhY2NlcHRlZFVwZGF0ZXNbaV07XG4gICAgICAgIC8vanNoaW50IC1XMDgzXG4gICAgICAgIGlmICghaGFzKHJ1bnRpbWVNb2R1bGVJbmZvLCBhbikpIHtcbiAgICAgICAgICAvLyBuZXcgbW9kdWxlc1xuICAgICAgICAgIHJ1bnRpbWVNb2R1bGVJbmZvW2FuXSA9IHtcbiAgICAgICAgICAgIGluZGV4OiBhbixcbiAgICAgICAgICAgIGhhc2g6IGxvY2FsSG1yLm5ld0xvYWQubW9kdWxlTWV0YVthbl0uaGFzaCxcbiAgICAgICAgICAgIHBhcmVudHM6IG5ldyBTdHJTZXQobG9jYWxIbXIubmV3TG9hZC5tb2R1bGVNZXRhW2FuXS5wYXJlbnRzKSxcbiAgICAgICAgICAgIG1vZHVsZTogbnVsbCxcbiAgICAgICAgICAgIGRpc3Bvc2VEYXRhOiBudWxsLFxuICAgICAgICAgICAgYWNjZXB0ZXJzOiBuZXcgU3RyU2V0KCksXG4gICAgICAgICAgICBhY2NlcHRpbmc6IG5ldyBTdHJTZXQoKSxcbiAgICAgICAgICAgIGRlY2xpbmVyczogbmV3IFN0clNldCgpLFxuICAgICAgICAgICAgZGVjbGluaW5nOiBuZXcgU3RyU2V0KCksXG4gICAgICAgICAgICBzZWxmQWNjZXB0Q2JzOiBbXSxcbiAgICAgICAgICAgIGRpc3Bvc2VIYW5kbGVyczogW11cbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKCFoYXMobG9jYWxIbXIubmV3TG9hZC5tb2R1bGVNZXRhLCBhbikpIHtcbiAgICAgICAgICAvLyByZW1vdmVkIG1vZHVsZXNcbiAgICAgICAgICBkZWxldGUgY2FjaGVkTW9kdWxlc1tydW50aW1lTW9kdWxlSW5mb1thbl0uaW5kZXhdO1xuICAgICAgICAgIGRlbGV0ZSBydW50aW1lTW9kdWxlSW5mb1thbl07XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gdXBkYXRlZCBtb2R1bGVzXG4gICAgICAgICAgcnVudGltZU1vZHVsZUluZm9bYW5dLmhhc2ggPSBsb2NhbEhtci5uZXdMb2FkLm1vZHVsZU1ldGFbYW5dLmhhc2g7XG4gICAgICAgICAgcnVudGltZU1vZHVsZUluZm9bYW5dLnBhcmVudHMgPSBuZXcgU3RyU2V0KGxvY2FsSG1yLm5ld0xvYWQubW9kdWxlTWV0YVthbl0ucGFyZW50cyk7XG4gICAgICAgICAgcnVudGltZU1vZHVsZUluZm9bYW5dLm1vZHVsZSA9IG51bGw7XG4gICAgICAgICAgcnVudGltZU1vZHVsZUluZm9bYW5dLmFjY2VwdGluZy5mb3JFYWNoKGZ1bmN0aW9uKGFjY2VwdGVkKSB7XG4gICAgICAgICAgICBydW50aW1lTW9kdWxlSW5mb1thY2NlcHRlZF0uYWNjZXB0ZXJzLmRlbChhbik7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcnVudGltZU1vZHVsZUluZm9bYW5dLmFjY2VwdGluZyA9IG5ldyBTdHJTZXQoKTtcbiAgICAgICAgICBydW50aW1lTW9kdWxlSW5mb1thbl0uZGVjbGluaW5nLmZvckVhY2goZnVuY3Rpb24oYWNjZXB0ZWQpIHtcbiAgICAgICAgICAgIHJ1bnRpbWVNb2R1bGVJbmZvW2FjY2VwdGVkXS5kZWNsaW5lcnMuZGVsKGFuKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBydW50aW1lTW9kdWxlSW5mb1thbl0uZGVjbGluaW5nID0gbmV3IFN0clNldCgpO1xuICAgICAgICAgIGZvckVhY2gocnVudGltZU1vZHVsZUluZm9bYW5dLnNlbGZBY2NlcHRDYnMsIGZ1bmN0aW9uKGNiKSB7XG4gICAgICAgICAgICBzZWxmQWNjZXB0ZXJzLnB1c2goe25hbWU6IGFuLCBjYjogY2J9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBydW50aW1lTW9kdWxlSW5mb1thbl0uc2VsZkFjY2VwdENicyA9IFtdO1xuICAgICAgICAgIHJ1bnRpbWVNb2R1bGVJbmZvW2FuXS5kaXNwb3NlSGFuZGxlcnMgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIG1vZHVsZURlZnNbcnVudGltZU1vZHVsZUluZm9bYW5dLmluZGV4XSA9IFtcbiAgICAgICAgICAvLyBtb2R1bGUgZnVuY3Rpb25cbiAgICAgICAgICBsb2NhbEhtci5uZXdMb2FkLm1vZHVsZURlZnNbbG9jYWxIbXIubmV3TG9hZC5tb2R1bGVNZXRhW2FuXS5pbmRleF1bMF0sXG4gICAgICAgICAgLy8gbW9kdWxlIGRlcHNcbiAgICAgICAgICBtYXBWYWx1ZXMobG9jYWxIbXIubmV3TG9hZC5tb2R1bGVEZWZzW2xvY2FsSG1yLm5ld0xvYWQubW9kdWxlTWV0YVthbl0uaW5kZXhdWzFdLCBmdW5jdGlvbihkZXBJbmRleCwgZGVwUmVmKSB7XG4gICAgICAgICAgICB2YXIgZGVwTmFtZSA9IGxvY2FsSG1yLm5ld0xvYWQubW9kdWxlSW5kZXhlc1RvTmFtZXNbZGVwSW5kZXhdO1xuICAgICAgICAgICAgaWYgKGhhcyhsb2NhbEhtci5ydW50aW1lTW9kdWxlSW5mbywgZGVwTmFtZSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGxvY2FsSG1yLnJ1bnRpbWVNb2R1bGVJbmZvW2RlcE5hbWVdLmluZGV4O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGRlcE5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgXTtcbiAgICAgICAgY2FjaGVkTW9kdWxlc1tydW50aW1lTW9kdWxlSW5mb1thbl0uaW5kZXhdID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgLy8gVXBkYXRlIHRoZSBhY2NlcHQgaGFuZGxlcnMgbGlzdCBhbmQgY2FsbCB0aGUgcmlnaHQgb25lc1xuICAgICAgdmFyIGVyckNhbldhaXQgPSBudWxsO1xuICAgICAgdmFyIHVwZGF0ZWROYW1lcyA9IG5ldyBTdHJTZXQoYWNjZXB0ZWRVcGRhdGVzKTtcbiAgICAgIHZhciBvbGRVcGRhdGVIYW5kbGVycyA9IGxvY2FsSG1yLnVwZGF0ZUhhbmRsZXJzO1xuICAgICAgdmFyIHJlbGV2YW50VXBkYXRlSGFuZGxlcnMgPSBbXTtcbiAgICAgIHZhciBuZXdVcGRhdGVIYW5kbGVycyA9IFtdO1xuICAgICAgZm9yIChpPTAsIGxlbj1vbGRVcGRhdGVIYW5kbGVycy5sZW5ndGg7IGk8bGVuOyBpKyspIHtcbiAgICAgICAgaWYgKCF1cGRhdGVkTmFtZXMuaGFzKG9sZFVwZGF0ZUhhbmRsZXJzW2ldLmFjY2VwdGVyKSkge1xuICAgICAgICAgIG5ld1VwZGF0ZUhhbmRsZXJzLnB1c2gob2xkVXBkYXRlSGFuZGxlcnNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1cGRhdGVkTmFtZXMuaGFzSW50ZXJzZWN0aW9uKG9sZFVwZGF0ZUhhbmRsZXJzW2ldLmRlcHMpKSB7XG4gICAgICAgICAgcmVsZXZhbnRVcGRhdGVIYW5kbGVycy5wdXNoKG9sZFVwZGF0ZUhhbmRsZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbG9jYWxIbXIudXBkYXRlSGFuZGxlcnMgPSBuZXdVcGRhdGVIYW5kbGVycztcbiAgICAgIGZvciAoaT0wLCBsZW49cmVsZXZhbnRVcGRhdGVIYW5kbGVycy5sZW5ndGg7IGk8bGVuOyBpKyspIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZWxldmFudFVwZGF0ZUhhbmRsZXJzW2ldLmNiLmNhbGwobnVsbCwgYWNjZXB0ZWRVcGRhdGVzKTtcbiAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgaWYgKGVyckNhbldhaXQpIGVtaXRFcnJvcihlcnJDYW5XYWl0KTtcbiAgICAgICAgICBlcnJDYW5XYWl0ID0gZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBDYWxsIHRoZSBzZWxmLWFjY2VwdGluZyBtb2R1bGVzXG4gICAgICBmb3JFYWNoKHNlbGZBY2NlcHRlcnMsIGZ1bmN0aW9uKG9iaikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlcXVpcmUocnVudGltZU1vZHVsZUluZm9bb2JqLm5hbWVdLmluZGV4KTtcbiAgICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgICAgaWYgKG9iai5jYikge1xuICAgICAgICAgICAgb2JqLmNiLmNhbGwobnVsbCwgZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChlcnJDYW5XYWl0KSBlbWl0RXJyb3IoZXJyQ2FuV2FpdCk7XG4gICAgICAgICAgICBlcnJDYW5XYWl0ID0gZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBsb2NhbEhtci5zZXRTdGF0dXMoJ2lkbGUnKTtcbiAgICAgIGNiKGVyckNhbldhaXQsIGFjY2VwdGVkVXBkYXRlcyk7XG4gICAgfTtcblxuICAgIHZhciBtb2R1bGVIb3RTZXRVcGRhdGVNb2RlID0gZnVuY3Rpb24obW9kZSwgb3B0aW9ucykge1xuICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICAgIGlmIChzdXBwb3J0TW9kZXMuaW5kZXhPZihtb2RlKSA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTW9kZSBcIittb2RlK1wiIG5vdCBpbiBzdXBwb3J0TW9kZXMuIFBsZWFzZSBjaGVjayB0aGUgQnJvd3NlcmlmeS1ITVIgcGx1Z2luIG9wdGlvbnMuXCIpO1xuICAgICAgfVxuICAgICAgaWYgKG1vZGUgPT09ICdhamF4JyAmJiAhb3B0aW9ucy51cmwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidXJsIHJlcXVpcmVkIGZvciBhamF4IHVwZGF0ZSBtb2RlXCIpO1xuICAgICAgfVxuICAgICAgaWYgKGxvY2FsSG1yLnN0YXR1cyAhPT0gJ2lkbGUnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIm1vZHVsZS5ob3Quc2V0VXBkYXRlTW9kZSBjYW4gb25seSBiZSBjYWxsZWQgd2hpbGUgc3RhdHVzIGlzIGlkbGVcIik7XG4gICAgICB9XG5cbiAgICAgIGxvY2FsSG1yLm5ld0xvYWQgPSBudWxsO1xuICAgICAgbG9jYWxIbXIudXBkYXRlTW9kZSA9IHVwZGF0ZU1vZGUgPSBtb2RlO1xuICAgICAgbG9jYWxIbXIudXBkYXRlVXJsID0gdXBkYXRlVXJsID0gb3B0aW9ucy51cmw7XG4gICAgICB1cGRhdGVDYWNoZUJ1c3QgPSBvcHRpb25zLmNhY2hlQnVzdDtcbiAgICAgIGlnbm9yZVVuYWNjZXB0ZWQgPSBoYXMob3B0aW9ucywgJ2lnbm9yZVVuYWNjZXB0ZWQnKSA/IG9wdGlvbnMuaWdub3JlVW5hY2NlcHRlZCA6IHRydWU7XG5cbiAgICAgIGlmIChzb2NrZXQpIHtcbiAgICAgICAgc29ja2V0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgc29ja2V0ID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChtb2RlID09PSAnd2Vic29ja2V0Jykge1xuICAgICAgICBzb2NrZXQgPSBzZXR1cFNvY2tldCgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgc2V0dXBTb2NrZXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciB1cmwgPSB1cGRhdGVVcmwgfHwgJ2h0dHA6Ly9sb2NhbGhvc3Q6MzEyMyc7XG4gICAgICB2YXIgc29ja2V0ID0gc29ja2V0aW8odXJsLCB7J2ZvcmNlIG5ldyBjb25uZWN0aW9uJzogdHJ1ZX0pO1xuICAgICAgY29uc29sZS5sb2coJ1tITVJdIEF0dGVtcHRpbmcgd2Vic29ja2V0IGNvbm5lY3Rpb24gdG8nLCB1cmwpO1xuXG4gICAgICB2YXIgaXNBY2NlcHRpbmdNZXNzYWdlcyA9IGZhbHNlO1xuICAgICAgc29ja2V0Lm9uKCdjb25uZWN0JywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGlzQWNjZXB0aW5nTWVzc2FnZXMgPSBmYWxzZTtcbiAgICAgICAgdmFyIHN5bmNNc2cgPSBtYXBWYWx1ZXMocnVudGltZU1vZHVsZUluZm8sIGZ1bmN0aW9uKHZhbHVlLCBuYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGhhc2g6IHZhbHVlLmhhc2hcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgc29ja2V0LmVtaXQoJ3N5bmMnLCBzeW5jTXNnKTtcbiAgICAgIH0pO1xuICAgICAgdmFyIGlzVXBkYXRpbmcgPSBmYWxzZTtcbiAgICAgIHZhciBxdWV1ZWRVcGRhdGVNZXNzYWdlcyA9IFtdO1xuICAgICAgc29ja2V0Lm9uKCdzeW5jIGNvbmZpcm0nLCBmdW5jdGlvbigpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1tITVJdIFdlYnNvY2tldCBjb25uZWN0aW9uIHN1Y2Nlc3NmdWwuJyk7XG4gICAgICAgIGlzQWNjZXB0aW5nTWVzc2FnZXMgPSB0cnVlO1xuICAgICAgICBxdWV1ZWRVcGRhdGVNZXNzYWdlcyA9IFtdO1xuICAgICAgfSk7XG4gICAgICBzb2NrZXQub24oJ2Rpc2Nvbm5lY3QnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1tITVJdIFdlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QuJyk7XG4gICAgICB9KTtcbiAgICAgIHZhciBhY2NlcHROZXdNb2R1bGVzID0gZnVuY3Rpb24obXNnKSB7XG4gICAgICAgIC8vIE1ha2Ugc3VyZSB3ZSBkb24ndCBhY2NlcHQgbmV3IG1vZHVsZXMgYmVmb3JlIHdlJ3ZlIHN5bmNlZCBvdXJzZWx2ZXMuXG4gICAgICAgIGlmICghaXNBY2NlcHRpbmdNZXNzYWdlcykgcmV0dXJuO1xuICAgICAgICBpZiAoaXNVcGRhdGluZykge1xuICAgICAgICAgIHF1ZXVlZFVwZGF0ZU1lc3NhZ2VzLnB1c2gobXNnKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGFrZSB0aGUgbWVzc2FnZSBhbmQgY3JlYXRlIGEgbG9jYWxIbXIubmV3TG9hZCB2YWx1ZSBhcyBpZiB0aGVcbiAgICAgICAgLy8gYnVuZGxlIGhhZCBiZWVuIHJlLWV4ZWN1dGVkLCB0aGVuIGNhbGwgbW9kdWxlSG90QXBwbHkuXG4gICAgICAgIGlzVXBkYXRpbmcgPSB0cnVlO1xuXG4gICAgICAgIC8vIHJhbmRvbSBpZCBzbyB3ZSBjYW4gbWFrZSB0aGUgbm9ybWFsbHkgdW5uYW1lZCBhcmdzIGhhdmUgcmFuZG9tIG5hbWVzXG4gICAgICAgIHZhciByaWQgPSBTdHJpbmcoTWF0aC5yYW5kb20oKSkucmVwbGFjZSgvW14wLTldL2csICcnKTtcblxuICAgICAgICB2YXIgbmV3TW9kdWxlRGVmcyA9IGxvY2FsSG1yLm5ld0xvYWQgPyBsb2NhbEhtci5uZXdMb2FkLm1vZHVsZURlZnMgOiBhc3NpZ24oe30sIG1vZHVsZURlZnMpO1xuICAgICAgICB2YXIgbmV3TW9kdWxlTWV0YSA9IGxvY2FsSG1yLm5ld0xvYWQgP1xuICAgICAgICAgIGxvY2FsSG1yLm5ld0xvYWQubW9kdWxlTWV0YSA6IG1hcFZhbHVlcyhydW50aW1lTW9kdWxlSW5mbywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgaW5kZXg6IHZhbHVlLmluZGV4LFxuICAgICAgICAgICAgICBoYXNoOiB2YWx1ZS5oYXNoLFxuICAgICAgICAgICAgICBwYXJlbnRzOiB2YWx1ZS5wYXJlbnRzLnRvQXJyYXkoKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgZm9yT3duKG1zZy5uZXdNb2R1bGVEYXRhLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICAgICAgbmV3TW9kdWxlTWV0YVtrZXldID0ge1xuICAgICAgICAgICAgaW5kZXg6IHZhbHVlLmluZGV4LFxuICAgICAgICAgICAgaGFzaDogdmFsdWUuaGFzaCxcbiAgICAgICAgICAgIHBhcmVudHM6IHZhbHVlLnBhcmVudHNcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgZm9yRWFjaChtc2cucmVtb3ZlZE1vZHVsZXMsIGZ1bmN0aW9uKHJlbW92ZWROYW1lKSB7XG4gICAgICAgICAgZGVsZXRlIG5ld01vZHVsZURlZnNbcnVudGltZU1vZHVsZUluZm9bcmVtb3ZlZE5hbWVdLmluZGV4XTtcbiAgICAgICAgICBkZWxldGUgbmV3TW9kdWxlTWV0YVtyZW1vdmVkTmFtZV07XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgbmV3TW9kdWxlSW5kZXhlc1RvTmFtZXMgPSBtYWtlTW9kdWxlSW5kZXhlc1RvTmFtZXMobmV3TW9kdWxlTWV0YSk7XG4gICAgICAgIGZvck93bihtc2cubmV3TW9kdWxlRGF0YSwgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgICAgICAgIC8vIHRoaXMgcGFydCBuZWVkcyB0byBydW4gYWZ0ZXIgbmV3TW9kdWxlTWV0YSBhbmRcbiAgICAgICAgICAvLyBuZXdNb2R1bGVJbmRleGVzVG9OYW1lcyBhcmUgcG9wdWxhdGVkLlxuICAgICAgICAgIHZhciBuZXdNb2R1bGVGdW5jdGlvbiA9IChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBmbjtcbiAgICAgICAgICAgIC8vanNoaW50IGV2aWw6dHJ1ZVxuICAgICAgICAgICAgaWYgKGJ1bmRsZV9fZmlsZW5hbWUgfHwgYnVuZGxlX19kaXJuYW1lKSB7XG4gICAgICAgICAgICAgIGZuID0gbmV3IEZ1bmN0aW9uKCdyZXF1aXJlJywgJ21vZHVsZScsICdleHBvcnRzJywgJ191MScrcmlkLCAnX3UyJytyaWQsICdfX3UzJytyaWQsICdfX3U0JytyaWQsICdfX2ZpbGVuYW1lJywgJ19fZGlybmFtZScsIHZhbHVlLnNvdXJjZSk7XG4gICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUsIGV4cG9ydHMsIF91MSwgX3UyLCBfdTMsIF91NCkge1xuICAgICAgICAgICAgICAgIGdsb2JhbC5faG1yW2J1bmRsZUtleV0uaW5pdE1vZHVsZShrZXksIG1vZHVsZSk7XG4gICAgICAgICAgICAgICAgZm4uY2FsbCh0aGlzLCByZXF1aXJlLCBtb2R1bGUsIGV4cG9ydHMsIF91MSwgX3UyLCBfdTMsIF91NCwgYnVuZGxlX19maWxlbmFtZSwgYnVuZGxlX19kaXJuYW1lKTtcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGZuID0gbmV3IEZ1bmN0aW9uKCdyZXF1aXJlJywgJ21vZHVsZScsICdleHBvcnRzJywgICdfdTEnK3JpZCwgJ191MicrcmlkLCAnX191MycrcmlkLCAnX191NCcrcmlkLCB2YWx1ZS5zb3VyY2UpO1xuICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlLCBleHBvcnRzLCBfdTEsIF91MiwgX3UzLCBfdTQpIHtcbiAgICAgICAgICAgICAgICBnbG9iYWwuX2htcltidW5kbGVLZXldLmluaXRNb2R1bGUoa2V5LCBtb2R1bGUpO1xuICAgICAgICAgICAgICAgIGZuLmNhbGwodGhpcywgcmVxdWlyZSwgbW9kdWxlLCBleHBvcnRzLCBfdTEsIF91MiwgX3UzLCBfdTQpO1xuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pKCk7XG5cbiAgICAgICAgICBuZXdNb2R1bGVEZWZzW25ld01vZHVsZU1ldGFba2V5XS5pbmRleF0gPSBbXG4gICAgICAgICAgICAvLyBtb2R1bGUgZnVuY3Rpb25cbiAgICAgICAgICAgIG5ld01vZHVsZUZ1bmN0aW9uLFxuICAgICAgICAgICAgLy8gbW9kdWxlIGRlcHNcbiAgICAgICAgICAgIG1hcFZhbHVlcyh2YWx1ZS5kZXBzLCBmdW5jdGlvbihkZXBJbmRleCwgZGVwUmVmKSB7XG4gICAgICAgICAgICAgIHZhciBkZXBOYW1lID0gbmV3TW9kdWxlSW5kZXhlc1RvTmFtZXNbZGVwSW5kZXhdO1xuICAgICAgICAgICAgICBpZiAoaGFzKG5ld01vZHVsZU1ldGEsIGRlcE5hbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ld01vZHVsZU1ldGFbZGVwTmFtZV0uaW5kZXg7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlcE5hbWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgXTtcbiAgICAgICAgfSk7XG4gICAgICAgIGxvY2FsSG1yLm5ld0xvYWQgPSB7XG4gICAgICAgICAgbW9kdWxlRGVmczogbmV3TW9kdWxlRGVmcyxcbiAgICAgICAgICBtb2R1bGVNZXRhOiBuZXdNb2R1bGVNZXRhLFxuICAgICAgICAgIG1vZHVsZUluZGV4ZXNUb05hbWVzOiBuZXdNb2R1bGVJbmRleGVzVG9OYW1lc1xuICAgICAgICB9O1xuICAgICAgICBsb2NhbEhtci5zZXRTdGF0dXMoJ3JlYWR5Jyk7XG4gICAgICAgIHZhciBvdXRkYXRlZE1vZHVsZXMgPSBnZXRPdXRkYXRlZE1vZHVsZXMoKTtcbiAgICAgICAgbW9kdWxlSG90QXBwbHkoe2lnbm9yZVVuYWNjZXB0ZWQ6IGlnbm9yZVVuYWNjZXB0ZWR9LCBmdW5jdGlvbihlcnIsIHVwZGF0ZWROYW1lcykge1xuICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tITVJdIEVycm9yIGFwcGx5aW5nIHVwZGF0ZScsIGVycik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh1cGRhdGVkTmFtZXMpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdbSE1SXSBVcGRhdGVkIG1vZHVsZXMnLCB1cGRhdGVkTmFtZXMpO1xuICAgICAgICAgICAgaWYgKG91dGRhdGVkTW9kdWxlcy5sZW5ndGggIT09IHVwZGF0ZWROYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgdmFyIG5vdFVwZGF0ZWROYW1lcyA9IGZpbHRlcihvdXRkYXRlZE1vZHVsZXMsIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdXBkYXRlZE5hbWVzLmluZGV4T2YobmFtZSkgPT09IC0xO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1tITVJdIFNvbWUgbW9kdWxlcyB3ZXJlIG5vdCB1cGRhdGVkJywgbm90VXBkYXRlZE5hbWVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaXNVcGRhdGluZyA9IGZhbHNlO1xuICAgICAgICAgIHZhciBxdWV1ZWRNc2c7XG4gICAgICAgICAgd2hpbGUgKChxdWV1ZWRNc2cgPSBxdWV1ZWRVcGRhdGVNZXNzYWdlcy5zaGlmdCgpKSkge1xuICAgICAgICAgICAgYWNjZXB0TmV3TW9kdWxlcyhxdWV1ZWRNc2cpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgICAgc29ja2V0Lm9uKCduZXcgbW9kdWxlcycsIGFjY2VwdE5ld01vZHVsZXMpO1xuICAgICAgcmV0dXJuIHNvY2tldDtcbiAgICB9O1xuXG4gICAgdmFyIGxvY2FsSG1yID0ge1xuICAgICAgdXBkYXRlVXJsOiB1cGRhdGVVcmwsXG4gICAgICB1cGRhdGVNb2RlOiB1cGRhdGVNb2RlLFxuICAgICAgcnVudGltZU1vZHVsZUluZm86IHJ1bnRpbWVNb2R1bGVJbmZvLFxuXG4gICAgICBzdGF0dXM6IFwiaWRsZVwiLFxuICAgICAgc2V0U3RhdHVzOiBmdW5jdGlvbihzdGF0dXMpIHtcbiAgICAgICAgdGhpcy5zdGF0dXMgPSBzdGF0dXM7XG4gICAgICAgIHZhciBzdGF0dXNIYW5kbGVycyA9IHRoaXMuc3RhdHVzSGFuZGxlcnMuc2xpY2UoKTtcbiAgICAgICAgZm9yICh2YXIgaT0wLCBsZW49c3RhdHVzSGFuZGxlcnMubGVuZ3RoOyBpPGxlbjsgaSsrKSB7XG4gICAgICAgICAgc3RhdHVzSGFuZGxlcnNbaV0uY2FsbChudWxsLCBzdGF0dXMpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgc3RhdHVzSGFuZGxlcnM6IFtdLFxuICAgICAgdXBkYXRlSGFuZGxlcnM6IFtdLFxuXG4gICAgICAvLyBkdXJpbmcgYSByZWxvYWQgdGhpcyBpcyBzZXQgdG8gYW4gb2JqZWN0IHdpdGggbW9kdWxlRGVmcyxcbiAgICAgIC8vIG1vZHVsZU1ldGEsIGFuZCBtb2R1bGVJbmRleGVzVG9OYW1lcyBwcm9wZXJ0aWVzXG4gICAgICBuZXdMb2FkOiBudWxsLFxuXG4gICAgICBpbml0TW9kdWxlOiBmdW5jdGlvbihuYW1lLCBtb2R1bGUpIHtcbiAgICAgICAgcnVudGltZU1vZHVsZUluZm9bbmFtZV0ubW9kdWxlID0gbW9kdWxlO1xuICAgICAgICBtb2R1bGUuaG90ID0ge1xuICAgICAgICAgIGFjY2VwdDogZnVuY3Rpb24oZGVwcywgY2IpIHtcbiAgICAgICAgICAgIGlmICghY2IgJiYgKCFkZXBzIHx8IHR5cGVvZiBkZXBzID09PSAnZnVuY3Rpb24nKSkgeyAvLyBzZWxmXG4gICAgICAgICAgICAgIGNiID0gZGVwcztcbiAgICAgICAgICAgICAgZGVwcyA9IG51bGw7XG4gICAgICAgICAgICAgIHJ1bnRpbWVNb2R1bGVJbmZvW25hbWVdLnNlbGZBY2NlcHRDYnMucHVzaChjYik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIGRlcHMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgZGVwcyA9IFtkZXBzXTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB2YXIgZGVwTmFtZXMgPSBuZXcgU3RyU2V0KCk7XG4gICAgICAgICAgICAgIGZvciAodmFyIGk9MCwgZGVwc0xlbj1kZXBzLmxlbmd0aDsgaTxkZXBzTGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgZGVwSW5kZXggPSBtb2R1bGVEZWZzW3J1bnRpbWVNb2R1bGVJbmZvW25hbWVdLmluZGV4XVsxXVtkZXBzW2ldXTtcbiAgICAgICAgICAgICAgICBpZiAoZGVwSW5kZXggPT09IHVuZGVmaW5lZCB8fCAhaGFzKG1vZHVsZUluZGV4ZXNUb05hbWVzLCBkZXBJbmRleCkpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkZpbGUgZG9lcyBub3QgdXNlIGRlcGVuZGVuY3k6IFwiK2RlcHNbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZXBOYW1lcy5hZGQobW9kdWxlSW5kZXhlc1RvTmFtZXNbZGVwSW5kZXhdKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBkZXBzID0gbnVsbDtcbiAgICAgICAgICAgICAgZGVwTmFtZXMuZm9yRWFjaChmdW5jdGlvbihkZXBOYW1lKSB7XG4gICAgICAgICAgICAgICAgcnVudGltZU1vZHVsZUluZm9bZGVwTmFtZV0uYWNjZXB0ZXJzLmFkZChuYW1lKTtcbiAgICAgICAgICAgICAgICBydW50aW1lTW9kdWxlSW5mb1tuYW1lXS5hY2NlcHRpbmcuYWRkKGRlcE5hbWUpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgaWYgKGNiKSB7XG4gICAgICAgICAgICAgICAgbG9jYWxIbXIudXBkYXRlSGFuZGxlcnMucHVzaCh7XG4gICAgICAgICAgICAgICAgICBhY2NlcHRlcjogbmFtZSxcbiAgICAgICAgICAgICAgICAgIGRlcHM6IGRlcE5hbWVzLFxuICAgICAgICAgICAgICAgICAgY2I6IGNiXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIGRlY2xpbmU6IGZ1bmN0aW9uKGRlcHMpIHtcbiAgICAgICAgICAgIGlmICghZGVwcykgeyAvLyBzZWxmXG4gICAgICAgICAgICAgIHJ1bnRpbWVNb2R1bGVJbmZvW25hbWVdLmRlY2xpbmVycy5hZGQobmFtZSk7XG4gICAgICAgICAgICAgIHJ1bnRpbWVNb2R1bGVJbmZvW25hbWVdLmRlY2xpbmluZy5hZGQobmFtZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIGRlcHMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgZGVwcyA9IFtkZXBzXTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBmb3IgKHZhciBpPTAsIGRlcHNMZW49ZGVwcy5sZW5ndGg7IGk8ZGVwc0xlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIGRlcEluZGV4ID0gbW9kdWxlRGVmc1tydW50aW1lTW9kdWxlSW5mb1tuYW1lXS5pbmRleF1bMV1bZGVwc1tpXV07XG4gICAgICAgICAgICAgICAgaWYgKGRlcEluZGV4ID09PSB1bmRlZmluZWQgfHwgIWhhcyhtb2R1bGVJbmRleGVzVG9OYW1lcywgZGVwSW5kZXgpKSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJGaWxlIGRvZXMgbm90IHVzZSBkZXBlbmRlbmN5OiBcIitkZXBzW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGRlcE5hbWUgPSBtb2R1bGVJbmRleGVzVG9OYW1lc1tkZXBJbmRleF07XG4gICAgICAgICAgICAgICAgcnVudGltZU1vZHVsZUluZm9bZGVwTmFtZV0uZGVjbGluZXJzLmFkZChuYW1lKTtcbiAgICAgICAgICAgICAgICBydW50aW1lTW9kdWxlSW5mb1tuYW1lXS5kZWNsaW5pbmcuYWRkKGRlcE5hbWUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBkYXRhOiBydW50aW1lTW9kdWxlSW5mb1tuYW1lXS5kaXNwb3NlRGF0YSxcbiAgICAgICAgICBkaXNwb3NlOiBmdW5jdGlvbihjYikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRkRGlzcG9zZUhhbmRsZXIoY2IpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgYWRkRGlzcG9zZUhhbmRsZXI6IGZ1bmN0aW9uKGNiKSB7XG4gICAgICAgICAgICBydW50aW1lTW9kdWxlSW5mb1tuYW1lXS5kaXNwb3NlSGFuZGxlcnMucHVzaChjYik7XG4gICAgICAgICAgfSxcbiAgICAgICAgICByZW1vdmVEaXNwb3NlSGFuZGxlcjogZnVuY3Rpb24oY2IpIHtcbiAgICAgICAgICAgIHZhciBpeCA9IHJ1bnRpbWVNb2R1bGVJbmZvW25hbWVdLmRpc3Bvc2VIYW5kbGVycy5pbmRleE9mKGNiKTtcbiAgICAgICAgICAgIGlmIChpeCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgcnVudGltZU1vZHVsZUluZm9bbmFtZV0uZGlzcG9zZUhhbmRsZXJzLnNwbGljZShpeCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcblxuICAgICAgICAgIC8vIE1hbmFnZW1lbnRcbiAgICAgICAgICBjaGVjazogbW9kdWxlSG90Q2hlY2ssXG4gICAgICAgICAgYXBwbHk6IG1vZHVsZUhvdEFwcGx5LFxuICAgICAgICAgIHN0YXR1czogZnVuY3Rpb24oY2IpIHtcbiAgICAgICAgICAgIGlmIChjYikge1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGRTdGF0dXNIYW5kbGVyKGNiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBsb2NhbEhtci5zdGF0dXM7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBhZGRTdGF0dXNIYW5kbGVyOiBmdW5jdGlvbihjYikge1xuICAgICAgICAgICAgbG9jYWxIbXIuc3RhdHVzSGFuZGxlcnMucHVzaChjYik7XG4gICAgICAgICAgfSxcbiAgICAgICAgICByZW1vdmVTdGF0dXNIYW5kbGVyOiBmdW5jdGlvbihjYikge1xuICAgICAgICAgICAgdmFyIGl4ID0gbG9jYWxIbXIuc3RhdHVzSGFuZGxlcnMuaW5kZXhPZihjYik7XG4gICAgICAgICAgICBpZiAoaXggIT09IC0xKSB7XG4gICAgICAgICAgICAgIGxvY2FsSG1yLnN0YXR1c0hhbmRsZXJzLnNwbGljZShpeCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzZXRVcGRhdGVNb2RlOiBtb2R1bGVIb3RTZXRVcGRhdGVNb2RlXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfTtcbiAgICBnbG9iYWwuX2htcltidW5kbGVLZXldID0gbG9jYWxIbXI7XG5cbiAgICBpZiAodXBkYXRlTW9kZSA9PT0gJ3dlYnNvY2tldCcpIHtcbiAgICAgIHNvY2tldCA9IHNldHVwU29ja2V0KCk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgeyAvLyBXZSdyZSBpbiBhIHJlbG9hZCFcbiAgICBnbG9iYWwuX2htcltidW5kbGVLZXldLm5ld0xvYWQgPSB7XG4gICAgICBtb2R1bGVEZWZzOiBtb2R1bGVEZWZzLFxuICAgICAgbW9kdWxlTWV0YTogbW9kdWxlTWV0YSxcbiAgICAgIG1vZHVsZUluZGV4ZXNUb05hbWVzOiBtb2R1bGVJbmRleGVzVG9OYW1lc1xuICAgIH07XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFpbjtcbiIsIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gaGFzKG9iamVjdCwgcHJvcE5hbWUpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BOYW1lKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gaGFzO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gcmVxdWlyZSgnLi9oYXMnKTtcblxuZnVuY3Rpb24gU3RyU2V0KG90aGVyKSB7XG4gIHRoaXMuX21hcCA9IHt9O1xuICB0aGlzLl9zaXplID0gMDtcbiAgaWYgKG90aGVyKSB7XG4gICAgZm9yICh2YXIgaT0wLGxlbj1vdGhlci5sZW5ndGg7IGk8bGVuOyBpKyspIHtcbiAgICAgIHRoaXMuYWRkKG90aGVyW2ldKTtcbiAgICB9XG4gIH1cbn1cblN0clNldC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgaWYgKCF0aGlzLmhhcyh2YWx1ZSkpIHtcbiAgICB0aGlzLl9tYXBbdmFsdWVdID0gdHJ1ZTtcbiAgICB0aGlzLl9zaXplKys7XG4gIH1cbn07XG5TdHJTZXQucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiBoYXModGhpcy5fbWFwLCB2YWx1ZSk7XG59O1xuU3RyU2V0LnByb3RvdHlwZS5kZWwgPSBmdW5jdGlvbih2YWx1ZSkge1xuICBpZiAodGhpcy5oYXModmFsdWUpKSB7XG4gICAgZGVsZXRlIHRoaXMuX21hcFt2YWx1ZV07XG4gICAgdGhpcy5fc2l6ZS0tO1xuICB9XG59O1xuU3RyU2V0LnByb3RvdHlwZS5zaXplID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9zaXplO1xufTtcblN0clNldC5wcm90b3R5cGUuZm9yRWFjaCA9IGZ1bmN0aW9uKGNiKSB7XG4gIGZvciAodmFyIHZhbHVlIGluIHRoaXMuX21hcCkge1xuICAgIGlmIChoYXModGhpcy5fbWFwLCB2YWx1ZSkpIHtcbiAgICAgIGNiKHZhbHVlKTtcbiAgICB9XG4gIH1cbn07XG5TdHJTZXQucHJvdG90eXBlLnNvbWUgPSBmdW5jdGlvbihjYikge1xuICBmb3IgKHZhciB2YWx1ZSBpbiB0aGlzLl9tYXApIHtcbiAgICBpZiAoaGFzKHRoaXMuX21hcCwgdmFsdWUpKSB7XG4gICAgICBpZiAoY2IodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59O1xuU3RyU2V0LnByb3RvdHlwZS5ldmVyeSA9IGZ1bmN0aW9uKGNiKSB7XG4gIHJldHVybiAhdGhpcy5zb21lKGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gIWNiKHgpO1xuICB9KTtcbn07XG5TdHJTZXQucHJvdG90eXBlLmhhc0ludGVyc2VjdGlvbiA9IGZ1bmN0aW9uKG90aGVyU3RyU2V0KSB7XG4gIHZhciB2YWx1ZTtcbiAgaWYgKHRoaXMuX3NpemUgPCBvdGhlclN0clNldC5fc2l6ZSkge1xuICAgIHJldHVybiB0aGlzLnNvbWUoZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiBvdGhlclN0clNldC5oYXModmFsdWUpO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICByZXR1cm4gb3RoZXJTdHJTZXQuc29tZShmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIHNlbGYuaGFzKHZhbHVlKTtcbiAgICB9KTtcbiAgfVxufTtcblN0clNldC5wcm90b3R5cGUudG9BcnJheSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgYXJyID0gW107XG4gIHRoaXMuZm9yRWFjaChmdW5jdGlvbih2YWx1ZSkge1xuICAgIGFyci5wdXNoKHZhbHVlKTtcbiAgfSk7XG4gIHJldHVybiBhcnI7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFN0clNldDtcbiIsIi8qKlxuICogU2xpY2UgcmVmZXJlbmNlLlxuICovXG5cbnZhciBzbGljZSA9IFtdLnNsaWNlO1xuXG4vKipcbiAqIEJpbmQgYG9iamAgdG8gYGZuYC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufFN0cmluZ30gZm4gb3Igc3RyaW5nXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvYmosIGZuKXtcbiAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiBmbikgZm4gPSBvYmpbZm5dO1xuICBpZiAoJ2Z1bmN0aW9uJyAhPSB0eXBlb2YgZm4pIHRocm93IG5ldyBFcnJvcignYmluZCgpIHJlcXVpcmVzIGEgZnVuY3Rpb24nKTtcbiAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gIHJldHVybiBmdW5jdGlvbigpe1xuICAgIHJldHVybiBmbi5hcHBseShvYmosIGFyZ3MuY29uY2F0KHNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xuICB9XG59O1xuIiwiXG4vKipcbiAqIEV4cG9zZSBgRW1pdHRlcmAuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBFbWl0dGVyO1xuXG4vKipcbiAqIEluaXRpYWxpemUgYSBuZXcgYEVtaXR0ZXJgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gRW1pdHRlcihvYmopIHtcbiAgaWYgKG9iaikgcmV0dXJuIG1peGluKG9iaik7XG59O1xuXG4vKipcbiAqIE1peGluIHRoZSBlbWl0dGVyIHByb3BlcnRpZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7T2JqZWN0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gbWl4aW4ob2JqKSB7XG4gIGZvciAodmFyIGtleSBpbiBFbWl0dGVyLnByb3RvdHlwZSkge1xuICAgIG9ialtrZXldID0gRW1pdHRlci5wcm90b3R5cGVba2V5XTtcbiAgfVxuICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub24gPVxuRW1pdHRlci5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgKHRoaXMuX2NhbGxiYWNrc1tldmVudF0gPSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdIHx8IFtdKVxuICAgIC5wdXNoKGZuKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICogdGltZSB0aGVuIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG5cbiAgZnVuY3Rpb24gb24oKSB7XG4gICAgc2VsZi5vZmYoZXZlbnQsIG9uKTtcbiAgICBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgb24uZm4gPSBmbjtcbiAgdGhpcy5vbihldmVudCwgb24pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcbiAqIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9mZiA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBmbil7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICAvLyBhbGxcbiAgaWYgKDAgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHRoaXMuX2NhbGxiYWNrcyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gc3BlY2lmaWMgZXZlbnRcbiAgdmFyIGNhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrc1tldmVudF07XG4gIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gIGlmICgxID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICBkZWxldGUgdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHJlbW92ZSBzcGVjaWZpYyBoYW5kbGVyXG4gIHZhciBjYjtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyBpKyspIHtcbiAgICBjYiA9IGNhbGxiYWNrc1tpXTtcbiAgICBpZiAoY2IgPT09IGZuIHx8IGNiLmZuID09PSBmbikge1xuICAgICAgY2FsbGJhY2tzLnNwbGljZShpLCAxKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRW1pdCBgZXZlbnRgIHdpdGggdGhlIGdpdmVuIGFyZ3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge01peGVkfSAuLi5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxuICAgICwgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcblxuICBpZiAoY2FsbGJhY2tzKSB7XG4gICAgY2FsbGJhY2tzID0gY2FsbGJhY2tzLnNsaWNlKDApO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjYWxsYmFja3MubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIGNhbGxiYWNrc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmV0dXJuIGFycmF5IG9mIGNhbGxiYWNrcyBmb3IgYGV2ZW50YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEByZXR1cm4ge0FycmF5fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbihldmVudCl7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgcmV0dXJuIHRoaXMuX2NhbGxiYWNrc1tldmVudF0gfHwgW107XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIHRoaXMgZW1pdHRlciBoYXMgYGV2ZW50YCBoYW5kbGVycy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmhhc0xpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgcmV0dXJuICEhIHRoaXMubGlzdGVuZXJzKGV2ZW50KS5sZW5ndGg7XG59O1xuIiwiXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGEsIGIpe1xuICB2YXIgZm4gPSBmdW5jdGlvbigpe307XG4gIGZuLnByb3RvdHlwZSA9IGIucHJvdG90eXBlO1xuICBhLnByb3RvdHlwZSA9IG5ldyBmbjtcbiAgYS5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBhO1xufTsiLCJyZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5zeW1ib2wnKTtcbnJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM2Lm9iamVjdC50by1zdHJpbmcnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy8kLmNvcmUnKS5TeW1ib2w7IiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIGlmKHR5cGVvZiBpdCAhPSAnZnVuY3Rpb24nKXRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgZnVuY3Rpb24hJyk7XG4gIHJldHVybiBpdDtcbn07IiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi8kLmlzLW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpdCl7XG4gIGlmKCFpc09iamVjdChpdCkpdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYW4gb2JqZWN0IScpO1xuICByZXR1cm4gaXQ7XG59OyIsInZhciB0b1N0cmluZyA9IHt9LnRvU3RyaW5nO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoaXQpLnNsaWNlKDgsIC0xKTtcbn07IiwidmFyIGNvcmUgPSBtb2R1bGUuZXhwb3J0cyA9IHt2ZXJzaW9uOiAnMS4yLjYnfTtcbmlmKHR5cGVvZiBfX2UgPT0gJ251bWJlcicpX19lID0gY29yZTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bmRlZiIsIi8vIG9wdGlvbmFsIC8gc2ltcGxlIGNvbnRleHQgYmluZGluZ1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vJC5hLWZ1bmN0aW9uJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZuLCB0aGF0LCBsZW5ndGgpe1xuICBhRnVuY3Rpb24oZm4pO1xuICBpZih0aGF0ID09PSB1bmRlZmluZWQpcmV0dXJuIGZuO1xuICBzd2l0Y2gobGVuZ3RoKXtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbihhKXtcbiAgICAgIHJldHVybiBmbi5jYWxsKHRoYXQsIGEpO1xuICAgIH07XG4gICAgY2FzZSAyOiByZXR1cm4gZnVuY3Rpb24oYSwgYil7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uKGEsIGIsIGMpe1xuICAgICAgcmV0dXJuIGZuLmNhbGwodGhhdCwgYSwgYiwgYyk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24oLyogLi4uYXJncyAqLyl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoYXQsIGFyZ3VtZW50cyk7XG4gIH07XG59OyIsIi8vIDcuMi4xIFJlcXVpcmVPYmplY3RDb2VyY2libGUoYXJndW1lbnQpXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgaWYoaXQgPT0gdW5kZWZpbmVkKXRocm93IFR5cGVFcnJvcihcIkNhbid0IGNhbGwgbWV0aG9kIG9uICBcIiArIGl0KTtcbiAgcmV0dXJuIGl0O1xufTsiLCIvLyBUaGFuaydzIElFOCBmb3IgaGlzIGZ1bm55IGRlZmluZVByb3BlcnR5XG5tb2R1bGUuZXhwb3J0cyA9ICFyZXF1aXJlKCcuLyQuZmFpbHMnKShmdW5jdGlvbigpe1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAnYScsIHtnZXQ6IGZ1bmN0aW9uKCl7IHJldHVybiA3OyB9fSkuYSAhPSA3O1xufSk7IiwiLy8gYWxsIGVudW1lcmFibGUgb2JqZWN0IGtleXMsIGluY2x1ZGVzIHN5bWJvbHNcbnZhciAkID0gcmVxdWlyZSgnLi8kJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgdmFyIGtleXMgICAgICAgPSAkLmdldEtleXMoaXQpXG4gICAgLCBnZXRTeW1ib2xzID0gJC5nZXRTeW1ib2xzO1xuICBpZihnZXRTeW1ib2xzKXtcbiAgICB2YXIgc3ltYm9scyA9IGdldFN5bWJvbHMoaXQpXG4gICAgICAsIGlzRW51bSAgPSAkLmlzRW51bVxuICAgICAgLCBpICAgICAgID0gMFxuICAgICAgLCBrZXk7XG4gICAgd2hpbGUoc3ltYm9scy5sZW5ndGggPiBpKWlmKGlzRW51bS5jYWxsKGl0LCBrZXkgPSBzeW1ib2xzW2krK10pKWtleXMucHVzaChrZXkpO1xuICB9XG4gIHJldHVybiBrZXlzO1xufTsiLCJ2YXIgZ2xvYmFsICAgID0gcmVxdWlyZSgnLi8kLmdsb2JhbCcpXG4gICwgY29yZSAgICAgID0gcmVxdWlyZSgnLi8kLmNvcmUnKVxuICAsIGN0eCAgICAgICA9IHJlcXVpcmUoJy4vJC5jdHgnKVxuICAsIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xuXG52YXIgJGV4cG9ydCA9IGZ1bmN0aW9uKHR5cGUsIG5hbWUsIHNvdXJjZSl7XG4gIHZhciBJU19GT1JDRUQgPSB0eXBlICYgJGV4cG9ydC5GXG4gICAgLCBJU19HTE9CQUwgPSB0eXBlICYgJGV4cG9ydC5HXG4gICAgLCBJU19TVEFUSUMgPSB0eXBlICYgJGV4cG9ydC5TXG4gICAgLCBJU19QUk9UTyAgPSB0eXBlICYgJGV4cG9ydC5QXG4gICAgLCBJU19CSU5EICAgPSB0eXBlICYgJGV4cG9ydC5CXG4gICAgLCBJU19XUkFQICAgPSB0eXBlICYgJGV4cG9ydC5XXG4gICAgLCBleHBvcnRzICAgPSBJU19HTE9CQUwgPyBjb3JlIDogY29yZVtuYW1lXSB8fCAoY29yZVtuYW1lXSA9IHt9KVxuICAgICwgdGFyZ2V0ICAgID0gSVNfR0xPQkFMID8gZ2xvYmFsIDogSVNfU1RBVElDID8gZ2xvYmFsW25hbWVdIDogKGdsb2JhbFtuYW1lXSB8fCB7fSlbUFJPVE9UWVBFXVxuICAgICwga2V5LCBvd24sIG91dDtcbiAgaWYoSVNfR0xPQkFMKXNvdXJjZSA9IG5hbWU7XG4gIGZvcihrZXkgaW4gc291cmNlKXtcbiAgICAvLyBjb250YWlucyBpbiBuYXRpdmVcbiAgICBvd24gPSAhSVNfRk9SQ0VEICYmIHRhcmdldCAmJiBrZXkgaW4gdGFyZ2V0O1xuICAgIGlmKG93biAmJiBrZXkgaW4gZXhwb3J0cyljb250aW51ZTtcbiAgICAvLyBleHBvcnQgbmF0aXZlIG9yIHBhc3NlZFxuICAgIG91dCA9IG93biA/IHRhcmdldFtrZXldIDogc291cmNlW2tleV07XG4gICAgLy8gcHJldmVudCBnbG9iYWwgcG9sbHV0aW9uIGZvciBuYW1lc3BhY2VzXG4gICAgZXhwb3J0c1trZXldID0gSVNfR0xPQkFMICYmIHR5cGVvZiB0YXJnZXRba2V5XSAhPSAnZnVuY3Rpb24nID8gc291cmNlW2tleV1cbiAgICAvLyBiaW5kIHRpbWVycyB0byBnbG9iYWwgZm9yIGNhbGwgZnJvbSBleHBvcnQgY29udGV4dFxuICAgIDogSVNfQklORCAmJiBvd24gPyBjdHgob3V0LCBnbG9iYWwpXG4gICAgLy8gd3JhcCBnbG9iYWwgY29uc3RydWN0b3JzIGZvciBwcmV2ZW50IGNoYW5nZSB0aGVtIGluIGxpYnJhcnlcbiAgICA6IElTX1dSQVAgJiYgdGFyZ2V0W2tleV0gPT0gb3V0ID8gKGZ1bmN0aW9uKEMpe1xuICAgICAgdmFyIEYgPSBmdW5jdGlvbihwYXJhbSl7XG4gICAgICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgQyA/IG5ldyBDKHBhcmFtKSA6IEMocGFyYW0pO1xuICAgICAgfTtcbiAgICAgIEZbUFJPVE9UWVBFXSA9IENbUFJPVE9UWVBFXTtcbiAgICAgIHJldHVybiBGO1xuICAgIC8vIG1ha2Ugc3RhdGljIHZlcnNpb25zIGZvciBwcm90b3R5cGUgbWV0aG9kc1xuICAgIH0pKG91dCkgOiBJU19QUk9UTyAmJiB0eXBlb2Ygb3V0ID09ICdmdW5jdGlvbicgPyBjdHgoRnVuY3Rpb24uY2FsbCwgb3V0KSA6IG91dDtcbiAgICBpZihJU19QUk9UTykoZXhwb3J0c1tQUk9UT1RZUEVdIHx8IChleHBvcnRzW1BST1RPVFlQRV0gPSB7fSkpW2tleV0gPSBvdXQ7XG4gIH1cbn07XG4vLyB0eXBlIGJpdG1hcFxuJGV4cG9ydC5GID0gMTsgIC8vIGZvcmNlZFxuJGV4cG9ydC5HID0gMjsgIC8vIGdsb2JhbFxuJGV4cG9ydC5TID0gNDsgIC8vIHN0YXRpY1xuJGV4cG9ydC5QID0gODsgIC8vIHByb3RvXG4kZXhwb3J0LkIgPSAxNjsgLy8gYmluZFxuJGV4cG9ydC5XID0gMzI7IC8vIHdyYXBcbm1vZHVsZS5leHBvcnRzID0gJGV4cG9ydDsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGV4ZWMpe1xuICB0cnkge1xuICAgIHJldHVybiAhIWV4ZWMoKTtcbiAgfSBjYXRjaChlKXtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTsiLCIvLyBmYWxsYmFjayBmb3IgSUUxMSBidWdneSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB3aXRoIGlmcmFtZSBhbmQgd2luZG93XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi8kLnRvLWlvYmplY3QnKVxuICAsIGdldE5hbWVzICA9IHJlcXVpcmUoJy4vJCcpLmdldE5hbWVzXG4gICwgdG9TdHJpbmcgID0ge30udG9TdHJpbmc7XG5cbnZhciB3aW5kb3dOYW1lcyA9IHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCcgJiYgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXNcbiAgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh3aW5kb3cpIDogW107XG5cbnZhciBnZXRXaW5kb3dOYW1lcyA9IGZ1bmN0aW9uKGl0KXtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZ2V0TmFtZXMoaXQpO1xuICB9IGNhdGNoKGUpe1xuICAgIHJldHVybiB3aW5kb3dOYW1lcy5zbGljZSgpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5nZXQgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eU5hbWVzKGl0KXtcbiAgaWYod2luZG93TmFtZXMgJiYgdG9TdHJpbmcuY2FsbChpdCkgPT0gJ1tvYmplY3QgV2luZG93XScpcmV0dXJuIGdldFdpbmRvd05hbWVzKGl0KTtcbiAgcmV0dXJuIGdldE5hbWVzKHRvSU9iamVjdChpdCkpO1xufTsiLCIvLyBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvODYjaXNzdWVjb21tZW50LTExNTc1OTAyOFxudmFyIGdsb2JhbCA9IG1vZHVsZS5leHBvcnRzID0gdHlwZW9mIHdpbmRvdyAhPSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuTWF0aCA9PSBNYXRoXG4gID8gd2luZG93IDogdHlwZW9mIHNlbGYgIT0gJ3VuZGVmaW5lZCcgJiYgc2VsZi5NYXRoID09IE1hdGggPyBzZWxmIDogRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcbmlmKHR5cGVvZiBfX2cgPT0gJ251bWJlcicpX19nID0gZ2xvYmFsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmIiwidmFyIGhhc093blByb3BlcnR5ID0ge30uaGFzT3duUHJvcGVydHk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCBrZXkpe1xuICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChpdCwga2V5KTtcbn07IiwidmFyICQgICAgICAgICAgPSByZXF1aXJlKCcuLyQnKVxuICAsIGNyZWF0ZURlc2MgPSByZXF1aXJlKCcuLyQucHJvcGVydHktZGVzYycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLyQuZGVzY3JpcHRvcnMnKSA/IGZ1bmN0aW9uKG9iamVjdCwga2V5LCB2YWx1ZSl7XG4gIHJldHVybiAkLnNldERlc2Mob2JqZWN0LCBrZXksIGNyZWF0ZURlc2MoMSwgdmFsdWUpKTtcbn0gOiBmdW5jdGlvbihvYmplY3QsIGtleSwgdmFsdWUpe1xuICBvYmplY3Rba2V5XSA9IHZhbHVlO1xuICByZXR1cm4gb2JqZWN0O1xufTsiLCIvLyBmYWxsYmFjayBmb3Igbm9uLWFycmF5LWxpa2UgRVMzIGFuZCBub24tZW51bWVyYWJsZSBvbGQgVjggc3RyaW5nc1xudmFyIGNvZiA9IHJlcXVpcmUoJy4vJC5jb2YnKTtcbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0KCd6JykucHJvcGVydHlJc0VudW1lcmFibGUoMCkgPyBPYmplY3QgOiBmdW5jdGlvbihpdCl7XG4gIHJldHVybiBjb2YoaXQpID09ICdTdHJpbmcnID8gaXQuc3BsaXQoJycpIDogT2JqZWN0KGl0KTtcbn07IiwiLy8gNy4yLjIgSXNBcnJheShhcmd1bWVudClcbnZhciBjb2YgPSByZXF1aXJlKCcuLyQuY29mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24oYXJnKXtcbiAgcmV0dXJuIGNvZihhcmcpID09ICdBcnJheSc7XG59OyIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oaXQpe1xuICByZXR1cm4gdHlwZW9mIGl0ID09PSAnb2JqZWN0JyA/IGl0ICE9PSBudWxsIDogdHlwZW9mIGl0ID09PSAnZnVuY3Rpb24nO1xufTsiLCJ2YXIgJE9iamVjdCA9IE9iamVjdDtcbm1vZHVsZS5leHBvcnRzID0ge1xuICBjcmVhdGU6ICAgICAkT2JqZWN0LmNyZWF0ZSxcbiAgZ2V0UHJvdG86ICAgJE9iamVjdC5nZXRQcm90b3R5cGVPZixcbiAgaXNFbnVtOiAgICAge30ucHJvcGVydHlJc0VudW1lcmFibGUsXG4gIGdldERlc2M6ICAgICRPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yLFxuICBzZXREZXNjOiAgICAkT2JqZWN0LmRlZmluZVByb3BlcnR5LFxuICBzZXREZXNjczogICAkT2JqZWN0LmRlZmluZVByb3BlcnRpZXMsXG4gIGdldEtleXM6ICAgICRPYmplY3Qua2V5cyxcbiAgZ2V0TmFtZXM6ICAgJE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzLFxuICBnZXRTeW1ib2xzOiAkT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyxcbiAgZWFjaDogICAgICAgW10uZm9yRWFjaFxufTsiLCJ2YXIgJCAgICAgICAgID0gcmVxdWlyZSgnLi8kJylcbiAgLCB0b0lPYmplY3QgPSByZXF1aXJlKCcuLyQudG8taW9iamVjdCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvYmplY3QsIGVsKXtcbiAgdmFyIE8gICAgICA9IHRvSU9iamVjdChvYmplY3QpXG4gICAgLCBrZXlzICAgPSAkLmdldEtleXMoTylcbiAgICAsIGxlbmd0aCA9IGtleXMubGVuZ3RoXG4gICAgLCBpbmRleCAgPSAwXG4gICAgLCBrZXk7XG4gIHdoaWxlKGxlbmd0aCA+IGluZGV4KWlmKE9ba2V5ID0ga2V5c1tpbmRleCsrXV0gPT09IGVsKXJldHVybiBrZXk7XG59OyIsIm1vZHVsZS5leHBvcnRzID0gdHJ1ZTsiLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGJpdG1hcCwgdmFsdWUpe1xuICByZXR1cm4ge1xuICAgIGVudW1lcmFibGUgIDogIShiaXRtYXAgJiAxKSxcbiAgICBjb25maWd1cmFibGU6ICEoYml0bWFwICYgMiksXG4gICAgd3JpdGFibGUgICAgOiAhKGJpdG1hcCAmIDQpLFxuICAgIHZhbHVlICAgICAgIDogdmFsdWVcbiAgfTtcbn07IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLyQuaGlkZScpOyIsInZhciBkZWYgPSByZXF1aXJlKCcuLyQnKS5zZXREZXNjXG4gICwgaGFzID0gcmVxdWlyZSgnLi8kLmhhcycpXG4gICwgVEFHID0gcmVxdWlyZSgnLi8kLndrcycpKCd0b1N0cmluZ1RhZycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0LCB0YWcsIHN0YXQpe1xuICBpZihpdCAmJiAhaGFzKGl0ID0gc3RhdCA/IGl0IDogaXQucHJvdG90eXBlLCBUQUcpKWRlZihpdCwgVEFHLCB7Y29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogdGFnfSk7XG59OyIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuLyQuZ2xvYmFsJylcbiAgLCBTSEFSRUQgPSAnX19jb3JlLWpzX3NoYXJlZF9fJ1xuICAsIHN0b3JlICA9IGdsb2JhbFtTSEFSRURdIHx8IChnbG9iYWxbU0hBUkVEXSA9IHt9KTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oa2V5KXtcbiAgcmV0dXJuIHN0b3JlW2tleV0gfHwgKHN0b3JlW2tleV0gPSB7fSk7XG59OyIsIi8vIHRvIGluZGV4ZWQgb2JqZWN0LCB0b09iamVjdCB3aXRoIGZhbGxiYWNrIGZvciBub24tYXJyYXktbGlrZSBFUzMgc3RyaW5nc1xudmFyIElPYmplY3QgPSByZXF1aXJlKCcuLyQuaW9iamVjdCcpXG4gICwgZGVmaW5lZCA9IHJlcXVpcmUoJy4vJC5kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGl0KXtcbiAgcmV0dXJuIElPYmplY3QoZGVmaW5lZChpdCkpO1xufTsiLCJ2YXIgaWQgPSAwXG4gICwgcHggPSBNYXRoLnJhbmRvbSgpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihrZXkpe1xuICByZXR1cm4gJ1N5bWJvbCgnLmNvbmNhdChrZXkgPT09IHVuZGVmaW5lZCA/ICcnIDoga2V5LCAnKV8nLCAoKytpZCArIHB4KS50b1N0cmluZygzNikpO1xufTsiLCJ2YXIgc3RvcmUgID0gcmVxdWlyZSgnLi8kLnNoYXJlZCcpKCd3a3MnKVxuICAsIHVpZCAgICA9IHJlcXVpcmUoJy4vJC51aWQnKVxuICAsIFN5bWJvbCA9IHJlcXVpcmUoJy4vJC5nbG9iYWwnKS5TeW1ib2w7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG5hbWUpe1xuICByZXR1cm4gc3RvcmVbbmFtZV0gfHwgKHN0b3JlW25hbWVdID1cbiAgICBTeW1ib2wgJiYgU3ltYm9sW25hbWVdIHx8IChTeW1ib2wgfHwgdWlkKSgnU3ltYm9sLicgKyBuYW1lKSk7XG59OyIsIl9obXJbXCJ3ZWJzb2NrZXQ6bnVsbFwiXS5pbml0TW9kdWxlKFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5vYmplY3QudG8tc3RyaW5nLmpzXCIsIG1vZHVsZSk7XG4oZnVuY3Rpb24oKXtcblxufSkuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsZXlKMlpYSnphVzl1SWpvekxDSnpiM1Z5WTJWeklqcGJYU3dpYm1GdFpYTWlPbHRkTENKdFlYQndhVzVuY3lJNklpSXNJbk52ZFhKalpYTkRiMjUwWlc1MElqcGJYWDA9IiwiJ3VzZSBzdHJpY3QnO1xuLy8gRUNNQVNjcmlwdCA2IHN5bWJvbHMgc2hpbVxudmFyICQgICAgICAgICAgICAgID0gcmVxdWlyZSgnLi8kJylcbiAgLCBnbG9iYWwgICAgICAgICA9IHJlcXVpcmUoJy4vJC5nbG9iYWwnKVxuICAsIGhhcyAgICAgICAgICAgID0gcmVxdWlyZSgnLi8kLmhhcycpXG4gICwgREVTQ1JJUFRPUlMgICAgPSByZXF1aXJlKCcuLyQuZGVzY3JpcHRvcnMnKVxuICAsICRleHBvcnQgICAgICAgID0gcmVxdWlyZSgnLi8kLmV4cG9ydCcpXG4gICwgcmVkZWZpbmUgICAgICAgPSByZXF1aXJlKCcuLyQucmVkZWZpbmUnKVxuICAsICRmYWlscyAgICAgICAgID0gcmVxdWlyZSgnLi8kLmZhaWxzJylcbiAgLCBzaGFyZWQgICAgICAgICA9IHJlcXVpcmUoJy4vJC5zaGFyZWQnKVxuICAsIHNldFRvU3RyaW5nVGFnID0gcmVxdWlyZSgnLi8kLnNldC10by1zdHJpbmctdGFnJylcbiAgLCB1aWQgICAgICAgICAgICA9IHJlcXVpcmUoJy4vJC51aWQnKVxuICAsIHdrcyAgICAgICAgICAgID0gcmVxdWlyZSgnLi8kLndrcycpXG4gICwga2V5T2YgICAgICAgICAgPSByZXF1aXJlKCcuLyQua2V5b2YnKVxuICAsICRuYW1lcyAgICAgICAgID0gcmVxdWlyZSgnLi8kLmdldC1uYW1lcycpXG4gICwgZW51bUtleXMgICAgICAgPSByZXF1aXJlKCcuLyQuZW51bS1rZXlzJylcbiAgLCBpc0FycmF5ICAgICAgICA9IHJlcXVpcmUoJy4vJC5pcy1hcnJheScpXG4gICwgYW5PYmplY3QgICAgICAgPSByZXF1aXJlKCcuLyQuYW4tb2JqZWN0JylcbiAgLCB0b0lPYmplY3QgICAgICA9IHJlcXVpcmUoJy4vJC50by1pb2JqZWN0JylcbiAgLCBjcmVhdGVEZXNjICAgICA9IHJlcXVpcmUoJy4vJC5wcm9wZXJ0eS1kZXNjJylcbiAgLCBnZXREZXNjICAgICAgICA9ICQuZ2V0RGVzY1xuICAsIHNldERlc2MgICAgICAgID0gJC5zZXREZXNjXG4gICwgX2NyZWF0ZSAgICAgICAgPSAkLmNyZWF0ZVxuICAsIGdldE5hbWVzICAgICAgID0gJG5hbWVzLmdldFxuICAsICRTeW1ib2wgICAgICAgID0gZ2xvYmFsLlN5bWJvbFxuICAsICRKU09OICAgICAgICAgID0gZ2xvYmFsLkpTT05cbiAgLCBfc3RyaW5naWZ5ICAgICA9ICRKU09OICYmICRKU09OLnN0cmluZ2lmeVxuICAsIHNldHRlciAgICAgICAgID0gZmFsc2VcbiAgLCBISURERU4gICAgICAgICA9IHdrcygnX2hpZGRlbicpXG4gICwgaXNFbnVtICAgICAgICAgPSAkLmlzRW51bVxuICAsIFN5bWJvbFJlZ2lzdHJ5ID0gc2hhcmVkKCdzeW1ib2wtcmVnaXN0cnknKVxuICAsIEFsbFN5bWJvbHMgICAgID0gc2hhcmVkKCdzeW1ib2xzJylcbiAgLCB1c2VOYXRpdmUgICAgICA9IHR5cGVvZiAkU3ltYm9sID09ICdmdW5jdGlvbidcbiAgLCBPYmplY3RQcm90byAgICA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8vIGZhbGxiYWNrIGZvciBvbGQgQW5kcm9pZCwgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC92OC9pc3N1ZXMvZGV0YWlsP2lkPTY4N1xudmFyIHNldFN5bWJvbERlc2MgPSBERVNDUklQVE9SUyAmJiAkZmFpbHMoZnVuY3Rpb24oKXtcbiAgcmV0dXJuIF9jcmVhdGUoc2V0RGVzYyh7fSwgJ2EnLCB7XG4gICAgZ2V0OiBmdW5jdGlvbigpeyByZXR1cm4gc2V0RGVzYyh0aGlzLCAnYScsIHt2YWx1ZTogN30pLmE7IH1cbiAgfSkpLmEgIT0gNztcbn0pID8gZnVuY3Rpb24oaXQsIGtleSwgRCl7XG4gIHZhciBwcm90b0Rlc2MgPSBnZXREZXNjKE9iamVjdFByb3RvLCBrZXkpO1xuICBpZihwcm90b0Rlc2MpZGVsZXRlIE9iamVjdFByb3RvW2tleV07XG4gIHNldERlc2MoaXQsIGtleSwgRCk7XG4gIGlmKHByb3RvRGVzYyAmJiBpdCAhPT0gT2JqZWN0UHJvdG8pc2V0RGVzYyhPYmplY3RQcm90bywga2V5LCBwcm90b0Rlc2MpO1xufSA6IHNldERlc2M7XG5cbnZhciB3cmFwID0gZnVuY3Rpb24odGFnKXtcbiAgdmFyIHN5bSA9IEFsbFN5bWJvbHNbdGFnXSA9IF9jcmVhdGUoJFN5bWJvbC5wcm90b3R5cGUpO1xuICBzeW0uX2sgPSB0YWc7XG4gIERFU0NSSVBUT1JTICYmIHNldHRlciAmJiBzZXRTeW1ib2xEZXNjKE9iamVjdFByb3RvLCB0YWcsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgc2V0OiBmdW5jdGlvbih2YWx1ZSl7XG4gICAgICBpZihoYXModGhpcywgSElEREVOKSAmJiBoYXModGhpc1tISURERU5dLCB0YWcpKXRoaXNbSElEREVOXVt0YWddID0gZmFsc2U7XG4gICAgICBzZXRTeW1ib2xEZXNjKHRoaXMsIHRhZywgY3JlYXRlRGVzYygxLCB2YWx1ZSkpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBzeW07XG59O1xuXG52YXIgaXNTeW1ib2wgPSBmdW5jdGlvbihpdCl7XG4gIHJldHVybiB0eXBlb2YgaXQgPT0gJ3N5bWJvbCc7XG59O1xuXG52YXIgJGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkoaXQsIGtleSwgRCl7XG4gIGlmKEQgJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkpe1xuICAgIGlmKCFELmVudW1lcmFibGUpe1xuICAgICAgaWYoIWhhcyhpdCwgSElEREVOKSlzZXREZXNjKGl0LCBISURERU4sIGNyZWF0ZURlc2MoMSwge30pKTtcbiAgICAgIGl0W0hJRERFTl1ba2V5XSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmKGhhcyhpdCwgSElEREVOKSAmJiBpdFtISURERU5dW2tleV0paXRbSElEREVOXVtrZXldID0gZmFsc2U7XG4gICAgICBEID0gX2NyZWF0ZShELCB7ZW51bWVyYWJsZTogY3JlYXRlRGVzYygwLCBmYWxzZSl9KTtcbiAgICB9IHJldHVybiBzZXRTeW1ib2xEZXNjKGl0LCBrZXksIEQpO1xuICB9IHJldHVybiBzZXREZXNjKGl0LCBrZXksIEQpO1xufTtcbnZhciAkZGVmaW5lUHJvcGVydGllcyA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXMoaXQsIFApe1xuICBhbk9iamVjdChpdCk7XG4gIHZhciBrZXlzID0gZW51bUtleXMoUCA9IHRvSU9iamVjdChQKSlcbiAgICAsIGkgICAgPSAwXG4gICAgLCBsID0ga2V5cy5sZW5ndGhcbiAgICAsIGtleTtcbiAgd2hpbGUobCA+IGkpJGRlZmluZVByb3BlcnR5KGl0LCBrZXkgPSBrZXlzW2krK10sIFBba2V5XSk7XG4gIHJldHVybiBpdDtcbn07XG52YXIgJGNyZWF0ZSA9IGZ1bmN0aW9uIGNyZWF0ZShpdCwgUCl7XG4gIHJldHVybiBQID09PSB1bmRlZmluZWQgPyBfY3JlYXRlKGl0KSA6ICRkZWZpbmVQcm9wZXJ0aWVzKF9jcmVhdGUoaXQpLCBQKTtcbn07XG52YXIgJHByb3BlcnR5SXNFbnVtZXJhYmxlID0gZnVuY3Rpb24gcHJvcGVydHlJc0VudW1lcmFibGUoa2V5KXtcbiAgdmFyIEUgPSBpc0VudW0uY2FsbCh0aGlzLCBrZXkpO1xuICByZXR1cm4gRSB8fCAhaGFzKHRoaXMsIGtleSkgfHwgIWhhcyhBbGxTeW1ib2xzLCBrZXkpIHx8IGhhcyh0aGlzLCBISURERU4pICYmIHRoaXNbSElEREVOXVtrZXldXG4gICAgPyBFIDogdHJ1ZTtcbn07XG52YXIgJGdldE93blByb3BlcnR5RGVzY3JpcHRvciA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5RGVzY3JpcHRvcihpdCwga2V5KXtcbiAgdmFyIEQgPSBnZXREZXNjKGl0ID0gdG9JT2JqZWN0KGl0KSwga2V5KTtcbiAgaWYoRCAmJiBoYXMoQWxsU3ltYm9scywga2V5KSAmJiAhKGhhcyhpdCwgSElEREVOKSAmJiBpdFtISURERU5dW2tleV0pKUQuZW51bWVyYWJsZSA9IHRydWU7XG4gIHJldHVybiBEO1xufTtcbnZhciAkZ2V0T3duUHJvcGVydHlOYW1lcyA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5TmFtZXMoaXQpe1xuICB2YXIgbmFtZXMgID0gZ2V0TmFtZXModG9JT2JqZWN0KGl0KSlcbiAgICAsIHJlc3VsdCA9IFtdXG4gICAgLCBpICAgICAgPSAwXG4gICAgLCBrZXk7XG4gIHdoaWxlKG5hbWVzLmxlbmd0aCA+IGkpaWYoIWhhcyhBbGxTeW1ib2xzLCBrZXkgPSBuYW1lc1tpKytdKSAmJiBrZXkgIT0gSElEREVOKXJlc3VsdC5wdXNoKGtleSk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xudmFyICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eVN5bWJvbHMoaXQpe1xuICB2YXIgbmFtZXMgID0gZ2V0TmFtZXModG9JT2JqZWN0KGl0KSlcbiAgICAsIHJlc3VsdCA9IFtdXG4gICAgLCBpICAgICAgPSAwXG4gICAgLCBrZXk7XG4gIHdoaWxlKG5hbWVzLmxlbmd0aCA+IGkpaWYoaGFzKEFsbFN5bWJvbHMsIGtleSA9IG5hbWVzW2krK10pKXJlc3VsdC5wdXNoKEFsbFN5bWJvbHNba2V5XSk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xudmFyICRzdHJpbmdpZnkgPSBmdW5jdGlvbiBzdHJpbmdpZnkoaXQpe1xuICBpZihpdCA9PT0gdW5kZWZpbmVkIHx8IGlzU3ltYm9sKGl0KSlyZXR1cm47IC8vIElFOCByZXR1cm5zIHN0cmluZyBvbiB1bmRlZmluZWRcbiAgdmFyIGFyZ3MgPSBbaXRdXG4gICAgLCBpICAgID0gMVxuICAgICwgJCQgICA9IGFyZ3VtZW50c1xuICAgICwgcmVwbGFjZXIsICRyZXBsYWNlcjtcbiAgd2hpbGUoJCQubGVuZ3RoID4gaSlhcmdzLnB1c2goJCRbaSsrXSk7XG4gIHJlcGxhY2VyID0gYXJnc1sxXTtcbiAgaWYodHlwZW9mIHJlcGxhY2VyID09ICdmdW5jdGlvbicpJHJlcGxhY2VyID0gcmVwbGFjZXI7XG4gIGlmKCRyZXBsYWNlciB8fCAhaXNBcnJheShyZXBsYWNlcikpcmVwbGFjZXIgPSBmdW5jdGlvbihrZXksIHZhbHVlKXtcbiAgICBpZigkcmVwbGFjZXIpdmFsdWUgPSAkcmVwbGFjZXIuY2FsbCh0aGlzLCBrZXksIHZhbHVlKTtcbiAgICBpZighaXNTeW1ib2wodmFsdWUpKXJldHVybiB2YWx1ZTtcbiAgfTtcbiAgYXJnc1sxXSA9IHJlcGxhY2VyO1xuICByZXR1cm4gX3N0cmluZ2lmeS5hcHBseSgkSlNPTiwgYXJncyk7XG59O1xudmFyIGJ1Z2d5SlNPTiA9ICRmYWlscyhmdW5jdGlvbigpe1xuICB2YXIgUyA9ICRTeW1ib2woKTtcbiAgLy8gTVMgRWRnZSBjb252ZXJ0cyBzeW1ib2wgdmFsdWVzIHRvIEpTT04gYXMge31cbiAgLy8gV2ViS2l0IGNvbnZlcnRzIHN5bWJvbCB2YWx1ZXMgdG8gSlNPTiBhcyBudWxsXG4gIC8vIFY4IHRocm93cyBvbiBib3hlZCBzeW1ib2xzXG4gIHJldHVybiBfc3RyaW5naWZ5KFtTXSkgIT0gJ1tudWxsXScgfHwgX3N0cmluZ2lmeSh7YTogU30pICE9ICd7fScgfHwgX3N0cmluZ2lmeShPYmplY3QoUykpICE9ICd7fSc7XG59KTtcblxuLy8gMTkuNC4xLjEgU3ltYm9sKFtkZXNjcmlwdGlvbl0pXG5pZighdXNlTmF0aXZlKXtcbiAgJFN5bWJvbCA9IGZ1bmN0aW9uIFN5bWJvbCgpe1xuICAgIGlmKGlzU3ltYm9sKHRoaXMpKXRocm93IFR5cGVFcnJvcignU3ltYm9sIGlzIG5vdCBhIGNvbnN0cnVjdG9yJyk7XG4gICAgcmV0dXJuIHdyYXAodWlkKGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKSk7XG4gIH07XG4gIHJlZGVmaW5lKCRTeW1ib2wucHJvdG90eXBlLCAndG9TdHJpbmcnLCBmdW5jdGlvbiB0b1N0cmluZygpe1xuICAgIHJldHVybiB0aGlzLl9rO1xuICB9KTtcblxuICBpc1N5bWJvbCA9IGZ1bmN0aW9uKGl0KXtcbiAgICByZXR1cm4gaXQgaW5zdGFuY2VvZiAkU3ltYm9sO1xuICB9O1xuXG4gICQuY3JlYXRlICAgICA9ICRjcmVhdGU7XG4gICQuaXNFbnVtICAgICA9ICRwcm9wZXJ0eUlzRW51bWVyYWJsZTtcbiAgJC5nZXREZXNjICAgID0gJGdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbiAgJC5zZXREZXNjICAgID0gJGRlZmluZVByb3BlcnR5O1xuICAkLnNldERlc2NzICAgPSAkZGVmaW5lUHJvcGVydGllcztcbiAgJC5nZXROYW1lcyAgID0gJG5hbWVzLmdldCA9ICRnZXRPd25Qcm9wZXJ0eU5hbWVzO1xuICAkLmdldFN5bWJvbHMgPSAkZ2V0T3duUHJvcGVydHlTeW1ib2xzO1xuXG4gIGlmKERFU0NSSVBUT1JTICYmICFyZXF1aXJlKCcuLyQubGlicmFyeScpKXtcbiAgICByZWRlZmluZShPYmplY3RQcm90bywgJ3Byb3BlcnR5SXNFbnVtZXJhYmxlJywgJHByb3BlcnR5SXNFbnVtZXJhYmxlLCB0cnVlKTtcbiAgfVxufVxuXG52YXIgc3ltYm9sU3RhdGljcyA9IHtcbiAgLy8gMTkuNC4yLjEgU3ltYm9sLmZvcihrZXkpXG4gICdmb3InOiBmdW5jdGlvbihrZXkpe1xuICAgIHJldHVybiBoYXMoU3ltYm9sUmVnaXN0cnksIGtleSArPSAnJylcbiAgICAgID8gU3ltYm9sUmVnaXN0cnlba2V5XVxuICAgICAgOiBTeW1ib2xSZWdpc3RyeVtrZXldID0gJFN5bWJvbChrZXkpO1xuICB9LFxuICAvLyAxOS40LjIuNSBTeW1ib2wua2V5Rm9yKHN5bSlcbiAga2V5Rm9yOiBmdW5jdGlvbiBrZXlGb3Ioa2V5KXtcbiAgICByZXR1cm4ga2V5T2YoU3ltYm9sUmVnaXN0cnksIGtleSk7XG4gIH0sXG4gIHVzZVNldHRlcjogZnVuY3Rpb24oKXsgc2V0dGVyID0gdHJ1ZTsgfSxcbiAgdXNlU2ltcGxlOiBmdW5jdGlvbigpeyBzZXR0ZXIgPSBmYWxzZTsgfVxufTtcbi8vIDE5LjQuMi4yIFN5bWJvbC5oYXNJbnN0YW5jZVxuLy8gMTkuNC4yLjMgU3ltYm9sLmlzQ29uY2F0U3ByZWFkYWJsZVxuLy8gMTkuNC4yLjQgU3ltYm9sLml0ZXJhdG9yXG4vLyAxOS40LjIuNiBTeW1ib2wubWF0Y2hcbi8vIDE5LjQuMi44IFN5bWJvbC5yZXBsYWNlXG4vLyAxOS40LjIuOSBTeW1ib2wuc2VhcmNoXG4vLyAxOS40LjIuMTAgU3ltYm9sLnNwZWNpZXNcbi8vIDE5LjQuMi4xMSBTeW1ib2wuc3BsaXRcbi8vIDE5LjQuMi4xMiBTeW1ib2wudG9QcmltaXRpdmVcbi8vIDE5LjQuMi4xMyBTeW1ib2wudG9TdHJpbmdUYWdcbi8vIDE5LjQuMi4xNCBTeW1ib2wudW5zY29wYWJsZXNcbiQuZWFjaC5jYWxsKChcbiAgJ2hhc0luc3RhbmNlLGlzQ29uY2F0U3ByZWFkYWJsZSxpdGVyYXRvcixtYXRjaCxyZXBsYWNlLHNlYXJjaCwnICtcbiAgJ3NwZWNpZXMsc3BsaXQsdG9QcmltaXRpdmUsdG9TdHJpbmdUYWcsdW5zY29wYWJsZXMnXG4pLnNwbGl0KCcsJyksIGZ1bmN0aW9uKGl0KXtcbiAgdmFyIHN5bSA9IHdrcyhpdCk7XG4gIHN5bWJvbFN0YXRpY3NbaXRdID0gdXNlTmF0aXZlID8gc3ltIDogd3JhcChzeW0pO1xufSk7XG5cbnNldHRlciA9IHRydWU7XG5cbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XLCB7U3ltYm9sOiAkU3ltYm9sfSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnU3ltYm9sJywgc3ltYm9sU3RhdGljcyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIXVzZU5hdGl2ZSwgJ09iamVjdCcsIHtcbiAgLy8gMTkuMS4yLjIgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxuICBjcmVhdGU6ICRjcmVhdGUsXG4gIC8vIDE5LjEuMi40IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKVxuICBkZWZpbmVQcm9wZXJ0eTogJGRlZmluZVByb3BlcnR5LFxuICAvLyAxOS4xLjIuMyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhPLCBQcm9wZXJ0aWVzKVxuICBkZWZpbmVQcm9wZXJ0aWVzOiAkZGVmaW5lUHJvcGVydGllcyxcbiAgLy8gMTkuMS4yLjYgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihPLCBQKVxuICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I6ICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IsXG4gIC8vIDE5LjEuMi43IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKE8pXG4gIGdldE93blByb3BlcnR5TmFtZXM6ICRnZXRPd25Qcm9wZXJ0eU5hbWVzLFxuICAvLyAxOS4xLjIuOCBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKE8pXG4gIGdldE93blByb3BlcnR5U3ltYm9sczogJGdldE93blByb3BlcnR5U3ltYm9sc1xufSk7XG5cbi8vIDI0LjMuMiBKU09OLnN0cmluZ2lmeSh2YWx1ZSBbLCByZXBsYWNlciBbLCBzcGFjZV1dKVxuJEpTT04gJiYgJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoIXVzZU5hdGl2ZSB8fCBidWdneUpTT04pLCAnSlNPTicsIHtzdHJpbmdpZnk6ICRzdHJpbmdpZnl9KTtcblxuLy8gMTkuNC4zLjUgU3ltYm9sLnByb3RvdHlwZVtAQHRvU3RyaW5nVGFnXVxuc2V0VG9TdHJpbmdUYWcoJFN5bWJvbCwgJ1N5bWJvbCcpO1xuLy8gMjAuMi4xLjkgTWF0aFtAQHRvU3RyaW5nVGFnXVxuc2V0VG9TdHJpbmdUYWcoTWF0aCwgJ01hdGgnLCB0cnVlKTtcbi8vIDI0LjMuMyBKU09OW0BAdG9TdHJpbmdUYWddXG5zZXRUb1N0cmluZ1RhZyhnbG9iYWwuSlNPTiwgJ0pTT04nLCB0cnVlKTsiLCJcbi8qKlxuICogVGhpcyBpcyB0aGUgd2ViIGJyb3dzZXIgaW1wbGVtZW50YXRpb24gb2YgYGRlYnVnKClgLlxuICpcbiAqIEV4cG9zZSBgZGVidWcoKWAgYXMgdGhlIG1vZHVsZS5cbiAqL1xuXG5leHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2RlYnVnJyk7XG5leHBvcnRzLmxvZyA9IGxvZztcbmV4cG9ydHMuZm9ybWF0QXJncyA9IGZvcm1hdEFyZ3M7XG5leHBvcnRzLnNhdmUgPSBzYXZlO1xuZXhwb3J0cy5sb2FkID0gbG9hZDtcbmV4cG9ydHMudXNlQ29sb3JzID0gdXNlQ29sb3JzO1xuZXhwb3J0cy5zdG9yYWdlID0gJ3VuZGVmaW5lZCcgIT0gdHlwZW9mIGNocm9tZVxuICAgICAgICAgICAgICAgJiYgJ3VuZGVmaW5lZCcgIT0gdHlwZW9mIGNocm9tZS5zdG9yYWdlXG4gICAgICAgICAgICAgICAgICA/IGNocm9tZS5zdG9yYWdlLmxvY2FsXG4gICAgICAgICAgICAgICAgICA6IGxvY2Fsc3RvcmFnZSgpO1xuXG4vKipcbiAqIENvbG9ycy5cbiAqL1xuXG5leHBvcnRzLmNvbG9ycyA9IFtcbiAgJ2xpZ2h0c2VhZ3JlZW4nLFxuICAnZm9yZXN0Z3JlZW4nLFxuICAnZ29sZGVucm9kJyxcbiAgJ2RvZGdlcmJsdWUnLFxuICAnZGFya29yY2hpZCcsXG4gICdjcmltc29uJ1xuXTtcblxuLyoqXG4gKiBDdXJyZW50bHkgb25seSBXZWJLaXQtYmFzZWQgV2ViIEluc3BlY3RvcnMsIEZpcmVmb3ggPj0gdjMxLFxuICogYW5kIHRoZSBGaXJlYnVnIGV4dGVuc2lvbiAoYW55IEZpcmVmb3ggdmVyc2lvbikgYXJlIGtub3duXG4gKiB0byBzdXBwb3J0IFwiJWNcIiBDU1MgY3VzdG9taXphdGlvbnMuXG4gKlxuICogVE9ETzogYWRkIGEgYGxvY2FsU3RvcmFnZWAgdmFyaWFibGUgdG8gZXhwbGljaXRseSBlbmFibGUvZGlzYWJsZSBjb2xvcnNcbiAqL1xuXG5mdW5jdGlvbiB1c2VDb2xvcnMoKSB7XG4gIC8vIGlzIHdlYmtpdD8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTY0NTk2MDYvMzc2NzczXG4gIHJldHVybiAoJ1dlYmtpdEFwcGVhcmFuY2UnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZSkgfHxcbiAgICAvLyBpcyBmaXJlYnVnPyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8zOTgxMjAvMzc2NzczXG4gICAgKHdpbmRvdy5jb25zb2xlICYmIChjb25zb2xlLmZpcmVidWcgfHwgKGNvbnNvbGUuZXhjZXB0aW9uICYmIGNvbnNvbGUudGFibGUpKSkgfHxcbiAgICAvLyBpcyBmaXJlZm94ID49IHYzMT9cbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1Rvb2xzL1dlYl9Db25zb2xlI1N0eWxpbmdfbWVzc2FnZXNcbiAgICAobmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpLm1hdGNoKC9maXJlZm94XFwvKFxcZCspLykgJiYgcGFyc2VJbnQoUmVnRXhwLiQxLCAxMCkgPj0gMzEpO1xufVxuXG4vKipcbiAqIE1hcCAlaiB0byBgSlNPTi5zdHJpbmdpZnkoKWAsIHNpbmNlIG5vIFdlYiBJbnNwZWN0b3JzIGRvIHRoYXQgYnkgZGVmYXVsdC5cbiAqL1xuXG5leHBvcnRzLmZvcm1hdHRlcnMuaiA9IGZ1bmN0aW9uKHYpIHtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHYpO1xufTtcblxuXG4vKipcbiAqIENvbG9yaXplIGxvZyBhcmd1bWVudHMgaWYgZW5hYmxlZC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGZvcm1hdEFyZ3MoKSB7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICB2YXIgdXNlQ29sb3JzID0gdGhpcy51c2VDb2xvcnM7XG5cbiAgYXJnc1swXSA9ICh1c2VDb2xvcnMgPyAnJWMnIDogJycpXG4gICAgKyB0aGlzLm5hbWVzcGFjZVxuICAgICsgKHVzZUNvbG9ycyA/ICcgJWMnIDogJyAnKVxuICAgICsgYXJnc1swXVxuICAgICsgKHVzZUNvbG9ycyA/ICclYyAnIDogJyAnKVxuICAgICsgJysnICsgZXhwb3J0cy5odW1hbml6ZSh0aGlzLmRpZmYpO1xuXG4gIGlmICghdXNlQ29sb3JzKSByZXR1cm4gYXJncztcblxuICB2YXIgYyA9ICdjb2xvcjogJyArIHRoaXMuY29sb3I7XG4gIGFyZ3MgPSBbYXJnc1swXSwgYywgJ2NvbG9yOiBpbmhlcml0J10uY29uY2F0KEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MsIDEpKTtcblxuICAvLyB0aGUgZmluYWwgXCIlY1wiIGlzIHNvbWV3aGF0IHRyaWNreSwgYmVjYXVzZSB0aGVyZSBjb3VsZCBiZSBvdGhlclxuICAvLyBhcmd1bWVudHMgcGFzc2VkIGVpdGhlciBiZWZvcmUgb3IgYWZ0ZXIgdGhlICVjLCBzbyB3ZSBuZWVkIHRvXG4gIC8vIGZpZ3VyZSBvdXQgdGhlIGNvcnJlY3QgaW5kZXggdG8gaW5zZXJ0IHRoZSBDU1MgaW50b1xuICB2YXIgaW5kZXggPSAwO1xuICB2YXIgbGFzdEMgPSAwO1xuICBhcmdzWzBdLnJlcGxhY2UoLyVbYS16JV0vZywgZnVuY3Rpb24obWF0Y2gpIHtcbiAgICBpZiAoJyUlJyA9PT0gbWF0Y2gpIHJldHVybjtcbiAgICBpbmRleCsrO1xuICAgIGlmICgnJWMnID09PSBtYXRjaCkge1xuICAgICAgLy8gd2Ugb25seSBhcmUgaW50ZXJlc3RlZCBpbiB0aGUgKmxhc3QqICVjXG4gICAgICAvLyAodGhlIHVzZXIgbWF5IGhhdmUgcHJvdmlkZWQgdGhlaXIgb3duKVxuICAgICAgbGFzdEMgPSBpbmRleDtcbiAgICB9XG4gIH0pO1xuXG4gIGFyZ3Muc3BsaWNlKGxhc3RDLCAwLCBjKTtcbiAgcmV0dXJuIGFyZ3M7XG59XG5cbi8qKlxuICogSW52b2tlcyBgY29uc29sZS5sb2coKWAgd2hlbiBhdmFpbGFibGUuXG4gKiBOby1vcCB3aGVuIGBjb25zb2xlLmxvZ2AgaXMgbm90IGEgXCJmdW5jdGlvblwiLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gbG9nKCkge1xuICAvLyB0aGlzIGhhY2tlcnkgaXMgcmVxdWlyZWQgZm9yIElFOC85LCB3aGVyZVxuICAvLyB0aGUgYGNvbnNvbGUubG9nYCBmdW5jdGlvbiBkb2Vzbid0IGhhdmUgJ2FwcGx5J1xuICByZXR1cm4gJ29iamVjdCcgPT09IHR5cGVvZiBjb25zb2xlXG4gICAgJiYgY29uc29sZS5sb2dcbiAgICAmJiBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbChjb25zb2xlLmxvZywgY29uc29sZSwgYXJndW1lbnRzKTtcbn1cblxuLyoqXG4gKiBTYXZlIGBuYW1lc3BhY2VzYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlc1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2F2ZShuYW1lc3BhY2VzKSB7XG4gIHRyeSB7XG4gICAgaWYgKG51bGwgPT0gbmFtZXNwYWNlcykge1xuICAgICAgZXhwb3J0cy5zdG9yYWdlLnJlbW92ZUl0ZW0oJ2RlYnVnJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4cG9ydHMuc3RvcmFnZS5kZWJ1ZyA9IG5hbWVzcGFjZXM7XG4gICAgfVxuICB9IGNhdGNoKGUpIHt9XG59XG5cbi8qKlxuICogTG9hZCBgbmFtZXNwYWNlc2AuXG4gKlxuICogQHJldHVybiB7U3RyaW5nfSByZXR1cm5zIHRoZSBwcmV2aW91c2x5IHBlcnNpc3RlZCBkZWJ1ZyBtb2Rlc1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gbG9hZCgpIHtcbiAgdmFyIHI7XG4gIHRyeSB7XG4gICAgciA9IGV4cG9ydHMuc3RvcmFnZS5kZWJ1ZztcbiAgfSBjYXRjaChlKSB7fVxuICByZXR1cm4gcjtcbn1cblxuLyoqXG4gKiBFbmFibGUgbmFtZXNwYWNlcyBsaXN0ZWQgaW4gYGxvY2FsU3RvcmFnZS5kZWJ1Z2AgaW5pdGlhbGx5LlxuICovXG5cbmV4cG9ydHMuZW5hYmxlKGxvYWQoKSk7XG5cbi8qKlxuICogTG9jYWxzdG9yYWdlIGF0dGVtcHRzIHRvIHJldHVybiB0aGUgbG9jYWxzdG9yYWdlLlxuICpcbiAqIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2Ugc2FmYXJpIHRocm93c1xuICogd2hlbiBhIHVzZXIgZGlzYWJsZXMgY29va2llcy9sb2NhbHN0b3JhZ2VcbiAqIGFuZCB5b3UgYXR0ZW1wdCB0byBhY2Nlc3MgaXQuXG4gKlxuICogQHJldHVybiB7TG9jYWxTdG9yYWdlfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gbG9jYWxzdG9yYWdlKCl7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHdpbmRvdy5sb2NhbFN0b3JhZ2U7XG4gIH0gY2F0Y2ggKGUpIHt9XG59XG4iLCJcbi8qKlxuICogVGhpcyBpcyB0aGUgY29tbW9uIGxvZ2ljIGZvciBib3RoIHRoZSBOb2RlLmpzIGFuZCB3ZWIgYnJvd3NlclxuICogaW1wbGVtZW50YXRpb25zIG9mIGBkZWJ1ZygpYC5cbiAqXG4gKiBFeHBvc2UgYGRlYnVnKClgIGFzIHRoZSBtb2R1bGUuXG4gKi9cblxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZGVidWc7XG5leHBvcnRzLmNvZXJjZSA9IGNvZXJjZTtcbmV4cG9ydHMuZGlzYWJsZSA9IGRpc2FibGU7XG5leHBvcnRzLmVuYWJsZSA9IGVuYWJsZTtcbmV4cG9ydHMuZW5hYmxlZCA9IGVuYWJsZWQ7XG5leHBvcnRzLmh1bWFuaXplID0gcmVxdWlyZSgnbXMnKTtcblxuLyoqXG4gKiBUaGUgY3VycmVudGx5IGFjdGl2ZSBkZWJ1ZyBtb2RlIG5hbWVzLCBhbmQgbmFtZXMgdG8gc2tpcC5cbiAqL1xuXG5leHBvcnRzLm5hbWVzID0gW107XG5leHBvcnRzLnNraXBzID0gW107XG5cbi8qKlxuICogTWFwIG9mIHNwZWNpYWwgXCIlblwiIGhhbmRsaW5nIGZ1bmN0aW9ucywgZm9yIHRoZSBkZWJ1ZyBcImZvcm1hdFwiIGFyZ3VtZW50LlxuICpcbiAqIFZhbGlkIGtleSBuYW1lcyBhcmUgYSBzaW5nbGUsIGxvd2VyY2FzZWQgbGV0dGVyLCBpLmUuIFwiblwiLlxuICovXG5cbmV4cG9ydHMuZm9ybWF0dGVycyA9IHt9O1xuXG4vKipcbiAqIFByZXZpb3VzbHkgYXNzaWduZWQgY29sb3IuXG4gKi9cblxudmFyIHByZXZDb2xvciA9IDA7XG5cbi8qKlxuICogUHJldmlvdXMgbG9nIHRpbWVzdGFtcC5cbiAqL1xuXG52YXIgcHJldlRpbWU7XG5cbi8qKlxuICogU2VsZWN0IGEgY29sb3IuXG4gKlxuICogQHJldHVybiB7TnVtYmVyfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2VsZWN0Q29sb3IoKSB7XG4gIHJldHVybiBleHBvcnRzLmNvbG9yc1twcmV2Q29sb3IrKyAlIGV4cG9ydHMuY29sb3JzLmxlbmd0aF07XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgZGVidWdnZXIgd2l0aCB0aGUgZ2l2ZW4gYG5hbWVzcGFjZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRlYnVnKG5hbWVzcGFjZSkge1xuXG4gIC8vIGRlZmluZSB0aGUgYGRpc2FibGVkYCB2ZXJzaW9uXG4gIGZ1bmN0aW9uIGRpc2FibGVkKCkge1xuICB9XG4gIGRpc2FibGVkLmVuYWJsZWQgPSBmYWxzZTtcblxuICAvLyBkZWZpbmUgdGhlIGBlbmFibGVkYCB2ZXJzaW9uXG4gIGZ1bmN0aW9uIGVuYWJsZWQoKSB7XG5cbiAgICB2YXIgc2VsZiA9IGVuYWJsZWQ7XG5cbiAgICAvLyBzZXQgYGRpZmZgIHRpbWVzdGFtcFxuICAgIHZhciBjdXJyID0gK25ldyBEYXRlKCk7XG4gICAgdmFyIG1zID0gY3VyciAtIChwcmV2VGltZSB8fCBjdXJyKTtcbiAgICBzZWxmLmRpZmYgPSBtcztcbiAgICBzZWxmLnByZXYgPSBwcmV2VGltZTtcbiAgICBzZWxmLmN1cnIgPSBjdXJyO1xuICAgIHByZXZUaW1lID0gY3VycjtcblxuICAgIC8vIGFkZCB0aGUgYGNvbG9yYCBpZiBub3Qgc2V0XG4gICAgaWYgKG51bGwgPT0gc2VsZi51c2VDb2xvcnMpIHNlbGYudXNlQ29sb3JzID0gZXhwb3J0cy51c2VDb2xvcnMoKTtcbiAgICBpZiAobnVsbCA9PSBzZWxmLmNvbG9yICYmIHNlbGYudXNlQ29sb3JzKSBzZWxmLmNvbG9yID0gc2VsZWN0Q29sb3IoKTtcblxuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICAgIGFyZ3NbMF0gPSBleHBvcnRzLmNvZXJjZShhcmdzWzBdKTtcblxuICAgIGlmICgnc3RyaW5nJyAhPT0gdHlwZW9mIGFyZ3NbMF0pIHtcbiAgICAgIC8vIGFueXRoaW5nIGVsc2UgbGV0J3MgaW5zcGVjdCB3aXRoICVvXG4gICAgICBhcmdzID0gWyclbyddLmNvbmNhdChhcmdzKTtcbiAgICB9XG5cbiAgICAvLyBhcHBseSBhbnkgYGZvcm1hdHRlcnNgIHRyYW5zZm9ybWF0aW9uc1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgYXJnc1swXSA9IGFyZ3NbMF0ucmVwbGFjZSgvJShbYS16JV0pL2csIGZ1bmN0aW9uKG1hdGNoLCBmb3JtYXQpIHtcbiAgICAgIC8vIGlmIHdlIGVuY291bnRlciBhbiBlc2NhcGVkICUgdGhlbiBkb24ndCBpbmNyZWFzZSB0aGUgYXJyYXkgaW5kZXhcbiAgICAgIGlmIChtYXRjaCA9PT0gJyUlJykgcmV0dXJuIG1hdGNoO1xuICAgICAgaW5kZXgrKztcbiAgICAgIHZhciBmb3JtYXR0ZXIgPSBleHBvcnRzLmZvcm1hdHRlcnNbZm9ybWF0XTtcbiAgICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgZm9ybWF0dGVyKSB7XG4gICAgICAgIHZhciB2YWwgPSBhcmdzW2luZGV4XTtcbiAgICAgICAgbWF0Y2ggPSBmb3JtYXR0ZXIuY2FsbChzZWxmLCB2YWwpO1xuXG4gICAgICAgIC8vIG5vdyB3ZSBuZWVkIHRvIHJlbW92ZSBgYXJnc1tpbmRleF1gIHNpbmNlIGl0J3MgaW5saW5lZCBpbiB0aGUgYGZvcm1hdGBcbiAgICAgICAgYXJncy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBpbmRleC0tO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH0pO1xuXG4gICAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBleHBvcnRzLmZvcm1hdEFyZ3MpIHtcbiAgICAgIGFyZ3MgPSBleHBvcnRzLmZvcm1hdEFyZ3MuYXBwbHkoc2VsZiwgYXJncyk7XG4gICAgfVxuICAgIHZhciBsb2dGbiA9IGVuYWJsZWQubG9nIHx8IGV4cG9ydHMubG9nIHx8IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSk7XG4gICAgbG9nRm4uYXBwbHkoc2VsZiwgYXJncyk7XG4gIH1cbiAgZW5hYmxlZC5lbmFibGVkID0gdHJ1ZTtcblxuICB2YXIgZm4gPSBleHBvcnRzLmVuYWJsZWQobmFtZXNwYWNlKSA/IGVuYWJsZWQgOiBkaXNhYmxlZDtcblxuICBmbi5uYW1lc3BhY2UgPSBuYW1lc3BhY2U7XG5cbiAgcmV0dXJuIGZuO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgYSBkZWJ1ZyBtb2RlIGJ5IG5hbWVzcGFjZXMuIFRoaXMgY2FuIGluY2x1ZGUgbW9kZXNcbiAqIHNlcGFyYXRlZCBieSBhIGNvbG9uIGFuZCB3aWxkY2FyZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVzcGFjZXNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZW5hYmxlKG5hbWVzcGFjZXMpIHtcbiAgZXhwb3J0cy5zYXZlKG5hbWVzcGFjZXMpO1xuXG4gIHZhciBzcGxpdCA9IChuYW1lc3BhY2VzIHx8ICcnKS5zcGxpdCgvW1xccyxdKy8pO1xuICB2YXIgbGVuID0gc3BsaXQubGVuZ3RoO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoIXNwbGl0W2ldKSBjb250aW51ZTsgLy8gaWdub3JlIGVtcHR5IHN0cmluZ3NcbiAgICBuYW1lc3BhY2VzID0gc3BsaXRbaV0ucmVwbGFjZSgvXFwqL2csICcuKj8nKTtcbiAgICBpZiAobmFtZXNwYWNlc1swXSA9PT0gJy0nKSB7XG4gICAgICBleHBvcnRzLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzLnN1YnN0cigxKSArICckJykpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleHBvcnRzLm5hbWVzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzICsgJyQnKSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRGlzYWJsZSBkZWJ1ZyBvdXRwdXQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkaXNhYmxlKCkge1xuICBleHBvcnRzLmVuYWJsZSgnJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RlIG5hbWUgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGVkKG5hbWUpIHtcbiAgdmFyIGksIGxlbjtcbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5za2lwcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLnNraXBzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5uYW1lcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgIGlmIChleHBvcnRzLm5hbWVzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ29lcmNlIGB2YWxgLlxuICpcbiAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICogQHJldHVybiB7TWl4ZWR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBjb2VyY2UodmFsKSB7XG4gIGlmICh2YWwgaW5zdGFuY2VvZiBFcnJvcikgcmV0dXJuIHZhbC5zdGFjayB8fCB2YWwubWVzc2FnZTtcbiAgcmV0dXJuIHZhbDtcbn1cbiIsIlxubW9kdWxlLmV4cG9ydHMgPSAgcmVxdWlyZSgnLi9saWIvJyk7XG4iLCJcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9zb2NrZXQnKTtcblxuLyoqXG4gKiBFeHBvcnRzIHBhcnNlclxuICpcbiAqIEBhcGkgcHVibGljXG4gKlxuICovXG5tb2R1bGUuZXhwb3J0cy5wYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG4iLCIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHRyYW5zcG9ydHMgPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ2VuZ2luZS5pby1jbGllbnQ6c29ja2V0Jyk7XG52YXIgaW5kZXggPSByZXF1aXJlKCdpbmRleG9mJyk7XG52YXIgcGFyc2VyID0gcmVxdWlyZSgnZW5naW5lLmlvLXBhcnNlcicpO1xudmFyIHBhcnNldXJpID0gcmVxdWlyZSgncGFyc2V1cmknKTtcbnZhciBwYXJzZWpzb24gPSByZXF1aXJlKCdwYXJzZWpzb24nKTtcbnZhciBwYXJzZXFzID0gcmVxdWlyZSgncGFyc2VxcycpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gU29ja2V0O1xuXG4vKipcbiAqIE5vb3AgZnVuY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gbm9vcCgpe31cblxuLyoqXG4gKiBTb2NrZXQgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSB1cmkgb3Igb3B0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gU29ja2V0KHVyaSwgb3B0cyl7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTb2NrZXQpKSByZXR1cm4gbmV3IFNvY2tldCh1cmksIG9wdHMpO1xuXG4gIG9wdHMgPSBvcHRzIHx8IHt9O1xuXG4gIGlmICh1cmkgJiYgJ29iamVjdCcgPT0gdHlwZW9mIHVyaSkge1xuICAgIG9wdHMgPSB1cmk7XG4gICAgdXJpID0gbnVsbDtcbiAgfVxuXG4gIGlmICh1cmkpIHtcbiAgICB1cmkgPSBwYXJzZXVyaSh1cmkpO1xuICAgIG9wdHMuaG9zdG5hbWUgPSB1cmkuaG9zdDtcbiAgICBvcHRzLnNlY3VyZSA9IHVyaS5wcm90b2NvbCA9PSAnaHR0cHMnIHx8IHVyaS5wcm90b2NvbCA9PSAnd3NzJztcbiAgICBvcHRzLnBvcnQgPSB1cmkucG9ydDtcbiAgICBpZiAodXJpLnF1ZXJ5KSBvcHRzLnF1ZXJ5ID0gdXJpLnF1ZXJ5O1xuICB9IGVsc2UgaWYgKG9wdHMuaG9zdCkge1xuICAgIG9wdHMuaG9zdG5hbWUgPSBwYXJzZXVyaShvcHRzLmhvc3QpLmhvc3Q7XG4gIH1cblxuICB0aGlzLnNlY3VyZSA9IG51bGwgIT0gb3B0cy5zZWN1cmUgPyBvcHRzLnNlY3VyZSA6XG4gICAgKGdsb2JhbC5sb2NhdGlvbiAmJiAnaHR0cHM6JyA9PSBsb2NhdGlvbi5wcm90b2NvbCk7XG5cbiAgaWYgKG9wdHMuaG9zdG5hbWUgJiYgIW9wdHMucG9ydCkge1xuICAgIC8vIGlmIG5vIHBvcnQgaXMgc3BlY2lmaWVkIG1hbnVhbGx5LCB1c2UgdGhlIHByb3RvY29sIGRlZmF1bHRcbiAgICBvcHRzLnBvcnQgPSB0aGlzLnNlY3VyZSA/ICc0NDMnIDogJzgwJztcbiAgfVxuXG4gIHRoaXMuYWdlbnQgPSBvcHRzLmFnZW50IHx8IGZhbHNlO1xuICB0aGlzLmhvc3RuYW1lID0gb3B0cy5ob3N0bmFtZSB8fFxuICAgIChnbG9iYWwubG9jYXRpb24gPyBsb2NhdGlvbi5ob3N0bmFtZSA6ICdsb2NhbGhvc3QnKTtcbiAgdGhpcy5wb3J0ID0gb3B0cy5wb3J0IHx8IChnbG9iYWwubG9jYXRpb24gJiYgbG9jYXRpb24ucG9ydCA/XG4gICAgICAgbG9jYXRpb24ucG9ydCA6XG4gICAgICAgKHRoaXMuc2VjdXJlID8gNDQzIDogODApKTtcbiAgdGhpcy5xdWVyeSA9IG9wdHMucXVlcnkgfHwge307XG4gIGlmICgnc3RyaW5nJyA9PSB0eXBlb2YgdGhpcy5xdWVyeSkgdGhpcy5xdWVyeSA9IHBhcnNlcXMuZGVjb2RlKHRoaXMucXVlcnkpO1xuICB0aGlzLnVwZ3JhZGUgPSBmYWxzZSAhPT0gb3B0cy51cGdyYWRlO1xuICB0aGlzLnBhdGggPSAob3B0cy5wYXRoIHx8ICcvZW5naW5lLmlvJykucmVwbGFjZSgvXFwvJC8sICcnKSArICcvJztcbiAgdGhpcy5mb3JjZUpTT05QID0gISFvcHRzLmZvcmNlSlNPTlA7XG4gIHRoaXMuanNvbnAgPSBmYWxzZSAhPT0gb3B0cy5qc29ucDtcbiAgdGhpcy5mb3JjZUJhc2U2NCA9ICEhb3B0cy5mb3JjZUJhc2U2NDtcbiAgdGhpcy5lbmFibGVzWERSID0gISFvcHRzLmVuYWJsZXNYRFI7XG4gIHRoaXMudGltZXN0YW1wUGFyYW0gPSBvcHRzLnRpbWVzdGFtcFBhcmFtIHx8ICd0JztcbiAgdGhpcy50aW1lc3RhbXBSZXF1ZXN0cyA9IG9wdHMudGltZXN0YW1wUmVxdWVzdHM7XG4gIHRoaXMudHJhbnNwb3J0cyA9IG9wdHMudHJhbnNwb3J0cyB8fCBbJ3BvbGxpbmcnLCAnd2Vic29ja2V0J107XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICcnO1xuICB0aGlzLndyaXRlQnVmZmVyID0gW107XG4gIHRoaXMucG9saWN5UG9ydCA9IG9wdHMucG9saWN5UG9ydCB8fCA4NDM7XG4gIHRoaXMucmVtZW1iZXJVcGdyYWRlID0gb3B0cy5yZW1lbWJlclVwZ3JhZGUgfHwgZmFsc2U7XG4gIHRoaXMuYmluYXJ5VHlwZSA9IG51bGw7XG4gIHRoaXMub25seUJpbmFyeVVwZ3JhZGVzID0gb3B0cy5vbmx5QmluYXJ5VXBncmFkZXM7XG4gIHRoaXMucGVyTWVzc2FnZURlZmxhdGUgPSBmYWxzZSAhPT0gb3B0cy5wZXJNZXNzYWdlRGVmbGF0ZSA/IChvcHRzLnBlck1lc3NhZ2VEZWZsYXRlIHx8IHt9KSA6IGZhbHNlO1xuXG4gIGlmICh0cnVlID09PSB0aGlzLnBlck1lc3NhZ2VEZWZsYXRlKSB0aGlzLnBlck1lc3NhZ2VEZWZsYXRlID0ge307XG4gIGlmICh0aGlzLnBlck1lc3NhZ2VEZWZsYXRlICYmIG51bGwgPT0gdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZS50aHJlc2hvbGQpIHtcbiAgICB0aGlzLnBlck1lc3NhZ2VEZWZsYXRlLnRocmVzaG9sZCA9IDEwMjQ7XG4gIH1cblxuICAvLyBTU0wgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgdGhpcy5wZnggPSBvcHRzLnBmeCB8fCBudWxsO1xuICB0aGlzLmtleSA9IG9wdHMua2V5IHx8IG51bGw7XG4gIHRoaXMucGFzc3BocmFzZSA9IG9wdHMucGFzc3BocmFzZSB8fCBudWxsO1xuICB0aGlzLmNlcnQgPSBvcHRzLmNlcnQgfHwgbnVsbDtcbiAgdGhpcy5jYSA9IG9wdHMuY2EgfHwgbnVsbDtcbiAgdGhpcy5jaXBoZXJzID0gb3B0cy5jaXBoZXJzIHx8IG51bGw7XG4gIHRoaXMucmVqZWN0VW5hdXRob3JpemVkID0gb3B0cy5yZWplY3RVbmF1dGhvcml6ZWQgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBvcHRzLnJlamVjdFVuYXV0aG9yaXplZDtcblxuICAvLyBvdGhlciBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICB2YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwpIHtcbiAgICBpZiAob3B0cy5leHRyYUhlYWRlcnMgJiYgT2JqZWN0LmtleXMob3B0cy5leHRyYUhlYWRlcnMpLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuZXh0cmFIZWFkZXJzID0gb3B0cy5leHRyYUhlYWRlcnM7XG4gICAgfVxuICB9XG5cbiAgdGhpcy5vcGVuKCk7XG59XG5cblNvY2tldC5wcmlvcldlYnNvY2tldFN1Y2Nlc3MgPSBmYWxzZTtcblxuLyoqXG4gKiBNaXggaW4gYEVtaXR0ZXJgLlxuICovXG5cbkVtaXR0ZXIoU29ja2V0LnByb3RvdHlwZSk7XG5cbi8qKlxuICogUHJvdG9jb2wgdmVyc2lvbi5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b2NvbCA9IHBhcnNlci5wcm90b2NvbDsgLy8gdGhpcyBpcyBhbiBpbnRcblxuLyoqXG4gKiBFeHBvc2UgZGVwcyBmb3IgbGVnYWN5IGNvbXBhdGliaWxpdHlcbiAqIGFuZCBzdGFuZGFsb25lIGJyb3dzZXIgYWNjZXNzLlxuICovXG5cblNvY2tldC5Tb2NrZXQgPSBTb2NrZXQ7XG5Tb2NrZXQuVHJhbnNwb3J0ID0gcmVxdWlyZSgnLi90cmFuc3BvcnQnKTtcblNvY2tldC50cmFuc3BvcnRzID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzJyk7XG5Tb2NrZXQucGFyc2VyID0gcmVxdWlyZSgnZW5naW5lLmlvLXBhcnNlcicpO1xuXG4vKipcbiAqIENyZWF0ZXMgdHJhbnNwb3J0IG9mIHRoZSBnaXZlbiB0eXBlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0cmFuc3BvcnQgbmFtZVxuICogQHJldHVybiB7VHJhbnNwb3J0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5jcmVhdGVUcmFuc3BvcnQgPSBmdW5jdGlvbiAobmFtZSkge1xuICBkZWJ1ZygnY3JlYXRpbmcgdHJhbnNwb3J0IFwiJXNcIicsIG5hbWUpO1xuICB2YXIgcXVlcnkgPSBjbG9uZSh0aGlzLnF1ZXJ5KTtcblxuICAvLyBhcHBlbmQgZW5naW5lLmlvIHByb3RvY29sIGlkZW50aWZpZXJcbiAgcXVlcnkuRUlPID0gcGFyc2VyLnByb3RvY29sO1xuXG4gIC8vIHRyYW5zcG9ydCBuYW1lXG4gIHF1ZXJ5LnRyYW5zcG9ydCA9IG5hbWU7XG5cbiAgLy8gc2Vzc2lvbiBpZCBpZiB3ZSBhbHJlYWR5IGhhdmUgb25lXG4gIGlmICh0aGlzLmlkKSBxdWVyeS5zaWQgPSB0aGlzLmlkO1xuXG4gIHZhciB0cmFuc3BvcnQgPSBuZXcgdHJhbnNwb3J0c1tuYW1lXSh7XG4gICAgYWdlbnQ6IHRoaXMuYWdlbnQsXG4gICAgaG9zdG5hbWU6IHRoaXMuaG9zdG5hbWUsXG4gICAgcG9ydDogdGhpcy5wb3J0LFxuICAgIHNlY3VyZTogdGhpcy5zZWN1cmUsXG4gICAgcGF0aDogdGhpcy5wYXRoLFxuICAgIHF1ZXJ5OiBxdWVyeSxcbiAgICBmb3JjZUpTT05QOiB0aGlzLmZvcmNlSlNPTlAsXG4gICAganNvbnA6IHRoaXMuanNvbnAsXG4gICAgZm9yY2VCYXNlNjQ6IHRoaXMuZm9yY2VCYXNlNjQsXG4gICAgZW5hYmxlc1hEUjogdGhpcy5lbmFibGVzWERSLFxuICAgIHRpbWVzdGFtcFJlcXVlc3RzOiB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzLFxuICAgIHRpbWVzdGFtcFBhcmFtOiB0aGlzLnRpbWVzdGFtcFBhcmFtLFxuICAgIHBvbGljeVBvcnQ6IHRoaXMucG9saWN5UG9ydCxcbiAgICBzb2NrZXQ6IHRoaXMsXG4gICAgcGZ4OiB0aGlzLnBmeCxcbiAgICBrZXk6IHRoaXMua2V5LFxuICAgIHBhc3NwaHJhc2U6IHRoaXMucGFzc3BocmFzZSxcbiAgICBjZXJ0OiB0aGlzLmNlcnQsXG4gICAgY2E6IHRoaXMuY2EsXG4gICAgY2lwaGVyczogdGhpcy5jaXBoZXJzLFxuICAgIHJlamVjdFVuYXV0aG9yaXplZDogdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQsXG4gICAgcGVyTWVzc2FnZURlZmxhdGU6IHRoaXMucGVyTWVzc2FnZURlZmxhdGUsXG4gICAgZXh0cmFIZWFkZXJzOiB0aGlzLmV4dHJhSGVhZGVyc1xuICB9KTtcblxuICByZXR1cm4gdHJhbnNwb3J0O1xufTtcblxuZnVuY3Rpb24gY2xvbmUgKG9iaikge1xuICB2YXIgbyA9IHt9O1xuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgIG9baV0gPSBvYmpbaV07XG4gICAgfVxuICB9XG4gIHJldHVybiBvO1xufVxuXG4vKipcbiAqIEluaXRpYWxpemVzIHRyYW5zcG9ydCB0byB1c2UgYW5kIHN0YXJ0cyBwcm9iZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuU29ja2V0LnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdHJhbnNwb3J0O1xuICBpZiAodGhpcy5yZW1lbWJlclVwZ3JhZGUgJiYgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyAmJiB0aGlzLnRyYW5zcG9ydHMuaW5kZXhPZignd2Vic29ja2V0JykgIT0gLTEpIHtcbiAgICB0cmFuc3BvcnQgPSAnd2Vic29ja2V0JztcbiAgfSBlbHNlIGlmICgwID09PSB0aGlzLnRyYW5zcG9ydHMubGVuZ3RoKSB7XG4gICAgLy8gRW1pdCBlcnJvciBvbiBuZXh0IHRpY2sgc28gaXQgY2FuIGJlIGxpc3RlbmVkIHRvXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBzZWxmLmVtaXQoJ2Vycm9yJywgJ05vIHRyYW5zcG9ydHMgYXZhaWxhYmxlJyk7XG4gICAgfSwgMCk7XG4gICAgcmV0dXJuO1xuICB9IGVsc2Uge1xuICAgIHRyYW5zcG9ydCA9IHRoaXMudHJhbnNwb3J0c1swXTtcbiAgfVxuICB0aGlzLnJlYWR5U3RhdGUgPSAnb3BlbmluZyc7XG5cbiAgLy8gUmV0cnkgd2l0aCB0aGUgbmV4dCB0cmFuc3BvcnQgaWYgdGhlIHRyYW5zcG9ydCBpcyBkaXNhYmxlZCAoanNvbnA6IGZhbHNlKVxuICB0cnkge1xuICAgIHRyYW5zcG9ydCA9IHRoaXMuY3JlYXRlVHJhbnNwb3J0KHRyYW5zcG9ydCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aGlzLnRyYW5zcG9ydHMuc2hpZnQoKTtcbiAgICB0aGlzLm9wZW4oKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB0cmFuc3BvcnQub3BlbigpO1xuICB0aGlzLnNldFRyYW5zcG9ydCh0cmFuc3BvcnQpO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBjdXJyZW50IHRyYW5zcG9ydC4gRGlzYWJsZXMgdGhlIGV4aXN0aW5nIG9uZSAoaWYgYW55KS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uKHRyYW5zcG9ydCl7XG4gIGRlYnVnKCdzZXR0aW5nIHRyYW5zcG9ydCAlcycsIHRyYW5zcG9ydC5uYW1lKTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmICh0aGlzLnRyYW5zcG9ydCkge1xuICAgIGRlYnVnKCdjbGVhcmluZyBleGlzdGluZyB0cmFuc3BvcnQgJXMnLCB0aGlzLnRyYW5zcG9ydC5uYW1lKTtcbiAgICB0aGlzLnRyYW5zcG9ydC5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgfVxuXG4gIC8vIHNldCB1cCB0cmFuc3BvcnRcbiAgdGhpcy50cmFuc3BvcnQgPSB0cmFuc3BvcnQ7XG5cbiAgLy8gc2V0IHVwIHRyYW5zcG9ydCBsaXN0ZW5lcnNcbiAgdHJhbnNwb3J0XG4gIC5vbignZHJhaW4nLCBmdW5jdGlvbigpe1xuICAgIHNlbGYub25EcmFpbigpO1xuICB9KVxuICAub24oJ3BhY2tldCcsIGZ1bmN0aW9uKHBhY2tldCl7XG4gICAgc2VsZi5vblBhY2tldChwYWNrZXQpO1xuICB9KVxuICAub24oJ2Vycm9yJywgZnVuY3Rpb24oZSl7XG4gICAgc2VsZi5vbkVycm9yKGUpO1xuICB9KVxuICAub24oJ2Nsb3NlJywgZnVuY3Rpb24oKXtcbiAgICBzZWxmLm9uQ2xvc2UoJ3RyYW5zcG9ydCBjbG9zZScpO1xuICB9KTtcbn07XG5cbi8qKlxuICogUHJvYmVzIGEgdHJhbnNwb3J0LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0cmFuc3BvcnQgbmFtZVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5wcm9iZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlYnVnKCdwcm9iaW5nIHRyYW5zcG9ydCBcIiVzXCInLCBuYW1lKTtcbiAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuY3JlYXRlVHJhbnNwb3J0KG5hbWUsIHsgcHJvYmU6IDEgfSlcbiAgICAsIGZhaWxlZCA9IGZhbHNlXG4gICAgLCBzZWxmID0gdGhpcztcblxuICBTb2NrZXQucHJpb3JXZWJzb2NrZXRTdWNjZXNzID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gb25UcmFuc3BvcnRPcGVuKCl7XG4gICAgaWYgKHNlbGYub25seUJpbmFyeVVwZ3JhZGVzKSB7XG4gICAgICB2YXIgdXBncmFkZUxvc2VzQmluYXJ5ID0gIXRoaXMuc3VwcG9ydHNCaW5hcnkgJiYgc2VsZi50cmFuc3BvcnQuc3VwcG9ydHNCaW5hcnk7XG4gICAgICBmYWlsZWQgPSBmYWlsZWQgfHwgdXBncmFkZUxvc2VzQmluYXJ5O1xuICAgIH1cbiAgICBpZiAoZmFpbGVkKSByZXR1cm47XG5cbiAgICBkZWJ1ZygncHJvYmUgdHJhbnNwb3J0IFwiJXNcIiBvcGVuZWQnLCBuYW1lKTtcbiAgICB0cmFuc3BvcnQuc2VuZChbeyB0eXBlOiAncGluZycsIGRhdGE6ICdwcm9iZScgfV0pO1xuICAgIHRyYW5zcG9ydC5vbmNlKCdwYWNrZXQnLCBmdW5jdGlvbiAobXNnKSB7XG4gICAgICBpZiAoZmFpbGVkKSByZXR1cm47XG4gICAgICBpZiAoJ3BvbmcnID09IG1zZy50eXBlICYmICdwcm9iZScgPT0gbXNnLmRhdGEpIHtcbiAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgcG9uZycsIG5hbWUpO1xuICAgICAgICBzZWxmLnVwZ3JhZGluZyA9IHRydWU7XG4gICAgICAgIHNlbGYuZW1pdCgndXBncmFkaW5nJywgdHJhbnNwb3J0KTtcbiAgICAgICAgaWYgKCF0cmFuc3BvcnQpIHJldHVybjtcbiAgICAgICAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9ICd3ZWJzb2NrZXQnID09IHRyYW5zcG9ydC5uYW1lO1xuXG4gICAgICAgIGRlYnVnKCdwYXVzaW5nIGN1cnJlbnQgdHJhbnNwb3J0IFwiJXNcIicsIHNlbGYudHJhbnNwb3J0Lm5hbWUpO1xuICAgICAgICBzZWxmLnRyYW5zcG9ydC5wYXVzZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKGZhaWxlZCkgcmV0dXJuO1xuICAgICAgICAgIGlmICgnY2xvc2VkJyA9PSBzZWxmLnJlYWR5U3RhdGUpIHJldHVybjtcbiAgICAgICAgICBkZWJ1ZygnY2hhbmdpbmcgdHJhbnNwb3J0IGFuZCBzZW5kaW5nIHVwZ3JhZGUgcGFja2V0Jyk7XG5cbiAgICAgICAgICBjbGVhbnVwKCk7XG5cbiAgICAgICAgICBzZWxmLnNldFRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuICAgICAgICAgIHRyYW5zcG9ydC5zZW5kKFt7IHR5cGU6ICd1cGdyYWRlJyB9XSk7XG4gICAgICAgICAgc2VsZi5lbWl0KCd1cGdyYWRlJywgdHJhbnNwb3J0KTtcbiAgICAgICAgICB0cmFuc3BvcnQgPSBudWxsO1xuICAgICAgICAgIHNlbGYudXBncmFkaW5nID0gZmFsc2U7XG4gICAgICAgICAgc2VsZi5mbHVzaCgpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlYnVnKCdwcm9iZSB0cmFuc3BvcnQgXCIlc1wiIGZhaWxlZCcsIG5hbWUpO1xuICAgICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdwcm9iZSBlcnJvcicpO1xuICAgICAgICBlcnIudHJhbnNwb3J0ID0gdHJhbnNwb3J0Lm5hbWU7XG4gICAgICAgIHNlbGYuZW1pdCgndXBncmFkZUVycm9yJywgZXJyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZyZWV6ZVRyYW5zcG9ydCgpIHtcbiAgICBpZiAoZmFpbGVkKSByZXR1cm47XG5cbiAgICAvLyBBbnkgY2FsbGJhY2sgY2FsbGVkIGJ5IHRyYW5zcG9ydCBzaG91bGQgYmUgaWdub3JlZCBzaW5jZSBub3dcbiAgICBmYWlsZWQgPSB0cnVlO1xuXG4gICAgY2xlYW51cCgpO1xuXG4gICAgdHJhbnNwb3J0LmNsb3NlKCk7XG4gICAgdHJhbnNwb3J0ID0gbnVsbDtcbiAgfVxuXG4gIC8vSGFuZGxlIGFueSBlcnJvciB0aGF0IGhhcHBlbnMgd2hpbGUgcHJvYmluZ1xuICBmdW5jdGlvbiBvbmVycm9yKGVycikge1xuICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcigncHJvYmUgZXJyb3I6ICcgKyBlcnIpO1xuICAgIGVycm9yLnRyYW5zcG9ydCA9IHRyYW5zcG9ydC5uYW1lO1xuXG4gICAgZnJlZXplVHJhbnNwb3J0KCk7XG5cbiAgICBkZWJ1ZygncHJvYmUgdHJhbnNwb3J0IFwiJXNcIiBmYWlsZWQgYmVjYXVzZSBvZiBlcnJvcjogJXMnLCBuYW1lLCBlcnIpO1xuXG4gICAgc2VsZi5lbWl0KCd1cGdyYWRlRXJyb3InLCBlcnJvcik7XG4gIH1cblxuICBmdW5jdGlvbiBvblRyYW5zcG9ydENsb3NlKCl7XG4gICAgb25lcnJvcihcInRyYW5zcG9ydCBjbG9zZWRcIik7XG4gIH1cblxuICAvL1doZW4gdGhlIHNvY2tldCBpcyBjbG9zZWQgd2hpbGUgd2UncmUgcHJvYmluZ1xuICBmdW5jdGlvbiBvbmNsb3NlKCl7XG4gICAgb25lcnJvcihcInNvY2tldCBjbG9zZWRcIik7XG4gIH1cblxuICAvL1doZW4gdGhlIHNvY2tldCBpcyB1cGdyYWRlZCB3aGlsZSB3ZSdyZSBwcm9iaW5nXG4gIGZ1bmN0aW9uIG9udXBncmFkZSh0byl7XG4gICAgaWYgKHRyYW5zcG9ydCAmJiB0by5uYW1lICE9IHRyYW5zcG9ydC5uYW1lKSB7XG4gICAgICBkZWJ1ZygnXCIlc1wiIHdvcmtzIC0gYWJvcnRpbmcgXCIlc1wiJywgdG8ubmFtZSwgdHJhbnNwb3J0Lm5hbWUpO1xuICAgICAgZnJlZXplVHJhbnNwb3J0KCk7XG4gICAgfVxuICB9XG5cbiAgLy9SZW1vdmUgYWxsIGxpc3RlbmVycyBvbiB0aGUgdHJhbnNwb3J0IGFuZCBvbiBzZWxmXG4gIGZ1bmN0aW9uIGNsZWFudXAoKXtcbiAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ29wZW4nLCBvblRyYW5zcG9ydE9wZW4pO1xuICAgIHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25UcmFuc3BvcnRDbG9zZSk7XG4gICAgc2VsZi5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICBzZWxmLnJlbW92ZUxpc3RlbmVyKCd1cGdyYWRpbmcnLCBvbnVwZ3JhZGUpO1xuICB9XG5cbiAgdHJhbnNwb3J0Lm9uY2UoJ29wZW4nLCBvblRyYW5zcG9ydE9wZW4pO1xuICB0cmFuc3BvcnQub25jZSgnZXJyb3InLCBvbmVycm9yKTtcbiAgdHJhbnNwb3J0Lm9uY2UoJ2Nsb3NlJywgb25UcmFuc3BvcnRDbG9zZSk7XG5cbiAgdGhpcy5vbmNlKCdjbG9zZScsIG9uY2xvc2UpO1xuICB0aGlzLm9uY2UoJ3VwZ3JhZGluZycsIG9udXBncmFkZSk7XG5cbiAgdHJhbnNwb3J0Lm9wZW4oKTtcblxufTtcblxuLyoqXG4gKiBDYWxsZWQgd2hlbiBjb25uZWN0aW9uIGlzIGRlZW1lZCBvcGVuLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbk9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIGRlYnVnKCdzb2NrZXQgb3BlbicpO1xuICB0aGlzLnJlYWR5U3RhdGUgPSAnb3Blbic7XG4gIFNvY2tldC5wcmlvcldlYnNvY2tldFN1Y2Nlc3MgPSAnd2Vic29ja2V0JyA9PSB0aGlzLnRyYW5zcG9ydC5uYW1lO1xuICB0aGlzLmVtaXQoJ29wZW4nKTtcbiAgdGhpcy5mbHVzaCgpO1xuXG4gIC8vIHdlIGNoZWNrIGZvciBgcmVhZHlTdGF0ZWAgaW4gY2FzZSBhbiBgb3BlbmBcbiAgLy8gbGlzdGVuZXIgYWxyZWFkeSBjbG9zZWQgdGhlIHNvY2tldFxuICBpZiAoJ29wZW4nID09IHRoaXMucmVhZHlTdGF0ZSAmJiB0aGlzLnVwZ3JhZGUgJiYgdGhpcy50cmFuc3BvcnQucGF1c2UpIHtcbiAgICBkZWJ1Zygnc3RhcnRpbmcgdXBncmFkZSBwcm9iZXMnKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMudXBncmFkZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICB0aGlzLnByb2JlKHRoaXMudXBncmFkZXNbaV0pO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBIYW5kbGVzIGEgcGFja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25QYWNrZXQgPSBmdW5jdGlvbiAocGFja2V0KSB7XG4gIGlmICgnb3BlbmluZycgPT0gdGhpcy5yZWFkeVN0YXRlIHx8ICdvcGVuJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICBkZWJ1Zygnc29ja2V0IHJlY2VpdmU6IHR5cGUgXCIlc1wiLCBkYXRhIFwiJXNcIicsIHBhY2tldC50eXBlLCBwYWNrZXQuZGF0YSk7XG5cbiAgICB0aGlzLmVtaXQoJ3BhY2tldCcsIHBhY2tldCk7XG5cbiAgICAvLyBTb2NrZXQgaXMgbGl2ZSAtIGFueSBwYWNrZXQgY291bnRzXG4gICAgdGhpcy5lbWl0KCdoZWFydGJlYXQnKTtcblxuICAgIHN3aXRjaCAocGFja2V0LnR5cGUpIHtcbiAgICAgIGNhc2UgJ29wZW4nOlxuICAgICAgICB0aGlzLm9uSGFuZHNoYWtlKHBhcnNlanNvbihwYWNrZXQuZGF0YSkpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAncG9uZyc6XG4gICAgICAgIHRoaXMuc2V0UGluZygpO1xuICAgICAgICB0aGlzLmVtaXQoJ3BvbmcnKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignc2VydmVyIGVycm9yJyk7XG4gICAgICAgIGVyci5jb2RlID0gcGFja2V0LmRhdGE7XG4gICAgICAgIHRoaXMub25FcnJvcihlcnIpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnbWVzc2FnZSc6XG4gICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIHBhY2tldC5kYXRhKTtcbiAgICAgICAgdGhpcy5lbWl0KCdtZXNzYWdlJywgcGFja2V0LmRhdGEpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZGVidWcoJ3BhY2tldCByZWNlaXZlZCB3aXRoIHNvY2tldCByZWFkeVN0YXRlIFwiJXNcIicsIHRoaXMucmVhZHlTdGF0ZSk7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gaGFuZHNoYWtlIGNvbXBsZXRpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGhhbmRzaGFrZSBvYmpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25IYW5kc2hha2UgPSBmdW5jdGlvbiAoZGF0YSkge1xuICB0aGlzLmVtaXQoJ2hhbmRzaGFrZScsIGRhdGEpO1xuICB0aGlzLmlkID0gZGF0YS5zaWQ7XG4gIHRoaXMudHJhbnNwb3J0LnF1ZXJ5LnNpZCA9IGRhdGEuc2lkO1xuICB0aGlzLnVwZ3JhZGVzID0gdGhpcy5maWx0ZXJVcGdyYWRlcyhkYXRhLnVwZ3JhZGVzKTtcbiAgdGhpcy5waW5nSW50ZXJ2YWwgPSBkYXRhLnBpbmdJbnRlcnZhbDtcbiAgdGhpcy5waW5nVGltZW91dCA9IGRhdGEucGluZ1RpbWVvdXQ7XG4gIHRoaXMub25PcGVuKCk7XG4gIC8vIEluIGNhc2Ugb3BlbiBoYW5kbGVyIGNsb3NlcyBzb2NrZXRcbiAgaWYgICgnY2xvc2VkJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHJldHVybjtcbiAgdGhpcy5zZXRQaW5nKCk7XG5cbiAgLy8gUHJvbG9uZyBsaXZlbmVzcyBvZiBzb2NrZXQgb24gaGVhcnRiZWF0XG4gIHRoaXMucmVtb3ZlTGlzdGVuZXIoJ2hlYXJ0YmVhdCcsIHRoaXMub25IZWFydGJlYXQpO1xuICB0aGlzLm9uKCdoZWFydGJlYXQnLCB0aGlzLm9uSGVhcnRiZWF0KTtcbn07XG5cbi8qKlxuICogUmVzZXRzIHBpbmcgdGltZW91dC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uSGVhcnRiZWF0ID0gZnVuY3Rpb24gKHRpbWVvdXQpIHtcbiAgY2xlYXJUaW1lb3V0KHRoaXMucGluZ1RpbWVvdXRUaW1lcik7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgc2VsZi5waW5nVGltZW91dFRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCdjbG9zZWQnID09IHNlbGYucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgIHNlbGYub25DbG9zZSgncGluZyB0aW1lb3V0Jyk7XG4gIH0sIHRpbWVvdXQgfHwgKHNlbGYucGluZ0ludGVydmFsICsgc2VsZi5waW5nVGltZW91dCkpO1xufTtcblxuLyoqXG4gKiBQaW5ncyBzZXJ2ZXIgZXZlcnkgYHRoaXMucGluZ0ludGVydmFsYCBhbmQgZXhwZWN0cyByZXNwb25zZVxuICogd2l0aGluIGB0aGlzLnBpbmdUaW1lb3V0YCBvciBjbG9zZXMgY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnNldFBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgY2xlYXJUaW1lb3V0KHNlbGYucGluZ0ludGVydmFsVGltZXIpO1xuICBzZWxmLnBpbmdJbnRlcnZhbFRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgZGVidWcoJ3dyaXRpbmcgcGluZyBwYWNrZXQgLSBleHBlY3RpbmcgcG9uZyB3aXRoaW4gJXNtcycsIHNlbGYucGluZ1RpbWVvdXQpO1xuICAgIHNlbGYucGluZygpO1xuICAgIHNlbGYub25IZWFydGJlYXQoc2VsZi5waW5nVGltZW91dCk7XG4gIH0sIHNlbGYucGluZ0ludGVydmFsKTtcbn07XG5cbi8qKlxuKiBTZW5kcyBhIHBpbmcgcGFja2V0LlxuKlxuKiBAYXBpIHByaXZhdGVcbiovXG5cblNvY2tldC5wcm90b3R5cGUucGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLnNlbmRQYWNrZXQoJ3BpbmcnLCBmdW5jdGlvbigpe1xuICAgIHNlbGYuZW1pdCgncGluZycpO1xuICB9KTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIG9uIGBkcmFpbmAgZXZlbnRcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uRHJhaW4gPSBmdW5jdGlvbigpIHtcbiAgdGhpcy53cml0ZUJ1ZmZlci5zcGxpY2UoMCwgdGhpcy5wcmV2QnVmZmVyTGVuKTtcblxuICAvLyBzZXR0aW5nIHByZXZCdWZmZXJMZW4gPSAwIGlzIHZlcnkgaW1wb3J0YW50XG4gIC8vIGZvciBleGFtcGxlLCB3aGVuIHVwZ3JhZGluZywgdXBncmFkZSBwYWNrZXQgaXMgc2VudCBvdmVyLFxuICAvLyBhbmQgYSBub256ZXJvIHByZXZCdWZmZXJMZW4gY291bGQgY2F1c2UgcHJvYmxlbXMgb24gYGRyYWluYFxuICB0aGlzLnByZXZCdWZmZXJMZW4gPSAwO1xuXG4gIGlmICgwID09PSB0aGlzLndyaXRlQnVmZmVyLmxlbmd0aCkge1xuICAgIHRoaXMuZW1pdCgnZHJhaW4nKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZsdXNoKCk7XG4gIH1cbn07XG5cbi8qKlxuICogRmx1c2ggd3JpdGUgYnVmZmVycy5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICBpZiAoJ2Nsb3NlZCcgIT0gdGhpcy5yZWFkeVN0YXRlICYmIHRoaXMudHJhbnNwb3J0LndyaXRhYmxlICYmXG4gICAgIXRoaXMudXBncmFkaW5nICYmIHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgZGVidWcoJ2ZsdXNoaW5nICVkIHBhY2tldHMgaW4gc29ja2V0JywgdGhpcy53cml0ZUJ1ZmZlci5sZW5ndGgpO1xuICAgIHRoaXMudHJhbnNwb3J0LnNlbmQodGhpcy53cml0ZUJ1ZmZlcik7XG4gICAgLy8ga2VlcCB0cmFjayBvZiBjdXJyZW50IGxlbmd0aCBvZiB3cml0ZUJ1ZmZlclxuICAgIC8vIHNwbGljZSB3cml0ZUJ1ZmZlciBhbmQgY2FsbGJhY2tCdWZmZXIgb24gYGRyYWluYFxuICAgIHRoaXMucHJldkJ1ZmZlckxlbiA9IHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoO1xuICAgIHRoaXMuZW1pdCgnZmx1c2gnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZW5kcyBhIG1lc3NhZ2UuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQHJldHVybiB7U29ja2V0fSBmb3IgY2hhaW5pbmcuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUud3JpdGUgPVxuU29ja2V0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKG1zZywgb3B0aW9ucywgZm4pIHtcbiAgdGhpcy5zZW5kUGFja2V0KCdtZXNzYWdlJywgbXNnLCBvcHRpb25zLCBmbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZW5kcyBhIHBhY2tldC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFja2V0IHR5cGUuXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgZnVuY3Rpb24uXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnNlbmRQYWNrZXQgPSBmdW5jdGlvbiAodHlwZSwgZGF0YSwgb3B0aW9ucywgZm4pIHtcbiAgaWYoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkge1xuICAgIGZuID0gZGF0YTtcbiAgICBkYXRhID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIG9wdGlvbnMpIHtcbiAgICBmbiA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9IG51bGw7XG4gIH1cblxuICBpZiAoJ2Nsb3NpbmcnID09IHRoaXMucmVhZHlTdGF0ZSB8fCAnY2xvc2VkJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgb3B0aW9ucy5jb21wcmVzcyA9IGZhbHNlICE9PSBvcHRpb25zLmNvbXByZXNzO1xuXG4gIHZhciBwYWNrZXQgPSB7XG4gICAgdHlwZTogdHlwZSxcbiAgICBkYXRhOiBkYXRhLFxuICAgIG9wdGlvbnM6IG9wdGlvbnNcbiAgfTtcbiAgdGhpcy5lbWl0KCdwYWNrZXRDcmVhdGUnLCBwYWNrZXQpO1xuICB0aGlzLndyaXRlQnVmZmVyLnB1c2gocGFja2V0KTtcbiAgaWYgKGZuKSB0aGlzLm9uY2UoJ2ZsdXNoJywgZm4pO1xuICB0aGlzLmZsdXNoKCk7XG59O1xuXG4vKipcbiAqIENsb3NlcyB0aGUgY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICBpZiAoJ29wZW5pbmcnID09IHRoaXMucmVhZHlTdGF0ZSB8fCAnb3BlbicgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NpbmcnO1xuXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgICB0aGlzLm9uY2UoJ2RyYWluJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLnVwZ3JhZGluZykge1xuICAgICAgICAgIHdhaXRGb3JVcGdyYWRlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2xvc2UoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnVwZ3JhZGluZykge1xuICAgICAgd2FpdEZvclVwZ3JhZGUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2xvc2UoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICBzZWxmLm9uQ2xvc2UoJ2ZvcmNlZCBjbG9zZScpO1xuICAgIGRlYnVnKCdzb2NrZXQgY2xvc2luZyAtIHRlbGxpbmcgdHJhbnNwb3J0IHRvIGNsb3NlJyk7XG4gICAgc2VsZi50cmFuc3BvcnQuY2xvc2UoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsZWFudXBBbmRDbG9zZSgpIHtcbiAgICBzZWxmLnJlbW92ZUxpc3RlbmVyKCd1cGdyYWRlJywgY2xlYW51cEFuZENsb3NlKTtcbiAgICBzZWxmLnJlbW92ZUxpc3RlbmVyKCd1cGdyYWRlRXJyb3InLCBjbGVhbnVwQW5kQ2xvc2UpO1xuICAgIGNsb3NlKCk7XG4gIH1cblxuICBmdW5jdGlvbiB3YWl0Rm9yVXBncmFkZSgpIHtcbiAgICAvLyB3YWl0IGZvciB1cGdyYWRlIHRvIGZpbmlzaCBzaW5jZSB3ZSBjYW4ndCBzZW5kIHBhY2tldHMgd2hpbGUgcGF1c2luZyBhIHRyYW5zcG9ydFxuICAgIHNlbGYub25jZSgndXBncmFkZScsIGNsZWFudXBBbmRDbG9zZSk7XG4gICAgc2VsZi5vbmNlKCd1cGdyYWRlRXJyb3InLCBjbGVhbnVwQW5kQ2xvc2UpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHRyYW5zcG9ydCBlcnJvclxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25FcnJvciA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgZGVidWcoJ3NvY2tldCBlcnJvciAlaicsIGVycik7XG4gIFNvY2tldC5wcmlvcldlYnNvY2tldFN1Y2Nlc3MgPSBmYWxzZTtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gIHRoaXMub25DbG9zZSgndHJhbnNwb3J0IGVycm9yJywgZXJyKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IGNsb3NlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25DbG9zZSA9IGZ1bmN0aW9uIChyZWFzb24sIGRlc2MpIHtcbiAgaWYgKCdvcGVuaW5nJyA9PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09IHRoaXMucmVhZHlTdGF0ZSB8fCAnY2xvc2luZycgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgZGVidWcoJ3NvY2tldCBjbG9zZSB3aXRoIHJlYXNvbjogXCIlc1wiJywgcmVhc29uKTtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAvLyBjbGVhciB0aW1lcnNcbiAgICBjbGVhclRpbWVvdXQodGhpcy5waW5nSW50ZXJ2YWxUaW1lcik7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMucGluZ1RpbWVvdXRUaW1lcik7XG5cbiAgICAvLyBzdG9wIGV2ZW50IGZyb20gZmlyaW5nIGFnYWluIGZvciB0cmFuc3BvcnRcbiAgICB0aGlzLnRyYW5zcG9ydC5yZW1vdmVBbGxMaXN0ZW5lcnMoJ2Nsb3NlJyk7XG5cbiAgICAvLyBlbnN1cmUgdHJhbnNwb3J0IHdvbid0IHN0YXkgb3BlblxuICAgIHRoaXMudHJhbnNwb3J0LmNsb3NlKCk7XG5cbiAgICAvLyBpZ25vcmUgZnVydGhlciB0cmFuc3BvcnQgY29tbXVuaWNhdGlvblxuICAgIHRoaXMudHJhbnNwb3J0LnJlbW92ZUFsbExpc3RlbmVycygpO1xuXG4gICAgLy8gc2V0IHJlYWR5IHN0YXRlXG4gICAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG5cbiAgICAvLyBjbGVhciBzZXNzaW9uIGlkXG4gICAgdGhpcy5pZCA9IG51bGw7XG5cbiAgICAvLyBlbWl0IGNsb3NlIGV2ZW50XG4gICAgdGhpcy5lbWl0KCdjbG9zZScsIHJlYXNvbiwgZGVzYyk7XG5cbiAgICAvLyBjbGVhbiBidWZmZXJzIGFmdGVyLCBzbyB1c2VycyBjYW4gc3RpbGxcbiAgICAvLyBncmFiIHRoZSBidWZmZXJzIG9uIGBjbG9zZWAgZXZlbnRcbiAgICBzZWxmLndyaXRlQnVmZmVyID0gW107XG4gICAgc2VsZi5wcmV2QnVmZmVyTGVuID0gMDtcbiAgfVxufTtcblxuLyoqXG4gKiBGaWx0ZXJzIHVwZ3JhZGVzLCByZXR1cm5pbmcgb25seSB0aG9zZSBtYXRjaGluZyBjbGllbnQgdHJhbnNwb3J0cy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBzZXJ2ZXIgdXBncmFkZXNcbiAqIEBhcGkgcHJpdmF0ZVxuICpcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmZpbHRlclVwZ3JhZGVzID0gZnVuY3Rpb24gKHVwZ3JhZGVzKSB7XG4gIHZhciBmaWx0ZXJlZFVwZ3JhZGVzID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBqID0gdXBncmFkZXMubGVuZ3RoOyBpPGo7IGkrKykge1xuICAgIGlmICh+aW5kZXgodGhpcy50cmFuc3BvcnRzLCB1cGdyYWRlc1tpXSkpIGZpbHRlcmVkVXBncmFkZXMucHVzaCh1cGdyYWRlc1tpXSk7XG4gIH1cbiAgcmV0dXJuIGZpbHRlcmVkVXBncmFkZXM7XG59O1xuIiwiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBwYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBUcmFuc3BvcnQ7XG5cbi8qKlxuICogVHJhbnNwb3J0IGFic3RyYWN0IGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gVHJhbnNwb3J0IChvcHRzKSB7XG4gIHRoaXMucGF0aCA9IG9wdHMucGF0aDtcbiAgdGhpcy5ob3N0bmFtZSA9IG9wdHMuaG9zdG5hbWU7XG4gIHRoaXMucG9ydCA9IG9wdHMucG9ydDtcbiAgdGhpcy5zZWN1cmUgPSBvcHRzLnNlY3VyZTtcbiAgdGhpcy5xdWVyeSA9IG9wdHMucXVlcnk7XG4gIHRoaXMudGltZXN0YW1wUGFyYW0gPSBvcHRzLnRpbWVzdGFtcFBhcmFtO1xuICB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzID0gb3B0cy50aW1lc3RhbXBSZXF1ZXN0cztcbiAgdGhpcy5yZWFkeVN0YXRlID0gJyc7XG4gIHRoaXMuYWdlbnQgPSBvcHRzLmFnZW50IHx8IGZhbHNlO1xuICB0aGlzLnNvY2tldCA9IG9wdHMuc29ja2V0O1xuICB0aGlzLmVuYWJsZXNYRFIgPSBvcHRzLmVuYWJsZXNYRFI7XG5cbiAgLy8gU1NMIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIHRoaXMucGZ4ID0gb3B0cy5wZng7XG4gIHRoaXMua2V5ID0gb3B0cy5rZXk7XG4gIHRoaXMucGFzc3BocmFzZSA9IG9wdHMucGFzc3BocmFzZTtcbiAgdGhpcy5jZXJ0ID0gb3B0cy5jZXJ0O1xuICB0aGlzLmNhID0gb3B0cy5jYTtcbiAgdGhpcy5jaXBoZXJzID0gb3B0cy5jaXBoZXJzO1xuICB0aGlzLnJlamVjdFVuYXV0aG9yaXplZCA9IG9wdHMucmVqZWN0VW5hdXRob3JpemVkO1xuXG4gIC8vIG90aGVyIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIHRoaXMuZXh0cmFIZWFkZXJzID0gb3B0cy5leHRyYUhlYWRlcnM7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFRyYW5zcG9ydC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIEVtaXRzIGFuIGVycm9yLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge1RyYW5zcG9ydH0gZm9yIGNoYWluaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25FcnJvciA9IGZ1bmN0aW9uIChtc2csIGRlc2MpIHtcbiAgdmFyIGVyciA9IG5ldyBFcnJvcihtc2cpO1xuICBlcnIudHlwZSA9ICdUcmFuc3BvcnRFcnJvcic7XG4gIGVyci5kZXNjcmlwdGlvbiA9IGRlc2M7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3BlbnMgdGhlIHRyYW5zcG9ydC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCdjbG9zZWQnID09IHRoaXMucmVhZHlTdGF0ZSB8fCAnJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSAnb3BlbmluZyc7XG4gICAgdGhpcy5kb09wZW4oKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBDbG9zZXMgdGhlIHRyYW5zcG9ydC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICBpZiAoJ29wZW5pbmcnID09IHRoaXMucmVhZHlTdGF0ZSB8fCAnb3BlbicgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgdGhpcy5kb0Nsb3NlKCk7XG4gICAgdGhpcy5vbkNsb3NlKCk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2VuZHMgbXVsdGlwbGUgcGFja2V0cy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBwYWNrZXRzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbihwYWNrZXRzKXtcbiAgaWYgKCdvcGVuJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICB0aGlzLndyaXRlKHBhY2tldHMpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignVHJhbnNwb3J0IG5vdCBvcGVuJyk7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gb3BlblxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25PcGVuID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLnJlYWR5U3RhdGUgPSAnb3Blbic7XG4gIHRoaXMud3JpdGFibGUgPSB0cnVlO1xuICB0aGlzLmVtaXQoJ29wZW4nKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHdpdGggZGF0YS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuVHJhbnNwb3J0LnByb3RvdHlwZS5vbkRhdGEgPSBmdW5jdGlvbihkYXRhKXtcbiAgdmFyIHBhY2tldCA9IHBhcnNlci5kZWNvZGVQYWNrZXQoZGF0YSwgdGhpcy5zb2NrZXQuYmluYXJ5VHlwZSk7XG4gIHRoaXMub25QYWNrZXQocGFja2V0KTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHdpdGggYSBkZWNvZGVkIHBhY2tldC5cbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uUGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICB0aGlzLmVtaXQoJ3BhY2tldCcsIHBhY2tldCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGNsb3NlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIHRoaXMuZW1pdCgnY2xvc2UnKTtcbn07XG4iLCIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXNcbiAqL1xuXG52YXIgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdC1zc2wnKTtcbnZhciBYSFIgPSByZXF1aXJlKCcuL3BvbGxpbmcteGhyJyk7XG52YXIgSlNPTlAgPSByZXF1aXJlKCcuL3BvbGxpbmctanNvbnAnKTtcbnZhciB3ZWJzb2NrZXQgPSByZXF1aXJlKCcuL3dlYnNvY2tldCcpO1xuXG4vKipcbiAqIEV4cG9ydCB0cmFuc3BvcnRzLlxuICovXG5cbmV4cG9ydHMucG9sbGluZyA9IHBvbGxpbmc7XG5leHBvcnRzLndlYnNvY2tldCA9IHdlYnNvY2tldDtcblxuLyoqXG4gKiBQb2xsaW5nIHRyYW5zcG9ydCBwb2x5bW9ycGhpYyBjb25zdHJ1Y3Rvci5cbiAqIERlY2lkZXMgb24geGhyIHZzIGpzb25wIGJhc2VkIG9uIGZlYXR1cmUgZGV0ZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBvbGxpbmcob3B0cyl7XG4gIHZhciB4aHI7XG4gIHZhciB4ZCA9IGZhbHNlO1xuICB2YXIgeHMgPSBmYWxzZTtcbiAgdmFyIGpzb25wID0gZmFsc2UgIT09IG9wdHMuanNvbnA7XG5cbiAgaWYgKGdsb2JhbC5sb2NhdGlvbikge1xuICAgIHZhciBpc1NTTCA9ICdodHRwczonID09IGxvY2F0aW9uLnByb3RvY29sO1xuICAgIHZhciBwb3J0ID0gbG9jYXRpb24ucG9ydDtcblxuICAgIC8vIHNvbWUgdXNlciBhZ2VudHMgaGF2ZSBlbXB0eSBgbG9jYXRpb24ucG9ydGBcbiAgICBpZiAoIXBvcnQpIHtcbiAgICAgIHBvcnQgPSBpc1NTTCA/IDQ0MyA6IDgwO1xuICAgIH1cblxuICAgIHhkID0gb3B0cy5ob3N0bmFtZSAhPSBsb2NhdGlvbi5ob3N0bmFtZSB8fCBwb3J0ICE9IG9wdHMucG9ydDtcbiAgICB4cyA9IG9wdHMuc2VjdXJlICE9IGlzU1NMO1xuICB9XG5cbiAgb3B0cy54ZG9tYWluID0geGQ7XG4gIG9wdHMueHNjaGVtZSA9IHhzO1xuICB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3Qob3B0cyk7XG5cbiAgaWYgKCdvcGVuJyBpbiB4aHIgJiYgIW9wdHMuZm9yY2VKU09OUCkge1xuICAgIHJldHVybiBuZXcgWEhSKG9wdHMpO1xuICB9IGVsc2Uge1xuICAgIGlmICghanNvbnApIHRocm93IG5ldyBFcnJvcignSlNPTlAgZGlzYWJsZWQnKTtcbiAgICByZXR1cm4gbmV3IEpTT05QKG9wdHMpO1xuICB9XG59XG4iLCJcbi8qKlxuICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAqL1xuXG52YXIgUG9sbGluZyA9IHJlcXVpcmUoJy4vcG9sbGluZycpO1xudmFyIGluaGVyaXQgPSByZXF1aXJlKCdjb21wb25lbnQtaW5oZXJpdCcpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gSlNPTlBQb2xsaW5nO1xuXG4vKipcbiAqIENhY2hlZCByZWd1bGFyIGV4cHJlc3Npb25zLlxuICovXG5cbnZhciByTmV3bGluZSA9IC9cXG4vZztcbnZhciByRXNjYXBlZE5ld2xpbmUgPSAvXFxcXG4vZztcblxuLyoqXG4gKiBHbG9iYWwgSlNPTlAgY2FsbGJhY2tzLlxuICovXG5cbnZhciBjYWxsYmFja3M7XG5cbi8qKlxuICogQ2FsbGJhY2tzIGNvdW50LlxuICovXG5cbnZhciBpbmRleCA9IDA7XG5cbi8qKlxuICogTm9vcC5cbiAqL1xuXG5mdW5jdGlvbiBlbXB0eSAoKSB7IH1cblxuLyoqXG4gKiBKU09OUCBQb2xsaW5nIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBKU09OUFBvbGxpbmcgKG9wdHMpIHtcbiAgUG9sbGluZy5jYWxsKHRoaXMsIG9wdHMpO1xuXG4gIHRoaXMucXVlcnkgPSB0aGlzLnF1ZXJ5IHx8IHt9O1xuXG4gIC8vIGRlZmluZSBnbG9iYWwgY2FsbGJhY2tzIGFycmF5IGlmIG5vdCBwcmVzZW50XG4gIC8vIHdlIGRvIHRoaXMgaGVyZSAobGF6aWx5KSB0byBhdm9pZCB1bm5lZWRlZCBnbG9iYWwgcG9sbHV0aW9uXG4gIGlmICghY2FsbGJhY2tzKSB7XG4gICAgLy8gd2UgbmVlZCB0byBjb25zaWRlciBtdWx0aXBsZSBlbmdpbmVzIGluIHRoZSBzYW1lIHBhZ2VcbiAgICBpZiAoIWdsb2JhbC5fX19laW8pIGdsb2JhbC5fX19laW8gPSBbXTtcbiAgICBjYWxsYmFja3MgPSBnbG9iYWwuX19fZWlvO1xuICB9XG5cbiAgLy8gY2FsbGJhY2sgaWRlbnRpZmllclxuICB0aGlzLmluZGV4ID0gY2FsbGJhY2tzLmxlbmd0aDtcblxuICAvLyBhZGQgY2FsbGJhY2sgdG8ganNvbnAgZ2xvYmFsXG4gIHZhciBzZWxmID0gdGhpcztcbiAgY2FsbGJhY2tzLnB1c2goZnVuY3Rpb24gKG1zZykge1xuICAgIHNlbGYub25EYXRhKG1zZyk7XG4gIH0pO1xuXG4gIC8vIGFwcGVuZCB0byBxdWVyeSBzdHJpbmdcbiAgdGhpcy5xdWVyeS5qID0gdGhpcy5pbmRleDtcblxuICAvLyBwcmV2ZW50IHNwdXJpb3VzIGVycm9ycyBmcm9tIGJlaW5nIGVtaXR0ZWQgd2hlbiB0aGUgd2luZG93IGlzIHVubG9hZGVkXG4gIGlmIChnbG9iYWwuZG9jdW1lbnQgJiYgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHNlbGYuc2NyaXB0KSBzZWxmLnNjcmlwdC5vbmVycm9yID0gZW1wdHk7XG4gICAgfSwgZmFsc2UpO1xuICB9XG59XG5cbi8qKlxuICogSW5oZXJpdHMgZnJvbSBQb2xsaW5nLlxuICovXG5cbmluaGVyaXQoSlNPTlBQb2xsaW5nLCBQb2xsaW5nKTtcblxuLypcbiAqIEpTT05QIG9ubHkgc3VwcG9ydHMgYmluYXJ5IGFzIGJhc2U2NCBlbmNvZGVkIHN0cmluZ3NcbiAqL1xuXG5KU09OUFBvbGxpbmcucHJvdG90eXBlLnN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG5cbi8qKlxuICogQ2xvc2VzIHRoZSBzb2NrZXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zY3JpcHQpIHtcbiAgICB0aGlzLnNjcmlwdC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuc2NyaXB0KTtcbiAgICB0aGlzLnNjcmlwdCA9IG51bGw7XG4gIH1cblxuICBpZiAodGhpcy5mb3JtKSB7XG4gICAgdGhpcy5mb3JtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5mb3JtKTtcbiAgICB0aGlzLmZvcm0gPSBudWxsO1xuICAgIHRoaXMuaWZyYW1lID0gbnVsbDtcbiAgfVxuXG4gIFBvbGxpbmcucHJvdG90eXBlLmRvQ2xvc2UuY2FsbCh0aGlzKTtcbn07XG5cbi8qKlxuICogU3RhcnRzIGEgcG9sbCBjeWNsZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5KU09OUFBvbGxpbmcucHJvdG90eXBlLmRvUG9sbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG5cbiAgaWYgKHRoaXMuc2NyaXB0KSB7XG4gICAgdGhpcy5zY3JpcHQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnNjcmlwdCk7XG4gICAgdGhpcy5zY3JpcHQgPSBudWxsO1xuICB9XG5cbiAgc2NyaXB0LmFzeW5jID0gdHJ1ZTtcbiAgc2NyaXB0LnNyYyA9IHRoaXMudXJpKCk7XG4gIHNjcmlwdC5vbmVycm9yID0gZnVuY3Rpb24oZSl7XG4gICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsIGVycm9yJyxlKTtcbiAgfTtcblxuICB2YXIgaW5zZXJ0QXQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0JylbMF07XG4gIGlmIChpbnNlcnRBdCkge1xuICAgIGluc2VydEF0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHNjcmlwdCwgaW5zZXJ0QXQpO1xuICB9XG4gIGVsc2Uge1xuICAgIChkb2N1bWVudC5oZWFkIHx8IGRvY3VtZW50LmJvZHkpLmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gIH1cbiAgdGhpcy5zY3JpcHQgPSBzY3JpcHQ7XG5cbiAgdmFyIGlzVUFnZWNrbyA9ICd1bmRlZmluZWQnICE9IHR5cGVvZiBuYXZpZ2F0b3IgJiYgL2dlY2tvL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgXG4gIGlmIChpc1VBZ2Vja28pIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgICB9LCAxMDApO1xuICB9XG59O1xuXG4vKipcbiAqIFdyaXRlcyB3aXRoIGEgaGlkZGVuIGlmcmFtZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSB0byBzZW5kXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsZWQgdXBvbiBmbHVzaC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkpTT05QUG9sbGluZy5wcm90b3R5cGUuZG9Xcml0ZSA9IGZ1bmN0aW9uIChkYXRhLCBmbikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKCF0aGlzLmZvcm0pIHtcbiAgICB2YXIgZm9ybSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2Zvcm0nKTtcbiAgICB2YXIgYXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgdmFyIGlkID0gdGhpcy5pZnJhbWVJZCA9ICdlaW9faWZyYW1lXycgKyB0aGlzLmluZGV4O1xuICAgIHZhciBpZnJhbWU7XG5cbiAgICBmb3JtLmNsYXNzTmFtZSA9ICdzb2NrZXRpbyc7XG4gICAgZm9ybS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgZm9ybS5zdHlsZS50b3AgPSAnLTEwMDBweCc7XG4gICAgZm9ybS5zdHlsZS5sZWZ0ID0gJy0xMDAwcHgnO1xuICAgIGZvcm0udGFyZ2V0ID0gaWQ7XG4gICAgZm9ybS5tZXRob2QgPSAnUE9TVCc7XG4gICAgZm9ybS5zZXRBdHRyaWJ1dGUoJ2FjY2VwdC1jaGFyc2V0JywgJ3V0Zi04Jyk7XG4gICAgYXJlYS5uYW1lID0gJ2QnO1xuICAgIGZvcm0uYXBwZW5kQ2hpbGQoYXJlYSk7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChmb3JtKTtcblxuICAgIHRoaXMuZm9ybSA9IGZvcm07XG4gICAgdGhpcy5hcmVhID0gYXJlYTtcbiAgfVxuXG4gIHRoaXMuZm9ybS5hY3Rpb24gPSB0aGlzLnVyaSgpO1xuXG4gIGZ1bmN0aW9uIGNvbXBsZXRlICgpIHtcbiAgICBpbml0SWZyYW1lKCk7XG4gICAgZm4oKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRJZnJhbWUgKCkge1xuICAgIGlmIChzZWxmLmlmcmFtZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2VsZi5mb3JtLnJlbW92ZUNoaWxkKHNlbGYuaWZyYW1lKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsaW5nIGlmcmFtZSByZW1vdmFsIGVycm9yJywgZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIGllNiBkeW5hbWljIGlmcmFtZXMgd2l0aCB0YXJnZXQ9XCJcIiBzdXBwb3J0ICh0aGFua3MgQ2hyaXMgTGFtYmFjaGVyKVxuICAgICAgdmFyIGh0bWwgPSAnPGlmcmFtZSBzcmM9XCJqYXZhc2NyaXB0OjBcIiBuYW1lPVwiJysgc2VsZi5pZnJhbWVJZCArJ1wiPic7XG4gICAgICBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGh0bWwpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xuICAgICAgaWZyYW1lLm5hbWUgPSBzZWxmLmlmcmFtZUlkO1xuICAgICAgaWZyYW1lLnNyYyA9ICdqYXZhc2NyaXB0OjAnO1xuICAgIH1cblxuICAgIGlmcmFtZS5pZCA9IHNlbGYuaWZyYW1lSWQ7XG5cbiAgICBzZWxmLmZvcm0uYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgICBzZWxmLmlmcmFtZSA9IGlmcmFtZTtcbiAgfVxuXG4gIGluaXRJZnJhbWUoKTtcblxuICAvLyBlc2NhcGUgXFxuIHRvIHByZXZlbnQgaXQgZnJvbSBiZWluZyBjb252ZXJ0ZWQgaW50byBcXHJcXG4gYnkgc29tZSBVQXNcbiAgLy8gZG91YmxlIGVzY2FwaW5nIGlzIHJlcXVpcmVkIGZvciBlc2NhcGVkIG5ldyBsaW5lcyBiZWNhdXNlIHVuZXNjYXBpbmcgb2YgbmV3IGxpbmVzIGNhbiBiZSBkb25lIHNhZmVseSBvbiBzZXJ2ZXItc2lkZVxuICBkYXRhID0gZGF0YS5yZXBsYWNlKHJFc2NhcGVkTmV3bGluZSwgJ1xcXFxcXG4nKTtcbiAgdGhpcy5hcmVhLnZhbHVlID0gZGF0YS5yZXBsYWNlKHJOZXdsaW5lLCAnXFxcXG4nKTtcblxuICB0cnkge1xuICAgIHRoaXMuZm9ybS5zdWJtaXQoKTtcbiAgfSBjYXRjaChlKSB7fVxuXG4gIGlmICh0aGlzLmlmcmFtZS5hdHRhY2hFdmVudCkge1xuICAgIHRoaXMuaWZyYW1lLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCl7XG4gICAgICBpZiAoc2VsZi5pZnJhbWUucmVhZHlTdGF0ZSA9PSAnY29tcGxldGUnKSB7XG4gICAgICAgIGNvbXBsZXRlKCk7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmlmcmFtZS5vbmxvYWQgPSBjb21wbGV0ZTtcbiAgfVxufTtcbiIsIi8qKlxuICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAqL1xuXG52YXIgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdC1zc2wnKTtcbnZhciBQb2xsaW5nID0gcmVxdWlyZSgnLi9wb2xsaW5nJyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgaW5oZXJpdCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1pbmhlcml0Jyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnBvbGxpbmcteGhyJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBYSFI7XG5tb2R1bGUuZXhwb3J0cy5SZXF1ZXN0ID0gUmVxdWVzdDtcblxuLyoqXG4gKiBFbXB0eSBmdW5jdGlvblxuICovXG5cbmZ1bmN0aW9uIGVtcHR5KCl7fVxuXG4vKipcbiAqIFhIUiBQb2xsaW5nIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFhIUihvcHRzKXtcbiAgUG9sbGluZy5jYWxsKHRoaXMsIG9wdHMpO1xuXG4gIGlmIChnbG9iYWwubG9jYXRpb24pIHtcbiAgICB2YXIgaXNTU0wgPSAnaHR0cHM6JyA9PSBsb2NhdGlvbi5wcm90b2NvbDtcbiAgICB2YXIgcG9ydCA9IGxvY2F0aW9uLnBvcnQ7XG5cbiAgICAvLyBzb21lIHVzZXIgYWdlbnRzIGhhdmUgZW1wdHkgYGxvY2F0aW9uLnBvcnRgXG4gICAgaWYgKCFwb3J0KSB7XG4gICAgICBwb3J0ID0gaXNTU0wgPyA0NDMgOiA4MDtcbiAgICB9XG5cbiAgICB0aGlzLnhkID0gb3B0cy5ob3N0bmFtZSAhPSBnbG9iYWwubG9jYXRpb24uaG9zdG5hbWUgfHxcbiAgICAgIHBvcnQgIT0gb3B0cy5wb3J0O1xuICAgIHRoaXMueHMgPSBvcHRzLnNlY3VyZSAhPSBpc1NTTDtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmV4dHJhSGVhZGVycyA9IG9wdHMuZXh0cmFIZWFkZXJzO1xuICB9XG59XG5cbi8qKlxuICogSW5oZXJpdHMgZnJvbSBQb2xsaW5nLlxuICovXG5cbmluaGVyaXQoWEhSLCBQb2xsaW5nKTtcblxuLyoqXG4gKiBYSFIgc3VwcG9ydHMgYmluYXJ5XG4gKi9cblxuWEhSLnByb3RvdHlwZS5zdXBwb3J0c0JpbmFyeSA9IHRydWU7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHJlcXVlc3QuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuWEhSLnByb3RvdHlwZS5yZXF1ZXN0ID0gZnVuY3Rpb24ob3B0cyl7XG4gIG9wdHMgPSBvcHRzIHx8IHt9O1xuICBvcHRzLnVyaSA9IHRoaXMudXJpKCk7XG4gIG9wdHMueGQgPSB0aGlzLnhkO1xuICBvcHRzLnhzID0gdGhpcy54cztcbiAgb3B0cy5hZ2VudCA9IHRoaXMuYWdlbnQgfHwgZmFsc2U7XG4gIG9wdHMuc3VwcG9ydHNCaW5hcnkgPSB0aGlzLnN1cHBvcnRzQmluYXJ5O1xuICBvcHRzLmVuYWJsZXNYRFIgPSB0aGlzLmVuYWJsZXNYRFI7XG5cbiAgLy8gU1NMIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIG9wdHMucGZ4ID0gdGhpcy5wZng7XG4gIG9wdHMua2V5ID0gdGhpcy5rZXk7XG4gIG9wdHMucGFzc3BocmFzZSA9IHRoaXMucGFzc3BocmFzZTtcbiAgb3B0cy5jZXJ0ID0gdGhpcy5jZXJ0O1xuICBvcHRzLmNhID0gdGhpcy5jYTtcbiAgb3B0cy5jaXBoZXJzID0gdGhpcy5jaXBoZXJzO1xuICBvcHRzLnJlamVjdFVuYXV0aG9yaXplZCA9IHRoaXMucmVqZWN0VW5hdXRob3JpemVkO1xuXG4gIC8vIG90aGVyIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gIG9wdHMuZXh0cmFIZWFkZXJzID0gdGhpcy5leHRyYUhlYWRlcnM7XG5cbiAgcmV0dXJuIG5ldyBSZXF1ZXN0KG9wdHMpO1xufTtcblxuLyoqXG4gKiBTZW5kcyBkYXRhLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIHRvIHNlbmQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsZWQgdXBvbiBmbHVzaC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblhIUi5wcm90b3R5cGUuZG9Xcml0ZSA9IGZ1bmN0aW9uKGRhdGEsIGZuKXtcbiAgdmFyIGlzQmluYXJ5ID0gdHlwZW9mIGRhdGEgIT09ICdzdHJpbmcnICYmIGRhdGEgIT09IHVuZGVmaW5lZDtcbiAgdmFyIHJlcSA9IHRoaXMucmVxdWVzdCh7IG1ldGhvZDogJ1BPU1QnLCBkYXRhOiBkYXRhLCBpc0JpbmFyeTogaXNCaW5hcnkgfSk7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgcmVxLm9uKCdzdWNjZXNzJywgZm4pO1xuICByZXEub24oJ2Vycm9yJywgZnVuY3Rpb24oZXJyKXtcbiAgICBzZWxmLm9uRXJyb3IoJ3hociBwb3N0IGVycm9yJywgZXJyKTtcbiAgfSk7XG4gIHRoaXMuc2VuZFhociA9IHJlcTtcbn07XG5cbi8qKlxuICogU3RhcnRzIGEgcG9sbCBjeWNsZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5YSFIucHJvdG90eXBlLmRvUG9sbCA9IGZ1bmN0aW9uKCl7XG4gIGRlYnVnKCd4aHIgcG9sbCcpO1xuICB2YXIgcmVxID0gdGhpcy5yZXF1ZXN0KCk7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgcmVxLm9uKCdkYXRhJywgZnVuY3Rpb24oZGF0YSl7XG4gICAgc2VsZi5vbkRhdGEoZGF0YSk7XG4gIH0pO1xuICByZXEub24oJ2Vycm9yJywgZnVuY3Rpb24oZXJyKXtcbiAgICBzZWxmLm9uRXJyb3IoJ3hociBwb2xsIGVycm9yJywgZXJyKTtcbiAgfSk7XG4gIHRoaXMucG9sbFhociA9IHJlcTtcbn07XG5cbi8qKlxuICogUmVxdWVzdCBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFJlcXVlc3Qob3B0cyl7XG4gIHRoaXMubWV0aG9kID0gb3B0cy5tZXRob2QgfHwgJ0dFVCc7XG4gIHRoaXMudXJpID0gb3B0cy51cmk7XG4gIHRoaXMueGQgPSAhIW9wdHMueGQ7XG4gIHRoaXMueHMgPSAhIW9wdHMueHM7XG4gIHRoaXMuYXN5bmMgPSBmYWxzZSAhPT0gb3B0cy5hc3luYztcbiAgdGhpcy5kYXRhID0gdW5kZWZpbmVkICE9IG9wdHMuZGF0YSA/IG9wdHMuZGF0YSA6IG51bGw7XG4gIHRoaXMuYWdlbnQgPSBvcHRzLmFnZW50O1xuICB0aGlzLmlzQmluYXJ5ID0gb3B0cy5pc0JpbmFyeTtcbiAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IG9wdHMuc3VwcG9ydHNCaW5hcnk7XG4gIHRoaXMuZW5hYmxlc1hEUiA9IG9wdHMuZW5hYmxlc1hEUjtcblxuICAvLyBTU0wgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgdGhpcy5wZnggPSBvcHRzLnBmeDtcbiAgdGhpcy5rZXkgPSBvcHRzLmtleTtcbiAgdGhpcy5wYXNzcGhyYXNlID0gb3B0cy5wYXNzcGhyYXNlO1xuICB0aGlzLmNlcnQgPSBvcHRzLmNlcnQ7XG4gIHRoaXMuY2EgPSBvcHRzLmNhO1xuICB0aGlzLmNpcGhlcnMgPSBvcHRzLmNpcGhlcnM7XG4gIHRoaXMucmVqZWN0VW5hdXRob3JpemVkID0gb3B0cy5yZWplY3RVbmF1dGhvcml6ZWQ7XG5cbiAgLy8gb3RoZXIgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgdGhpcy5leHRyYUhlYWRlcnMgPSBvcHRzLmV4dHJhSGVhZGVycztcblxuICB0aGlzLmNyZWF0ZSgpO1xufVxuXG4vKipcbiAqIE1peCBpbiBgRW1pdHRlcmAuXG4gKi9cblxuRW1pdHRlcihSZXF1ZXN0LnByb3RvdHlwZSk7XG5cbi8qKlxuICogQ3JlYXRlcyB0aGUgWEhSIG9iamVjdCBhbmQgc2VuZHMgdGhlIHJlcXVlc3QuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24oKXtcbiAgdmFyIG9wdHMgPSB7IGFnZW50OiB0aGlzLmFnZW50LCB4ZG9tYWluOiB0aGlzLnhkLCB4c2NoZW1lOiB0aGlzLnhzLCBlbmFibGVzWERSOiB0aGlzLmVuYWJsZXNYRFIgfTtcblxuICAvLyBTU0wgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgb3B0cy5wZnggPSB0aGlzLnBmeDtcbiAgb3B0cy5rZXkgPSB0aGlzLmtleTtcbiAgb3B0cy5wYXNzcGhyYXNlID0gdGhpcy5wYXNzcGhyYXNlO1xuICBvcHRzLmNlcnQgPSB0aGlzLmNlcnQ7XG4gIG9wdHMuY2EgPSB0aGlzLmNhO1xuICBvcHRzLmNpcGhlcnMgPSB0aGlzLmNpcGhlcnM7XG4gIG9wdHMucmVqZWN0VW5hdXRob3JpemVkID0gdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQ7XG5cbiAgdmFyIHhociA9IHRoaXMueGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KG9wdHMpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdHJ5IHtcbiAgICBkZWJ1ZygneGhyIG9wZW4gJXM6ICVzJywgdGhpcy5tZXRob2QsIHRoaXMudXJpKTtcbiAgICB4aHIub3Blbih0aGlzLm1ldGhvZCwgdGhpcy51cmksIHRoaXMuYXN5bmMpO1xuICAgIHRyeSB7XG4gICAgICBpZiAodGhpcy5leHRyYUhlYWRlcnMpIHtcbiAgICAgICAgeGhyLnNldERpc2FibGVIZWFkZXJDaGVjayh0cnVlKTtcbiAgICAgICAgZm9yICh2YXIgaSBpbiB0aGlzLmV4dHJhSGVhZGVycykge1xuICAgICAgICAgIGlmICh0aGlzLmV4dHJhSGVhZGVycy5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoaSwgdGhpcy5leHRyYUhlYWRlcnNbaV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgaWYgKHRoaXMuc3VwcG9ydHNCaW5hcnkpIHtcbiAgICAgIC8vIFRoaXMgaGFzIHRvIGJlIGRvbmUgYWZ0ZXIgb3BlbiBiZWNhdXNlIEZpcmVmb3ggaXMgc3R1cGlkXG4gICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEzMjE2OTAzL2dldC1iaW5hcnktZGF0YS13aXRoLXhtbGh0dHByZXF1ZXN0LWluLWEtZmlyZWZveC1leHRlbnNpb25cbiAgICAgIHhoci5yZXNwb25zZVR5cGUgPSAnYXJyYXlidWZmZXInO1xuICAgIH1cblxuICAgIGlmICgnUE9TVCcgPT0gdGhpcy5tZXRob2QpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICh0aGlzLmlzQmluYXJ5KSB7XG4gICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC10eXBlJywgJ3RleHQvcGxhaW47Y2hhcnNldD1VVEYtOCcpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7fVxuICAgIH1cblxuICAgIC8vIGllNiBjaGVja1xuICAgIGlmICgnd2l0aENyZWRlbnRpYWxzJyBpbiB4aHIpIHtcbiAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmhhc1hEUigpKSB7XG4gICAgICB4aHIub25sb2FkID0gZnVuY3Rpb24oKXtcbiAgICAgICAgc2VsZi5vbkxvYWQoKTtcbiAgICAgIH07XG4gICAgICB4aHIub25lcnJvciA9IGZ1bmN0aW9uKCl7XG4gICAgICAgIHNlbGYub25FcnJvcih4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpe1xuICAgICAgICBpZiAoNCAhPSB4aHIucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgICAgICBpZiAoMjAwID09IHhoci5zdGF0dXMgfHwgMTIyMyA9PSB4aHIuc3RhdHVzKSB7XG4gICAgICAgICAgc2VsZi5vbkxvYWQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIGBlcnJvcmAgZXZlbnQgaGFuZGxlciB0aGF0J3MgdXNlci1zZXRcbiAgICAgICAgICAvLyBkb2VzIG5vdCB0aHJvdyBpbiB0aGUgc2FtZSB0aWNrIGFuZCBnZXRzIGNhdWdodCBoZXJlXG4gICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgICAgICAgc2VsZi5vbkVycm9yKHhoci5zdGF0dXMpO1xuICAgICAgICAgIH0sIDApO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cblxuICAgIGRlYnVnKCd4aHIgZGF0YSAlcycsIHRoaXMuZGF0YSk7XG4gICAgeGhyLnNlbmQodGhpcy5kYXRhKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIE5lZWQgdG8gZGVmZXIgc2luY2UgLmNyZWF0ZSgpIGlzIGNhbGxlZCBkaXJlY3RseSBmaHJvbSB0aGUgY29uc3RydWN0b3JcbiAgICAvLyBhbmQgdGh1cyB0aGUgJ2Vycm9yJyBldmVudCBjYW4gb25seSBiZSBvbmx5IGJvdW5kICphZnRlciogdGhpcyBleGNlcHRpb25cbiAgICAvLyBvY2N1cnMuICBUaGVyZWZvcmUsIGFsc28sIHdlIGNhbm5vdCB0aHJvdyBoZXJlIGF0IGFsbC5cbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgc2VsZi5vbkVycm9yKGUpO1xuICAgIH0sIDApO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChnbG9iYWwuZG9jdW1lbnQpIHtcbiAgICB0aGlzLmluZGV4ID0gUmVxdWVzdC5yZXF1ZXN0c0NvdW50Kys7XG4gICAgUmVxdWVzdC5yZXF1ZXN0c1t0aGlzLmluZGV4XSA9IHRoaXM7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gc3VjY2Vzc2Z1bCByZXNwb25zZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vblN1Y2Nlc3MgPSBmdW5jdGlvbigpe1xuICB0aGlzLmVtaXQoJ3N1Y2Nlc3MnKTtcbiAgdGhpcy5jbGVhbnVwKCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCBpZiB3ZSBoYXZlIGRhdGEuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24oZGF0YSl7XG4gIHRoaXMuZW1pdCgnZGF0YScsIGRhdGEpO1xuICB0aGlzLm9uU3VjY2VzcygpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24oZXJyKXtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gIHRoaXMuY2xlYW51cCh0cnVlKTtcbn07XG5cbi8qKlxuICogQ2xlYW5zIHVwIGhvdXNlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmNsZWFudXAgPSBmdW5jdGlvbihmcm9tRXJyb3Ipe1xuICBpZiAoJ3VuZGVmaW5lZCcgPT0gdHlwZW9mIHRoaXMueGhyIHx8IG51bGwgPT09IHRoaXMueGhyKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIHhtbGh0dHByZXF1ZXN0XG4gIGlmICh0aGlzLmhhc1hEUigpKSB7XG4gICAgdGhpcy54aHIub25sb2FkID0gdGhpcy54aHIub25lcnJvciA9IGVtcHR5O1xuICB9IGVsc2Uge1xuICAgIHRoaXMueGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGVtcHR5O1xuICB9XG5cbiAgaWYgKGZyb21FcnJvcikge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnhoci5hYm9ydCgpO1xuICAgIH0gY2F0Y2goZSkge31cbiAgfVxuXG4gIGlmIChnbG9iYWwuZG9jdW1lbnQpIHtcbiAgICBkZWxldGUgUmVxdWVzdC5yZXF1ZXN0c1t0aGlzLmluZGV4XTtcbiAgfVxuXG4gIHRoaXMueGhyID0gbnVsbDtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gbG9hZC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vbkxvYWQgPSBmdW5jdGlvbigpe1xuICB2YXIgZGF0YTtcbiAgdHJ5IHtcbiAgICB2YXIgY29udGVudFR5cGU7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnRlbnRUeXBlID0gdGhpcy54aHIuZ2V0UmVzcG9uc2VIZWFkZXIoJ0NvbnRlbnQtVHlwZScpLnNwbGl0KCc7JylbMF07XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICBpZiAoY29udGVudFR5cGUgPT09ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nKSB7XG4gICAgICBkYXRhID0gdGhpcy54aHIucmVzcG9uc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy5zdXBwb3J0c0JpbmFyeSkge1xuICAgICAgICBkYXRhID0gdGhpcy54aHIucmVzcG9uc2VUZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDhBcnJheSh0aGlzLnhoci5yZXNwb25zZSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdmFyIHVpOEFyciA9IG5ldyBVaW50OEFycmF5KHRoaXMueGhyLnJlc3BvbnNlKTtcbiAgICAgICAgICB2YXIgZGF0YUFycmF5ID0gW107XG4gICAgICAgICAgZm9yICh2YXIgaWR4ID0gMCwgbGVuZ3RoID0gdWk4QXJyLmxlbmd0aDsgaWR4IDwgbGVuZ3RoOyBpZHgrKykge1xuICAgICAgICAgICAgZGF0YUFycmF5LnB1c2godWk4QXJyW2lkeF0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGRhdGFBcnJheSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aGlzLm9uRXJyb3IoZSk7XG4gIH1cbiAgaWYgKG51bGwgIT0gZGF0YSkge1xuICAgIHRoaXMub25EYXRhKGRhdGEpO1xuICB9XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIGl0IGhhcyBYRG9tYWluUmVxdWVzdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5oYXNYRFIgPSBmdW5jdGlvbigpe1xuICByZXR1cm4gJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiBnbG9iYWwuWERvbWFpblJlcXVlc3QgJiYgIXRoaXMueHMgJiYgdGhpcy5lbmFibGVzWERSO1xufTtcblxuLyoqXG4gKiBBYm9ydHMgdGhlIHJlcXVlc3QuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5hYm9ydCA9IGZ1bmN0aW9uKCl7XG4gIHRoaXMuY2xlYW51cCgpO1xufTtcblxuLyoqXG4gKiBBYm9ydHMgcGVuZGluZyByZXF1ZXN0cyB3aGVuIHVubG9hZGluZyB0aGUgd2luZG93LiBUaGlzIGlzIG5lZWRlZCB0byBwcmV2ZW50XG4gKiBtZW1vcnkgbGVha3MgKGUuZy4gd2hlbiB1c2luZyBJRSkgYW5kIHRvIGVuc3VyZSB0aGF0IG5vIHNwdXJpb3VzIGVycm9yIGlzXG4gKiBlbWl0dGVkLlxuICovXG5cbmlmIChnbG9iYWwuZG9jdW1lbnQpIHtcbiAgUmVxdWVzdC5yZXF1ZXN0c0NvdW50ID0gMDtcbiAgUmVxdWVzdC5yZXF1ZXN0cyA9IHt9O1xuICBpZiAoZ2xvYmFsLmF0dGFjaEV2ZW50KSB7XG4gICAgZ2xvYmFsLmF0dGFjaEV2ZW50KCdvbnVubG9hZCcsIHVubG9hZEhhbmRsZXIpO1xuICB9IGVsc2UgaWYgKGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoJ2JlZm9yZXVubG9hZCcsIHVubG9hZEhhbmRsZXIsIGZhbHNlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB1bmxvYWRIYW5kbGVyKCkge1xuICBmb3IgKHZhciBpIGluIFJlcXVlc3QucmVxdWVzdHMpIHtcbiAgICBpZiAoUmVxdWVzdC5yZXF1ZXN0cy5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgUmVxdWVzdC5yZXF1ZXN0c1tpXS5hYm9ydCgpO1xuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBUcmFuc3BvcnQgPSByZXF1aXJlKCcuLi90cmFuc3BvcnQnKTtcbnZhciBwYXJzZXFzID0gcmVxdWlyZSgncGFyc2VxcycpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcbnZhciB5ZWFzdCA9IHJlcXVpcmUoJ3llYXN0Jyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnBvbGxpbmcnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFBvbGxpbmc7XG5cbi8qKlxuICogSXMgWEhSMiBzdXBwb3J0ZWQ/XG4gKi9cblxudmFyIGhhc1hIUjIgPSAoZnVuY3Rpb24oKSB7XG4gIHZhciBYTUxIdHRwUmVxdWVzdCA9IHJlcXVpcmUoJ3htbGh0dHByZXF1ZXN0LXNzbCcpO1xuICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KHsgeGRvbWFpbjogZmFsc2UgfSk7XG4gIHJldHVybiBudWxsICE9IHhoci5yZXNwb25zZVR5cGU7XG59KSgpO1xuXG4vKipcbiAqIFBvbGxpbmcgaW50ZXJmYWNlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBQb2xsaW5nKG9wdHMpe1xuICB2YXIgZm9yY2VCYXNlNjQgPSAob3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0KTtcbiAgaWYgKCFoYXNYSFIyIHx8IGZvcmNlQmFzZTY0KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG4gIFRyYW5zcG9ydC5jYWxsKHRoaXMsIG9wdHMpO1xufVxuXG4vKipcbiAqIEluaGVyaXRzIGZyb20gVHJhbnNwb3J0LlxuICovXG5cbmluaGVyaXQoUG9sbGluZywgVHJhbnNwb3J0KTtcblxuLyoqXG4gKiBUcmFuc3BvcnQgbmFtZS5cbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5uYW1lID0gJ3BvbGxpbmcnO1xuXG4vKipcbiAqIE9wZW5zIHRoZSBzb2NrZXQgKHRyaWdnZXJzIHBvbGxpbmcpLiBXZSB3cml0ZSBhIFBJTkcgbWVzc2FnZSB0byBkZXRlcm1pbmVcbiAqIHdoZW4gdGhlIHRyYW5zcG9ydCBpcyBvcGVuLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLmRvT3BlbiA9IGZ1bmN0aW9uKCl7XG4gIHRoaXMucG9sbCgpO1xufTtcblxuLyoqXG4gKiBQYXVzZXMgcG9sbGluZy5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB1cG9uIGJ1ZmZlcnMgYXJlIGZsdXNoZWQgYW5kIHRyYW5zcG9ydCBpcyBwYXVzZWRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24ob25QYXVzZSl7XG4gIHZhciBwZW5kaW5nID0gMDtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdwYXVzaW5nJztcblxuICBmdW5jdGlvbiBwYXVzZSgpe1xuICAgIGRlYnVnKCdwYXVzZWQnKTtcbiAgICBzZWxmLnJlYWR5U3RhdGUgPSAncGF1c2VkJztcbiAgICBvblBhdXNlKCk7XG4gIH1cblxuICBpZiAodGhpcy5wb2xsaW5nIHx8ICF0aGlzLndyaXRhYmxlKSB7XG4gICAgdmFyIHRvdGFsID0gMDtcblxuICAgIGlmICh0aGlzLnBvbGxpbmcpIHtcbiAgICAgIGRlYnVnKCd3ZSBhcmUgY3VycmVudGx5IHBvbGxpbmcgLSB3YWl0aW5nIHRvIHBhdXNlJyk7XG4gICAgICB0b3RhbCsrO1xuICAgICAgdGhpcy5vbmNlKCdwb2xsQ29tcGxldGUnLCBmdW5jdGlvbigpe1xuICAgICAgICBkZWJ1ZygncHJlLXBhdXNlIHBvbGxpbmcgY29tcGxldGUnKTtcbiAgICAgICAgLS10b3RhbCB8fCBwYXVzZSgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLndyaXRhYmxlKSB7XG4gICAgICBkZWJ1Zygnd2UgYXJlIGN1cnJlbnRseSB3cml0aW5nIC0gd2FpdGluZyB0byBwYXVzZScpO1xuICAgICAgdG90YWwrKztcbiAgICAgIHRoaXMub25jZSgnZHJhaW4nLCBmdW5jdGlvbigpe1xuICAgICAgICBkZWJ1ZygncHJlLXBhdXNlIHdyaXRpbmcgY29tcGxldGUnKTtcbiAgICAgICAgLS10b3RhbCB8fCBwYXVzZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHBhdXNlKCk7XG4gIH1cbn07XG5cbi8qKlxuICogU3RhcnRzIHBvbGxpbmcgY3ljbGUuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5wb2xsID0gZnVuY3Rpb24oKXtcbiAgZGVidWcoJ3BvbGxpbmcnKTtcbiAgdGhpcy5wb2xsaW5nID0gdHJ1ZTtcbiAgdGhpcy5kb1BvbGwoKTtcbiAgdGhpcy5lbWl0KCdwb2xsJyk7XG59O1xuXG4vKipcbiAqIE92ZXJsb2FkcyBvbkRhdGEgdG8gZGV0ZWN0IHBheWxvYWRzLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uKGRhdGEpe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGRlYnVnKCdwb2xsaW5nIGdvdCBkYXRhICVzJywgZGF0YSk7XG4gIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uKHBhY2tldCwgaW5kZXgsIHRvdGFsKSB7XG4gICAgLy8gaWYgaXRzIHRoZSBmaXJzdCBtZXNzYWdlIHdlIGNvbnNpZGVyIHRoZSB0cmFuc3BvcnQgb3BlblxuICAgIGlmICgnb3BlbmluZycgPT0gc2VsZi5yZWFkeVN0YXRlKSB7XG4gICAgICBzZWxmLm9uT3BlbigpO1xuICAgIH1cblxuICAgIC8vIGlmIGl0cyBhIGNsb3NlIHBhY2tldCwgd2UgY2xvc2UgdGhlIG9uZ29pbmcgcmVxdWVzdHNcbiAgICBpZiAoJ2Nsb3NlJyA9PSBwYWNrZXQudHlwZSkge1xuICAgICAgc2VsZi5vbkNsb3NlKCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gb3RoZXJ3aXNlIGJ5cGFzcyBvbkRhdGEgYW5kIGhhbmRsZSB0aGUgbWVzc2FnZVxuICAgIHNlbGYub25QYWNrZXQocGFja2V0KTtcbiAgfTtcblxuICAvLyBkZWNvZGUgcGF5bG9hZFxuICBwYXJzZXIuZGVjb2RlUGF5bG9hZChkYXRhLCB0aGlzLnNvY2tldC5iaW5hcnlUeXBlLCBjYWxsYmFjayk7XG5cbiAgLy8gaWYgYW4gZXZlbnQgZGlkIG5vdCB0cmlnZ2VyIGNsb3NpbmdcbiAgaWYgKCdjbG9zZWQnICE9IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIC8vIGlmIHdlIGdvdCBkYXRhIHdlJ3JlIG5vdCBwb2xsaW5nXG4gICAgdGhpcy5wb2xsaW5nID0gZmFsc2U7XG4gICAgdGhpcy5lbWl0KCdwb2xsQ29tcGxldGUnKTtcblxuICAgIGlmICgnb3BlbicgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgICB0aGlzLnBvbGwoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWcoJ2lnbm9yaW5nIHBvbGwgLSB0cmFuc3BvcnQgc3RhdGUgXCIlc1wiJywgdGhpcy5yZWFkeVN0YXRlKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogRm9yIHBvbGxpbmcsIHNlbmQgYSBjbG9zZSBwYWNrZXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUuZG9DbG9zZSA9IGZ1bmN0aW9uKCl7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBmdW5jdGlvbiBjbG9zZSgpe1xuICAgIGRlYnVnKCd3cml0aW5nIGNsb3NlIHBhY2tldCcpO1xuICAgIHNlbGYud3JpdGUoW3sgdHlwZTogJ2Nsb3NlJyB9XSk7XG4gIH1cblxuICBpZiAoJ29wZW4nID09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIGRlYnVnKCd0cmFuc3BvcnQgb3BlbiAtIGNsb3NpbmcnKTtcbiAgICBjbG9zZSgpO1xuICB9IGVsc2Uge1xuICAgIC8vIGluIGNhc2Ugd2UncmUgdHJ5aW5nIHRvIGNsb3NlIHdoaWxlXG4gICAgLy8gaGFuZHNoYWtpbmcgaXMgaW4gcHJvZ3Jlc3MgKEdILTE2NClcbiAgICBkZWJ1ZygndHJhbnNwb3J0IG5vdCBvcGVuIC0gZGVmZXJyaW5nIGNsb3NlJyk7XG4gICAgdGhpcy5vbmNlKCdvcGVuJywgY2xvc2UpO1xuICB9XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIHBhY2tldHMgcGF5bG9hZC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBkYXRhIHBhY2tldHNcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGRyYWluIGNhbGxiYWNrXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHBhY2tldHMpe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcbiAgdmFyIGNhbGxiYWNrZm4gPSBmdW5jdGlvbigpIHtcbiAgICBzZWxmLndyaXRhYmxlID0gdHJ1ZTtcbiAgICBzZWxmLmVtaXQoJ2RyYWluJyk7XG4gIH07XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBwYXJzZXIuZW5jb2RlUGF5bG9hZChwYWNrZXRzLCB0aGlzLnN1cHBvcnRzQmluYXJ5LCBmdW5jdGlvbihkYXRhKSB7XG4gICAgc2VsZi5kb1dyaXRlKGRhdGEsIGNhbGxiYWNrZm4pO1xuICB9KTtcbn07XG5cbi8qKlxuICogR2VuZXJhdGVzIHVyaSBmb3IgY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS51cmkgPSBmdW5jdGlvbigpe1xuICB2YXIgcXVlcnkgPSB0aGlzLnF1ZXJ5IHx8IHt9O1xuICB2YXIgc2NoZW1hID0gdGhpcy5zZWN1cmUgPyAnaHR0cHMnIDogJ2h0dHAnO1xuICB2YXIgcG9ydCA9ICcnO1xuXG4gIC8vIGNhY2hlIGJ1c3RpbmcgaXMgZm9yY2VkXG4gIGlmIChmYWxzZSAhPT0gdGhpcy50aW1lc3RhbXBSZXF1ZXN0cykge1xuICAgIHF1ZXJ5W3RoaXMudGltZXN0YW1wUGFyYW1dID0geWVhc3QoKTtcbiAgfVxuXG4gIGlmICghdGhpcy5zdXBwb3J0c0JpbmFyeSAmJiAhcXVlcnkuc2lkKSB7XG4gICAgcXVlcnkuYjY0ID0gMTtcbiAgfVxuXG4gIHF1ZXJ5ID0gcGFyc2Vxcy5lbmNvZGUocXVlcnkpO1xuXG4gIC8vIGF2b2lkIHBvcnQgaWYgZGVmYXVsdCBmb3Igc2NoZW1hXG4gIGlmICh0aGlzLnBvcnQgJiYgKCgnaHR0cHMnID09IHNjaGVtYSAmJiB0aGlzLnBvcnQgIT0gNDQzKSB8fFxuICAgICAoJ2h0dHAnID09IHNjaGVtYSAmJiB0aGlzLnBvcnQgIT0gODApKSkge1xuICAgIHBvcnQgPSAnOicgKyB0aGlzLnBvcnQ7XG4gIH1cblxuICAvLyBwcmVwZW5kID8gdG8gcXVlcnlcbiAgaWYgKHF1ZXJ5Lmxlbmd0aCkge1xuICAgIHF1ZXJ5ID0gJz8nICsgcXVlcnk7XG4gIH1cblxuICB2YXIgaXB2NiA9IHRoaXMuaG9zdG5hbWUuaW5kZXhPZignOicpICE9PSAtMTtcbiAgcmV0dXJuIHNjaGVtYSArICc6Ly8nICsgKGlwdjYgPyAnWycgKyB0aGlzLmhvc3RuYW1lICsgJ10nIDogdGhpcy5ob3N0bmFtZSkgKyBwb3J0ICsgdGhpcy5wYXRoICsgcXVlcnk7XG59O1xuIiwiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBUcmFuc3BvcnQgPSByZXF1aXJlKCcuLi90cmFuc3BvcnQnKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG52YXIgcGFyc2VxcyA9IHJlcXVpcmUoJ3BhcnNlcXMnKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcbnZhciB5ZWFzdCA9IHJlcXVpcmUoJ3llYXN0Jyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OndlYnNvY2tldCcpO1xudmFyIEJyb3dzZXJXZWJTb2NrZXQgPSBnbG9iYWwuV2ViU29ja2V0IHx8IGdsb2JhbC5Nb3pXZWJTb2NrZXQ7XG5cbi8qKlxuICogR2V0IGVpdGhlciB0aGUgYFdlYlNvY2tldGAgb3IgYE1veldlYlNvY2tldGAgZ2xvYmFsc1xuICogaW4gdGhlIGJyb3dzZXIgb3IgdHJ5IHRvIHJlc29sdmUgV2ViU29ja2V0LWNvbXBhdGlibGVcbiAqIGludGVyZmFjZSBleHBvc2VkIGJ5IGB3c2AgZm9yIE5vZGUtbGlrZSBlbnZpcm9ubWVudC5cbiAqL1xuXG52YXIgV2ViU29ja2V0ID0gQnJvd3NlcldlYlNvY2tldDtcbmlmICghV2ViU29ja2V0ICYmIHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gIHRyeSB7XG4gICAgV2ViU29ja2V0ID0gcmVxdWlyZSgnd3MnKTtcbiAgfSBjYXRjaCAoZSkgeyB9XG59XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBXUztcblxuLyoqXG4gKiBXZWJTb2NrZXQgdHJhbnNwb3J0IGNvbnN0cnVjdG9yLlxuICpcbiAqIEBhcGkge09iamVjdH0gY29ubmVjdGlvbiBvcHRpb25zXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFdTKG9wdHMpe1xuICB2YXIgZm9yY2VCYXNlNjQgPSAob3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0KTtcbiAgaWYgKGZvcmNlQmFzZTY0KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG4gIHRoaXMucGVyTWVzc2FnZURlZmxhdGUgPSBvcHRzLnBlck1lc3NhZ2VEZWZsYXRlO1xuICBUcmFuc3BvcnQuY2FsbCh0aGlzLCBvcHRzKTtcbn1cblxuLyoqXG4gKiBJbmhlcml0cyBmcm9tIFRyYW5zcG9ydC5cbiAqL1xuXG5pbmhlcml0KFdTLCBUcmFuc3BvcnQpO1xuXG4vKipcbiAqIFRyYW5zcG9ydCBuYW1lLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuV1MucHJvdG90eXBlLm5hbWUgPSAnd2Vic29ja2V0JztcblxuLypcbiAqIFdlYlNvY2tldHMgc3VwcG9ydCBiaW5hcnlcbiAqL1xuXG5XUy5wcm90b3R5cGUuc3VwcG9ydHNCaW5hcnkgPSB0cnVlO1xuXG4vKipcbiAqIE9wZW5zIHNvY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5XUy5wcm90b3R5cGUuZG9PcGVuID0gZnVuY3Rpb24oKXtcbiAgaWYgKCF0aGlzLmNoZWNrKCkpIHtcbiAgICAvLyBsZXQgcHJvYmUgdGltZW91dFxuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHVyaSA9IHRoaXMudXJpKCk7XG4gIHZhciBwcm90b2NvbHMgPSB2b2lkKDApO1xuICB2YXIgb3B0cyA9IHtcbiAgICBhZ2VudDogdGhpcy5hZ2VudCxcbiAgICBwZXJNZXNzYWdlRGVmbGF0ZTogdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZVxuICB9O1xuXG4gIC8vIFNTTCBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICBvcHRzLnBmeCA9IHRoaXMucGZ4O1xuICBvcHRzLmtleSA9IHRoaXMua2V5O1xuICBvcHRzLnBhc3NwaHJhc2UgPSB0aGlzLnBhc3NwaHJhc2U7XG4gIG9wdHMuY2VydCA9IHRoaXMuY2VydDtcbiAgb3B0cy5jYSA9IHRoaXMuY2E7XG4gIG9wdHMuY2lwaGVycyA9IHRoaXMuY2lwaGVycztcbiAgb3B0cy5yZWplY3RVbmF1dGhvcml6ZWQgPSB0aGlzLnJlamVjdFVuYXV0aG9yaXplZDtcbiAgaWYgKHRoaXMuZXh0cmFIZWFkZXJzKSB7XG4gICAgb3B0cy5oZWFkZXJzID0gdGhpcy5leHRyYUhlYWRlcnM7XG4gIH1cblxuICB0aGlzLndzID0gQnJvd3NlcldlYlNvY2tldCA/IG5ldyBXZWJTb2NrZXQodXJpKSA6IG5ldyBXZWJTb2NrZXQodXJpLCBwcm90b2NvbHMsIG9wdHMpO1xuXG4gIGlmICh0aGlzLndzLmJpbmFyeVR5cGUgPT09IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSBmYWxzZTtcbiAgfVxuXG4gIGlmICh0aGlzLndzLnN1cHBvcnRzICYmIHRoaXMud3Muc3VwcG9ydHMuYmluYXJ5KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IHRydWU7XG4gICAgdGhpcy53cy5iaW5hcnlUeXBlID0gJ2J1ZmZlcic7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy53cy5iaW5hcnlUeXBlID0gJ2FycmF5YnVmZmVyJztcbiAgfVxuXG4gIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcnMoKTtcbn07XG5cbi8qKlxuICogQWRkcyBldmVudCBsaXN0ZW5lcnMgdG8gdGhlIHNvY2tldFxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbldTLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVycyA9IGZ1bmN0aW9uKCl7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLndzLm9ub3BlbiA9IGZ1bmN0aW9uKCl7XG4gICAgc2VsZi5vbk9wZW4oKTtcbiAgfTtcbiAgdGhpcy53cy5vbmNsb3NlID0gZnVuY3Rpb24oKXtcbiAgICBzZWxmLm9uQ2xvc2UoKTtcbiAgfTtcbiAgdGhpcy53cy5vbm1lc3NhZ2UgPSBmdW5jdGlvbihldil7XG4gICAgc2VsZi5vbkRhdGEoZXYuZGF0YSk7XG4gIH07XG4gIHRoaXMud3Mub25lcnJvciA9IGZ1bmN0aW9uKGUpe1xuICAgIHNlbGYub25FcnJvcignd2Vic29ja2V0IGVycm9yJywgZSk7XG4gIH07XG59O1xuXG4vKipcbiAqIE92ZXJyaWRlIGBvbkRhdGFgIHRvIHVzZSBhIHRpbWVyIG9uIGlPUy5cbiAqIFNlZTogaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vbWxvdWdocmFuLzIwNTIwMDZcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5pZiAoJ3VuZGVmaW5lZCcgIT0gdHlwZW9mIG5hdmlnYXRvclxuICAmJiAvaVBhZHxpUGhvbmV8aVBvZC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHtcbiAgV1MucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uKGRhdGEpe1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICBUcmFuc3BvcnQucHJvdG90eXBlLm9uRGF0YS5jYWxsKHNlbGYsIGRhdGEpO1xuICAgIH0sIDApO1xuICB9O1xufVxuXG4vKipcbiAqIFdyaXRlcyBkYXRhIHRvIHNvY2tldC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBvZiBwYWNrZXRzLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24ocGFja2V0cyl7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuXG4gIC8vIGVuY29kZVBhY2tldCBlZmZpY2llbnQgYXMgaXQgdXNlcyBXUyBmcmFtaW5nXG4gIC8vIG5vIG5lZWQgZm9yIGVuY29kZVBheWxvYWRcbiAgdmFyIHRvdGFsID0gcGFja2V0cy5sZW5ndGg7XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdG90YWw7IGkgPCBsOyBpKyspIHtcbiAgICAoZnVuY3Rpb24ocGFja2V0KSB7XG4gICAgICBwYXJzZXIuZW5jb2RlUGFja2V0KHBhY2tldCwgc2VsZi5zdXBwb3J0c0JpbmFyeSwgZnVuY3Rpb24oZGF0YSkge1xuICAgICAgICBpZiAoIUJyb3dzZXJXZWJTb2NrZXQpIHtcbiAgICAgICAgICAvLyBhbHdheXMgY3JlYXRlIGEgbmV3IG9iamVjdCAoR0gtNDM3KVxuICAgICAgICAgIHZhciBvcHRzID0ge307XG4gICAgICAgICAgaWYgKHBhY2tldC5vcHRpb25zKSB7XG4gICAgICAgICAgICBvcHRzLmNvbXByZXNzID0gcGFja2V0Lm9wdGlvbnMuY29tcHJlc3M7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHNlbGYucGVyTWVzc2FnZURlZmxhdGUpIHtcbiAgICAgICAgICAgIHZhciBsZW4gPSAnc3RyaW5nJyA9PSB0eXBlb2YgZGF0YSA/IGdsb2JhbC5CdWZmZXIuYnl0ZUxlbmd0aChkYXRhKSA6IGRhdGEubGVuZ3RoO1xuICAgICAgICAgICAgaWYgKGxlbiA8IHNlbGYucGVyTWVzc2FnZURlZmxhdGUudGhyZXNob2xkKSB7XG4gICAgICAgICAgICAgIG9wdHMuY29tcHJlc3MgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvL1NvbWV0aW1lcyB0aGUgd2Vic29ja2V0IGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkIGJ1dCB0aGUgYnJvd3NlciBkaWRuJ3RcbiAgICAgICAgLy9oYXZlIGEgY2hhbmNlIG9mIGluZm9ybWluZyB1cyBhYm91dCBpdCB5ZXQsIGluIHRoYXQgY2FzZSBzZW5kIHdpbGxcbiAgICAgICAgLy90aHJvdyBhbiBlcnJvclxuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChCcm93c2VyV2ViU29ja2V0KSB7XG4gICAgICAgICAgICAvLyBUeXBlRXJyb3IgaXMgdGhyb3duIHdoZW4gcGFzc2luZyB0aGUgc2Vjb25kIGFyZ3VtZW50IG9uIFNhZmFyaVxuICAgICAgICAgICAgc2VsZi53cy5zZW5kKGRhdGEpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzZWxmLndzLnNlbmQoZGF0YSwgb3B0cyk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgICBkZWJ1Zygnd2Vic29ja2V0IGNsb3NlZCBiZWZvcmUgb25jbG9zZSBldmVudCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLS10b3RhbCB8fCBkb25lKCk7XG4gICAgICB9KTtcbiAgICB9KShwYWNrZXRzW2ldKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRvbmUoKXtcbiAgICBzZWxmLmVtaXQoJ2ZsdXNoJyk7XG5cbiAgICAvLyBmYWtlIGRyYWluXG4gICAgLy8gZGVmZXIgdG8gbmV4dCB0aWNrIHRvIGFsbG93IFNvY2tldCB0byBjbGVhciB3cml0ZUJ1ZmZlclxuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIHNlbGYud3JpdGFibGUgPSB0cnVlO1xuICAgICAgc2VsZi5lbWl0KCdkcmFpbicpO1xuICAgIH0sIDApO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGNsb3NlXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLm9uQ2xvc2UgPSBmdW5jdGlvbigpe1xuICBUcmFuc3BvcnQucHJvdG90eXBlLm9uQ2xvc2UuY2FsbCh0aGlzKTtcbn07XG5cbi8qKlxuICogQ2xvc2VzIHNvY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5XUy5wcm90b3R5cGUuZG9DbG9zZSA9IGZ1bmN0aW9uKCl7XG4gIGlmICh0eXBlb2YgdGhpcy53cyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0aGlzLndzLmNsb3NlKCk7XG4gIH1cbn07XG5cbi8qKlxuICogR2VuZXJhdGVzIHVyaSBmb3IgY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5XUy5wcm90b3R5cGUudXJpID0gZnVuY3Rpb24oKXtcbiAgdmFyIHF1ZXJ5ID0gdGhpcy5xdWVyeSB8fCB7fTtcbiAgdmFyIHNjaGVtYSA9IHRoaXMuc2VjdXJlID8gJ3dzcycgOiAnd3MnO1xuICB2YXIgcG9ydCA9ICcnO1xuXG4gIC8vIGF2b2lkIHBvcnQgaWYgZGVmYXVsdCBmb3Igc2NoZW1hXG4gIGlmICh0aGlzLnBvcnQgJiYgKCgnd3NzJyA9PSBzY2hlbWEgJiYgdGhpcy5wb3J0ICE9IDQ0MylcbiAgICB8fCAoJ3dzJyA9PSBzY2hlbWEgJiYgdGhpcy5wb3J0ICE9IDgwKSkpIHtcbiAgICBwb3J0ID0gJzonICsgdGhpcy5wb3J0O1xuICB9XG5cbiAgLy8gYXBwZW5kIHRpbWVzdGFtcCB0byBVUklcbiAgaWYgKHRoaXMudGltZXN0YW1wUmVxdWVzdHMpIHtcbiAgICBxdWVyeVt0aGlzLnRpbWVzdGFtcFBhcmFtXSA9IHllYXN0KCk7XG4gIH1cblxuICAvLyBjb21tdW5pY2F0ZSBiaW5hcnkgc3VwcG9ydCBjYXBhYmlsaXRpZXNcbiAgaWYgKCF0aGlzLnN1cHBvcnRzQmluYXJ5KSB7XG4gICAgcXVlcnkuYjY0ID0gMTtcbiAgfVxuXG4gIHF1ZXJ5ID0gcGFyc2Vxcy5lbmNvZGUocXVlcnkpO1xuXG4gIC8vIHByZXBlbmQgPyB0byBxdWVyeVxuICBpZiAocXVlcnkubGVuZ3RoKSB7XG4gICAgcXVlcnkgPSAnPycgKyBxdWVyeTtcbiAgfVxuXG4gIHZhciBpcHY2ID0gdGhpcy5ob3N0bmFtZS5pbmRleE9mKCc6JykgIT09IC0xO1xuICByZXR1cm4gc2NoZW1hICsgJzovLycgKyAoaXB2NiA/ICdbJyArIHRoaXMuaG9zdG5hbWUgKyAnXScgOiB0aGlzLmhvc3RuYW1lKSArIHBvcnQgKyB0aGlzLnBhdGggKyBxdWVyeTtcbn07XG5cbi8qKlxuICogRmVhdHVyZSBkZXRlY3Rpb24gZm9yIFdlYlNvY2tldC5cbiAqXG4gKiBAcmV0dXJuIHtCb29sZWFufSB3aGV0aGVyIHRoaXMgdHJhbnNwb3J0IGlzIGF2YWlsYWJsZS5cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuV1MucHJvdG90eXBlLmNoZWNrID0gZnVuY3Rpb24oKXtcbiAgcmV0dXJuICEhV2ViU29ja2V0ICYmICEoJ19faW5pdGlhbGl6ZScgaW4gV2ViU29ja2V0ICYmIHRoaXMubmFtZSA9PT0gV1MucHJvdG90eXBlLm5hbWUpO1xufTtcbiIsIi8vIGJyb3dzZXIgc2hpbSBmb3IgeG1saHR0cHJlcXVlc3QgbW9kdWxlXG52YXIgaGFzQ09SUyA9IHJlcXVpcmUoJ2hhcy1jb3JzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ob3B0cykge1xuICB2YXIgeGRvbWFpbiA9IG9wdHMueGRvbWFpbjtcblxuICAvLyBzY2hlbWUgbXVzdCBiZSBzYW1lIHdoZW4gdXNpZ24gWERvbWFpblJlcXVlc3RcbiAgLy8gaHR0cDovL2Jsb2dzLm1zZG4uY29tL2IvaWVpbnRlcm5hbHMvYXJjaGl2ZS8yMDEwLzA1LzEzL3hkb21haW5yZXF1ZXN0LXJlc3RyaWN0aW9ucy1saW1pdGF0aW9ucy1hbmQtd29ya2Fyb3VuZHMuYXNweFxuICB2YXIgeHNjaGVtZSA9IG9wdHMueHNjaGVtZTtcblxuICAvLyBYRG9tYWluUmVxdWVzdCBoYXMgYSBmbG93IG9mIG5vdCBzZW5kaW5nIGNvb2tpZSwgdGhlcmVmb3JlIGl0IHNob3VsZCBiZSBkaXNhYmxlZCBhcyBhIGRlZmF1bHQuXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9BdXRvbWF0dGljL2VuZ2luZS5pby1jbGllbnQvcHVsbC8yMTdcbiAgdmFyIGVuYWJsZXNYRFIgPSBvcHRzLmVuYWJsZXNYRFI7XG5cbiAgLy8gWE1MSHR0cFJlcXVlc3QgY2FuIGJlIGRpc2FibGVkIG9uIElFXG4gIHRyeSB7XG4gICAgaWYgKCd1bmRlZmluZWQnICE9IHR5cGVvZiBYTUxIdHRwUmVxdWVzdCAmJiAoIXhkb21haW4gfHwgaGFzQ09SUykpIHtcbiAgICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHsgfVxuXG4gIC8vIFVzZSBYRG9tYWluUmVxdWVzdCBmb3IgSUU4IGlmIGVuYWJsZXNYRFIgaXMgdHJ1ZVxuICAvLyBiZWNhdXNlIGxvYWRpbmcgYmFyIGtlZXBzIGZsYXNoaW5nIHdoZW4gdXNpbmcganNvbnAtcG9sbGluZ1xuICAvLyBodHRwczovL2dpdGh1Yi5jb20veXVqaW9zYWthL3NvY2tlLmlvLWllOC1sb2FkaW5nLWV4YW1wbGVcbiAgdHJ5IHtcbiAgICBpZiAoJ3VuZGVmaW5lZCcgIT0gdHlwZW9mIFhEb21haW5SZXF1ZXN0ICYmICF4c2NoZW1lICYmIGVuYWJsZXNYRFIpIHtcbiAgICAgIHJldHVybiBuZXcgWERvbWFpblJlcXVlc3QoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHsgfVxuXG4gIGlmICgheGRvbWFpbikge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01pY3Jvc29mdC5YTUxIVFRQJyk7XG4gICAgfSBjYXRjaChlKSB7IH1cbiAgfVxufVxuIiwiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG52YXIgaGFzQmluYXJ5ID0gcmVxdWlyZSgnaGFzLWJpbmFyeScpO1xudmFyIHNsaWNlQnVmZmVyID0gcmVxdWlyZSgnYXJyYXlidWZmZXIuc2xpY2UnKTtcbnZhciBiYXNlNjRlbmNvZGVyID0gcmVxdWlyZSgnYmFzZTY0LWFycmF5YnVmZmVyJyk7XG52YXIgYWZ0ZXIgPSByZXF1aXJlKCdhZnRlcicpO1xudmFyIHV0ZjggPSByZXF1aXJlKCd1dGY4Jyk7XG5cbi8qKlxuICogQ2hlY2sgaWYgd2UgYXJlIHJ1bm5pbmcgYW4gYW5kcm9pZCBicm93c2VyLiBUaGF0IHJlcXVpcmVzIHVzIHRvIHVzZVxuICogQXJyYXlCdWZmZXIgd2l0aCBwb2xsaW5nIHRyYW5zcG9ydHMuLi5cbiAqXG4gKiBodHRwOi8vZ2hpbmRhLm5ldC9qcGVnLWJsb2ItYWpheC1hbmRyb2lkL1xuICovXG5cbnZhciBpc0FuZHJvaWQgPSBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpO1xuXG4vKipcbiAqIENoZWNrIGlmIHdlIGFyZSBydW5uaW5nIGluIFBoYW50b21KUy5cbiAqIFVwbG9hZGluZyBhIEJsb2Igd2l0aCBQaGFudG9tSlMgZG9lcyBub3Qgd29yayBjb3JyZWN0bHksIGFzIHJlcG9ydGVkIGhlcmU6XG4gKiBodHRwczovL2dpdGh1Yi5jb20vYXJpeWEvcGhhbnRvbWpzL2lzc3Vlcy8xMTM5NVxuICogQHR5cGUgYm9vbGVhblxuICovXG52YXIgaXNQaGFudG9tSlMgPSAvUGhhbnRvbUpTL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcblxuLyoqXG4gKiBXaGVuIHRydWUsIGF2b2lkcyB1c2luZyBCbG9icyB0byBlbmNvZGUgcGF5bG9hZHMuXG4gKiBAdHlwZSBib29sZWFuXG4gKi9cbnZhciBkb250U2VuZEJsb2JzID0gaXNBbmRyb2lkIHx8IGlzUGhhbnRvbUpTO1xuXG4vKipcbiAqIEN1cnJlbnQgcHJvdG9jb2wgdmVyc2lvbi5cbiAqL1xuXG5leHBvcnRzLnByb3RvY29sID0gMztcblxuLyoqXG4gKiBQYWNrZXQgdHlwZXMuXG4gKi9cblxudmFyIHBhY2tldHMgPSBleHBvcnRzLnBhY2tldHMgPSB7XG4gICAgb3BlbjogICAgIDAgICAgLy8gbm9uLXdzXG4gICwgY2xvc2U6ICAgIDEgICAgLy8gbm9uLXdzXG4gICwgcGluZzogICAgIDJcbiAgLCBwb25nOiAgICAgM1xuICAsIG1lc3NhZ2U6ICA0XG4gICwgdXBncmFkZTogIDVcbiAgLCBub29wOiAgICAgNlxufTtcblxudmFyIHBhY2tldHNsaXN0ID0ga2V5cyhwYWNrZXRzKTtcblxuLyoqXG4gKiBQcmVtYWRlIGVycm9yIHBhY2tldC5cbiAqL1xuXG52YXIgZXJyID0geyB0eXBlOiAnZXJyb3InLCBkYXRhOiAncGFyc2VyIGVycm9yJyB9O1xuXG4vKipcbiAqIENyZWF0ZSBhIGJsb2IgYXBpIGV2ZW4gZm9yIGJsb2IgYnVpbGRlciB3aGVuIHZlbmRvciBwcmVmaXhlcyBleGlzdFxuICovXG5cbnZhciBCbG9iID0gcmVxdWlyZSgnYmxvYicpO1xuXG4vKipcbiAqIEVuY29kZXMgYSBwYWNrZXQuXG4gKlxuICogICAgIDxwYWNrZXQgdHlwZSBpZD4gWyA8ZGF0YT4gXVxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogICAgIDVoZWxsbyB3b3JsZFxuICogICAgIDNcbiAqICAgICA0XG4gKlxuICogQmluYXJ5IGlzIGVuY29kZWQgaW4gYW4gaWRlbnRpY2FsIHByaW5jaXBsZVxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZW5jb2RlUGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIHV0ZjhlbmNvZGUsIGNhbGxiYWNrKSB7XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBzdXBwb3J0c0JpbmFyeSkge1xuICAgIGNhbGxiYWNrID0gc3VwcG9ydHNCaW5hcnk7XG4gICAgc3VwcG9ydHNCaW5hcnkgPSBmYWxzZTtcbiAgfVxuXG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiB1dGY4ZW5jb2RlKSB7XG4gICAgY2FsbGJhY2sgPSB1dGY4ZW5jb2RlO1xuICAgIHV0ZjhlbmNvZGUgPSBudWxsO1xuICB9XG5cbiAgdmFyIGRhdGEgPSAocGFja2V0LmRhdGEgPT09IHVuZGVmaW5lZClcbiAgICA/IHVuZGVmaW5lZFxuICAgIDogcGFja2V0LmRhdGEuYnVmZmVyIHx8IHBhY2tldC5kYXRhO1xuXG4gIGlmIChnbG9iYWwuQXJyYXlCdWZmZXIgJiYgZGF0YSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIGVuY29kZUFycmF5QnVmZmVyKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKTtcbiAgfSBlbHNlIGlmIChCbG9iICYmIGRhdGEgaW5zdGFuY2VvZiBnbG9iYWwuQmxvYikge1xuICAgIHJldHVybiBlbmNvZGVCbG9iKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8vIG1pZ2h0IGJlIGFuIG9iamVjdCB3aXRoIHsgYmFzZTY0OiB0cnVlLCBkYXRhOiBkYXRhQXNCYXNlNjRTdHJpbmcgfVxuICBpZiAoZGF0YSAmJiBkYXRhLmJhc2U2NCkge1xuICAgIHJldHVybiBlbmNvZGVCYXNlNjRPYmplY3QocGFja2V0LCBjYWxsYmFjayk7XG4gIH1cblxuICAvLyBTZW5kaW5nIGRhdGEgYXMgYSB1dGYtOCBzdHJpbmdcbiAgdmFyIGVuY29kZWQgPSBwYWNrZXRzW3BhY2tldC50eXBlXTtcblxuICAvLyBkYXRhIGZyYWdtZW50IGlzIG9wdGlvbmFsXG4gIGlmICh1bmRlZmluZWQgIT09IHBhY2tldC5kYXRhKSB7XG4gICAgZW5jb2RlZCArPSB1dGY4ZW5jb2RlID8gdXRmOC5lbmNvZGUoU3RyaW5nKHBhY2tldC5kYXRhKSkgOiBTdHJpbmcocGFja2V0LmRhdGEpO1xuICB9XG5cbiAgcmV0dXJuIGNhbGxiYWNrKCcnICsgZW5jb2RlZCk7XG5cbn07XG5cbmZ1bmN0aW9uIGVuY29kZUJhc2U2NE9iamVjdChwYWNrZXQsIGNhbGxiYWNrKSB7XG4gIC8vIHBhY2tldCBkYXRhIGlzIGFuIG9iamVjdCB7IGJhc2U2NDogdHJ1ZSwgZGF0YTogZGF0YUFzQmFzZTY0U3RyaW5nIH1cbiAgdmFyIG1lc3NhZ2UgPSAnYicgKyBleHBvcnRzLnBhY2tldHNbcGFja2V0LnR5cGVdICsgcGFja2V0LmRhdGEuZGF0YTtcbiAgcmV0dXJuIGNhbGxiYWNrKG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIEVuY29kZSBwYWNrZXQgaGVscGVycyBmb3IgYmluYXJ5IHR5cGVzXG4gKi9cblxuZnVuY3Rpb24gZW5jb2RlQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgaWYgKCFzdXBwb3J0c0JpbmFyeSkge1xuICAgIHJldHVybiBleHBvcnRzLmVuY29kZUJhc2U2NFBhY2tldChwYWNrZXQsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIHZhciBkYXRhID0gcGFja2V0LmRhdGE7XG4gIHZhciBjb250ZW50QXJyYXkgPSBuZXcgVWludDhBcnJheShkYXRhKTtcbiAgdmFyIHJlc3VsdEJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDEgKyBkYXRhLmJ5dGVMZW5ndGgpO1xuXG4gIHJlc3VsdEJ1ZmZlclswXSA9IHBhY2tldHNbcGFja2V0LnR5cGVdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbnRlbnRBcnJheS5sZW5ndGg7IGkrKykge1xuICAgIHJlc3VsdEJ1ZmZlcltpKzFdID0gY29udGVudEFycmF5W2ldO1xuICB9XG5cbiAgcmV0dXJuIGNhbGxiYWNrKHJlc3VsdEJ1ZmZlci5idWZmZXIpO1xufVxuXG5mdW5jdGlvbiBlbmNvZGVCbG9iQXNBcnJheUJ1ZmZlcihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjaykge1xuICBpZiAoIXN1cHBvcnRzQmluYXJ5KSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuZW5jb2RlQmFzZTY0UGFja2V0KHBhY2tldCwgY2FsbGJhY2spO1xuICB9XG5cbiAgdmFyIGZyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgZnIub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgcGFja2V0LmRhdGEgPSBmci5yZXN1bHQ7XG4gICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgdHJ1ZSwgY2FsbGJhY2spO1xuICB9O1xuICByZXR1cm4gZnIucmVhZEFzQXJyYXlCdWZmZXIocGFja2V0LmRhdGEpO1xufVxuXG5mdW5jdGlvbiBlbmNvZGVCbG9iKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKSB7XG4gIGlmICghc3VwcG9ydHNCaW5hcnkpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQocGFja2V0LCBjYWxsYmFjayk7XG4gIH1cblxuICBpZiAoZG9udFNlbmRCbG9icykge1xuICAgIHJldHVybiBlbmNvZGVCbG9iQXNBcnJheUJ1ZmZlcihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjayk7XG4gIH1cblxuICB2YXIgbGVuZ3RoID0gbmV3IFVpbnQ4QXJyYXkoMSk7XG4gIGxlbmd0aFswXSA9IHBhY2tldHNbcGFja2V0LnR5cGVdO1xuICB2YXIgYmxvYiA9IG5ldyBCbG9iKFtsZW5ndGguYnVmZmVyLCBwYWNrZXQuZGF0YV0pO1xuXG4gIHJldHVybiBjYWxsYmFjayhibG9iKTtcbn1cblxuLyoqXG4gKiBFbmNvZGVzIGEgcGFja2V0IHdpdGggYmluYXJ5IGRhdGEgaW4gYSBiYXNlNjQgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldCwgaGFzIGB0eXBlYCBhbmQgYGRhdGFgXG4gKiBAcmV0dXJuIHtTdHJpbmd9IGJhc2U2NCBlbmNvZGVkIG1lc3NhZ2VcbiAqL1xuXG5leHBvcnRzLmVuY29kZUJhc2U2NFBhY2tldCA9IGZ1bmN0aW9uKHBhY2tldCwgY2FsbGJhY2spIHtcbiAgdmFyIG1lc3NhZ2UgPSAnYicgKyBleHBvcnRzLnBhY2tldHNbcGFja2V0LnR5cGVdO1xuICBpZiAoQmxvYiAmJiBwYWNrZXQuZGF0YSBpbnN0YW5jZW9mIGdsb2JhbC5CbG9iKSB7XG4gICAgdmFyIGZyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICBmci5vbmxvYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBiNjQgPSBmci5yZXN1bHQuc3BsaXQoJywnKVsxXTtcbiAgICAgIGNhbGxiYWNrKG1lc3NhZ2UgKyBiNjQpO1xuICAgIH07XG4gICAgcmV0dXJuIGZyLnJlYWRBc0RhdGFVUkwocGFja2V0LmRhdGEpO1xuICB9XG5cbiAgdmFyIGI2NGRhdGE7XG4gIHRyeSB7XG4gICAgYjY0ZGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgbmV3IFVpbnQ4QXJyYXkocGFja2V0LmRhdGEpKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIGlQaG9uZSBTYWZhcmkgZG9lc24ndCBsZXQgeW91IGFwcGx5IHdpdGggdHlwZWQgYXJyYXlzXG4gICAgdmFyIHR5cGVkID0gbmV3IFVpbnQ4QXJyYXkocGFja2V0LmRhdGEpO1xuICAgIHZhciBiYXNpYyA9IG5ldyBBcnJheSh0eXBlZC5sZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdHlwZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGJhc2ljW2ldID0gdHlwZWRbaV07XG4gICAgfVxuICAgIGI2NGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGJhc2ljKTtcbiAgfVxuICBtZXNzYWdlICs9IGdsb2JhbC5idG9hKGI2NGRhdGEpO1xuICByZXR1cm4gY2FsbGJhY2sobWVzc2FnZSk7XG59O1xuXG4vKipcbiAqIERlY29kZXMgYSBwYWNrZXQuIENoYW5nZXMgZm9ybWF0IHRvIEJsb2IgaWYgcmVxdWVzdGVkLlxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCBgdHlwZWAgYW5kIGBkYXRhYCAoaWYgYW55KVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZXhwb3J0cy5kZWNvZGVQYWNrZXQgPSBmdW5jdGlvbiAoZGF0YSwgYmluYXJ5VHlwZSwgdXRmOGRlY29kZSkge1xuICAvLyBTdHJpbmcgZGF0YVxuICBpZiAodHlwZW9mIGRhdGEgPT0gJ3N0cmluZycgfHwgZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKGRhdGEuY2hhckF0KDApID09ICdiJykge1xuICAgICAgcmV0dXJuIGV4cG9ydHMuZGVjb2RlQmFzZTY0UGFja2V0KGRhdGEuc3Vic3RyKDEpLCBiaW5hcnlUeXBlKTtcbiAgICB9XG5cbiAgICBpZiAodXRmOGRlY29kZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZGF0YSA9IHV0ZjguZGVjb2RlKGRhdGEpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZXJyO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgdHlwZSA9IGRhdGEuY2hhckF0KDApO1xuXG4gICAgaWYgKE51bWJlcih0eXBlKSAhPSB0eXBlIHx8ICFwYWNrZXRzbGlzdFt0eXBlXSkge1xuICAgICAgcmV0dXJuIGVycjtcbiAgICB9XG5cbiAgICBpZiAoZGF0YS5sZW5ndGggPiAxKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBwYWNrZXRzbGlzdFt0eXBlXSwgZGF0YTogZGF0YS5zdWJzdHJpbmcoMSkgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHsgdHlwZTogcGFja2V0c2xpc3RbdHlwZV0gfTtcbiAgICB9XG4gIH1cblxuICB2YXIgYXNBcnJheSA9IG5ldyBVaW50OEFycmF5KGRhdGEpO1xuICB2YXIgdHlwZSA9IGFzQXJyYXlbMF07XG4gIHZhciByZXN0ID0gc2xpY2VCdWZmZXIoZGF0YSwgMSk7XG4gIGlmIChCbG9iICYmIGJpbmFyeVR5cGUgPT09ICdibG9iJykge1xuICAgIHJlc3QgPSBuZXcgQmxvYihbcmVzdF0pO1xuICB9XG4gIHJldHVybiB7IHR5cGU6IHBhY2tldHNsaXN0W3R5cGVdLCBkYXRhOiByZXN0IH07XG59O1xuXG4vKipcbiAqIERlY29kZXMgYSBwYWNrZXQgZW5jb2RlZCBpbiBhIGJhc2U2NCBzdHJpbmdcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gYmFzZTY0IGVuY29kZWQgbWVzc2FnZVxuICogQHJldHVybiB7T2JqZWN0fSB3aXRoIGB0eXBlYCBhbmQgYGRhdGFgIChpZiBhbnkpXG4gKi9cblxuZXhwb3J0cy5kZWNvZGVCYXNlNjRQYWNrZXQgPSBmdW5jdGlvbihtc2csIGJpbmFyeVR5cGUpIHtcbiAgdmFyIHR5cGUgPSBwYWNrZXRzbGlzdFttc2cuY2hhckF0KDApXTtcbiAgaWYgKCFnbG9iYWwuQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4geyB0eXBlOiB0eXBlLCBkYXRhOiB7IGJhc2U2NDogdHJ1ZSwgZGF0YTogbXNnLnN1YnN0cigxKSB9IH07XG4gIH1cblxuICB2YXIgZGF0YSA9IGJhc2U2NGVuY29kZXIuZGVjb2RlKG1zZy5zdWJzdHIoMSkpO1xuXG4gIGlmIChiaW5hcnlUeXBlID09PSAnYmxvYicgJiYgQmxvYikge1xuICAgIGRhdGEgPSBuZXcgQmxvYihbZGF0YV0pO1xuICB9XG5cbiAgcmV0dXJuIHsgdHlwZTogdHlwZSwgZGF0YTogZGF0YSB9O1xufTtcblxuLyoqXG4gKiBFbmNvZGVzIG11bHRpcGxlIG1lc3NhZ2VzIChwYXlsb2FkKS5cbiAqXG4gKiAgICAgPGxlbmd0aD46ZGF0YVxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogICAgIDExOmhlbGxvIHdvcmxkMjpoaVxuICpcbiAqIElmIGFueSBjb250ZW50cyBhcmUgYmluYXJ5LCB0aGV5IHdpbGwgYmUgZW5jb2RlZCBhcyBiYXNlNjQgc3RyaW5ncy4gQmFzZTY0XG4gKiBlbmNvZGVkIHN0cmluZ3MgYXJlIG1hcmtlZCB3aXRoIGEgYiBiZWZvcmUgdGhlIGxlbmd0aCBzcGVjaWZpZXJcbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBwYWNrZXRzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5leHBvcnRzLmVuY29kZVBheWxvYWQgPSBmdW5jdGlvbiAocGFja2V0cywgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKSB7XG4gIGlmICh0eXBlb2Ygc3VwcG9ydHNCaW5hcnkgPT0gJ2Z1bmN0aW9uJykge1xuICAgIGNhbGxiYWNrID0gc3VwcG9ydHNCaW5hcnk7XG4gICAgc3VwcG9ydHNCaW5hcnkgPSBudWxsO1xuICB9XG5cbiAgdmFyIGlzQmluYXJ5ID0gaGFzQmluYXJ5KHBhY2tldHMpO1xuXG4gIGlmIChzdXBwb3J0c0JpbmFyeSAmJiBpc0JpbmFyeSkge1xuICAgIGlmIChCbG9iICYmICFkb250U2VuZEJsb2JzKSB7XG4gICAgICByZXR1cm4gZXhwb3J0cy5lbmNvZGVQYXlsb2FkQXNCbG9iKHBhY2tldHMsIGNhbGxiYWNrKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXhwb3J0cy5lbmNvZGVQYXlsb2FkQXNBcnJheUJ1ZmZlcihwYWNrZXRzLCBjYWxsYmFjayk7XG4gIH1cblxuICBpZiAoIXBhY2tldHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGNhbGxiYWNrKCcwOicpO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0TGVuZ3RoSGVhZGVyKG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gbWVzc2FnZS5sZW5ndGggKyAnOicgKyBtZXNzYWdlO1xuICB9XG5cbiAgZnVuY3Rpb24gZW5jb2RlT25lKHBhY2tldCwgZG9uZUNhbGxiYWNrKSB7XG4gICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCAhaXNCaW5hcnkgPyBmYWxzZSA6IHN1cHBvcnRzQmluYXJ5LCB0cnVlLCBmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgICBkb25lQ2FsbGJhY2sobnVsbCwgc2V0TGVuZ3RoSGVhZGVyKG1lc3NhZ2UpKTtcbiAgICB9KTtcbiAgfVxuXG4gIG1hcChwYWNrZXRzLCBlbmNvZGVPbmUsIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICAgIHJldHVybiBjYWxsYmFjayhyZXN1bHRzLmpvaW4oJycpKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEFzeW5jIGFycmF5IG1hcCB1c2luZyBhZnRlclxuICovXG5cbmZ1bmN0aW9uIG1hcChhcnksIGVhY2gsIGRvbmUpIHtcbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheShhcnkubGVuZ3RoKTtcbiAgdmFyIG5leHQgPSBhZnRlcihhcnkubGVuZ3RoLCBkb25lKTtcblxuICB2YXIgZWFjaFdpdGhJbmRleCA9IGZ1bmN0aW9uKGksIGVsLCBjYikge1xuICAgIGVhY2goZWwsIGZ1bmN0aW9uKGVycm9yLCBtc2cpIHtcbiAgICAgIHJlc3VsdFtpXSA9IG1zZztcbiAgICAgIGNiKGVycm9yLCByZXN1bHQpO1xuICAgIH0pO1xuICB9O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgZWFjaFdpdGhJbmRleChpLCBhcnlbaV0sIG5leHQpO1xuICB9XG59XG5cbi8qXG4gKiBEZWNvZGVzIGRhdGEgd2hlbiBhIHBheWxvYWQgaXMgbWF5YmUgZXhwZWN0ZWQuIFBvc3NpYmxlIGJpbmFyeSBjb250ZW50cyBhcmVcbiAqIGRlY29kZWQgZnJvbSB0aGVpciBiYXNlNjQgcmVwcmVzZW50YXRpb25cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSwgY2FsbGJhY2sgbWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZGVjb2RlUGF5bG9hZCA9IGZ1bmN0aW9uIChkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIGRhdGEgIT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5kZWNvZGVQYXlsb2FkQXNCaW5hcnkoZGF0YSwgYmluYXJ5VHlwZSwgY2FsbGJhY2spO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBiaW5hcnlUeXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBiaW5hcnlUeXBlO1xuICAgIGJpbmFyeVR5cGUgPSBudWxsO1xuICB9XG5cbiAgdmFyIHBhY2tldDtcbiAgaWYgKGRhdGEgPT0gJycpIHtcbiAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG4gIH1cblxuICB2YXIgbGVuZ3RoID0gJydcbiAgICAsIG4sIG1zZztcblxuICBmb3IgKHZhciBpID0gMCwgbCA9IGRhdGEubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgdmFyIGNociA9IGRhdGEuY2hhckF0KGkpO1xuXG4gICAgaWYgKCc6JyAhPSBjaHIpIHtcbiAgICAgIGxlbmd0aCArPSBjaHI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICgnJyA9PSBsZW5ndGggfHwgKGxlbmd0aCAhPSAobiA9IE51bWJlcihsZW5ndGgpKSkpIHtcbiAgICAgICAgLy8gcGFyc2VyIGVycm9yIC0gaWdub3JpbmcgcGF5bG9hZFxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgICAgIH1cblxuICAgICAgbXNnID0gZGF0YS5zdWJzdHIoaSArIDEsIG4pO1xuXG4gICAgICBpZiAobGVuZ3RoICE9IG1zZy5sZW5ndGgpIHtcbiAgICAgICAgLy8gcGFyc2VyIGVycm9yIC0gaWdub3JpbmcgcGF5bG9hZFxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1zZy5sZW5ndGgpIHtcbiAgICAgICAgcGFja2V0ID0gZXhwb3J0cy5kZWNvZGVQYWNrZXQobXNnLCBiaW5hcnlUeXBlLCB0cnVlKTtcblxuICAgICAgICBpZiAoZXJyLnR5cGUgPT0gcGFja2V0LnR5cGUgJiYgZXJyLmRhdGEgPT0gcGFja2V0LmRhdGEpIHtcbiAgICAgICAgICAvLyBwYXJzZXIgZXJyb3IgaW4gaW5kaXZpZHVhbCBwYWNrZXQgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmV0ID0gY2FsbGJhY2socGFja2V0LCBpICsgbiwgbCk7XG4gICAgICAgIGlmIChmYWxzZSA9PT0gcmV0KSByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGFkdmFuY2UgY3Vyc29yXG4gICAgICBpICs9IG47XG4gICAgICBsZW5ndGggPSAnJztcbiAgICB9XG4gIH1cblxuICBpZiAobGVuZ3RoICE9ICcnKSB7XG4gICAgLy8gcGFyc2VyIGVycm9yIC0gaWdub3JpbmcgcGF5bG9hZFxuICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICB9XG5cbn07XG5cbi8qKlxuICogRW5jb2RlcyBtdWx0aXBsZSBtZXNzYWdlcyAocGF5bG9hZCkgYXMgYmluYXJ5LlxuICpcbiAqIDwxID0gYmluYXJ5LCAwID0gc3RyaW5nPjxudW1iZXIgZnJvbSAwLTk+PG51bWJlciBmcm9tIDAtOT5bLi4uXTxudW1iZXJcbiAqIDI1NT48ZGF0YT5cbiAqXG4gKiBFeGFtcGxlOlxuICogMSAzIDI1NSAxIDIgMywgaWYgdGhlIGJpbmFyeSBjb250ZW50cyBhcmUgaW50ZXJwcmV0ZWQgYXMgOCBiaXQgaW50ZWdlcnNcbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBwYWNrZXRzXG4gKiBAcmV0dXJuIHtBcnJheUJ1ZmZlcn0gZW5jb2RlZCBwYXlsb2FkXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5leHBvcnRzLmVuY29kZVBheWxvYWRBc0FycmF5QnVmZmVyID0gZnVuY3Rpb24ocGFja2V0cywgY2FsbGJhY2spIHtcbiAgaWYgKCFwYWNrZXRzLmxlbmd0aCkge1xuICAgIHJldHVybiBjYWxsYmFjayhuZXcgQXJyYXlCdWZmZXIoMCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gZW5jb2RlT25lKHBhY2tldCwgZG9uZUNhbGxiYWNrKSB7XG4gICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCB0cnVlLCB0cnVlLCBmdW5jdGlvbihkYXRhKSB7XG4gICAgICByZXR1cm4gZG9uZUNhbGxiYWNrKG51bGwsIGRhdGEpO1xuICAgIH0pO1xuICB9XG5cbiAgbWFwKHBhY2tldHMsIGVuY29kZU9uZSwgZnVuY3Rpb24oZXJyLCBlbmNvZGVkUGFja2V0cykge1xuICAgIHZhciB0b3RhbExlbmd0aCA9IGVuY29kZWRQYWNrZXRzLnJlZHVjZShmdW5jdGlvbihhY2MsIHApIHtcbiAgICAgIHZhciBsZW47XG4gICAgICBpZiAodHlwZW9mIHAgPT09ICdzdHJpbmcnKXtcbiAgICAgICAgbGVuID0gcC5sZW5ndGg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZW4gPSBwLmJ5dGVMZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjICsgbGVuLnRvU3RyaW5nKCkubGVuZ3RoICsgbGVuICsgMjsgLy8gc3RyaW5nL2JpbmFyeSBpZGVudGlmaWVyICsgc2VwYXJhdG9yID0gMlxuICAgIH0sIDApO1xuXG4gICAgdmFyIHJlc3VsdEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkodG90YWxMZW5ndGgpO1xuXG4gICAgdmFyIGJ1ZmZlckluZGV4ID0gMDtcbiAgICBlbmNvZGVkUGFja2V0cy5mb3JFYWNoKGZ1bmN0aW9uKHApIHtcbiAgICAgIHZhciBpc1N0cmluZyA9IHR5cGVvZiBwID09PSAnc3RyaW5nJztcbiAgICAgIHZhciBhYiA9IHA7XG4gICAgICBpZiAoaXNTdHJpbmcpIHtcbiAgICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShwLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZpZXdbaV0gPSBwLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIH1cbiAgICAgICAgYWIgPSB2aWV3LmJ1ZmZlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzU3RyaW5nKSB7IC8vIG5vdCB0cnVlIGJpbmFyeVxuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IDA7XG4gICAgICB9IGVsc2UgeyAvLyB0cnVlIGJpbmFyeVxuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IDE7XG4gICAgICB9XG5cbiAgICAgIHZhciBsZW5TdHIgPSBhYi5ieXRlTGVuZ3RoLnRvU3RyaW5nKCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlblN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IHBhcnNlSW50KGxlblN0cltpXSk7XG4gICAgICB9XG4gICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IDI1NTtcblxuICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShhYik7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZpZXcubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVzdWx0QXJyYXlbYnVmZmVySW5kZXgrK10gPSB2aWV3W2ldO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNhbGxiYWNrKHJlc3VsdEFycmF5LmJ1ZmZlcik7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBFbmNvZGUgYXMgQmxvYlxuICovXG5cbmV4cG9ydHMuZW5jb2RlUGF5bG9hZEFzQmxvYiA9IGZ1bmN0aW9uKHBhY2tldHMsIGNhbGxiYWNrKSB7XG4gIGZ1bmN0aW9uIGVuY29kZU9uZShwYWNrZXQsIGRvbmVDYWxsYmFjaykge1xuICAgIGV4cG9ydHMuZW5jb2RlUGFja2V0KHBhY2tldCwgdHJ1ZSwgdHJ1ZSwgZnVuY3Rpb24oZW5jb2RlZCkge1xuICAgICAgdmFyIGJpbmFyeUlkZW50aWZpZXIgPSBuZXcgVWludDhBcnJheSgxKTtcbiAgICAgIGJpbmFyeUlkZW50aWZpZXJbMF0gPSAxO1xuICAgICAgaWYgKHR5cGVvZiBlbmNvZGVkID09PSAnc3RyaW5nJykge1xuICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGVuY29kZWQubGVuZ3RoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbmNvZGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmlld1tpXSA9IGVuY29kZWQuY2hhckNvZGVBdChpKTtcbiAgICAgICAgfVxuICAgICAgICBlbmNvZGVkID0gdmlldy5idWZmZXI7XG4gICAgICAgIGJpbmFyeUlkZW50aWZpZXJbMF0gPSAwO1xuICAgICAgfVxuXG4gICAgICB2YXIgbGVuID0gKGVuY29kZWQgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcilcbiAgICAgICAgPyBlbmNvZGVkLmJ5dGVMZW5ndGhcbiAgICAgICAgOiBlbmNvZGVkLnNpemU7XG5cbiAgICAgIHZhciBsZW5TdHIgPSBsZW4udG9TdHJpbmcoKTtcbiAgICAgIHZhciBsZW5ndGhBcnkgPSBuZXcgVWludDhBcnJheShsZW5TdHIubGVuZ3RoICsgMSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlblN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZW5ndGhBcnlbaV0gPSBwYXJzZUludChsZW5TdHJbaV0pO1xuICAgICAgfVxuICAgICAgbGVuZ3RoQXJ5W2xlblN0ci5sZW5ndGhdID0gMjU1O1xuXG4gICAgICBpZiAoQmxvYikge1xuICAgICAgICB2YXIgYmxvYiA9IG5ldyBCbG9iKFtiaW5hcnlJZGVudGlmaWVyLmJ1ZmZlciwgbGVuZ3RoQXJ5LmJ1ZmZlciwgZW5jb2RlZF0pO1xuICAgICAgICBkb25lQ2FsbGJhY2sobnVsbCwgYmxvYik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBtYXAocGFja2V0cywgZW5jb2RlT25lLCBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHtcbiAgICByZXR1cm4gY2FsbGJhY2sobmV3IEJsb2IocmVzdWx0cykpO1xuICB9KTtcbn07XG5cbi8qXG4gKiBEZWNvZGVzIGRhdGEgd2hlbiBhIHBheWxvYWQgaXMgbWF5YmUgZXhwZWN0ZWQuIFN0cmluZ3MgYXJlIGRlY29kZWQgYnlcbiAqIGludGVycHJldGluZyBlYWNoIGJ5dGUgYXMgYSBrZXkgY29kZSBmb3IgZW50cmllcyBtYXJrZWQgdG8gc3RhcnQgd2l0aCAwLiBTZWVcbiAqIGRlc2NyaXB0aW9uIG9mIGVuY29kZVBheWxvYWRBc0JpbmFyeVxuICpcbiAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGRhdGEsIGNhbGxiYWNrIG1ldGhvZFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLmRlY29kZVBheWxvYWRBc0JpbmFyeSA9IGZ1bmN0aW9uIChkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIGJpbmFyeVR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IGJpbmFyeVR5cGU7XG4gICAgYmluYXJ5VHlwZSA9IG51bGw7XG4gIH1cblxuICB2YXIgYnVmZmVyVGFpbCA9IGRhdGE7XG4gIHZhciBidWZmZXJzID0gW107XG5cbiAgdmFyIG51bWJlclRvb0xvbmcgPSBmYWxzZTtcbiAgd2hpbGUgKGJ1ZmZlclRhaWwuYnl0ZUxlbmd0aCA+IDApIHtcbiAgICB2YXIgdGFpbEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyVGFpbCk7XG4gICAgdmFyIGlzU3RyaW5nID0gdGFpbEFycmF5WzBdID09PSAwO1xuICAgIHZhciBtc2dMZW5ndGggPSAnJztcblxuICAgIGZvciAodmFyIGkgPSAxOyA7IGkrKykge1xuICAgICAgaWYgKHRhaWxBcnJheVtpXSA9PSAyNTUpIGJyZWFrO1xuXG4gICAgICBpZiAobXNnTGVuZ3RoLmxlbmd0aCA+IDMxMCkge1xuICAgICAgICBudW1iZXJUb29Mb25nID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIG1zZ0xlbmd0aCArPSB0YWlsQXJyYXlbaV07XG4gICAgfVxuXG4gICAgaWYobnVtYmVyVG9vTG9uZykgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG5cbiAgICBidWZmZXJUYWlsID0gc2xpY2VCdWZmZXIoYnVmZmVyVGFpbCwgMiArIG1zZ0xlbmd0aC5sZW5ndGgpO1xuICAgIG1zZ0xlbmd0aCA9IHBhcnNlSW50KG1zZ0xlbmd0aCk7XG5cbiAgICB2YXIgbXNnID0gc2xpY2VCdWZmZXIoYnVmZmVyVGFpbCwgMCwgbXNnTGVuZ3RoKTtcbiAgICBpZiAoaXNTdHJpbmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIG1zZyA9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgbmV3IFVpbnQ4QXJyYXkobXNnKSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGlQaG9uZSBTYWZhcmkgZG9lc24ndCBsZXQgeW91IGFwcGx5IHRvIHR5cGVkIGFycmF5c1xuICAgICAgICB2YXIgdHlwZWQgPSBuZXcgVWludDhBcnJheShtc2cpO1xuICAgICAgICBtc2cgPSAnJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0eXBlZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIG1zZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHR5cGVkW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGJ1ZmZlcnMucHVzaChtc2cpO1xuICAgIGJ1ZmZlclRhaWwgPSBzbGljZUJ1ZmZlcihidWZmZXJUYWlsLCBtc2dMZW5ndGgpO1xuICB9XG5cbiAgdmFyIHRvdGFsID0gYnVmZmVycy5sZW5ndGg7XG4gIGJ1ZmZlcnMuZm9yRWFjaChmdW5jdGlvbihidWZmZXIsIGkpIHtcbiAgICBjYWxsYmFjayhleHBvcnRzLmRlY29kZVBhY2tldChidWZmZXIsIGJpbmFyeVR5cGUsIHRydWUpLCBpLCB0b3RhbCk7XG4gIH0pO1xufTtcbiIsIlxuLyoqXG4gKiBHZXRzIHRoZSBrZXlzIGZvciBhbiBvYmplY3QuXG4gKlxuICogQHJldHVybiB7QXJyYXl9IGtleXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ga2V5cyAob2JqKXtcbiAgdmFyIGFyciA9IFtdO1xuICB2YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGkpKSB7XG4gICAgICBhcnIucHVzaChpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycjtcbn07XG4iLCJcbi8qXG4gKiBNb2R1bGUgcmVxdWlyZW1lbnRzLlxuICovXG5cbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gaGFzQmluYXJ5O1xuXG4vKipcbiAqIENoZWNrcyBmb3IgYmluYXJ5IGRhdGEuXG4gKlxuICogUmlnaHQgbm93IG9ubHkgQnVmZmVyIGFuZCBBcnJheUJ1ZmZlciBhcmUgc3VwcG9ydGVkLi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gYW55dGhpbmdcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gaGFzQmluYXJ5KGRhdGEpIHtcblxuICBmdW5jdGlvbiBfaGFzQmluYXJ5KG9iaikge1xuICAgIGlmICghb2JqKSByZXR1cm4gZmFsc2U7XG5cbiAgICBpZiAoIChnbG9iYWwuQnVmZmVyICYmIGdsb2JhbC5CdWZmZXIuaXNCdWZmZXIob2JqKSkgfHxcbiAgICAgICAgIChnbG9iYWwuQXJyYXlCdWZmZXIgJiYgb2JqIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHx8XG4gICAgICAgICAoZ2xvYmFsLkJsb2IgJiYgb2JqIGluc3RhbmNlb2YgQmxvYikgfHxcbiAgICAgICAgIChnbG9iYWwuRmlsZSAmJiBvYmogaW5zdGFuY2VvZiBGaWxlKVxuICAgICAgICApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKF9oYXNCaW5hcnkob2JqW2ldKSkge1xuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChvYmogJiYgJ29iamVjdCcgPT0gdHlwZW9mIG9iaikge1xuICAgICAgaWYgKG9iai50b0pTT04pIHtcbiAgICAgICAgb2JqID0gb2JqLnRvSlNPTigpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpICYmIF9oYXNCaW5hcnkob2JqW2tleV0pKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gX2hhc0JpbmFyeShkYXRhKTtcbn1cbiIsIlxuLypcbiAqIE1vZHVsZSByZXF1aXJlbWVudHMuXG4gKi9cblxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5Jyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBoYXNCaW5hcnk7XG5cbi8qKlxuICogQ2hlY2tzIGZvciBiaW5hcnkgZGF0YS5cbiAqXG4gKiBSaWdodCBub3cgb25seSBCdWZmZXIgYW5kIEFycmF5QnVmZmVyIGFyZSBzdXBwb3J0ZWQuLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBhbnl0aGluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBoYXNCaW5hcnkoZGF0YSkge1xuXG4gIGZ1bmN0aW9uIF9oYXNCaW5hcnkob2JqKSB7XG4gICAgaWYgKCFvYmopIHJldHVybiBmYWxzZTtcblxuICAgIGlmICggKGdsb2JhbC5CdWZmZXIgJiYgZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlciAmJiBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyKG9iaikpIHx8XG4gICAgICAgICAoZ2xvYmFsLkFycmF5QnVmZmVyICYmIG9iaiBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB8fFxuICAgICAgICAgKGdsb2JhbC5CbG9iICYmIG9iaiBpbnN0YW5jZW9mIEJsb2IpIHx8XG4gICAgICAgICAoZ2xvYmFsLkZpbGUgJiYgb2JqIGluc3RhbmNlb2YgRmlsZSlcbiAgICAgICAgKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmIChfaGFzQmluYXJ5KG9ialtpXSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAob2JqICYmICdvYmplY3QnID09IHR5cGVvZiBvYmopIHtcbiAgICAgIC8vIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL0F1dG9tYXR0aWMvaGFzLWJpbmFyeS9wdWxsLzRcbiAgICAgIGlmIChvYmoudG9KU09OICYmICdmdW5jdGlvbicgPT0gdHlwZW9mIG9iai50b0pTT04pIHtcbiAgICAgICAgb2JqID0gb2JqLnRvSlNPTigpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpICYmIF9oYXNCaW5hcnkob2JqW2tleV0pKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gX2hhc0JpbmFyeShkYXRhKTtcbn1cbiIsIlxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqXG4gKiBMb2dpYyBib3Jyb3dlZCBmcm9tIE1vZGVybml6cjpcbiAqXG4gKiAgIC0gaHR0cHM6Ly9naXRodWIuY29tL01vZGVybml6ci9Nb2Rlcm5penIvYmxvYi9tYXN0ZXIvZmVhdHVyZS1kZXRlY3RzL2NvcnMuanNcbiAqL1xuXG50cnkge1xuICBtb2R1bGUuZXhwb3J0cyA9IHR5cGVvZiBYTUxIdHRwUmVxdWVzdCAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAnd2l0aENyZWRlbnRpYWxzJyBpbiBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbn0gY2F0Y2ggKGVycikge1xuICAvLyBpZiBYTUxIdHRwIHN1cHBvcnQgaXMgZGlzYWJsZWQgaW4gSUUgdGhlbiBpdCB3aWxsIHRocm93XG4gIC8vIHdoZW4gdHJ5aW5nIHRvIGNyZWF0ZVxuICBtb2R1bGUuZXhwb3J0cyA9IGZhbHNlO1xufVxuIiwiXG52YXIgaW5kZXhPZiA9IFtdLmluZGV4T2Y7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYXJyLCBvYmope1xuICBpZiAoaW5kZXhPZikgcmV0dXJuIGFyci5pbmRleE9mKG9iaik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGFycltpXSA9PT0gb2JqKSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59OyIsIm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoYXJyKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiIsIi8qKlxuICogR2V0cyB0aGUgbGFzdCBlbGVtZW50IG9mIGBhcnJheWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBBcnJheVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGxhc3QgZWxlbWVudCBvZiBgYXJyYXlgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmxhc3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IDNcbiAqL1xuZnVuY3Rpb24gbGFzdChhcnJheSkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkgPyBhcnJheS5sZW5ndGggOiAwO1xuICByZXR1cm4gbGVuZ3RoID8gYXJyYXlbbGVuZ3RoIC0gMV0gOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbGFzdDtcbiIsInZhciBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5Jyk7XG5cbi8qKlxuICogVGhlIGludmVyc2Ugb2YgYF8ucGFpcnNgOyB0aGlzIG1ldGhvZCByZXR1cm5zIGFuIG9iamVjdCBjb21wb3NlZCBmcm9tIGFycmF5c1xuICogb2YgcHJvcGVydHkgbmFtZXMgYW5kIHZhbHVlcy4gUHJvdmlkZSBlaXRoZXIgYSBzaW5nbGUgdHdvIGRpbWVuc2lvbmFsIGFycmF5LFxuICogZS5nLiBgW1trZXkxLCB2YWx1ZTFdLCBba2V5MiwgdmFsdWUyXV1gIG9yIHR3byBhcnJheXMsIG9uZSBvZiBwcm9wZXJ0eSBuYW1lc1xuICogYW5kIG9uZSBvZiBjb3JyZXNwb25kaW5nIHZhbHVlcy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGFsaWFzIG9iamVjdFxuICogQGNhdGVnb3J5IEFycmF5XG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbdmFsdWVzPVtdXSBUaGUgcHJvcGVydHkgdmFsdWVzLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy56aXBPYmplY3QoW1snZnJlZCcsIDMwXSwgWydiYXJuZXknLCA0MF1dKTtcbiAqIC8vID0+IHsgJ2ZyZWQnOiAzMCwgJ2Jhcm5leSc6IDQwIH1cbiAqXG4gKiBfLnppcE9iamVjdChbJ2ZyZWQnLCAnYmFybmV5J10sIFszMCwgNDBdKTtcbiAqIC8vID0+IHsgJ2ZyZWQnOiAzMCwgJ2Jhcm5leSc6IDQwIH1cbiAqL1xuZnVuY3Rpb24gemlwT2JqZWN0KHByb3BzLCB2YWx1ZXMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBwcm9wcyA/IHByb3BzLmxlbmd0aCA6IDAsXG4gICAgICByZXN1bHQgPSB7fTtcblxuICBpZiAobGVuZ3RoICYmICF2YWx1ZXMgJiYgIWlzQXJyYXkocHJvcHNbMF0pKSB7XG4gICAgdmFsdWVzID0gW107XG4gIH1cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIga2V5ID0gcHJvcHNbaW5kZXhdO1xuICAgIGlmICh2YWx1ZXMpIHtcbiAgICAgIHJlc3VsdFtrZXldID0gdmFsdWVzW2luZGV4XTtcbiAgICB9IGVsc2UgaWYgKGtleSkge1xuICAgICAgcmVzdWx0W2tleVswXV0gPSBrZXlbMV07XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gemlwT2JqZWN0O1xuIiwidmFyIGFycmF5RmlsdGVyID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlGaWx0ZXInKSxcbiAgICBiYXNlQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2FsbGJhY2snKSxcbiAgICBiYXNlRmlsdGVyID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUZpbHRlcicpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCwgcmV0dXJuaW5nIGFuIGFycmF5IG9mIGFsbCBlbGVtZW50c1xuICogYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yLiBUaGUgcHJlZGljYXRlIGlzIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmRcbiAqIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAqXG4gKiBJZiBhIHByb3BlcnR5IG5hbWUgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLnByb3BlcnR5YFxuICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUgb2YgdGhlIGdpdmVuIGVsZW1lbnQuXG4gKlxuICogSWYgYSB2YWx1ZSBpcyBhbHNvIHByb3ZpZGVkIGZvciBgdGhpc0FyZ2AgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc1Byb3BlcnR5YFxuICogc3R5bGUgY2FsbGJhY2sgcmV0dXJucyBgdHJ1ZWAgZm9yIGVsZW1lbnRzIHRoYXQgaGF2ZSBhIG1hdGNoaW5nIHByb3BlcnR5XG4gKiB2YWx1ZSwgZWxzZSBgZmFsc2VgLlxuICpcbiAqIElmIGFuIG9iamVjdCBpcyBwcm92aWRlZCBmb3IgYHByZWRpY2F0ZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGFsaWFzIHNlbGVjdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWRcbiAqICBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBwcmVkaWNhdGVgLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmlsdGVyZWQgYXJyYXkuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uZmlsdGVyKFs0LCA1LCA2XSwgZnVuY3Rpb24obikge1xuICogICByZXR1cm4gbiAlIDIgPT0gMDtcbiAqIH0pO1xuICogLy8gPT4gWzQsIDZdXG4gKlxuICogdmFyIHVzZXJzID0gW1xuICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiwgJ2FjdGl2ZSc6IHRydWUgfSxcbiAqICAgeyAndXNlcic6ICdmcmVkJywgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9XG4gKiBdO1xuICpcbiAqIC8vIHVzaW5nIHRoZSBgXy5tYXRjaGVzYCBjYWxsYmFjayBzaG9ydGhhbmRcbiAqIF8ucGx1Y2soXy5maWx0ZXIodXNlcnMsIHsgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9KSwgJ3VzZXInKTtcbiAqIC8vID0+IFsnYmFybmV5J11cbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAqIF8ucGx1Y2soXy5maWx0ZXIodXNlcnMsICdhY3RpdmUnLCBmYWxzZSksICd1c2VyJyk7XG4gKiAvLyA9PiBbJ2ZyZWQnXVxuICpcbiAqIC8vIHVzaW5nIHRoZSBgXy5wcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnBsdWNrKF8uZmlsdGVyKHVzZXJzLCAnYWN0aXZlJyksICd1c2VyJyk7XG4gKiAvLyA9PiBbJ2Jhcm5leSddXG4gKi9cbmZ1bmN0aW9uIGZpbHRlcihjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIHRoaXNBcmcpIHtcbiAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlGaWx0ZXIgOiBiYXNlRmlsdGVyO1xuICBwcmVkaWNhdGUgPSBiYXNlQ2FsbGJhY2socHJlZGljYXRlLCB0aGlzQXJnLCAzKTtcbiAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgcHJlZGljYXRlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmaWx0ZXI7XG4iLCJ2YXIgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlFYWNoJyksXG4gICAgYmFzZUVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlRWFjaCcpLFxuICAgIGNyZWF0ZUZvckVhY2ggPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoJyk7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3IgZWFjaCBlbGVtZW50LlxuICogVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5XG4gKiBieSBleHBsaWNpdGx5IHJldHVybmluZyBgZmFsc2VgLlxuICpcbiAqICoqTm90ZToqKiBBcyB3aXRoIG90aGVyIFwiQ29sbGVjdGlvbnNcIiBtZXRob2RzLCBvYmplY3RzIHdpdGggYSBcImxlbmd0aFwiIHByb3BlcnR5XG4gKiBhcmUgaXRlcmF0ZWQgbGlrZSBhcnJheXMuIFRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYF8uZm9ySW5gIG9yIGBfLmZvck93bmBcbiAqIG1heSBiZSB1c2VkIGZvciBvYmplY3QgaXRlcmF0aW9uLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgZWFjaFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICogQHJldHVybnMge0FycmF5fE9iamVjdHxzdHJpbmd9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfKFsxLCAyXSkuZm9yRWFjaChmdW5jdGlvbihuKSB7XG4gKiAgIGNvbnNvbGUubG9nKG4pO1xuICogfSkudmFsdWUoKTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZSBmcm9tIGxlZnQgdG8gcmlnaHQgYW5kIHJldHVybnMgdGhlIGFycmF5XG4gKlxuICogXy5mb3JFYWNoKHsgJ2EnOiAxLCAnYic6IDIgfSwgZnVuY3Rpb24obiwga2V5KSB7XG4gKiAgIGNvbnNvbGUubG9nKG4sIGtleSk7XG4gKiB9KTtcbiAqIC8vID0+IGxvZ3MgZWFjaCB2YWx1ZS1rZXkgcGFpciBhbmQgcmV0dXJucyB0aGUgb2JqZWN0IChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbnZhciBmb3JFYWNoID0gY3JlYXRlRm9yRWFjaChhcnJheUVhY2gsIGJhc2VFYWNoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmb3JFYWNoO1xuIiwidmFyIGFycmF5TWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYXJyYXlNYXAnKSxcbiAgICBiYXNlQ2FsbGJhY2sgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlQ2FsbGJhY2snKSxcbiAgICBiYXNlTWFwID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZU1hcCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHZhbHVlcyBieSBydW5uaW5nIGVhY2ggZWxlbWVudCBpbiBgY29sbGVjdGlvbmAgdGhyb3VnaFxuICogYGl0ZXJhdGVlYC4gVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGggdGhyZWVcbiAqIGFyZ3VtZW50czogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICpcbiAqIElmIGEgcHJvcGVydHkgbmFtZSBpcyBwcm92aWRlZCBmb3IgYGl0ZXJhdGVlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ubWF0Y2hlc2Agc3R5bGVcbiAqIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgdGhlIHByb3BlcnRpZXMgb2YgdGhlIGdpdmVuXG4gKiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBNYW55IGxvZGFzaCBtZXRob2RzIGFyZSBndWFyZGVkIHRvIHdvcmsgYXMgaXRlcmF0ZWVzIGZvciBtZXRob2RzIGxpa2VcbiAqIGBfLmV2ZXJ5YCwgYF8uZmlsdGVyYCwgYF8ubWFwYCwgYF8ubWFwVmFsdWVzYCwgYF8ucmVqZWN0YCwgYW5kIGBfLnNvbWVgLlxuICpcbiAqIFRoZSBndWFyZGVkIG1ldGhvZHMgYXJlOlxuICogYGFyeWAsIGBjYWxsYmFja2AsIGBjaHVua2AsIGBjbG9uZWAsIGBjcmVhdGVgLCBgY3VycnlgLCBgY3VycnlSaWdodGAsXG4gKiBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZXZlcnlgLCBgZmlsbGAsIGBmbGF0dGVuYCwgYGludmVydGAsIGBtYXhgLCBgbWluYCxcbiAqIGBwYXJzZUludGAsIGBzbGljZWAsIGBzb3J0QnlgLCBgdGFrZWAsIGB0YWtlUmlnaHRgLCBgdGVtcGxhdGVgLCBgdHJpbWAsXG4gKiBgdHJpbUxlZnRgLCBgdHJpbVJpZ2h0YCwgYHRydW5jYCwgYHJhbmRvbWAsIGByYW5nZWAsIGBzYW1wbGVgLCBgc29tZWAsXG4gKiBgc3VtYCwgYHVuaXFgLCBhbmQgYHdvcmRzYFxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAYWxpYXMgY29sbGVjdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICogIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gdGltZXNUaHJlZShuKSB7XG4gKiAgIHJldHVybiBuICogMztcbiAqIH1cbiAqXG4gKiBfLm1hcChbMSwgMl0sIHRpbWVzVGhyZWUpO1xuICogLy8gPT4gWzMsIDZdXG4gKlxuICogXy5tYXAoeyAnYSc6IDEsICdiJzogMiB9LCB0aW1lc1RocmVlKTtcbiAqIC8vID0+IFszLCA2XSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICogXTtcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5tYXAodXNlcnMsICd1c2VyJyk7XG4gKiAvLyA9PiBbJ2Jhcm5leScsICdmcmVkJ11cbiAqL1xuZnVuY3Rpb24gbWFwKGNvbGxlY3Rpb24sIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5TWFwIDogYmFzZU1hcDtcbiAgaXRlcmF0ZWUgPSBiYXNlQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwO1xuIiwidmFyIGFycmF5U29tZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2FycmF5U29tZScpLFxuICAgIGJhc2VDYWxsYmFjayA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VDYWxsYmFjaycpLFxuICAgIGJhc2VTb21lID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZVNvbWUnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNJdGVyYXRlZUNhbGwgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0l0ZXJhdGVlQ2FsbCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IgKiphbnkqKiBlbGVtZW50IG9mIGBjb2xsZWN0aW9uYC5cbiAqIFRoZSBmdW5jdGlvbiByZXR1cm5zIGFzIHNvb24gYXMgaXQgZmluZHMgYSBwYXNzaW5nIHZhbHVlIGFuZCBkb2VzIG5vdCBpdGVyYXRlXG4gKiBvdmVyIHRoZSBlbnRpcmUgY29sbGVjdGlvbi4gVGhlIHByZWRpY2F0ZSBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWRcbiAqIHdpdGggdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGluZGV4fGtleSwgY29sbGVjdGlvbikuXG4gKlxuICogSWYgYSBwcm9wZXJ0eSBuYW1lIGlzIHByb3ZpZGVkIGZvciBgcHJlZGljYXRlYCB0aGUgY3JlYXRlZCBgXy5wcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIElmIGEgdmFsdWUgaXMgYWxzbyBwcm92aWRlZCBmb3IgYHRoaXNBcmdgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNQcm9wZXJ0eWBcbiAqIHN0eWxlIGNhbGxiYWNrIHJldHVybnMgYHRydWVgIGZvciBlbGVtZW50cyB0aGF0IGhhdmUgYSBtYXRjaGluZyBwcm9wZXJ0eVxuICogdmFsdWUsIGVsc2UgYGZhbHNlYC5cbiAqXG4gKiBJZiBhbiBvYmplY3QgaXMgcHJvdmlkZWQgZm9yIGBwcmVkaWNhdGVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBhbGlhcyBhbnlcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbnxPYmplY3R8c3RyaW5nfSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkXG4gKiAgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgcHJlZGljYXRlYC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbnkgZWxlbWVudCBwYXNzZXMgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uc29tZShbbnVsbCwgMCwgJ3llcycsIGZhbHNlXSwgQm9vbGVhbik7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogdmFyIHVzZXJzID0gW1xuICogICB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiB0cnVlIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcsICAgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAqIF07XG4gKlxuICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5zb21lKHVzZXJzLCB7ICd1c2VyJzogJ2Jhcm5leScsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogLy8gdXNpbmcgdGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgY2FsbGJhY2sgc2hvcnRoYW5kXG4gKiBfLnNvbWUodXNlcnMsICdhY3RpdmUnLCBmYWxzZSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogLy8gdXNpbmcgdGhlIGBfLnByb3BlcnR5YCBjYWxsYmFjayBzaG9ydGhhbmRcbiAqIF8uc29tZSh1c2VycywgJ2FjdGl2ZScpO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBzb21lKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSwgdGhpc0FyZykge1xuICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheVNvbWUgOiBiYXNlU29tZTtcbiAgaWYgKHRoaXNBcmcgJiYgaXNJdGVyYXRlZUNhbGwoY29sbGVjdGlvbiwgcHJlZGljYXRlLCB0aGlzQXJnKSkge1xuICAgIHByZWRpY2F0ZSA9IHVuZGVmaW5lZDtcbiAgfVxuICBpZiAodHlwZW9mIHByZWRpY2F0ZSAhPSAnZnVuY3Rpb24nIHx8IHRoaXNBcmcgIT09IHVuZGVmaW5lZCkge1xuICAgIHByZWRpY2F0ZSA9IGJhc2VDYWxsYmFjayhwcmVkaWNhdGUsIHRoaXNBcmcsIDMpO1xuICB9XG4gIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc29tZTtcbiIsIi8qKiBVc2VkIGFzIHRoZSBgVHlwZUVycm9yYCBtZXNzYWdlIGZvciBcIkZ1bmN0aW9uc1wiIG1ldGhvZHMuICovXG52YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIHRoZVxuICogY3JlYXRlZCBmdW5jdGlvbiBhbmQgYXJndW1lbnRzIGZyb20gYHN0YXJ0YCBhbmQgYmV5b25kIHByb3ZpZGVkIGFzIGFuIGFycmF5LlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBpcyBiYXNlZCBvbiB0aGUgW3Jlc3QgcGFyYW1ldGVyXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvRnVuY3Rpb25zL3Jlc3RfcGFyYW1ldGVycykuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYXBwbHkgYSByZXN0IHBhcmFtZXRlciB0by5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9ZnVuYy5sZW5ndGgtMV0gVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXN0IHBhcmFtZXRlci5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgc2F5ID0gXy5yZXN0UGFyYW0oZnVuY3Rpb24od2hhdCwgbmFtZXMpIHtcbiAqICAgcmV0dXJuIHdoYXQgKyAnICcgKyBfLmluaXRpYWwobmFtZXMpLmpvaW4oJywgJykgK1xuICogICAgIChfLnNpemUobmFtZXMpID4gMSA/ICcsICYgJyA6ICcnKSArIF8ubGFzdChuYW1lcyk7XG4gKiB9KTtcbiAqXG4gKiBzYXkoJ2hlbGxvJywgJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnKTtcbiAqIC8vID0+ICdoZWxsbyBmcmVkLCBiYXJuZXksICYgcGViYmxlcydcbiAqL1xuZnVuY3Rpb24gcmVzdFBhcmFtKGZ1bmMsIHN0YXJ0KSB7XG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIHN0YXJ0ID0gbmF0aXZlTWF4KHN0YXJ0ID09PSB1bmRlZmluZWQgPyAoZnVuYy5sZW5ndGggLSAxKSA6ICgrc3RhcnQgfHwgMCksIDApO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIHN0YXJ0LCAwKSxcbiAgICAgICAgcmVzdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgcmVzdFtpbmRleF0gPSBhcmdzW3N0YXJ0ICsgaW5kZXhdO1xuICAgIH1cbiAgICBzd2l0Y2ggKHN0YXJ0KSB7XG4gICAgICBjYXNlIDA6IHJldHVybiBmdW5jLmNhbGwodGhpcywgcmVzdCk7XG4gICAgICBjYXNlIDE6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJnc1swXSwgcmVzdCk7XG4gICAgICBjYXNlIDI6IHJldHVybiBmdW5jLmNhbGwodGhpcywgYXJnc1swXSwgYXJnc1sxXSwgcmVzdCk7XG4gICAgfVxuICAgIHZhciBvdGhlckFyZ3MgPSBBcnJheShzdGFydCArIDEpO1xuICAgIGluZGV4ID0gLTE7XG4gICAgd2hpbGUgKCsraW5kZXggPCBzdGFydCkge1xuICAgICAgb3RoZXJBcmdzW2luZGV4XSA9IGFyZ3NbaW5kZXhdO1xuICAgIH1cbiAgICBvdGhlckFyZ3Nbc3RhcnRdID0gcmVzdDtcbiAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBvdGhlckFyZ3MpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlc3RQYXJhbTtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLmZvckVhY2hgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5RWFjaChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAoaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpID09PSBmYWxzZSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUVhY2g7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5maWx0ZXJgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBhcnJheUZpbHRlcihhcnJheSwgcHJlZGljYXRlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgcmVzSW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBhcnJheSkpIHtcbiAgICAgIHJlc3VsdFsrK3Jlc0luZGV4XSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5RmlsdGVyO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWFwYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2tcbiAqIHNob3J0aGFuZHMgYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqL1xuZnVuY3Rpb24gYXJyYXlNYXAoYXJyYXksIGl0ZXJhdGVlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSBpdGVyYXRlZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheU1hcDtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnNvbWVgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbnkgZWxlbWVudCBwYXNzZXMgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5U29tZShhcnJheSwgcHJlZGljYXRlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgaWYgKHByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlTb21lO1xuIiwidmFyIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5hc3NpZ25gIGZvciBjdXN0b21pemluZyBhc3NpZ25lZCB2YWx1ZXMgd2l0aG91dFxuICogc3VwcG9ydCBmb3IgYXJndW1lbnQganVnZ2xpbmcsIG11bHRpcGxlIHNvdXJjZXMsIGFuZCBgdGhpc2AgYmluZGluZyBgY3VzdG9taXplcmBcbiAqIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICogQHBhcmFtIHtPYmplY3R9IHNvdXJjZSBUaGUgc291cmNlIG9iamVjdC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBhc3NpZ25XaXRoKG9iamVjdCwgc291cmNlLCBjdXN0b21pemVyKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcHJvcHMgPSBrZXlzKHNvdXJjZSksXG4gICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIga2V5ID0gcHJvcHNbaW5kZXhdLFxuICAgICAgICB2YWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICByZXN1bHQgPSBjdXN0b21pemVyKHZhbHVlLCBzb3VyY2Vba2V5XSwga2V5LCBvYmplY3QsIHNvdXJjZSk7XG5cbiAgICBpZiAoKHJlc3VsdCA9PT0gcmVzdWx0ID8gKHJlc3VsdCAhPT0gdmFsdWUpIDogKHZhbHVlID09PSB2YWx1ZSkpIHx8XG4gICAgICAgICh2YWx1ZSA9PT0gdW5kZWZpbmVkICYmICEoa2V5IGluIG9iamVjdCkpKSB7XG4gICAgICBvYmplY3Rba2V5XSA9IHJlc3VsdDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhc3NpZ25XaXRoO1xuIiwidmFyIGJhc2VDb3B5ID0gcmVxdWlyZSgnLi9iYXNlQ29weScpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmFzc2lnbmAgd2l0aG91dCBzdXBwb3J0IGZvciBhcmd1bWVudCBqdWdnbGluZyxcbiAqIG11bHRpcGxlIHNvdXJjZXMsIGFuZCBgY3VzdG9taXplcmAgZnVuY3Rpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBkZXN0aW5hdGlvbiBvYmplY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBzb3VyY2Ugb2JqZWN0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUFzc2lnbihvYmplY3QsIHNvdXJjZSkge1xuICByZXR1cm4gc291cmNlID09IG51bGxcbiAgICA/IG9iamVjdFxuICAgIDogYmFzZUNvcHkoc291cmNlLCBrZXlzKHNvdXJjZSksIG9iamVjdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUFzc2lnbjtcbiIsInZhciBiYXNlTWF0Y2hlcyA9IHJlcXVpcmUoJy4vYmFzZU1hdGNoZXMnKSxcbiAgICBiYXNlTWF0Y2hlc1Byb3BlcnR5ID0gcmVxdWlyZSgnLi9iYXNlTWF0Y2hlc1Byb3BlcnR5JyksXG4gICAgYmluZENhbGxiYWNrID0gcmVxdWlyZSgnLi9iaW5kQ2FsbGJhY2snKSxcbiAgICBpZGVudGl0eSA9IHJlcXVpcmUoJy4uL3V0aWxpdHkvaWRlbnRpdHknKSxcbiAgICBwcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL3V0aWxpdHkvcHJvcGVydHknKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jYWxsYmFja2Agd2hpY2ggc3VwcG9ydHMgc3BlY2lmeWluZyB0aGVcbiAqIG51bWJlciBvZiBhcmd1bWVudHMgdG8gcHJvdmlkZSB0byBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gW2Z1bmM9Xy5pZGVudGl0eV0gVGhlIHZhbHVlIHRvIGNvbnZlcnQgdG8gYSBjYWxsYmFjay5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyZ0NvdW50XSBUaGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgY2FsbGJhY2suXG4gKi9cbmZ1bmN0aW9uIGJhc2VDYWxsYmFjayhmdW5jLCB0aGlzQXJnLCBhcmdDb3VudCkge1xuICB2YXIgdHlwZSA9IHR5cGVvZiBmdW5jO1xuICBpZiAodHlwZSA9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHRoaXNBcmcgPT09IHVuZGVmaW5lZFxuICAgICAgPyBmdW5jXG4gICAgICA6IGJpbmRDYWxsYmFjayhmdW5jLCB0aGlzQXJnLCBhcmdDb3VudCk7XG4gIH1cbiAgaWYgKGZ1bmMgPT0gbnVsbCkge1xuICAgIHJldHVybiBpZGVudGl0eTtcbiAgfVxuICBpZiAodHlwZSA9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBiYXNlTWF0Y2hlcyhmdW5jKTtcbiAgfVxuICByZXR1cm4gdGhpc0FyZyA9PT0gdW5kZWZpbmVkXG4gICAgPyBwcm9wZXJ0eShmdW5jKVxuICAgIDogYmFzZU1hdGNoZXNQcm9wZXJ0eShmdW5jLCB0aGlzQXJnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ2FsbGJhY2s7XG4iLCIvKipcbiAqIENvcGllcyBwcm9wZXJ0aWVzIG9mIGBzb3VyY2VgIHRvIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIGZyb20uXG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gY29weS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0PXt9XSBUaGUgb2JqZWN0IHRvIGNvcHkgcHJvcGVydGllcyB0by5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VDb3B5KHNvdXJjZSwgcHJvcHMsIG9iamVjdCkge1xuICBvYmplY3QgfHwgKG9iamVjdCA9IHt9KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgb2JqZWN0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgfVxuICByZXR1cm4gb2JqZWN0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VDb3B5O1xuIiwidmFyIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKSxcbiAgICBjcmVhdGVCYXNlRWFjaCA9IHJlcXVpcmUoJy4vY3JlYXRlQmFzZUVhY2gnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R8c3RyaW5nfSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fHN0cmluZ30gUmV0dXJucyBgY29sbGVjdGlvbmAuXG4gKi9cbnZhciBiYXNlRWFjaCA9IGNyZWF0ZUJhc2VFYWNoKGJhc2VGb3JPd24pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VFYWNoO1xuIiwidmFyIGJhc2VFYWNoID0gcmVxdWlyZSgnLi9iYXNlRWFjaCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZpbHRlcmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBiYXNlRmlsdGVyKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSkge1xuICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZpbHRlcjtcbiIsInZhciBjcmVhdGVCYXNlRm9yID0gcmVxdWlyZSgnLi9jcmVhdGVCYXNlRm9yJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JJbmAgYW5kIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlc1xuICogb3ZlciBgb2JqZWN0YCBwcm9wZXJ0aWVzIHJldHVybmVkIGJ5IGBrZXlzRnVuY2AgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3JcbiAqIGVhY2ggcHJvcGVydHkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseVxuICogcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3I7XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vYmFzZUZvcicpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5cycpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZvck93bmAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gIHJldHVybiBiYXNlRm9yKG9iamVjdCwgaXRlcmF0ZWUsIGtleXMpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3JPd247XG4iLCJ2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldGAgd2l0aG91dCBzdXBwb3J0IGZvciBzdHJpbmcgcGF0aHNcbiAqIGFuZCBkZWZhdWx0IHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheX0gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXRoS2V5XSBUaGUga2V5IHJlcHJlc2VudGF0aW9uIG9mIHBhdGguXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXQob2JqZWN0LCBwYXRoLCBwYXRoS2V5KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAocGF0aEtleSAhPT0gdW5kZWZpbmVkICYmIHBhdGhLZXkgaW4gdG9PYmplY3Qob2JqZWN0KSkge1xuICAgIHBhdGggPSBbcGF0aEtleV07XG4gIH1cbiAgdmFyIGluZGV4ID0gMCxcbiAgICAgIGxlbmd0aCA9IHBhdGgubGVuZ3RoO1xuXG4gIHdoaWxlIChvYmplY3QgIT0gbnVsbCAmJiBpbmRleCA8IGxlbmd0aCkge1xuICAgIG9iamVjdCA9IG9iamVjdFtwYXRoW2luZGV4KytdXTtcbiAgfVxuICByZXR1cm4gKGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCkgPyBvYmplY3QgOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUdldDtcbiIsInZhciBiYXNlSXNFcXVhbERlZXAgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsRGVlcCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi4vbGFuZy9pc09iamVjdCcpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNFcXVhbGAgd2l0aG91dCBzdXBwb3J0IGZvciBgdGhpc2AgYmluZGluZ1xuICogYGN1c3RvbWl6ZXJgIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Kn0gb3RoZXIgVGhlIG90aGVyIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpbmcgdmFsdWVzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0JdIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQikge1xuICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0KHZhbHVlKSAmJiAhaXNPYmplY3RMaWtlKG90aGVyKSkpIHtcbiAgICByZXR1cm4gdmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcjtcbiAgfVxuICByZXR1cm4gYmFzZUlzRXF1YWxEZWVwKHZhbHVlLCBvdGhlciwgYmFzZUlzRXF1YWwsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbDtcbiIsInZhciBlcXVhbEFycmF5cyA9IHJlcXVpcmUoJy4vZXF1YWxBcnJheXMnKSxcbiAgICBlcXVhbEJ5VGFnID0gcmVxdWlyZSgnLi9lcXVhbEJ5VGFnJyksXG4gICAgZXF1YWxPYmplY3RzID0gcmVxdWlyZSgnLi9lcXVhbE9iamVjdHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FycmF5JyksXG4gICAgaXNUeXBlZEFycmF5ID0gcmVxdWlyZSgnLi4vbGFuZy9pc1R5cGVkQXJyYXknKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJyxcbiAgICBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XSc7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxgIGZvciBhcnJheXMgYW5kIG9iamVjdHMgd2hpY2ggcGVyZm9ybXNcbiAqIGRlZXAgY29tcGFyaXNvbnMgYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cyBlbmFibGluZyBvYmplY3RzIHdpdGggY2lyY3VsYXJcbiAqIHJlZmVyZW5jZXMgdG8gYmUgY29tcGFyZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmluZyBvYmplY3RzLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNMb29zZV0gU3BlY2lmeSBwZXJmb3JtaW5nIHBhcnRpYWwgY29tcGFyaXNvbnMuXG4gKiBAcGFyYW0ge0FycmF5fSBbc3RhY2tBPVtdXSBUcmFja3MgdHJhdmVyc2VkIGB2YWx1ZWAgb2JqZWN0cy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0I9W11dIFRyYWNrcyB0cmF2ZXJzZWQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc0VxdWFsRGVlcChvYmplY3QsIG90aGVyLCBlcXVhbEZ1bmMsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSB7XG4gIHZhciBvYmpJc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgIG90aElzQXJyID0gaXNBcnJheShvdGhlciksXG4gICAgICBvYmpUYWcgPSBhcnJheVRhZyxcbiAgICAgIG90aFRhZyA9IGFycmF5VGFnO1xuXG4gIGlmICghb2JqSXNBcnIpIHtcbiAgICBvYmpUYWcgPSBvYmpUb1N0cmluZy5jYWxsKG9iamVjdCk7XG4gICAgaWYgKG9ialRhZyA9PSBhcmdzVGFnKSB7XG4gICAgICBvYmpUYWcgPSBvYmplY3RUYWc7XG4gICAgfSBlbHNlIGlmIChvYmpUYWcgIT0gb2JqZWN0VGFnKSB7XG4gICAgICBvYmpJc0FyciA9IGlzVHlwZWRBcnJheShvYmplY3QpO1xuICAgIH1cbiAgfVxuICBpZiAoIW90aElzQXJyKSB7XG4gICAgb3RoVGFnID0gb2JqVG9TdHJpbmcuY2FsbChvdGhlcik7XG4gICAgaWYgKG90aFRhZyA9PSBhcmdzVGFnKSB7XG4gICAgICBvdGhUYWcgPSBvYmplY3RUYWc7XG4gICAgfSBlbHNlIGlmIChvdGhUYWcgIT0gb2JqZWN0VGFnKSB7XG4gICAgICBvdGhJc0FyciA9IGlzVHlwZWRBcnJheShvdGhlcik7XG4gICAgfVxuICB9XG4gIHZhciBvYmpJc09iaiA9IG9ialRhZyA9PSBvYmplY3RUYWcsXG4gICAgICBvdGhJc09iaiA9IG90aFRhZyA9PSBvYmplY3RUYWcsXG4gICAgICBpc1NhbWVUYWcgPSBvYmpUYWcgPT0gb3RoVGFnO1xuXG4gIGlmIChpc1NhbWVUYWcgJiYgIShvYmpJc0FyciB8fCBvYmpJc09iaikpIHtcbiAgICByZXR1cm4gZXF1YWxCeVRhZyhvYmplY3QsIG90aGVyLCBvYmpUYWcpO1xuICB9XG4gIGlmICghaXNMb29zZSkge1xuICAgIHZhciBvYmpJc1dyYXBwZWQgPSBvYmpJc09iaiAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgJ19fd3JhcHBlZF9fJyksXG4gICAgICAgIG90aElzV3JhcHBlZCA9IG90aElzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsICdfX3dyYXBwZWRfXycpO1xuXG4gICAgaWYgKG9iaklzV3JhcHBlZCB8fCBvdGhJc1dyYXBwZWQpIHtcbiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqSXNXcmFwcGVkID8gb2JqZWN0LnZhbHVlKCkgOiBvYmplY3QsIG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlciwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xuICAgIH1cbiAgfVxuICBpZiAoIWlzU2FtZVRhZykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBBc3N1bWUgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gIC8vIEZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGRldGVjdGluZyBjaXJjdWxhciByZWZlcmVuY2VzIHNlZSBodHRwczovL2VzNS5naXRodWIuaW8vI0pPLlxuICBzdGFja0EgfHwgKHN0YWNrQSA9IFtdKTtcbiAgc3RhY2tCIHx8IChzdGFja0IgPSBbXSk7XG5cbiAgdmFyIGxlbmd0aCA9IHN0YWNrQS5sZW5ndGg7XG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIGlmIChzdGFja0FbbGVuZ3RoXSA9PSBvYmplY3QpIHtcbiAgICAgIHJldHVybiBzdGFja0JbbGVuZ3RoXSA9PSBvdGhlcjtcbiAgICB9XG4gIH1cbiAgLy8gQWRkIGBvYmplY3RgIGFuZCBgb3RoZXJgIHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgc3RhY2tBLnB1c2gob2JqZWN0KTtcbiAgc3RhY2tCLnB1c2gob3RoZXIpO1xuXG4gIHZhciByZXN1bHQgPSAob2JqSXNBcnIgPyBlcXVhbEFycmF5cyA6IGVxdWFsT2JqZWN0cykob2JqZWN0LCBvdGhlciwgZXF1YWxGdW5jLCBjdXN0b21pemVyLCBpc0xvb3NlLCBzdGFja0EsIHN0YWNrQik7XG5cbiAgc3RhY2tBLnBvcCgpO1xuICBzdGFja0IucG9wKCk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbERlZXA7XG4iLCJ2YXIgYmFzZUlzRXF1YWwgPSByZXF1aXJlKCcuL2Jhc2VJc0VxdWFsJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXNNYXRjaGAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFja1xuICogc2hvcnRoYW5kcyBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpbnNwZWN0LlxuICogQHBhcmFtIHtBcnJheX0gbWF0Y2hEYXRhIFRoZSBwcm9wZXJ5IG5hbWVzLCB2YWx1ZXMsIGFuZCBjb21wYXJlIGZsYWdzIHRvIG1hdGNoLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2N1c3RvbWl6ZXJdIFRoZSBmdW5jdGlvbiB0byBjdXN0b21pemUgY29tcGFyaW5nIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYG9iamVjdGAgaXMgYSBtYXRjaCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSwgY3VzdG9taXplcikge1xuICB2YXIgaW5kZXggPSBtYXRjaERhdGEubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gaW5kZXgsXG4gICAgICBub0N1c3RvbWl6ZXIgPSAhY3VzdG9taXplcjtcblxuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICByZXR1cm4gIWxlbmd0aDtcbiAgfVxuICBvYmplY3QgPSB0b09iamVjdChvYmplY3QpO1xuICB3aGlsZSAoaW5kZXgtLSkge1xuICAgIHZhciBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICBpZiAoKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKVxuICAgICAgICAgID8gZGF0YVsxXSAhPT0gb2JqZWN0W2RhdGFbMF1dXG4gICAgICAgICAgOiAhKGRhdGFbMF0gaW4gb2JqZWN0KVxuICAgICAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBkYXRhID0gbWF0Y2hEYXRhW2luZGV4XTtcbiAgICB2YXIga2V5ID0gZGF0YVswXSxcbiAgICAgICAgb2JqVmFsdWUgPSBvYmplY3Rba2V5XSxcbiAgICAgICAgc3JjVmFsdWUgPSBkYXRhWzFdO1xuXG4gICAgaWYgKG5vQ3VzdG9taXplciAmJiBkYXRhWzJdKSB7XG4gICAgICBpZiAob2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5KSA6IHVuZGVmaW5lZDtcbiAgICAgIGlmICghKHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBjdXN0b21pemVyLCB0cnVlKSA6IHJlc3VsdCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNNYXRjaDtcbiIsInZhciBiYXNlRWFjaCA9IHJlcXVpcmUoJy4vYmFzZUVhY2gnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5tYXBgIHdpdGhvdXQgc3VwcG9ydCBmb3IgY2FsbGJhY2sgc2hvcnRoYW5kc1xuICogYW5kIGB0aGlzYCBiaW5kaW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxzdHJpbmd9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IG1hcHBlZCBhcnJheS5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IGlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pID8gQXJyYXkoY29sbGVjdGlvbi5sZW5ndGgpIDogW107XG5cbiAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgIHJlc3VsdFsrK2luZGV4XSA9IGl0ZXJhdGVlKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWFwO1xuIiwidmFyIGJhc2VJc01hdGNoID0gcmVxdWlyZSgnLi9iYXNlSXNNYXRjaCcpLFxuICAgIGdldE1hdGNoRGF0YSA9IHJlcXVpcmUoJy4vZ2V0TWF0Y2hEYXRhJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWF0Y2hlc2Agd2hpY2ggZG9lcyBub3QgY2xvbmUgYHNvdXJjZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hdGNoZXMoc291cmNlKSB7XG4gIHZhciBtYXRjaERhdGEgPSBnZXRNYXRjaERhdGEoc291cmNlKTtcbiAgaWYgKG1hdGNoRGF0YS5sZW5ndGggPT0gMSAmJiBtYXRjaERhdGFbMF1bMl0pIHtcbiAgICB2YXIga2V5ID0gbWF0Y2hEYXRhWzBdWzBdLFxuICAgICAgICB2YWx1ZSA9IG1hdGNoRGF0YVswXVsxXTtcblxuICAgIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gb2JqZWN0W2tleV0gPT09IHZhbHVlICYmICh2YWx1ZSAhPT0gdW5kZWZpbmVkIHx8IChrZXkgaW4gdG9PYmplY3Qob2JqZWN0KSkpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBiYXNlSXNNYXRjaChvYmplY3QsIG1hdGNoRGF0YSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZU1hdGNoZXM7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vYmFzZUdldCcpLFxuICAgIGJhc2VJc0VxdWFsID0gcmVxdWlyZSgnLi9iYXNlSXNFcXVhbCcpLFxuICAgIGJhc2VTbGljZSA9IHJlcXVpcmUoJy4vYmFzZVNsaWNlJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzS2V5ID0gcmVxdWlyZSgnLi9pc0tleScpLFxuICAgIGlzU3RyaWN0Q29tcGFyYWJsZSA9IHJlcXVpcmUoJy4vaXNTdHJpY3RDb21wYXJhYmxlJyksXG4gICAgbGFzdCA9IHJlcXVpcmUoJy4uL2FycmF5L2xhc3QnKSxcbiAgICB0b09iamVjdCA9IHJlcXVpcmUoJy4vdG9PYmplY3QnKSxcbiAgICB0b1BhdGggPSByZXF1aXJlKCcuL3RvUGF0aCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNQcm9wZXJ0eWAgd2hpY2ggZG9lcyBub3QgY2xvbmUgYHNyY1ZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEBwYXJhbSB7Kn0gc3JjVmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZU1hdGNoZXNQcm9wZXJ0eShwYXRoLCBzcmNWYWx1ZSkge1xuICB2YXIgaXNBcnIgPSBpc0FycmF5KHBhdGgpLFxuICAgICAgaXNDb21tb24gPSBpc0tleShwYXRoKSAmJiBpc1N0cmljdENvbXBhcmFibGUoc3JjVmFsdWUpLFxuICAgICAgcGF0aEtleSA9IChwYXRoICsgJycpO1xuXG4gIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIGtleSA9IHBhdGhLZXk7XG4gICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICBpZiAoKGlzQXJyIHx8ICFpc0NvbW1vbikgJiYgIShrZXkgaW4gb2JqZWN0KSkge1xuICAgICAgb2JqZWN0ID0gcGF0aC5sZW5ndGggPT0gMSA/IG9iamVjdCA6IGJhc2VHZXQob2JqZWN0LCBiYXNlU2xpY2UocGF0aCwgMCwgLTEpKTtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBrZXkgPSBsYXN0KHBhdGgpO1xuICAgICAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdFtrZXldID09PSBzcmNWYWx1ZVxuICAgICAgPyAoc3JjVmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIG9iamVjdCkpXG4gICAgICA6IGJhc2VJc0VxdWFsKHNyY1ZhbHVlLCBvYmplY3Rba2V5XSwgdW5kZWZpbmVkLCB0cnVlKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWF0Y2hlc1Byb3BlcnR5O1xuIiwiLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5wcm9wZXJ0eWAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlUHJvcGVydHkoa2V5KSB7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlUHJvcGVydHk7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vYmFzZUdldCcpLFxuICAgIHRvUGF0aCA9IHJlcXVpcmUoJy4vdG9QYXRoJyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlUHJvcGVydHlgIHdoaWNoIHN1cHBvcnRzIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZVByb3BlcnR5RGVlcChwYXRoKSB7XG4gIHZhciBwYXRoS2V5ID0gKHBhdGggKyAnJyk7XG4gIHBhdGggPSB0b1BhdGgocGF0aCk7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICByZXR1cm4gYmFzZUdldChvYmplY3QsIHBhdGgsIHBhdGhLZXkpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eURlZXA7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnNsaWNlYCB3aXRob3V0IGFuIGl0ZXJhdGVlIGNhbGwgZ3VhcmQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBzbGljZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc3RhcnQ9MF0gVGhlIHN0YXJ0IHBvc2l0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFtlbmQ9YXJyYXkubGVuZ3RoXSBUaGUgZW5kIHBvc2l0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBzbGljZSBvZiBgYXJyYXlgLlxuICovXG5mdW5jdGlvbiBiYXNlU2xpY2UoYXJyYXksIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgc3RhcnQgPSBzdGFydCA9PSBudWxsID8gMCA6ICgrc3RhcnQgfHwgMCk7XG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCA9IC1zdGFydCA+IGxlbmd0aCA/IDAgOiAobGVuZ3RoICsgc3RhcnQpO1xuICB9XG4gIGVuZCA9IChlbmQgPT09IHVuZGVmaW5lZCB8fCBlbmQgPiBsZW5ndGgpID8gbGVuZ3RoIDogKCtlbmQgfHwgMCk7XG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlbmd0aDtcbiAgfVxuICBsZW5ndGggPSBzdGFydCA+IGVuZCA/IDAgOiAoKGVuZCAtIHN0YXJ0KSA+Pj4gMCk7XG4gIHN0YXJ0ID4+Pj0gMDtcblxuICB2YXIgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICByZXN1bHRbaW5kZXhdID0gYXJyYXlbaW5kZXggKyBzdGFydF07XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlU2xpY2U7XG4iLCJ2YXIgYmFzZUVhY2ggPSByZXF1aXJlKCcuL2Jhc2VFYWNoJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uc29tZWAgd2l0aG91dCBzdXBwb3J0IGZvciBjYWxsYmFjayBzaG9ydGhhbmRzXG4gKiBhbmQgYHRoaXNgIGJpbmRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fHN0cmluZ30gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbnkgZWxlbWVudCBwYXNzZXMgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VTb21lKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICB2YXIgcmVzdWx0O1xuXG4gIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgIHJlc3VsdCA9IHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgIHJldHVybiAhcmVzdWx0O1xuICB9KTtcbiAgcmV0dXJuICEhcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VTb21lO1xuIiwiLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIGlmIGl0J3Mgbm90IG9uZS4gQW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkXG4gKiBmb3IgYG51bGxgIG9yIGB1bmRlZmluZWRgIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gYmFzZVRvU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PSBudWxsID8gJycgOiAodmFsdWUgKyAnJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVRvU3RyaW5nO1xuIiwidmFyIGlkZW50aXR5ID0gcmVxdWlyZSgnLi4vdXRpbGl0eS9pZGVudGl0eScpO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUNhbGxiYWNrYCB3aGljaCBvbmx5IHN1cHBvcnRzIGB0aGlzYCBiaW5kaW5nXG4gKiBhbmQgc3BlY2lmeWluZyB0aGUgbnVtYmVyIG9mIGFyZ3VtZW50cyB0byBwcm92aWRlIHRvIGBmdW5jYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gYmluZC5cbiAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcmdDb3VudF0gVGhlIG51bWJlciBvZiBhcmd1bWVudHMgdG8gcHJvdmlkZSB0byBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIGNhbGxiYWNrLlxuICovXG5mdW5jdGlvbiBiaW5kQ2FsbGJhY2soZnVuYywgdGhpc0FyZywgYXJnQ291bnQpIHtcbiAgaWYgKHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gaWRlbnRpdHk7XG4gIH1cbiAgaWYgKHRoaXNBcmcgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBmdW5jO1xuICB9XG4gIHN3aXRjaCAoYXJnQ291bnQpIHtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCB2YWx1ZSk7XG4gICAgfTtcbiAgICBjYXNlIDM6IHJldHVybiBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgIHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKTtcbiAgICB9O1xuICAgIGNhc2UgNDogcmV0dXJuIGZ1bmN0aW9uKGFjY3VtdWxhdG9yLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pIHtcbiAgICAgIHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7XG4gICAgfTtcbiAgICBjYXNlIDU6IHJldHVybiBmdW5jdGlvbih2YWx1ZSwgb3RoZXIsIGtleSwgb2JqZWN0LCBzb3VyY2UpIHtcbiAgICAgIHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgdmFsdWUsIG90aGVyLCBrZXksIG9iamVjdCwgc291cmNlKTtcbiAgICB9O1xuICB9XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmd1bWVudHMpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmRDYWxsYmFjaztcbiIsInZhciBiaW5kQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2JpbmRDYWxsYmFjaycpLFxuICAgIGlzSXRlcmF0ZWVDYWxsID0gcmVxdWlyZSgnLi9pc0l0ZXJhdGVlQ2FsbCcpLFxuICAgIHJlc3RQYXJhbSA9IHJlcXVpcmUoJy4uL2Z1bmN0aW9uL3Jlc3RQYXJhbScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgXy5hc3NpZ25gLCBgXy5kZWZhdWx0c2AsIG9yIGBfLm1lcmdlYCBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gYXNzaWduZXIgVGhlIGZ1bmN0aW9uIHRvIGFzc2lnbiB2YWx1ZXMuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhc3NpZ25lciBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQXNzaWduZXIoYXNzaWduZXIpIHtcbiAgcmV0dXJuIHJlc3RQYXJhbShmdW5jdGlvbihvYmplY3QsIHNvdXJjZXMpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID09IG51bGwgPyAwIDogc291cmNlcy5sZW5ndGgsXG4gICAgICAgIGN1c3RvbWl6ZXIgPSBsZW5ndGggPiAyID8gc291cmNlc1tsZW5ndGggLSAyXSA6IHVuZGVmaW5lZCxcbiAgICAgICAgZ3VhcmQgPSBsZW5ndGggPiAyID8gc291cmNlc1syXSA6IHVuZGVmaW5lZCxcbiAgICAgICAgdGhpc0FyZyA9IGxlbmd0aCA+IDEgPyBzb3VyY2VzW2xlbmd0aCAtIDFdIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKHR5cGVvZiBjdXN0b21pemVyID09ICdmdW5jdGlvbicpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSBiaW5kQ2FsbGJhY2soY3VzdG9taXplciwgdGhpc0FyZywgNSk7XG4gICAgICBsZW5ndGggLT0gMjtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VzdG9taXplciA9IHR5cGVvZiB0aGlzQXJnID09ICdmdW5jdGlvbicgPyB0aGlzQXJnIDogdW5kZWZpbmVkO1xuICAgICAgbGVuZ3RoIC09IChjdXN0b21pemVyID8gMSA6IDApO1xuICAgIH1cbiAgICBpZiAoZ3VhcmQgJiYgaXNJdGVyYXRlZUNhbGwoc291cmNlc1swXSwgc291cmNlc1sxXSwgZ3VhcmQpKSB7XG4gICAgICBjdXN0b21pemVyID0gbGVuZ3RoIDwgMyA/IHVuZGVmaW5lZCA6IGN1c3RvbWl6ZXI7XG4gICAgICBsZW5ndGggPSAxO1xuICAgIH1cbiAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNbaW5kZXhdO1xuICAgICAgaWYgKHNvdXJjZSkge1xuICAgICAgICBhc3NpZ25lcihvYmplY3QsIHNvdXJjZSwgY3VzdG9taXplcik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmplY3Q7XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUFzc2lnbmVyO1xuIiwidmFyIGdldExlbmd0aCA9IHJlcXVpcmUoJy4vZ2V0TGVuZ3RoJyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuL2lzTGVuZ3RoJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGBiYXNlRWFjaGAgb3IgYGJhc2VFYWNoUmlnaHRgIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2Zyb21SaWdodF0gU3BlY2lmeSBpdGVyYXRpbmcgZnJvbSByaWdodCB0byBsZWZ0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYmFzZSBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQmFzZUVhY2goZWFjaEZ1bmMsIGZyb21SaWdodCkge1xuICByZXR1cm4gZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgICB2YXIgbGVuZ3RoID0gY29sbGVjdGlvbiA/IGdldExlbmd0aChjb2xsZWN0aW9uKSA6IDA7XG4gICAgaWYgKCFpc0xlbmd0aChsZW5ndGgpKSB7XG4gICAgICByZXR1cm4gZWFjaEZ1bmMoY29sbGVjdGlvbiwgaXRlcmF0ZWUpO1xuICAgIH1cbiAgICB2YXIgaW5kZXggPSBmcm9tUmlnaHQgPyBsZW5ndGggOiAtMSxcbiAgICAgICAgaXRlcmFibGUgPSB0b09iamVjdChjb2xsZWN0aW9uKTtcblxuICAgIHdoaWxlICgoZnJvbVJpZ2h0ID8gaW5kZXgtLSA6ICsraW5kZXggPCBsZW5ndGgpKSB7XG4gICAgICBpZiAoaXRlcmF0ZWUoaXRlcmFibGVbaW5kZXhdLCBpbmRleCwgaXRlcmFibGUpID09PSBmYWxzZSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNvbGxlY3Rpb247XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQmFzZUVhY2g7XG4iLCJ2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL3RvT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGJhc2UgZnVuY3Rpb24gZm9yIGBfLmZvckluYCBvciBgXy5mb3JJblJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVCYXNlRm9yKGZyb21SaWdodCkge1xuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSwga2V5c0Z1bmMpIHtcbiAgICB2YXIgaXRlcmFibGUgPSB0b09iamVjdChvYmplY3QpLFxuICAgICAgICBwcm9wcyA9IGtleXNGdW5jKG9iamVjdCksXG4gICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aCxcbiAgICAgICAgaW5kZXggPSBmcm9tUmlnaHQgPyBsZW5ndGggOiAtMTtcblxuICAgIHdoaWxlICgoZnJvbVJpZ2h0ID8gaW5kZXgtLSA6ICsraW5kZXggPCBsZW5ndGgpKSB7XG4gICAgICB2YXIga2V5ID0gcHJvcHNbaW5kZXhdO1xuICAgICAgaWYgKGl0ZXJhdGVlKGl0ZXJhYmxlW2tleV0sIGtleSwgaXRlcmFibGUpID09PSBmYWxzZSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCYXNlRm9yO1xuIiwidmFyIGJpbmRDYWxsYmFjayA9IHJlcXVpcmUoJy4vYmluZENhbGxiYWNrJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiBmb3IgYF8uZm9yRWFjaGAgb3IgYF8uZm9yRWFjaFJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gYXJyYXlGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYW4gYXJyYXkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBlYWNoRnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGEgY29sbGVjdGlvbi5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGVhY2ggZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUZvckVhY2goYXJyYXlGdW5jLCBlYWNoRnVuYykge1xuICByZXR1cm4gZnVuY3Rpb24oY29sbGVjdGlvbiwgaXRlcmF0ZWUsIHRoaXNBcmcpIHtcbiAgICByZXR1cm4gKHR5cGVvZiBpdGVyYXRlZSA9PSAnZnVuY3Rpb24nICYmIHRoaXNBcmcgPT09IHVuZGVmaW5lZCAmJiBpc0FycmF5KGNvbGxlY3Rpb24pKVxuICAgICAgPyBhcnJheUZ1bmMoY29sbGVjdGlvbiwgaXRlcmF0ZWUpXG4gICAgICA6IGVhY2hGdW5jKGNvbGxlY3Rpb24sIGJpbmRDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgMykpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUZvckVhY2g7XG4iLCJ2YXIgYmluZENhbGxiYWNrID0gcmVxdWlyZSgnLi9iaW5kQ2FsbGJhY2snKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gZm9yIGBfLmZvck93bmAgb3IgYF8uZm9yT3duUmlnaHRgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBvYmplY3RGdW5jIFRoZSBmdW5jdGlvbiB0byBpdGVyYXRlIG92ZXIgYW4gb2JqZWN0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZWFjaCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRm9yT3duKG9iamVjdEZ1bmMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCwgaXRlcmF0ZWUsIHRoaXNBcmcpIHtcbiAgICBpZiAodHlwZW9mIGl0ZXJhdGVlICE9ICdmdW5jdGlvbicgfHwgdGhpc0FyZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpdGVyYXRlZSA9IGJpbmRDYWxsYmFjayhpdGVyYXRlZSwgdGhpc0FyZywgMyk7XG4gICAgfVxuICAgIHJldHVybiBvYmplY3RGdW5jKG9iamVjdCwgaXRlcmF0ZWUpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUZvck93bjtcbiIsInZhciBiYXNlQ2FsbGJhY2sgPSByZXF1aXJlKCcuL2Jhc2VDYWxsYmFjaycpLFxuICAgIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuL2Jhc2VGb3JPd24nKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gZm9yIGBfLm1hcEtleXNgIG9yIGBfLm1hcFZhbHVlc2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzTWFwS2V5c10gU3BlY2lmeSBtYXBwaW5nIGtleXMgaW5zdGVhZCBvZiB2YWx1ZXMuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBtYXAgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZU9iamVjdE1hcHBlcihpc01hcEtleXMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCwgaXRlcmF0ZWUsIHRoaXNBcmcpIHtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgaXRlcmF0ZWUgPSBiYXNlQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuXG4gICAgYmFzZUZvck93bihvYmplY3QsIGZ1bmN0aW9uKHZhbHVlLCBrZXksIG9iamVjdCkge1xuICAgICAgdmFyIG1hcHBlZCA9IGl0ZXJhdGVlKHZhbHVlLCBrZXksIG9iamVjdCk7XG4gICAgICBrZXkgPSBpc01hcEtleXMgPyBtYXBwZWQgOiBrZXk7XG4gICAgICB2YWx1ZSA9IGlzTWFwS2V5cyA/IHZhbHVlIDogbWFwcGVkO1xuICAgICAgcmVzdWx0W2tleV0gPSB2YWx1ZTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZU9iamVjdE1hcHBlcjtcbiIsInZhciBhcnJheVNvbWUgPSByZXF1aXJlKCcuL2FycmF5U29tZScpO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgYXJyYXlzIHdpdGggc3VwcG9ydCBmb3JcbiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0FycmF5fSBvdGhlciBUaGUgb3RoZXIgYXJyYXkgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmluZyBhcnJheXMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0xvb3NlXSBTcGVjaWZ5IHBlcmZvcm1pbmcgcGFydGlhbCBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0FdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBvYmplY3RzLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQl0gVHJhY2tzIHRyYXZlcnNlZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGFycmF5cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbEFycmF5cyhhcnJheSwgb3RoZXIsIGVxdWFsRnVuYywgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBvdGhMZW5ndGggPSBvdGhlci5sZW5ndGg7XG5cbiAgaWYgKGFyckxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIShpc0xvb3NlICYmIG90aExlbmd0aCA+IGFyckxlbmd0aCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gSWdub3JlIG5vbi1pbmRleCBwcm9wZXJ0aWVzLlxuICB3aGlsZSAoKytpbmRleCA8IGFyckxlbmd0aCkge1xuICAgIHZhciBhcnJWYWx1ZSA9IGFycmF5W2luZGV4XSxcbiAgICAgICAgb3RoVmFsdWUgPSBvdGhlcltpbmRleF0sXG4gICAgICAgIHJlc3VsdCA9IGN1c3RvbWl6ZXIgPyBjdXN0b21pemVyKGlzTG9vc2UgPyBvdGhWYWx1ZSA6IGFyclZhbHVlLCBpc0xvb3NlID8gYXJyVmFsdWUgOiBvdGhWYWx1ZSwgaW5kZXgpIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgIGlmIChpc0xvb3NlKSB7XG4gICAgICBpZiAoIWFycmF5U29tZShvdGhlciwgZnVuY3Rpb24ob3RoVmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiBhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHwgZXF1YWxGdW5jKGFyclZhbHVlLCBvdGhWYWx1ZSwgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpO1xuICAgICAgICAgIH0pKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCEoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXF1YWxBcnJheXM7XG4iLCIvKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJztcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIGNvbXBhcmluZyBvYmplY3RzIG9mXG4gKiB0aGUgc2FtZSBgdG9TdHJpbmdUYWdgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIG9ubHkgc3VwcG9ydHMgY29tcGFyaW5nIHZhbHVlcyB3aXRoIHRhZ3Mgb2ZcbiAqIGBCb29sZWFuYCwgYERhdGVgLCBgRXJyb3JgLCBgTnVtYmVyYCwgYFJlZ0V4cGAsIG9yIGBTdHJpbmdgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRoZSBgdG9TdHJpbmdUYWdgIG9mIHRoZSBvYmplY3RzIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxCeVRhZyhvYmplY3QsIG90aGVyLCB0YWcpIHtcbiAgc3dpdGNoICh0YWcpIHtcbiAgICBjYXNlIGJvb2xUYWc6XG4gICAgY2FzZSBkYXRlVGFnOlxuICAgICAgLy8gQ29lcmNlIGRhdGVzIGFuZCBib29sZWFucyB0byBudW1iZXJzLCBkYXRlcyB0byBtaWxsaXNlY29uZHMgYW5kIGJvb2xlYW5zXG4gICAgICAvLyB0byBgMWAgb3IgYDBgIHRyZWF0aW5nIGludmFsaWQgZGF0ZXMgY29lcmNlZCB0byBgTmFOYCBhcyBub3QgZXF1YWwuXG4gICAgICByZXR1cm4gK29iamVjdCA9PSArb3RoZXI7XG5cbiAgICBjYXNlIGVycm9yVGFnOlxuICAgICAgcmV0dXJuIG9iamVjdC5uYW1lID09IG90aGVyLm5hbWUgJiYgb2JqZWN0Lm1lc3NhZ2UgPT0gb3RoZXIubWVzc2FnZTtcblxuICAgIGNhc2UgbnVtYmVyVGFnOlxuICAgICAgLy8gVHJlYXQgYE5hTmAgdnMuIGBOYU5gIGFzIGVxdWFsLlxuICAgICAgcmV0dXJuIChvYmplY3QgIT0gK29iamVjdClcbiAgICAgICAgPyBvdGhlciAhPSArb3RoZXJcbiAgICAgICAgOiBvYmplY3QgPT0gK290aGVyO1xuXG4gICAgY2FzZSByZWdleHBUYWc6XG4gICAgY2FzZSBzdHJpbmdUYWc6XG4gICAgICAvLyBDb2VyY2UgcmVnZXhlcyB0byBzdHJpbmdzIGFuZCB0cmVhdCBzdHJpbmdzIHByaW1pdGl2ZXMgYW5kIHN0cmluZ1xuICAgICAgLy8gb2JqZWN0cyBhcyBlcXVhbC4gU2VlIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDE1LjEwLjYuNCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgICAgcmV0dXJuIG9iamVjdCA9PSAob3RoZXIgKyAnJyk7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsQnlUYWc7XG4iLCJ2YXIga2V5cyA9IHJlcXVpcmUoJy4uL29iamVjdC9rZXlzJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3Igb2JqZWN0cyB3aXRoIHN1cHBvcnQgZm9yXG4gKiBwYXJ0aWFsIGRlZXAgY29tcGFyaXNvbnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmluZyB2YWx1ZXMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0xvb3NlXSBTcGVjaWZ5IHBlcmZvcm1pbmcgcGFydGlhbCBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7QXJyYXl9IFtzdGFja0FdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBvYmplY3RzLlxuICogQHBhcmFtIHtBcnJheX0gW3N0YWNrQl0gVHJhY2tzIHRyYXZlcnNlZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxPYmplY3RzKG9iamVjdCwgb3RoZXIsIGVxdWFsRnVuYywgY3VzdG9taXplciwgaXNMb29zZSwgc3RhY2tBLCBzdGFja0IpIHtcbiAgdmFyIG9ialByb3BzID0ga2V5cyhvYmplY3QpLFxuICAgICAgb2JqTGVuZ3RoID0gb2JqUHJvcHMubGVuZ3RoLFxuICAgICAgb3RoUHJvcHMgPSBrZXlzKG90aGVyKSxcbiAgICAgIG90aExlbmd0aCA9IG90aFByb3BzLmxlbmd0aDtcblxuICBpZiAob2JqTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhaXNMb29zZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgaW5kZXggPSBvYmpMZW5ndGg7XG4gIHdoaWxlIChpbmRleC0tKSB7XG4gICAgdmFyIGtleSA9IG9ialByb3BzW2luZGV4XTtcbiAgICBpZiAoIShpc0xvb3NlID8ga2V5IGluIG90aGVyIDogaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwga2V5KSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgdmFyIHNraXBDdG9yID0gaXNMb29zZTtcbiAgd2hpbGUgKCsraW5kZXggPCBvYmpMZW5ndGgpIHtcbiAgICBrZXkgPSBvYmpQcm9wc1tpbmRleF07XG4gICAgdmFyIG9ialZhbHVlID0gb2JqZWN0W2tleV0sXG4gICAgICAgIG90aFZhbHVlID0gb3RoZXJba2V5XSxcbiAgICAgICAgcmVzdWx0ID0gY3VzdG9taXplciA/IGN1c3RvbWl6ZXIoaXNMb29zZSA/IG90aFZhbHVlIDogb2JqVmFsdWUsIGlzTG9vc2U/IG9ialZhbHVlIDogb3RoVmFsdWUsIGtleSkgOiB1bmRlZmluZWQ7XG5cbiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoIShyZXN1bHQgPT09IHVuZGVmaW5lZCA/IGVxdWFsRnVuYyhvYmpWYWx1ZSwgb3RoVmFsdWUsIGN1c3RvbWl6ZXIsIGlzTG9vc2UsIHN0YWNrQSwgc3RhY2tCKSA6IHJlc3VsdCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgc2tpcEN0b3IgfHwgKHNraXBDdG9yID0ga2V5ID09ICdjb25zdHJ1Y3RvcicpO1xuICB9XG4gIGlmICghc2tpcEN0b3IpIHtcbiAgICB2YXIgb2JqQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcixcbiAgICAgICAgb3RoQ3RvciA9IG90aGVyLmNvbnN0cnVjdG9yO1xuXG4gICAgLy8gTm9uIGBPYmplY3RgIG9iamVjdCBpbnN0YW5jZXMgd2l0aCBkaWZmZXJlbnQgY29uc3RydWN0b3JzIGFyZSBub3QgZXF1YWwuXG4gICAgaWYgKG9iakN0b3IgIT0gb3RoQ3RvciAmJlxuICAgICAgICAoJ2NvbnN0cnVjdG9yJyBpbiBvYmplY3QgJiYgJ2NvbnN0cnVjdG9yJyBpbiBvdGhlcikgJiZcbiAgICAgICAgISh0eXBlb2Ygb2JqQ3RvciA9PSAnZnVuY3Rpb24nICYmIG9iakN0b3IgaW5zdGFuY2VvZiBvYmpDdG9yICYmXG4gICAgICAgICAgdHlwZW9mIG90aEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBvdGhDdG9yIGluc3RhbmNlb2Ygb3RoQ3RvcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXF1YWxPYmplY3RzO1xuIiwidmFyIGJhc2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vYmFzZVByb3BlcnR5Jyk7XG5cbi8qKlxuICogR2V0cyB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSB2YWx1ZSBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGF2b2lkIGEgW0pJVCBidWddKGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNDI3OTIpXG4gKiB0aGF0IGFmZmVjdHMgU2FmYXJpIG9uIGF0IGxlYXN0IGlPUyA4LjEtOC4zIEFSTTY0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgXCJsZW5ndGhcIiB2YWx1ZS5cbiAqL1xudmFyIGdldExlbmd0aCA9IGJhc2VQcm9wZXJ0eSgnbGVuZ3RoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TGVuZ3RoO1xuIiwidmFyIGlzU3RyaWN0Q29tcGFyYWJsZSA9IHJlcXVpcmUoJy4vaXNTdHJpY3RDb21wYXJhYmxlJyksXG4gICAgcGFpcnMgPSByZXF1aXJlKCcuLi9vYmplY3QvcGFpcnMnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBwcm9wZXJ5IG5hbWVzLCB2YWx1ZXMsIGFuZCBjb21wYXJlIGZsYWdzIG9mIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG1hdGNoIGRhdGEgb2YgYG9iamVjdGAuXG4gKi9cbmZ1bmN0aW9uIGdldE1hdGNoRGF0YShvYmplY3QpIHtcbiAgdmFyIHJlc3VsdCA9IHBhaXJzKG9iamVjdCksXG4gICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIHJlc3VsdFtsZW5ndGhdWzJdID0gaXNTdHJpY3RDb21wYXJhYmxlKHJlc3VsdFtsZW5ndGhdWzFdKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldE1hdGNoRGF0YTtcbiIsInZhciBpc05hdGl2ZSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNOYXRpdmUnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBuYXRpdmUgZnVuY3Rpb24gYXQgYGtleWAgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgbWV0aG9kIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBpZiBpdCdzIG5hdGl2ZSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqL1xuZnVuY3Rpb24gZ2V0TmF0aXZlKG9iamVjdCwga2V5KSB7XG4gIHZhciB2YWx1ZSA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG4gIHJldHVybiBpc05hdGl2ZSh2YWx1ZSkgPyB2YWx1ZSA6IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXROYXRpdmU7XG4iLCJ2YXIgZ2V0TGVuZ3RoID0gcmVxdWlyZSgnLi9nZXRMZW5ndGgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgoZ2V0TGVuZ3RoKHZhbHVlKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheUxpa2U7XG4iLCIvKiogVXNlZCB0byBkZXRlY3QgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuICovXG52YXIgcmVJc1VpbnQgPSAvXlxcZCskLztcblxuLyoqXG4gKiBVc2VkIGFzIHRoZSBbbWF4aW11bSBsZW5ndGhdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW51bWJlci5tYXhfc2FmZV9pbnRlZ2VyKVxuICogb2YgYW4gYXJyYXktbGlrZSB2YWx1ZS5cbiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBpbmRleC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcGFyYW0ge251bWJlcn0gW2xlbmd0aD1NQVhfU0FGRV9JTlRFR0VSXSBUaGUgdXBwZXIgYm91bmRzIG9mIGEgdmFsaWQgaW5kZXguXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGluZGV4LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzSW5kZXgodmFsdWUsIGxlbmd0aCkge1xuICB2YWx1ZSA9ICh0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgfHwgcmVJc1VpbnQudGVzdCh2YWx1ZSkpID8gK3ZhbHVlIDogLTE7XG4gIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcbiAgcmV0dXJuIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPCBsZW5ndGg7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJbmRleDtcbiIsInZhciBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9pc0luZGV4JyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBwcm92aWRlZCBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIHZhbHVlIGFyZ3VtZW50LlxuICogQHBhcmFtIHsqfSBpbmRleCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIGluZGV4IG9yIGtleSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBwb3RlbnRpYWwgaXRlcmF0ZWUgb2JqZWN0IGFyZ3VtZW50LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcmd1bWVudHMgYXJlIGZyb20gYW4gaXRlcmF0ZWUgY2FsbCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0l0ZXJhdGVlQ2FsbCh2YWx1ZSwgaW5kZXgsIG9iamVjdCkge1xuICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHR5cGUgPSB0eXBlb2YgaW5kZXg7XG4gIGlmICh0eXBlID09ICdudW1iZXInXG4gICAgICA/IChpc0FycmF5TGlrZShvYmplY3QpICYmIGlzSW5kZXgoaW5kZXgsIG9iamVjdC5sZW5ndGgpKVxuICAgICAgOiAodHlwZSA9PSAnc3RyaW5nJyAmJiBpbmRleCBpbiBvYmplY3QpKSB7XG4gICAgdmFyIG90aGVyID0gb2JqZWN0W2luZGV4XTtcbiAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlID8gKHZhbHVlID09PSBvdGhlcikgOiAob3RoZXIgIT09IG90aGVyKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJdGVyYXRlZUNhbGw7XG4iLCJ2YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi90b09iamVjdCcpO1xuXG4vKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovXG52YXIgcmVJc0RlZXBQcm9wID0gL1xcLnxcXFsoPzpbXltcXF1dKnwoW1wiJ10pKD86KD8hXFwxKVteXFxuXFxcXF18XFxcXC4pKj9cXDEpXFxdLyxcbiAgICByZUlzUGxhaW5Qcm9wID0gL15cXHcqJC87XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCBub3QgYSBwcm9wZXJ0eSBwYXRoLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5IGtleXMgb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNLZXkodmFsdWUsIG9iamVjdCkge1xuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgaWYgKCh0eXBlID09ICdzdHJpbmcnICYmIHJlSXNQbGFpblByb3AudGVzdCh2YWx1ZSkpIHx8IHR5cGUgPT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHJlc3VsdCA9ICFyZUlzRGVlcFByb3AudGVzdCh2YWx1ZSk7XG4gIHJldHVybiByZXN1bHQgfHwgKG9iamVjdCAhPSBudWxsICYmIHZhbHVlIGluIHRvT2JqZWN0KG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzS2V5O1xuIiwiLyoqXG4gKiBVc2VkIGFzIHRoZSBbbWF4aW11bSBsZW5ndGhdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW51bWJlci5tYXhfc2FmZV9pbnRlZ2VyKVxuICogb2YgYW4gYXJyYXktbGlrZSB2YWx1ZS5cbiAqL1xudmFyIE1BWF9TQUZFX0lOVEVHRVIgPSA5MDA3MTk5MjU0NzQwOTkxO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gaXMgYmFzZWQgb24gW2BUb0xlbmd0aGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbGVuZ3RoKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0xlbmd0aDtcbiIsIi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gIHJldHVybiAhIXZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdExpa2U7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUgZm9yIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29ucywgaS5lLiBgPT09YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpZiBzdWl0YWJsZSBmb3Igc3RyaWN0XG4gKiAgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNTdHJpY3RDb21wYXJhYmxlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PT0gdmFsdWUgJiYgIWlzT2JqZWN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1N0cmljdENvbXBhcmFibGU7XG4iLCJ2YXIgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJndW1lbnRzJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpLFxuICAgIGlzSW5kZXggPSByZXF1aXJlKCcuL2lzSW5kZXgnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICBrZXlzSW4gPSByZXF1aXJlKCcuLi9vYmplY3Qva2V5c0luJyk7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEEgZmFsbGJhY2sgaW1wbGVtZW50YXRpb24gb2YgYE9iamVjdC5rZXlzYCB3aGljaCBjcmVhdGVzIGFuIGFycmF5IG9mIHRoZVxuICogb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIHNoaW1LZXlzKG9iamVjdCkge1xuICB2YXIgcHJvcHMgPSBrZXlzSW4ob2JqZWN0KSxcbiAgICAgIHByb3BzTGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gcHJvcHNMZW5ndGggJiYgb2JqZWN0Lmxlbmd0aDtcblxuICB2YXIgYWxsb3dJbmRleGVzID0gISFsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJlxuICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IHByb3BzTGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHByb3BzW2luZGV4XTtcbiAgICBpZiAoKGFsbG93SW5kZXhlcyAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSkgfHwgaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc2hpbUtleXM7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuLi9sYW5nL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhbiBvYmplY3QgaWYgaXQncyBub3Qgb25lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgb2JqZWN0LlxuICovXG5mdW5jdGlvbiB0b09iamVjdCh2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3QodmFsdWUpID8gdmFsdWUgOiBPYmplY3QodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvT2JqZWN0O1xuIiwidmFyIGJhc2VUb1N0cmluZyA9IHJlcXVpcmUoJy4vYmFzZVRvU3RyaW5nJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4uL2xhbmcvaXNBcnJheScpO1xuXG4vKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovXG52YXIgcmVQcm9wTmFtZSA9IC9bXi5bXFxdXSt8XFxbKD86KC0/XFxkKyg/OlxcLlxcZCspPyl8KFtcIiddKSgoPzooPyFcXDIpW15cXG5cXFxcXXxcXFxcLikqPylcXDIpXFxdL2c7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlRXNjYXBlQ2hhciA9IC9cXFxcKFxcXFwpPy9nO1xuXG4vKipcbiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gcHJvcGVydHkgcGF0aCBhcnJheSBpZiBpdCdzIG5vdCBvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHByb3BlcnR5IHBhdGggYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIHRvUGF0aCh2YWx1ZSkge1xuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBiYXNlVG9TdHJpbmcodmFsdWUpLnJlcGxhY2UocmVQcm9wTmFtZSwgZnVuY3Rpb24obWF0Y2gsIG51bWJlciwgcXVvdGUsIHN0cmluZykge1xuICAgIHJlc3VsdC5wdXNoKHF1b3RlID8gc3RyaW5nLnJlcGxhY2UocmVFc2NhcGVDaGFyLCAnJDEnKSA6IChudW1iZXIgfHwgbWF0Y2gpKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdG9QYXRoO1xuIiwidmFyIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNBcnJheUxpa2UnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90by5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBhcmd1bWVudHNgIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0FyZ3VtZW50cyhmdW5jdGlvbigpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJndW1lbnRzKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0FyZ3VtZW50cyh2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBpc0FycmF5TGlrZSh2YWx1ZSkgJiZcbiAgICBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnY2FsbGVlJykgJiYgIXByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwodmFsdWUsICdjYWxsZWUnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FyZ3VtZW50cztcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9nZXROYXRpdmUnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2lzTGVuZ3RoJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XSc7XG5cbi8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmpUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZUlzQXJyYXkgPSBnZXROYXRpdmUoQXJyYXksICdpc0FycmF5Jyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhbiBgQXJyYXlgIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0FycmF5KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5KGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzQXJyYXkgPSBuYXRpdmVJc0FycmF5IHx8IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gYXJyYXlUYWc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJyYXk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0Jyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBGdW5jdGlvbmAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oXyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0Z1bmN0aW9uKC9hYmMvKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWUpIHtcbiAgLy8gVGhlIHVzZSBvZiBgT2JqZWN0I3RvU3RyaW5nYCBhdm9pZHMgaXNzdWVzIHdpdGggdGhlIGB0eXBlb2ZgIG9wZXJhdG9yXG4gIC8vIGluIG9sZGVyIHZlcnNpb25zIG9mIENocm9tZSBhbmQgU2FmYXJpIHdoaWNoIHJldHVybiAnZnVuY3Rpb24nIGZvciByZWdleGVzXG4gIC8vIGFuZCBTYWZhcmkgOCB3aGljaCByZXR1cm5zICdvYmplY3QnIGZvciB0eXBlZCBhcnJheSBjb25zdHJ1Y3RvcnMuXG4gIHJldHVybiBpc09iamVjdCh2YWx1ZSkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gZnVuY1RhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0Z1bmN0aW9uO1xuIiwidmFyIGlzRnVuY3Rpb24gPSByZXF1aXJlKCcuL2lzRnVuY3Rpb24nKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGhvc3QgY29uc3RydWN0b3JzIChTYWZhcmkgPiA1KS4gKi9cbnZhciByZUlzSG9zdEN0b3IgPSAvXlxcW29iamVjdCAuKz9Db25zdHJ1Y3RvclxcXSQvO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xudmFyIGZuVG9TdHJpbmcgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBpZiBhIG1ldGhvZCBpcyBuYXRpdmUuICovXG52YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICBmblRvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkpLnJlcGxhY2UoL1tcXFxcXiQuKis/KClbXFxde318XS9nLCAnXFxcXCQmJylcbiAgLnJlcGxhY2UoL2hhc093blByb3BlcnR5fChmdW5jdGlvbikuKj8oPz1cXFxcXFwoKXwgZm9yIC4rPyg/PVxcXFxcXF0pL2csICckMS4qPycpICsgJyQnXG4pO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgbmF0aXZlIGZ1bmN0aW9uLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbiwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzTmF0aXZlKEFycmF5LnByb3RvdHlwZS5wdXNoKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzTmF0aXZlKF8pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNOYXRpdmUodmFsdWUpIHtcbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgcmV0dXJuIHJlSXNOYXRpdmUudGVzdChmblRvU3RyaW5nLmNhbGwodmFsdWUpKTtcbiAgfVxuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJiByZUlzSG9zdEN0b3IudGVzdCh2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNOYXRpdmU7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZSBbbGFuZ3VhZ2UgdHlwZV0oaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4OCkgb2YgYE9iamVjdGAuXG4gKiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3Qoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KDEpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgLy8gQXZvaWQgYSBWOCBKSVQgYnVnIGluIENocm9tZSAxOS0yMC5cbiAgLy8gU2VlIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0yMjkxIGZvciBtb3JlIGRldGFpbHMuXG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICByZXR1cm4gISF2YWx1ZSAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzT2JqZWN0O1xuIiwidmFyIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJyxcbiAgICBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsXG4gICAgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICBvYmplY3RUYWcgPSAnW29iamVjdCBPYmplY3RdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICB3ZWFrTWFwVGFnID0gJ1tvYmplY3QgV2Vha01hcF0nO1xuXG52YXIgYXJyYXlCdWZmZXJUYWcgPSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nLFxuICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4vKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBvZiB0eXBlZCBhcnJheXMuICovXG52YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTtcbnR5cGVkQXJyYXlUYWdzW2Zsb2F0MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbZmxvYXQ2NFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQxNlRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xudHlwZWRBcnJheVRhZ3NbYXJnc1RhZ10gPSB0eXBlZEFycmF5VGFnc1thcnJheVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gdHlwZWRBcnJheVRhZ3NbYm9vbFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZGF0ZVRhZ10gPSB0eXBlZEFycmF5VGFnc1tlcnJvclRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZnVuY1RhZ10gPSB0eXBlZEFycmF5VGFnc1ttYXBUYWddID1cbnR5cGVkQXJyYXlUYWdzW251bWJlclRhZ10gPSB0eXBlZEFycmF5VGFnc1tvYmplY3RUYWddID1cbnR5cGVkQXJyYXlUYWdzW3JlZ2V4cFRhZ10gPSB0eXBlZEFycmF5VGFnc1tzZXRUYWddID1cbnR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZ10gPSB0eXBlZEFycmF5VGFnc1t3ZWFrTWFwVGFnXSA9IGZhbHNlO1xuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqVG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNUeXBlZEFycmF5KG5ldyBVaW50OEFycmF5KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShbXSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1R5cGVkQXJyYXkodmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNMZW5ndGgodmFsdWUubGVuZ3RoKSAmJiAhIXR5cGVkQXJyYXlUYWdzW29ialRvU3RyaW5nLmNhbGwodmFsdWUpXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1R5cGVkQXJyYXk7XG4iLCJ2YXIgYXNzaWduV2l0aCA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Fzc2lnbldpdGgnKSxcbiAgICBiYXNlQXNzaWduID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvYmFzZUFzc2lnbicpLFxuICAgIGNyZWF0ZUFzc2lnbmVyID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlQXNzaWduZXInKTtcblxuLyoqXG4gKiBBc3NpZ25zIG93biBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb2Ygc291cmNlIG9iamVjdChzKSB0byB0aGUgZGVzdGluYXRpb25cbiAqIG9iamVjdC4gU3Vic2VxdWVudCBzb3VyY2VzIG92ZXJ3cml0ZSBwcm9wZXJ0eSBhc3NpZ25tZW50cyBvZiBwcmV2aW91cyBzb3VyY2VzLlxuICogSWYgYGN1c3RvbWl6ZXJgIGlzIHByb3ZpZGVkIGl0J3MgaW52b2tlZCB0byBwcm9kdWNlIHRoZSBhc3NpZ25lZCB2YWx1ZXMuXG4gKiBUaGUgYGN1c3RvbWl6ZXJgIGlzIGJvdW5kIHRvIGB0aGlzQXJnYCBhbmQgaW52b2tlZCB3aXRoIGZpdmUgYXJndW1lbnRzOlxuICogKG9iamVjdFZhbHVlLCBzb3VyY2VWYWx1ZSwga2V5LCBvYmplY3QsIHNvdXJjZSkuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIG11dGF0ZXMgYG9iamVjdGAgYW5kIGlzIGJhc2VkIG9uXG4gKiBbYE9iamVjdC5hc3NpZ25gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QuYXNzaWduKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGFsaWFzIGV4dGVuZFxuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBhc3NpZ25lZCB2YWx1ZXMuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGN1c3RvbWl6ZXJgLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5hc3NpZ24oeyAndXNlcic6ICdiYXJuZXknIH0sIHsgJ2FnZSc6IDQwIH0sIHsgJ3VzZXInOiAnZnJlZCcgfSk7XG4gKiAvLyA9PiB7ICd1c2VyJzogJ2ZyZWQnLCAnYWdlJzogNDAgfVxuICpcbiAqIC8vIHVzaW5nIGEgY3VzdG9taXplciBjYWxsYmFja1xuICogdmFyIGRlZmF1bHRzID0gXy5wYXJ0aWFsUmlnaHQoXy5hc3NpZ24sIGZ1bmN0aW9uKHZhbHVlLCBvdGhlcikge1xuICogICByZXR1cm4gXy5pc1VuZGVmaW5lZCh2YWx1ZSkgPyBvdGhlciA6IHZhbHVlO1xuICogfSk7XG4gKlxuICogZGVmYXVsdHMoeyAndXNlcic6ICdiYXJuZXknIH0sIHsgJ2FnZSc6IDM2IH0sIHsgJ3VzZXInOiAnZnJlZCcgfSk7XG4gKiAvLyA9PiB7ICd1c2VyJzogJ2Jhcm5leScsICdhZ2UnOiAzNiB9XG4gKi9cbnZhciBhc3NpZ24gPSBjcmVhdGVBc3NpZ25lcihmdW5jdGlvbihvYmplY3QsIHNvdXJjZSwgY3VzdG9taXplcikge1xuICByZXR1cm4gY3VzdG9taXplclxuICAgID8gYXNzaWduV2l0aChvYmplY3QsIHNvdXJjZSwgY3VzdG9taXplcilcbiAgICA6IGJhc2VBc3NpZ24ob2JqZWN0LCBzb3VyY2UpO1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gYXNzaWduO1xuIiwidmFyIGJhc2VGb3JPd24gPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlRm9yT3duJyksXG4gICAgY3JlYXRlRm9yT3duID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY3JlYXRlRm9yT3duJyk7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBvd24gZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIGFuIG9iamVjdCBpbnZva2luZyBgaXRlcmF0ZWVgXG4gKiBmb3IgZWFjaCBwcm9wZXJ0eS4gVGhlIGBpdGVyYXRlZWAgaXMgYm91bmQgdG8gYHRoaXNBcmdgIGFuZCBpbnZva2VkIHdpdGhcbiAqIHRocmVlIGFyZ3VtZW50czogKHZhbHVlLCBrZXksIG9iamVjdCkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb25cbiAqIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgaXRlcmF0ZWVgLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy5mb3JPd24obmV3IEZvbywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICogICBjb25zb2xlLmxvZyhrZXkpO1xuICogfSk7XG4gKiAvLyA9PiBsb2dzICdhJyBhbmQgJ2InIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbnZhciBmb3JPd24gPSBjcmVhdGVGb3JPd24oYmFzZUZvck93bik7XG5cbm1vZHVsZS5leHBvcnRzID0gZm9yT3duO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2dldE5hdGl2ZScpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNBcnJheUxpa2UnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKSxcbiAgICBzaGltS2V5cyA9IHJlcXVpcmUoJy4uL2ludGVybmFsL3NoaW1LZXlzJyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlS2V5cyA9IGdldE5hdGl2ZShPYmplY3QsICdrZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuIFNlZSB0aGVcbiAqIFtFUyBzcGVjXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3Qua2V5cylcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5cyhuZXcgRm9vKTtcbiAqIC8vID0+IFsnYScsICdiJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqXG4gKiBfLmtleXMoJ2hpJyk7XG4gKiAvLyA9PiBbJzAnLCAnMSddXG4gKi9cbnZhciBrZXlzID0gIW5hdGl2ZUtleXMgPyBzaGltS2V5cyA6IGZ1bmN0aW9uKG9iamVjdCkge1xuICB2YXIgQ3RvciA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0LmNvbnN0cnVjdG9yO1xuICBpZiAoKHR5cGVvZiBDdG9yID09ICdmdW5jdGlvbicgJiYgQ3Rvci5wcm90b3R5cGUgPT09IG9iamVjdCkgfHxcbiAgICAgICh0eXBlb2Ygb2JqZWN0ICE9ICdmdW5jdGlvbicgJiYgaXNBcnJheUxpa2Uob2JqZWN0KSkpIHtcbiAgICByZXR1cm4gc2hpbUtleXMob2JqZWN0KTtcbiAgfVxuICByZXR1cm4gaXNPYmplY3Qob2JqZWN0KSA/IG5hdGl2ZUtleXMob2JqZWN0KSA6IFtdO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBrZXlzO1xuIiwidmFyIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi4vbGFuZy9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuLi9sYW5nL2lzQXJyYXknKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNJbmRleCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4uL2xhbmcvaXNPYmplY3QnKTtcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGFuZCBpbmhlcml0ZWQgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy5rZXlzSW4obmV3IEZvbyk7XG4gKiAvLyA9PiBbJ2EnLCAnYicsICdjJ10gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqL1xuZnVuY3Rpb24ga2V5c0luKG9iamVjdCkge1xuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XG4gICAgb2JqZWN0ID0gT2JqZWN0KG9iamVjdCk7XG4gIH1cbiAgdmFyIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7XG4gIGxlbmd0aCA9IChsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJlxuICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSkgJiYgbGVuZ3RoKSB8fCAwO1xuXG4gIHZhciBDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgaW5kZXggPSAtMSxcbiAgICAgIGlzUHJvdG8gPSB0eXBlb2YgQ3RvciA9PSAnZnVuY3Rpb24nICYmIEN0b3IucHJvdG90eXBlID09PSBvYmplY3QsXG4gICAgICByZXN1bHQgPSBBcnJheShsZW5ndGgpLFxuICAgICAgc2tpcEluZGV4ZXMgPSBsZW5ndGggPiAwO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IChpbmRleCArICcnKTtcbiAgfVxuICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgaWYgKCEoc2tpcEluZGV4ZXMgJiYgaXNJbmRleChrZXksIGxlbmd0aCkpICYmXG4gICAgICAgICEoa2V5ID09ICdjb25zdHJ1Y3RvcicgJiYgKGlzUHJvdG8gfHwgIWhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5c0luO1xuIiwidmFyIGNyZWF0ZU9iamVjdE1hcHBlciA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2NyZWF0ZU9iamVjdE1hcHBlcicpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gb2JqZWN0IHdpdGggdGhlIHNhbWUga2V5cyBhcyBgb2JqZWN0YCBhbmQgdmFsdWVzIGdlbmVyYXRlZCBieVxuICogcnVubmluZyBlYWNoIG93biBlbnVtZXJhYmxlIHByb3BlcnR5IG9mIGBvYmplY3RgIHRocm91Z2ggYGl0ZXJhdGVlYC4gVGhlXG4gKiBpdGVyYXRlZSBmdW5jdGlvbiBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6XG4gKiAodmFsdWUsIGtleSwgb2JqZWN0KS5cbiAqXG4gKiBJZiBhIHByb3BlcnR5IG5hbWUgaXMgcHJvdmlkZWQgZm9yIGBpdGVyYXRlZWAgdGhlIGNyZWF0ZWQgYF8ucHJvcGVydHlgXG4gKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIHRoZSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAqXG4gKiBJZiBhIHZhbHVlIGlzIGFsc28gcHJvdmlkZWQgZm9yIGB0aGlzQXJnYCB0aGUgY3JlYXRlZCBgXy5tYXRjaGVzUHJvcGVydHlgXG4gKiBzdHlsZSBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIGEgbWF0Y2hpbmcgcHJvcGVydHlcbiAqIHZhbHVlLCBlbHNlIGBmYWxzZWAuXG4gKlxuICogSWYgYW4gb2JqZWN0IGlzIHByb3ZpZGVkIGZvciBgaXRlcmF0ZWVgIHRoZSBjcmVhdGVkIGBfLm1hdGNoZXNgIHN0eWxlXG4gKiBjYWxsYmFjayByZXR1cm5zIGB0cnVlYCBmb3IgZWxlbWVudHMgdGhhdCBoYXZlIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBnaXZlblxuICogb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdHxzdHJpbmd9IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZFxuICogIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGl0ZXJhdGVlYC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgb2JqZWN0LlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLm1hcFZhbHVlcyh7ICdhJzogMSwgJ2InOiAyIH0sIGZ1bmN0aW9uKG4pIHtcbiAqICAgcmV0dXJuIG4gKiAzO1xuICogfSk7XG4gKiAvLyA9PiB7ICdhJzogMywgJ2InOiA2IH1cbiAqXG4gKiB2YXIgdXNlcnMgPSB7XG4gKiAgICdmcmVkJzogICAgeyAndXNlcic6ICdmcmVkJywgICAgJ2FnZSc6IDQwIH0sXG4gKiAgICdwZWJibGVzJzogeyAndXNlcic6ICdwZWJibGVzJywgJ2FnZSc6IDEgfVxuICogfTtcbiAqXG4gKiAvLyB1c2luZyB0aGUgYF8ucHJvcGVydHlgIGNhbGxiYWNrIHNob3J0aGFuZFxuICogXy5tYXBWYWx1ZXModXNlcnMsICdhZ2UnKTtcbiAqIC8vID0+IHsgJ2ZyZWQnOiA0MCwgJ3BlYmJsZXMnOiAxIH0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqL1xudmFyIG1hcFZhbHVlcyA9IGNyZWF0ZU9iamVjdE1hcHBlcigpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG1hcFZhbHVlcztcbiIsInZhciBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyksXG4gICAgdG9PYmplY3QgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC90b09iamVjdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSB0d28gZGltZW5zaW9uYWwgYXJyYXkgb2YgdGhlIGtleS12YWx1ZSBwYWlycyBmb3IgYG9iamVjdGAsXG4gKiBlLmcuIGBbW2tleTEsIHZhbHVlMV0sIFtrZXkyLCB2YWx1ZTJdXWAuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGtleS12YWx1ZSBwYWlycy5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5wYWlycyh7ICdiYXJuZXknOiAzNiwgJ2ZyZWQnOiA0MCB9KTtcbiAqIC8vID0+IFtbJ2Jhcm5leScsIDM2XSwgWydmcmVkJywgNDBdXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICovXG5mdW5jdGlvbiBwYWlycyhvYmplY3QpIHtcbiAgb2JqZWN0ID0gdG9PYmplY3Qob2JqZWN0KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHByb3BzID0ga2V5cyhvYmplY3QpLFxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG4gICAgcmVzdWx0W2luZGV4XSA9IFtrZXksIG9iamVjdFtrZXldXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBhaXJzO1xuIiwiLyoqXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBmaXJzdCBhcmd1bWVudCBwcm92aWRlZCB0byBpdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IFV0aWxpdHlcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgQW55IHZhbHVlLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgYHZhbHVlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiBfLmlkZW50aXR5KG9iamVjdCkgPT09IG9iamVjdDtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaWRlbnRpdHkodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlkZW50aXR5O1xuIiwidmFyIGJhc2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2Jhc2VQcm9wZXJ0eScpLFxuICAgIGJhc2VQcm9wZXJ0eURlZXAgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9iYXNlUHJvcGVydHlEZWVwJyksXG4gICAgaXNLZXkgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pc0tleScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIHByb3BlcnR5IHZhbHVlIGF0IGBwYXRoYCBvbiBhXG4gKiBnaXZlbiBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsaXR5XG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3RzID0gW1xuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAyIH0gfSB9LFxuICogICB7ICdhJzogeyAnYic6IHsgJ2MnOiAxIH0gfSB9XG4gKiBdO1xuICpcbiAqIF8ubWFwKG9iamVjdHMsIF8ucHJvcGVydHkoJ2EuYi5jJykpO1xuICogLy8gPT4gWzIsIDFdXG4gKlxuICogXy5wbHVjayhfLnNvcnRCeShvYmplY3RzLCBfLnByb3BlcnR5KFsnYScsICdiJywgJ2MnXSkpLCAnYS5iLmMnKTtcbiAqIC8vID0+IFsxLCAyXVxuICovXG5mdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7XG4gIHJldHVybiBpc0tleShwYXRoKSA/IGJhc2VQcm9wZXJ0eShwYXRoKSA6IGJhc2VQcm9wZXJ0eURlZXAocGF0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcHJvcGVydHk7XG4iLCIvKipcbiAqIEhlbHBlcnMuXG4gKi9cblxudmFyIHMgPSAxMDAwO1xudmFyIG0gPSBzICogNjA7XG52YXIgaCA9IG0gKiA2MDtcbnZhciBkID0gaCAqIDI0O1xudmFyIHkgPSBkICogMzY1LjI1O1xuXG4vKipcbiAqIFBhcnNlIG9yIGZvcm1hdCB0aGUgZ2l2ZW4gYHZhbGAuXG4gKlxuICogT3B0aW9uczpcbiAqXG4gKiAgLSBgbG9uZ2AgdmVyYm9zZSBmb3JtYXR0aW5nIFtmYWxzZV1cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xOdW1iZXJ9IHZhbFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge1N0cmluZ3xOdW1iZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24odmFsLCBvcHRpb25zKXtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGlmICgnc3RyaW5nJyA9PSB0eXBlb2YgdmFsKSByZXR1cm4gcGFyc2UodmFsKTtcbiAgcmV0dXJuIG9wdGlvbnMubG9uZ1xuICAgID8gbG9uZyh2YWwpXG4gICAgOiBzaG9ydCh2YWwpO1xufTtcblxuLyoqXG4gKiBQYXJzZSB0aGUgZ2l2ZW4gYHN0cmAgYW5kIHJldHVybiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7TnVtYmVyfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gcGFyc2Uoc3RyKSB7XG4gIHN0ciA9ICcnICsgc3RyO1xuICBpZiAoc3RyLmxlbmd0aCA+IDEwMDAwKSByZXR1cm47XG4gIHZhciBtYXRjaCA9IC9eKCg/OlxcZCspP1xcLj9cXGQrKSAqKG1pbGxpc2Vjb25kcz98bXNlY3M/fG1zfHNlY29uZHM/fHNlY3M/fHN8bWludXRlcz98bWlucz98bXxob3Vycz98aHJzP3xofGRheXM/fGR8eWVhcnM/fHlycz98eSk/JC9pLmV4ZWMoc3RyKTtcbiAgaWYgKCFtYXRjaCkgcmV0dXJuO1xuICB2YXIgbiA9IHBhcnNlRmxvYXQobWF0Y2hbMV0pO1xuICB2YXIgdHlwZSA9IChtYXRjaFsyXSB8fCAnbXMnKS50b0xvd2VyQ2FzZSgpO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICd5ZWFycyc6XG4gICAgY2FzZSAneWVhcic6XG4gICAgY2FzZSAneXJzJzpcbiAgICBjYXNlICd5cic6XG4gICAgY2FzZSAneSc6XG4gICAgICByZXR1cm4gbiAqIHk7XG4gICAgY2FzZSAnZGF5cyc6XG4gICAgY2FzZSAnZGF5JzpcbiAgICBjYXNlICdkJzpcbiAgICAgIHJldHVybiBuICogZDtcbiAgICBjYXNlICdob3Vycyc6XG4gICAgY2FzZSAnaG91cic6XG4gICAgY2FzZSAnaHJzJzpcbiAgICBjYXNlICdocic6XG4gICAgY2FzZSAnaCc6XG4gICAgICByZXR1cm4gbiAqIGg7XG4gICAgY2FzZSAnbWludXRlcyc6XG4gICAgY2FzZSAnbWludXRlJzpcbiAgICBjYXNlICdtaW5zJzpcbiAgICBjYXNlICdtaW4nOlxuICAgIGNhc2UgJ20nOlxuICAgICAgcmV0dXJuIG4gKiBtO1xuICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgIGNhc2UgJ3NlY29uZCc6XG4gICAgY2FzZSAnc2Vjcyc6XG4gICAgY2FzZSAnc2VjJzpcbiAgICBjYXNlICdzJzpcbiAgICAgIHJldHVybiBuICogcztcbiAgICBjYXNlICdtaWxsaXNlY29uZHMnOlxuICAgIGNhc2UgJ21pbGxpc2Vjb25kJzpcbiAgICBjYXNlICdtc2Vjcyc6XG4gICAgY2FzZSAnbXNlYyc6XG4gICAgY2FzZSAnbXMnOlxuICAgICAgcmV0dXJuIG47XG4gIH1cbn1cblxuLyoqXG4gKiBTaG9ydCBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzaG9ydChtcykge1xuICBpZiAobXMgPj0gZCkgcmV0dXJuIE1hdGgucm91bmQobXMgLyBkKSArICdkJztcbiAgaWYgKG1zID49IGgpIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gaCkgKyAnaCc7XG4gIGlmIChtcyA+PSBtKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIG0pICsgJ20nO1xuICBpZiAobXMgPj0gcykgcmV0dXJuIE1hdGgucm91bmQobXMgLyBzKSArICdzJztcbiAgcmV0dXJuIG1zICsgJ21zJztcbn1cblxuLyoqXG4gKiBMb25nIGZvcm1hdCBmb3IgYG1zYC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gbXNcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGxvbmcobXMpIHtcbiAgcmV0dXJuIHBsdXJhbChtcywgZCwgJ2RheScpXG4gICAgfHwgcGx1cmFsKG1zLCBoLCAnaG91cicpXG4gICAgfHwgcGx1cmFsKG1zLCBtLCAnbWludXRlJylcbiAgICB8fCBwbHVyYWwobXMsIHMsICdzZWNvbmQnKVxuICAgIHx8IG1zICsgJyBtcyc7XG59XG5cbi8qKlxuICogUGx1cmFsaXphdGlvbiBoZWxwZXIuXG4gKi9cblxuZnVuY3Rpb24gcGx1cmFsKG1zLCBuLCBuYW1lKSB7XG4gIGlmIChtcyA8IG4pIHJldHVybjtcbiAgaWYgKG1zIDwgbiAqIDEuNSkgcmV0dXJuIE1hdGguZmxvb3IobXMgLyBuKSArICcgJyArIG5hbWU7XG4gIHJldHVybiBNYXRoLmNlaWwobXMgLyBuKSArICcgJyArIG5hbWUgKyAncyc7XG59XG4iLCIvKipcbiAqIEpTT04gcGFyc2UuXG4gKlxuICogQHNlZSBCYXNlZCBvbiBqUXVlcnkjcGFyc2VKU09OIChNSVQpIGFuZCBKU09OMlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxudmFyIHJ2YWxpZGNoYXJzID0gL15bXFxdLDp7fVxcc10qJC87XG52YXIgcnZhbGlkZXNjYXBlID0gL1xcXFwoPzpbXCJcXFxcXFwvYmZucnRdfHVbMC05YS1mQS1GXXs0fSkvZztcbnZhciBydmFsaWR0b2tlbnMgPSAvXCJbXlwiXFxcXFxcblxccl0qXCJ8dHJ1ZXxmYWxzZXxudWxsfC0/XFxkKyg/OlxcLlxcZCopPyg/OltlRV1bK1xcLV0/XFxkKyk/L2c7XG52YXIgcnZhbGlkYnJhY2VzID0gLyg/Ol58OnwsKSg/OlxccypcXFspKy9nO1xudmFyIHJ0cmltTGVmdCA9IC9eXFxzKy87XG52YXIgcnRyaW1SaWdodCA9IC9cXHMrJC87XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFyc2Vqc29uKGRhdGEpIHtcbiAgaWYgKCdzdHJpbmcnICE9IHR5cGVvZiBkYXRhIHx8ICFkYXRhKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBkYXRhID0gZGF0YS5yZXBsYWNlKHJ0cmltTGVmdCwgJycpLnJlcGxhY2UocnRyaW1SaWdodCwgJycpO1xuXG4gIC8vIEF0dGVtcHQgdG8gcGFyc2UgdXNpbmcgdGhlIG5hdGl2ZSBKU09OIHBhcnNlciBmaXJzdFxuICBpZiAoZ2xvYmFsLkpTT04gJiYgSlNPTi5wYXJzZSkge1xuICAgIHJldHVybiBKU09OLnBhcnNlKGRhdGEpO1xuICB9XG5cbiAgaWYgKHJ2YWxpZGNoYXJzLnRlc3QoZGF0YS5yZXBsYWNlKHJ2YWxpZGVzY2FwZSwgJ0AnKVxuICAgICAgLnJlcGxhY2UocnZhbGlkdG9rZW5zLCAnXScpXG4gICAgICAucmVwbGFjZShydmFsaWRicmFjZXMsICcnKSkpIHtcbiAgICByZXR1cm4gKG5ldyBGdW5jdGlvbigncmV0dXJuICcgKyBkYXRhKSkoKTtcbiAgfVxufTsiLCIvKipcbiAqIENvbXBpbGVzIGEgcXVlcnlzdHJpbmdcbiAqIFJldHVybnMgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBvYmplY3RcbiAqXG4gKiBAcGFyYW0ge09iamVjdH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZW5jb2RlID0gZnVuY3Rpb24gKG9iaikge1xuICB2YXIgc3RyID0gJyc7XG5cbiAgZm9yICh2YXIgaSBpbiBvYmopIHtcbiAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGkpKSB7XG4gICAgICBpZiAoc3RyLmxlbmd0aCkgc3RyICs9ICcmJztcbiAgICAgIHN0ciArPSBlbmNvZGVVUklDb21wb25lbnQoaSkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQob2JqW2ldKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3RyO1xufTtcblxuLyoqXG4gKiBQYXJzZXMgYSBzaW1wbGUgcXVlcnlzdHJpbmcgaW50byBhbiBvYmplY3RcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZGVjb2RlID0gZnVuY3Rpb24ocXMpe1xuICB2YXIgcXJ5ID0ge307XG4gIHZhciBwYWlycyA9IHFzLnNwbGl0KCcmJyk7XG4gIGZvciAodmFyIGkgPSAwLCBsID0gcGFpcnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgdmFyIHBhaXIgPSBwYWlyc1tpXS5zcGxpdCgnPScpO1xuICAgIHFyeVtkZWNvZGVVUklDb21wb25lbnQocGFpclswXSldID0gZGVjb2RlVVJJQ29tcG9uZW50KHBhaXJbMV0pO1xuICB9XG4gIHJldHVybiBxcnk7XG59O1xuIiwiLyoqXG4gKiBQYXJzZXMgYW4gVVJJXG4gKlxuICogQGF1dGhvciBTdGV2ZW4gTGV2aXRoYW4gPHN0ZXZlbmxldml0aGFuLmNvbT4gKE1JVCBsaWNlbnNlKVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxudmFyIHJlID0gL14oPzooPyFbXjpAXSs6W146QFxcL10qQCkoaHR0cHxodHRwc3x3c3x3c3MpOlxcL1xcLyk/KCg/OigoW146QF0qKSg/OjooW146QF0qKSk/KT9AKT8oKD86W2EtZjAtOV17MCw0fTopezIsN31bYS1mMC05XXswLDR9fFteOlxcLz8jXSopKD86OihcXGQqKSk/KSgoKFxcLyg/OltePyNdKD8hW14/I1xcL10qXFwuW14/I1xcLy5dKyg/Ols/I118JCkpKSpcXC8/KT8oW14/I1xcL10qKSkoPzpcXD8oW14jXSopKT8oPzojKC4qKSk/KS87XG5cbnZhciBwYXJ0cyA9IFtcbiAgICAnc291cmNlJywgJ3Byb3RvY29sJywgJ2F1dGhvcml0eScsICd1c2VySW5mbycsICd1c2VyJywgJ3Bhc3N3b3JkJywgJ2hvc3QnLCAncG9ydCcsICdyZWxhdGl2ZScsICdwYXRoJywgJ2RpcmVjdG9yeScsICdmaWxlJywgJ3F1ZXJ5JywgJ2FuY2hvcidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFyc2V1cmkoc3RyKSB7XG4gICAgdmFyIHNyYyA9IHN0cixcbiAgICAgICAgYiA9IHN0ci5pbmRleE9mKCdbJyksXG4gICAgICAgIGUgPSBzdHIuaW5kZXhPZignXScpO1xuXG4gICAgaWYgKGIgIT0gLTEgJiYgZSAhPSAtMSkge1xuICAgICAgICBzdHIgPSBzdHIuc3Vic3RyaW5nKDAsIGIpICsgc3RyLnN1YnN0cmluZyhiLCBlKS5yZXBsYWNlKC86L2csICc7JykgKyBzdHIuc3Vic3RyaW5nKGUsIHN0ci5sZW5ndGgpO1xuICAgIH1cblxuICAgIHZhciBtID0gcmUuZXhlYyhzdHIgfHwgJycpLFxuICAgICAgICB1cmkgPSB7fSxcbiAgICAgICAgaSA9IDE0O1xuXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgICB1cmlbcGFydHNbaV1dID0gbVtpXSB8fCAnJztcbiAgICB9XG5cbiAgICBpZiAoYiAhPSAtMSAmJiBlICE9IC0xKSB7XG4gICAgICAgIHVyaS5zb3VyY2UgPSBzcmM7XG4gICAgICAgIHVyaS5ob3N0ID0gdXJpLmhvc3Quc3Vic3RyaW5nKDEsIHVyaS5ob3N0Lmxlbmd0aCAtIDEpLnJlcGxhY2UoLzsvZywgJzonKTtcbiAgICAgICAgdXJpLmF1dGhvcml0eSA9IHVyaS5hdXRob3JpdHkucmVwbGFjZSgnWycsICcnKS5yZXBsYWNlKCddJywgJycpLnJlcGxhY2UoLzsvZywgJzonKTtcbiAgICAgICAgdXJpLmlwdjZ1cmkgPSB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiB1cmk7XG59O1xuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG52YXIgY3VycmVudFF1ZXVlO1xudmFyIHF1ZXVlSW5kZXggPSAtMTtcblxuZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCkge1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgaWYgKGN1cnJlbnRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcXVldWUgPSBjdXJyZW50UXVldWUuY29uY2F0KHF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgfVxuICAgIGlmIChxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgZHJhaW5RdWV1ZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhaW5RdWV1ZSgpIHtcbiAgICBpZiAoZHJhaW5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoY2xlYW5VcE5leHRUaWNrKTtcbiAgICBkcmFpbmluZyA9IHRydWU7XG5cbiAgICB2YXIgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIHdoaWxlKGxlbikge1xuICAgICAgICBjdXJyZW50UXVldWUgPSBxdWV1ZTtcbiAgICAgICAgcXVldWUgPSBbXTtcbiAgICAgICAgd2hpbGUgKCsrcXVldWVJbmRleCA8IGxlbikge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRRdWV1ZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgY3VycmVudFF1ZXVlID0gbnVsbDtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbn1cblxucHJvY2Vzcy5uZXh0VGljayA9IGZ1bmN0aW9uIChmdW4pIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBxdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1biwgYXJncykpO1xuICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZHJhaW5RdWV1ZSwgMCk7XG4gICAgfVxufTtcblxuLy8gdjggbGlrZXMgcHJlZGljdGlibGUgb2JqZWN0c1xuZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG4gICAgdGhpcy5mdW4gPSBmdW47XG4gICAgdGhpcy5hcnJheSA9IGFycmF5O1xufVxuSXRlbS5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZnVuLmFwcGx5KG51bGwsIHRoaXMuYXJyYXkpO1xufTtcbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xucHJvY2Vzcy52ZXJzaW9uID0gJyc7IC8vIGVtcHR5IHN0cmluZyB0byBhdm9pZCByZWdleHAgaXNzdWVzXG5wcm9jZXNzLnZlcnNpb25zID0ge307XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5wcm9jZXNzLm9uID0gbm9vcDtcbnByb2Nlc3MuYWRkTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5vbmNlID0gbm9vcDtcbnByb2Nlc3Mub2ZmID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xucHJvY2Vzcy5lbWl0ID0gbm9vcDtcblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCJcbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgdXJsID0gcmVxdWlyZSgnLi91cmwnKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdzb2NrZXQuaW8tcGFyc2VyJyk7XG52YXIgTWFuYWdlciA9IHJlcXVpcmUoJy4vbWFuYWdlcicpO1xudmFyIGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnc29ja2V0LmlvLWNsaWVudCcpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IGxvb2t1cDtcblxuLyoqXG4gKiBNYW5hZ2VycyBjYWNoZS5cbiAqL1xuXG52YXIgY2FjaGUgPSBleHBvcnRzLm1hbmFnZXJzID0ge307XG5cbi8qKlxuICogTG9va3MgdXAgYW4gZXhpc3RpbmcgYE1hbmFnZXJgIGZvciBtdWx0aXBsZXhpbmcuXG4gKiBJZiB0aGUgdXNlciBzdW1tb25zOlxuICpcbiAqICAgYGlvKCdodHRwOi8vbG9jYWxob3N0L2EnKTtgXG4gKiAgIGBpbygnaHR0cDovL2xvY2FsaG9zdC9iJyk7YFxuICpcbiAqIFdlIHJldXNlIHRoZSBleGlzdGluZyBpbnN0YW5jZSBiYXNlZCBvbiBzYW1lIHNjaGVtZS9wb3J0L2hvc3QsXG4gKiBhbmQgd2UgaW5pdGlhbGl6ZSBzb2NrZXRzIGZvciBlYWNoIG5hbWVzcGFjZS5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGxvb2t1cCh1cmksIG9wdHMpIHtcbiAgaWYgKHR5cGVvZiB1cmkgPT0gJ29iamVjdCcpIHtcbiAgICBvcHRzID0gdXJpO1xuICAgIHVyaSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIG9wdHMgPSBvcHRzIHx8IHt9O1xuXG4gIHZhciBwYXJzZWQgPSB1cmwodXJpKTtcbiAgdmFyIHNvdXJjZSA9IHBhcnNlZC5zb3VyY2U7XG4gIHZhciBpZCA9IHBhcnNlZC5pZDtcbiAgdmFyIHBhdGggPSBwYXJzZWQucGF0aDtcbiAgdmFyIHNhbWVOYW1lc3BhY2UgPSBjYWNoZVtpZF0gJiYgcGF0aCBpbiBjYWNoZVtpZF0ubnNwcztcbiAgdmFyIG5ld0Nvbm5lY3Rpb24gPSBvcHRzLmZvcmNlTmV3IHx8IG9wdHNbJ2ZvcmNlIG5ldyBjb25uZWN0aW9uJ10gfHxcbiAgICAgICAgICAgICAgICAgICAgICBmYWxzZSA9PT0gb3B0cy5tdWx0aXBsZXggfHwgc2FtZU5hbWVzcGFjZTtcblxuICB2YXIgaW87XG5cbiAgaWYgKG5ld0Nvbm5lY3Rpb24pIHtcbiAgICBkZWJ1ZygnaWdub3Jpbmcgc29ja2V0IGNhY2hlIGZvciAlcycsIHNvdXJjZSk7XG4gICAgaW8gPSBNYW5hZ2VyKHNvdXJjZSwgb3B0cyk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFjYWNoZVtpZF0pIHtcbiAgICAgIGRlYnVnKCduZXcgaW8gaW5zdGFuY2UgZm9yICVzJywgc291cmNlKTtcbiAgICAgIGNhY2hlW2lkXSA9IE1hbmFnZXIoc291cmNlLCBvcHRzKTtcbiAgICB9XG4gICAgaW8gPSBjYWNoZVtpZF07XG4gIH1cblxuICByZXR1cm4gaW8uc29ja2V0KHBhcnNlZC5wYXRoKTtcbn1cblxuLyoqXG4gKiBQcm90b2NvbCB2ZXJzaW9uLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5wcm90b2NvbCA9IHBhcnNlci5wcm90b2NvbDtcblxuLyoqXG4gKiBgY29ubmVjdGAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVyaVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLmNvbm5lY3QgPSBsb29rdXA7XG5cbi8qKlxuICogRXhwb3NlIGNvbnN0cnVjdG9ycyBmb3Igc3RhbmRhbG9uZSBidWlsZC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuTWFuYWdlciA9IHJlcXVpcmUoJy4vbWFuYWdlcicpO1xuZXhwb3J0cy5Tb2NrZXQgPSByZXF1aXJlKCcuL3NvY2tldCcpO1xuIiwiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIGVpbyA9IHJlcXVpcmUoJ2VuZ2luZS5pby1jbGllbnQnKTtcbnZhciBTb2NrZXQgPSByZXF1aXJlKCcuL3NvY2tldCcpO1xudmFyIEVtaXR0ZXIgPSByZXF1aXJlKCdjb21wb25lbnQtZW1pdHRlcicpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBvbiA9IHJlcXVpcmUoJy4vb24nKTtcbnZhciBiaW5kID0gcmVxdWlyZSgnY29tcG9uZW50LWJpbmQnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6bWFuYWdlcicpO1xudmFyIGluZGV4T2YgPSByZXF1aXJlKCdpbmRleG9mJyk7XG52YXIgQmFja29mZiA9IHJlcXVpcmUoJ2JhY2tvMicpO1xuXG4vKipcbiAqIElFNisgaGFzT3duUHJvcGVydHlcbiAqL1xuXG52YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0c1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0gTWFuYWdlcjtcblxuLyoqXG4gKiBgTWFuYWdlcmAgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGVuZ2luZSBpbnN0YW5jZSBvciBlbmdpbmUgdXJpL29wdHNcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIE1hbmFnZXIodXJpLCBvcHRzKXtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIE1hbmFnZXIpKSByZXR1cm4gbmV3IE1hbmFnZXIodXJpLCBvcHRzKTtcbiAgaWYgKHVyaSAmJiAoJ29iamVjdCcgPT0gdHlwZW9mIHVyaSkpIHtcbiAgICBvcHRzID0gdXJpO1xuICAgIHVyaSA9IHVuZGVmaW5lZDtcbiAgfVxuICBvcHRzID0gb3B0cyB8fCB7fTtcblxuICBvcHRzLnBhdGggPSBvcHRzLnBhdGggfHwgJy9zb2NrZXQuaW8nO1xuICB0aGlzLm5zcHMgPSB7fTtcbiAgdGhpcy5zdWJzID0gW107XG4gIHRoaXMub3B0cyA9IG9wdHM7XG4gIHRoaXMucmVjb25uZWN0aW9uKG9wdHMucmVjb25uZWN0aW9uICE9PSBmYWxzZSk7XG4gIHRoaXMucmVjb25uZWN0aW9uQXR0ZW1wdHMob3B0cy5yZWNvbm5lY3Rpb25BdHRlbXB0cyB8fCBJbmZpbml0eSk7XG4gIHRoaXMucmVjb25uZWN0aW9uRGVsYXkob3B0cy5yZWNvbm5lY3Rpb25EZWxheSB8fCAxMDAwKTtcbiAgdGhpcy5yZWNvbm5lY3Rpb25EZWxheU1heChvcHRzLnJlY29ubmVjdGlvbkRlbGF5TWF4IHx8IDUwMDApO1xuICB0aGlzLnJhbmRvbWl6YXRpb25GYWN0b3Iob3B0cy5yYW5kb21pemF0aW9uRmFjdG9yIHx8IDAuNSk7XG4gIHRoaXMuYmFja29mZiA9IG5ldyBCYWNrb2ZmKHtcbiAgICBtaW46IHRoaXMucmVjb25uZWN0aW9uRGVsYXkoKSxcbiAgICBtYXg6IHRoaXMucmVjb25uZWN0aW9uRGVsYXlNYXgoKSxcbiAgICBqaXR0ZXI6IHRoaXMucmFuZG9taXphdGlvbkZhY3RvcigpXG4gIH0pO1xuICB0aGlzLnRpbWVvdXQobnVsbCA9PSBvcHRzLnRpbWVvdXQgPyAyMDAwMCA6IG9wdHMudGltZW91dCk7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuICB0aGlzLnVyaSA9IHVyaTtcbiAgdGhpcy5jb25uZWN0aW5nID0gW107XG4gIHRoaXMubGFzdFBpbmcgPSBudWxsO1xuICB0aGlzLmVuY29kaW5nID0gZmFsc2U7XG4gIHRoaXMucGFja2V0QnVmZmVyID0gW107XG4gIHRoaXMuZW5jb2RlciA9IG5ldyBwYXJzZXIuRW5jb2RlcigpO1xuICB0aGlzLmRlY29kZXIgPSBuZXcgcGFyc2VyLkRlY29kZXIoKTtcbiAgdGhpcy5hdXRvQ29ubmVjdCA9IG9wdHMuYXV0b0Nvbm5lY3QgIT09IGZhbHNlO1xuICBpZiAodGhpcy5hdXRvQ29ubmVjdCkgdGhpcy5vcGVuKCk7XG59XG5cbi8qKlxuICogUHJvcGFnYXRlIGdpdmVuIGV2ZW50IHRvIHNvY2tldHMgYW5kIGVtaXQgb24gYHRoaXNgXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUuZW1pdEFsbCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmVtaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgZm9yICh2YXIgbnNwIGluIHRoaXMubnNwcykge1xuICAgIGlmIChoYXMuY2FsbCh0aGlzLm5zcHMsIG5zcCkpIHtcbiAgICAgIHRoaXMubnNwc1tuc3BdLmVtaXQuYXBwbHkodGhpcy5uc3BzW25zcF0sIGFyZ3VtZW50cyk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFVwZGF0ZSBgc29ja2V0LmlkYCBvZiBhbGwgc29ja2V0c1xuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnVwZGF0ZVNvY2tldElkcyA9IGZ1bmN0aW9uKCl7XG4gIGZvciAodmFyIG5zcCBpbiB0aGlzLm5zcHMpIHtcbiAgICBpZiAoaGFzLmNhbGwodGhpcy5uc3BzLCBuc3ApKSB7XG4gICAgICB0aGlzLm5zcHNbbnNwXS5pZCA9IHRoaXMuZW5naW5lLmlkO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBNaXggaW4gYEVtaXR0ZXJgLlxuICovXG5cbkVtaXR0ZXIoTWFuYWdlci5wcm90b3R5cGUpO1xuXG4vKipcbiAqIFNldHMgdGhlIGByZWNvbm5lY3Rpb25gIGNvbmZpZy5cbiAqXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHRydWUvZmFsc2UgaWYgaXQgc2hvdWxkIGF1dG9tYXRpY2FsbHkgcmVjb25uZWN0XG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnJlY29ubmVjdGlvbiA9IGZ1bmN0aW9uKHYpe1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb247XG4gIHRoaXMuX3JlY29ubmVjdGlvbiA9ICEhdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIHJlY29ubmVjdGlvbiBhdHRlbXB0cyBjb25maWcuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1heCByZWNvbm5lY3Rpb24gYXR0ZW1wdHMgYmVmb3JlIGdpdmluZyB1cFxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25BdHRlbXB0cyA9IGZ1bmN0aW9uKHYpe1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb25BdHRlbXB0cztcbiAgdGhpcy5fcmVjb25uZWN0aW9uQXR0ZW1wdHMgPSB2O1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgZGVsYXkgYmV0d2VlbiByZWNvbm5lY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBkZWxheVxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25EZWxheSA9IGZ1bmN0aW9uKHYpe1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheTtcbiAgdGhpcy5fcmVjb25uZWN0aW9uRGVsYXkgPSB2O1xuICB0aGlzLmJhY2tvZmYgJiYgdGhpcy5iYWNrb2ZmLnNldE1pbih2KTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yYW5kb21pemF0aW9uRmFjdG9yID0gZnVuY3Rpb24odil7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JhbmRvbWl6YXRpb25GYWN0b3I7XG4gIHRoaXMuX3JhbmRvbWl6YXRpb25GYWN0b3IgPSB2O1xuICB0aGlzLmJhY2tvZmYgJiYgdGhpcy5iYWNrb2ZmLnNldEppdHRlcih2KTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIG1heGltdW0gZGVsYXkgYmV0d2VlbiByZWNvbm5lY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBkZWxheVxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25EZWxheU1heCA9IGZ1bmN0aW9uKHYpe1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheU1heDtcbiAgdGhpcy5fcmVjb25uZWN0aW9uRGVsYXlNYXggPSB2O1xuICB0aGlzLmJhY2tvZmYgJiYgdGhpcy5iYWNrb2ZmLnNldE1heCh2KTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIGNvbm5lY3Rpb24gdGltZW91dC4gYGZhbHNlYCB0byBkaXNhYmxlXG4gKlxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS50aW1lb3V0ID0gZnVuY3Rpb24odil7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3RpbWVvdXQ7XG4gIHRoaXMuX3RpbWVvdXQgPSB2O1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU3RhcnRzIHRyeWluZyB0byByZWNvbm5lY3QgaWYgcmVjb25uZWN0aW9uIGlzIGVuYWJsZWQgYW5kIHdlIGhhdmUgbm90XG4gKiBzdGFydGVkIHJlY29ubmVjdGluZyB5ZXRcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5tYXliZVJlY29ubmVjdE9uT3BlbiA9IGZ1bmN0aW9uKCkge1xuICAvLyBPbmx5IHRyeSB0byByZWNvbm5lY3QgaWYgaXQncyB0aGUgZmlyc3QgdGltZSB3ZSdyZSBjb25uZWN0aW5nXG4gIGlmICghdGhpcy5yZWNvbm5lY3RpbmcgJiYgdGhpcy5fcmVjb25uZWN0aW9uICYmIHRoaXMuYmFja29mZi5hdHRlbXB0cyA9PT0gMCkge1xuICAgIC8vIGtlZXBzIHJlY29ubmVjdGlvbiBmcm9tIGZpcmluZyB0d2ljZSBmb3IgdGhlIHNhbWUgcmVjb25uZWN0aW9uIGxvb3BcbiAgICB0aGlzLnJlY29ubmVjdCgpO1xuICB9XG59O1xuXG5cbi8qKlxuICogU2V0cyB0aGUgY3VycmVudCB0cmFuc3BvcnQgYHNvY2tldGAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gb3B0aW9uYWwsIGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9wZW4gPVxuTWFuYWdlci5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uKGZuKXtcbiAgZGVidWcoJ3JlYWR5U3RhdGUgJXMnLCB0aGlzLnJlYWR5U3RhdGUpO1xuICBpZiAofnRoaXMucmVhZHlTdGF0ZS5pbmRleE9mKCdvcGVuJykpIHJldHVybiB0aGlzO1xuXG4gIGRlYnVnKCdvcGVuaW5nICVzJywgdGhpcy51cmkpO1xuICB0aGlzLmVuZ2luZSA9IGVpbyh0aGlzLnVyaSwgdGhpcy5vcHRzKTtcbiAgdmFyIHNvY2tldCA9IHRoaXMuZW5naW5lO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJztcbiAgdGhpcy5za2lwUmVjb25uZWN0ID0gZmFsc2U7XG5cbiAgLy8gZW1pdCBgb3BlbmBcbiAgdmFyIG9wZW5TdWIgPSBvbihzb2NrZXQsICdvcGVuJywgZnVuY3Rpb24oKSB7XG4gICAgc2VsZi5vbm9wZW4oKTtcbiAgICBmbiAmJiBmbigpO1xuICB9KTtcblxuICAvLyBlbWl0IGBjb25uZWN0X2Vycm9yYFxuICB2YXIgZXJyb3JTdWIgPSBvbihzb2NrZXQsICdlcnJvcicsIGZ1bmN0aW9uKGRhdGEpe1xuICAgIGRlYnVnKCdjb25uZWN0X2Vycm9yJyk7XG4gICAgc2VsZi5jbGVhbnVwKCk7XG4gICAgc2VsZi5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gICAgc2VsZi5lbWl0QWxsKCdjb25uZWN0X2Vycm9yJywgZGF0YSk7XG4gICAgaWYgKGZuKSB7XG4gICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdDb25uZWN0aW9uIGVycm9yJyk7XG4gICAgICBlcnIuZGF0YSA9IGRhdGE7XG4gICAgICBmbihlcnIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBPbmx5IGRvIHRoaXMgaWYgdGhlcmUgaXMgbm8gZm4gdG8gaGFuZGxlIHRoZSBlcnJvclxuICAgICAgc2VsZi5tYXliZVJlY29ubmVjdE9uT3BlbigpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gZW1pdCBgY29ubmVjdF90aW1lb3V0YFxuICBpZiAoZmFsc2UgIT09IHRoaXMuX3RpbWVvdXQpIHtcbiAgICB2YXIgdGltZW91dCA9IHRoaXMuX3RpbWVvdXQ7XG4gICAgZGVidWcoJ2Nvbm5lY3QgYXR0ZW1wdCB3aWxsIHRpbWVvdXQgYWZ0ZXIgJWQnLCB0aW1lb3V0KTtcblxuICAgIC8vIHNldCB0aW1lclxuICAgIHZhciB0aW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIGRlYnVnKCdjb25uZWN0IGF0dGVtcHQgdGltZWQgb3V0IGFmdGVyICVkJywgdGltZW91dCk7XG4gICAgICBvcGVuU3ViLmRlc3Ryb3koKTtcbiAgICAgIHNvY2tldC5jbG9zZSgpO1xuICAgICAgc29ja2V0LmVtaXQoJ2Vycm9yJywgJ3RpbWVvdXQnKTtcbiAgICAgIHNlbGYuZW1pdEFsbCgnY29ubmVjdF90aW1lb3V0JywgdGltZW91dCk7XG4gICAgfSwgdGltZW91dCk7XG5cbiAgICB0aGlzLnN1YnMucHVzaCh7XG4gICAgICBkZXN0cm95OiBmdW5jdGlvbigpe1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdGhpcy5zdWJzLnB1c2gob3BlblN1Yik7XG4gIHRoaXMuc3Vicy5wdXNoKGVycm9yU3ViKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IG9wZW4uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25vcGVuID0gZnVuY3Rpb24oKXtcbiAgZGVidWcoJ29wZW4nKTtcblxuICAvLyBjbGVhciBvbGQgc3Vic1xuICB0aGlzLmNsZWFudXAoKTtcblxuICAvLyBtYXJrIGFzIG9wZW5cbiAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW4nO1xuICB0aGlzLmVtaXQoJ29wZW4nKTtcblxuICAvLyBhZGQgbmV3IHN1YnNcbiAgdmFyIHNvY2tldCA9IHRoaXMuZW5naW5lO1xuICB0aGlzLnN1YnMucHVzaChvbihzb2NrZXQsICdkYXRhJywgYmluZCh0aGlzLCAnb25kYXRhJykpKTtcbiAgdGhpcy5zdWJzLnB1c2gob24oc29ja2V0LCAncGluZycsIGJpbmQodGhpcywgJ29ucGluZycpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ3BvbmcnLCBiaW5kKHRoaXMsICdvbnBvbmcnKSkpO1xuICB0aGlzLnN1YnMucHVzaChvbihzb2NrZXQsICdlcnJvcicsIGJpbmQodGhpcywgJ29uZXJyb3InKSkpO1xuICB0aGlzLnN1YnMucHVzaChvbihzb2NrZXQsICdjbG9zZScsIGJpbmQodGhpcywgJ29uY2xvc2UnKSkpO1xuICB0aGlzLnN1YnMucHVzaChvbih0aGlzLmRlY29kZXIsICdkZWNvZGVkJywgYmluZCh0aGlzLCAnb25kZWNvZGVkJykpKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gYSBwaW5nLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9ucGluZyA9IGZ1bmN0aW9uKCl7XG4gIHRoaXMubGFzdFBpbmcgPSBuZXcgRGF0ZTtcbiAgdGhpcy5lbWl0QWxsKCdwaW5nJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgcGFja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9ucG9uZyA9IGZ1bmN0aW9uKCl7XG4gIHRoaXMuZW1pdEFsbCgncG9uZycsIG5ldyBEYXRlIC0gdGhpcy5sYXN0UGluZyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIGRhdGEuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25kYXRhID0gZnVuY3Rpb24oZGF0YSl7XG4gIHRoaXMuZGVjb2Rlci5hZGQoZGF0YSk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aGVuIHBhcnNlciBmdWxseSBkZWNvZGVzIGEgcGFja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9uZGVjb2RlZCA9IGZ1bmN0aW9uKHBhY2tldCkge1xuICB0aGlzLmVtaXQoJ3BhY2tldCcsIHBhY2tldCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHNvY2tldCBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5vbmVycm9yID0gZnVuY3Rpb24oZXJyKXtcbiAgZGVidWcoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5lbWl0QWxsKCdlcnJvcicsIGVycik7XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc29ja2V0IGZvciB0aGUgZ2l2ZW4gYG5zcGAuXG4gKlxuICogQHJldHVybiB7U29ja2V0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5zb2NrZXQgPSBmdW5jdGlvbihuc3Ape1xuICB2YXIgc29ja2V0ID0gdGhpcy5uc3BzW25zcF07XG4gIGlmICghc29ja2V0KSB7XG4gICAgc29ja2V0ID0gbmV3IFNvY2tldCh0aGlzLCBuc3ApO1xuICAgIHRoaXMubnNwc1tuc3BdID0gc29ja2V0O1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBzb2NrZXQub24oJ2Nvbm5lY3RpbmcnLCBvbkNvbm5lY3RpbmcpO1xuICAgIHNvY2tldC5vbignY29ubmVjdCcsIGZ1bmN0aW9uKCl7XG4gICAgICBzb2NrZXQuaWQgPSBzZWxmLmVuZ2luZS5pZDtcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLmF1dG9Db25uZWN0KSB7XG4gICAgICAvLyBtYW51YWxseSBjYWxsIGhlcmUgc2luY2UgY29ubmVjdGluZyBldm5ldCBpcyBmaXJlZCBiZWZvcmUgbGlzdGVuaW5nXG4gICAgICBvbkNvbm5lY3RpbmcoKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBvbkNvbm5lY3RpbmcoKSB7XG4gICAgaWYgKCF+aW5kZXhPZihzZWxmLmNvbm5lY3RpbmcsIHNvY2tldCkpIHtcbiAgICAgIHNlbGYuY29ubmVjdGluZy5wdXNoKHNvY2tldCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHNvY2tldDtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gYSBzb2NrZXQgY2xvc2UuXG4gKlxuICogQHBhcmFtIHtTb2NrZXR9IHNvY2tldFxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbihzb2NrZXQpe1xuICB2YXIgaW5kZXggPSBpbmRleE9mKHRoaXMuY29ubmVjdGluZywgc29ja2V0KTtcbiAgaWYgKH5pbmRleCkgdGhpcy5jb25uZWN0aW5nLnNwbGljZShpbmRleCwgMSk7XG4gIGlmICh0aGlzLmNvbm5lY3RpbmcubGVuZ3RoKSByZXR1cm47XG5cbiAgdGhpcy5jbG9zZSgpO1xufTtcblxuLyoqXG4gKiBXcml0ZXMgYSBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUucGFja2V0ID0gZnVuY3Rpb24ocGFja2V0KXtcbiAgZGVidWcoJ3dyaXRpbmcgcGFja2V0ICVqJywgcGFja2V0KTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmICghc2VsZi5lbmNvZGluZykge1xuICAgIC8vIGVuY29kZSwgdGhlbiB3cml0ZSB0byBlbmdpbmUgd2l0aCByZXN1bHRcbiAgICBzZWxmLmVuY29kaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmVuY29kZXIuZW5jb2RlKHBhY2tldCwgZnVuY3Rpb24oZW5jb2RlZFBhY2tldHMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW5jb2RlZFBhY2tldHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgc2VsZi5lbmdpbmUud3JpdGUoZW5jb2RlZFBhY2tldHNbaV0sIHBhY2tldC5vcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHNlbGYuZW5jb2RpbmcgPSBmYWxzZTtcbiAgICAgIHNlbGYucHJvY2Vzc1BhY2tldFF1ZXVlKCk7XG4gICAgfSk7XG4gIH0gZWxzZSB7IC8vIGFkZCBwYWNrZXQgdG8gdGhlIHF1ZXVlXG4gICAgc2VsZi5wYWNrZXRCdWZmZXIucHVzaChwYWNrZXQpO1xuICB9XG59O1xuXG4vKipcbiAqIElmIHBhY2tldCBidWZmZXIgaXMgbm9uLWVtcHR5LCBiZWdpbnMgZW5jb2RpbmcgdGhlXG4gKiBuZXh0IHBhY2tldCBpbiBsaW5lLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnByb2Nlc3NQYWNrZXRRdWV1ZSA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5wYWNrZXRCdWZmZXIubGVuZ3RoID4gMCAmJiAhdGhpcy5lbmNvZGluZykge1xuICAgIHZhciBwYWNrID0gdGhpcy5wYWNrZXRCdWZmZXIuc2hpZnQoKTtcbiAgICB0aGlzLnBhY2tldChwYWNrKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDbGVhbiB1cCB0cmFuc3BvcnQgc3Vic2NyaXB0aW9ucyBhbmQgcGFja2V0IGJ1ZmZlci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5jbGVhbnVwID0gZnVuY3Rpb24oKXtcbiAgZGVidWcoJ2NsZWFudXAnKTtcblxuICB2YXIgc3ViO1xuICB3aGlsZSAoc3ViID0gdGhpcy5zdWJzLnNoaWZ0KCkpIHN1Yi5kZXN0cm95KCk7XG5cbiAgdGhpcy5wYWNrZXRCdWZmZXIgPSBbXTtcbiAgdGhpcy5lbmNvZGluZyA9IGZhbHNlO1xuICB0aGlzLmxhc3RQaW5nID0gbnVsbDtcblxuICB0aGlzLmRlY29kZXIuZGVzdHJveSgpO1xufTtcblxuLyoqXG4gKiBDbG9zZSB0aGUgY3VycmVudCBzb2NrZXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUuY2xvc2UgPVxuTWFuYWdlci5wcm90b3R5cGUuZGlzY29ubmVjdCA9IGZ1bmN0aW9uKCl7XG4gIGRlYnVnKCdkaXNjb25uZWN0Jyk7XG4gIHRoaXMuc2tpcFJlY29ubmVjdCA9IHRydWU7XG4gIHRoaXMucmVjb25uZWN0aW5nID0gZmFsc2U7XG4gIGlmICgnb3BlbmluZycgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgLy8gYG9uY2xvc2VgIHdpbGwgbm90IGZpcmUgYmVjYXVzZVxuICAgIC8vIGFuIG9wZW4gZXZlbnQgbmV2ZXIgaGFwcGVuZWRcbiAgICB0aGlzLmNsZWFudXAoKTtcbiAgfVxuICB0aGlzLmJhY2tvZmYucmVzZXQoKTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIGlmICh0aGlzLmVuZ2luZSkgdGhpcy5lbmdpbmUuY2xvc2UoKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZW5naW5lIGNsb3NlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9uY2xvc2UgPSBmdW5jdGlvbihyZWFzb24pe1xuICBkZWJ1Zygnb25jbG9zZScpO1xuXG4gIHRoaXMuY2xlYW51cCgpO1xuICB0aGlzLmJhY2tvZmYucmVzZXQoKTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIHRoaXMuZW1pdCgnY2xvc2UnLCByZWFzb24pO1xuXG4gIGlmICh0aGlzLl9yZWNvbm5lY3Rpb24gJiYgIXRoaXMuc2tpcFJlY29ubmVjdCkge1xuICAgIHRoaXMucmVjb25uZWN0KCk7XG4gIH1cbn07XG5cbi8qKlxuICogQXR0ZW1wdCBhIHJlY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3QgPSBmdW5jdGlvbigpe1xuICBpZiAodGhpcy5yZWNvbm5lY3RpbmcgfHwgdGhpcy5za2lwUmVjb25uZWN0KSByZXR1cm4gdGhpcztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKHRoaXMuYmFja29mZi5hdHRlbXB0cyA+PSB0aGlzLl9yZWNvbm5lY3Rpb25BdHRlbXB0cykge1xuICAgIGRlYnVnKCdyZWNvbm5lY3QgZmFpbGVkJyk7XG4gICAgdGhpcy5iYWNrb2ZmLnJlc2V0KCk7XG4gICAgdGhpcy5lbWl0QWxsKCdyZWNvbm5lY3RfZmFpbGVkJyk7XG4gICAgdGhpcy5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgZGVsYXkgPSB0aGlzLmJhY2tvZmYuZHVyYXRpb24oKTtcbiAgICBkZWJ1Zygnd2lsbCB3YWl0ICVkbXMgYmVmb3JlIHJlY29ubmVjdCBhdHRlbXB0JywgZGVsYXkpO1xuXG4gICAgdGhpcy5yZWNvbm5lY3RpbmcgPSB0cnVlO1xuICAgIHZhciB0aW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIGlmIChzZWxmLnNraXBSZWNvbm5lY3QpIHJldHVybjtcblxuICAgICAgZGVidWcoJ2F0dGVtcHRpbmcgcmVjb25uZWN0Jyk7XG4gICAgICBzZWxmLmVtaXRBbGwoJ3JlY29ubmVjdF9hdHRlbXB0Jywgc2VsZi5iYWNrb2ZmLmF0dGVtcHRzKTtcbiAgICAgIHNlbGYuZW1pdEFsbCgncmVjb25uZWN0aW5nJywgc2VsZi5iYWNrb2ZmLmF0dGVtcHRzKTtcblxuICAgICAgLy8gY2hlY2sgYWdhaW4gZm9yIHRoZSBjYXNlIHNvY2tldCBjbG9zZWQgaW4gYWJvdmUgZXZlbnRzXG4gICAgICBpZiAoc2VsZi5za2lwUmVjb25uZWN0KSByZXR1cm47XG5cbiAgICAgIHNlbGYub3BlbihmdW5jdGlvbihlcnIpe1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgZGVidWcoJ3JlY29ubmVjdCBhdHRlbXB0IGVycm9yJyk7XG4gICAgICAgICAgc2VsZi5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLnJlY29ubmVjdCgpO1xuICAgICAgICAgIHNlbGYuZW1pdEFsbCgncmVjb25uZWN0X2Vycm9yJywgZXJyLmRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlYnVnKCdyZWNvbm5lY3Qgc3VjY2VzcycpO1xuICAgICAgICAgIHNlbGYub25yZWNvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSwgZGVsYXkpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgZGVzdHJveTogZnVuY3Rpb24oKXtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzdWNjZXNzZnVsIHJlY29ubmVjdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5vbnJlY29ubmVjdCA9IGZ1bmN0aW9uKCl7XG4gIHZhciBhdHRlbXB0ID0gdGhpcy5iYWNrb2ZmLmF0dGVtcHRzO1xuICB0aGlzLnJlY29ubmVjdGluZyA9IGZhbHNlO1xuICB0aGlzLmJhY2tvZmYucmVzZXQoKTtcbiAgdGhpcy51cGRhdGVTb2NrZXRJZHMoKTtcbiAgdGhpcy5lbWl0QWxsKCdyZWNvbm5lY3QnLCBhdHRlbXB0KTtcbn07XG4iLCJcbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBvbjtcblxuLyoqXG4gKiBIZWxwZXIgZm9yIHN1YnNjcmlwdGlvbnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8RXZlbnRFbWl0dGVyfSBvYmogd2l0aCBgRW1pdHRlcmAgbWl4aW4gb3IgYEV2ZW50RW1pdHRlcmBcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCBuYW1lXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBvbihvYmosIGV2LCBmbikge1xuICBvYmoub24oZXYsIGZuKTtcbiAgcmV0dXJuIHtcbiAgICBkZXN0cm95OiBmdW5jdGlvbigpe1xuICAgICAgb2JqLnJlbW92ZUxpc3RlbmVyKGV2LCBmbik7XG4gICAgfVxuICB9O1xufVxuIiwiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHBhcnNlciA9IHJlcXVpcmUoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciB0b0FycmF5ID0gcmVxdWlyZSgndG8tYXJyYXknKTtcbnZhciBvbiA9IHJlcXVpcmUoJy4vb24nKTtcbnZhciBiaW5kID0gcmVxdWlyZSgnY29tcG9uZW50LWJpbmQnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6c29ja2V0Jyk7XG52YXIgaGFzQmluID0gcmVxdWlyZSgnaGFzLWJpbmFyeScpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IFNvY2tldDtcblxuLyoqXG4gKiBJbnRlcm5hbCBldmVudHMgKGJsYWNrbGlzdGVkKS5cbiAqIFRoZXNlIGV2ZW50cyBjYW4ndCBiZSBlbWl0dGVkIGJ5IHRoZSB1c2VyLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbnZhciBldmVudHMgPSB7XG4gIGNvbm5lY3Q6IDEsXG4gIGNvbm5lY3RfZXJyb3I6IDEsXG4gIGNvbm5lY3RfdGltZW91dDogMSxcbiAgY29ubmVjdGluZzogMSxcbiAgZGlzY29ubmVjdDogMSxcbiAgZXJyb3I6IDEsXG4gIHJlY29ubmVjdDogMSxcbiAgcmVjb25uZWN0X2F0dGVtcHQ6IDEsXG4gIHJlY29ubmVjdF9mYWlsZWQ6IDEsXG4gIHJlY29ubmVjdF9lcnJvcjogMSxcbiAgcmVjb25uZWN0aW5nOiAxLFxuICBwaW5nOiAxLFxuICBwb25nOiAxXG59O1xuXG4vKipcbiAqIFNob3J0Y3V0IHRvIGBFbWl0dGVyI2VtaXRgLlxuICovXG5cbnZhciBlbWl0ID0gRW1pdHRlci5wcm90b3R5cGUuZW1pdDtcblxuLyoqXG4gKiBgU29ja2V0YCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFNvY2tldChpbywgbnNwKXtcbiAgdGhpcy5pbyA9IGlvO1xuICB0aGlzLm5zcCA9IG5zcDtcbiAgdGhpcy5qc29uID0gdGhpczsgLy8gY29tcGF0XG4gIHRoaXMuaWRzID0gMDtcbiAgdGhpcy5hY2tzID0ge307XG4gIHRoaXMucmVjZWl2ZUJ1ZmZlciA9IFtdO1xuICB0aGlzLnNlbmRCdWZmZXIgPSBbXTtcbiAgdGhpcy5jb25uZWN0ZWQgPSBmYWxzZTtcbiAgdGhpcy5kaXNjb25uZWN0ZWQgPSB0cnVlO1xuICBpZiAodGhpcy5pby5hdXRvQ29ubmVjdCkgdGhpcy5vcGVuKCk7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFNvY2tldC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIFN1YnNjcmliZSB0byBvcGVuLCBjbG9zZSBhbmQgcGFja2V0IGV2ZW50c1xuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc3ViRXZlbnRzID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLnN1YnMpIHJldHVybjtcblxuICB2YXIgaW8gPSB0aGlzLmlvO1xuICB0aGlzLnN1YnMgPSBbXG4gICAgb24oaW8sICdvcGVuJywgYmluZCh0aGlzLCAnb25vcGVuJykpLFxuICAgIG9uKGlvLCAncGFja2V0JywgYmluZCh0aGlzLCAnb25wYWNrZXQnKSksXG4gICAgb24oaW8sICdjbG9zZScsIGJpbmQodGhpcywgJ29uY2xvc2UnKSlcbiAgXTtcbn07XG5cbi8qKlxuICogXCJPcGVuc1wiIHRoZSBzb2NrZXQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9wZW4gPVxuU29ja2V0LnByb3RvdHlwZS5jb25uZWN0ID0gZnVuY3Rpb24oKXtcbiAgaWYgKHRoaXMuY29ubmVjdGVkKSByZXR1cm4gdGhpcztcblxuICB0aGlzLnN1YkV2ZW50cygpO1xuICB0aGlzLmlvLm9wZW4oKTsgLy8gZW5zdXJlIG9wZW5cbiAgaWYgKCdvcGVuJyA9PSB0aGlzLmlvLnJlYWR5U3RhdGUpIHRoaXMub25vcGVuKCk7XG4gIHRoaXMuZW1pdCgnY29ubmVjdGluZycpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2VuZHMgYSBgbWVzc2FnZWAgZXZlbnQuXG4gKlxuICogQHJldHVybiB7U29ja2V0fSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2VuZCA9IGZ1bmN0aW9uKCl7XG4gIHZhciBhcmdzID0gdG9BcnJheShhcmd1bWVudHMpO1xuICBhcmdzLnVuc2hpZnQoJ21lc3NhZ2UnKTtcbiAgdGhpcy5lbWl0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgYGVtaXRgLlxuICogSWYgdGhlIGV2ZW50IGlzIGluIGBldmVudHNgLCBpdCdzIGVtaXR0ZWQgbm9ybWFsbHkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IG5hbWVcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbihldil7XG4gIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoZXYpKSB7XG4gICAgZW1pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdmFyIGFyZ3MgPSB0b0FycmF5KGFyZ3VtZW50cyk7XG4gIHZhciBwYXJzZXJUeXBlID0gcGFyc2VyLkVWRU5UOyAvLyBkZWZhdWx0XG4gIGlmIChoYXNCaW4oYXJncykpIHsgcGFyc2VyVHlwZSA9IHBhcnNlci5CSU5BUllfRVZFTlQ7IH0gLy8gYmluYXJ5XG4gIHZhciBwYWNrZXQgPSB7IHR5cGU6IHBhcnNlclR5cGUsIGRhdGE6IGFyZ3MgfTtcblxuICBwYWNrZXQub3B0aW9ucyA9IHt9O1xuICBwYWNrZXQub3B0aW9ucy5jb21wcmVzcyA9ICF0aGlzLmZsYWdzIHx8IGZhbHNlICE9PSB0aGlzLmZsYWdzLmNvbXByZXNzO1xuXG4gIC8vIGV2ZW50IGFjayBjYWxsYmFja1xuICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgYXJnc1thcmdzLmxlbmd0aCAtIDFdKSB7XG4gICAgZGVidWcoJ2VtaXR0aW5nIHBhY2tldCB3aXRoIGFjayBpZCAlZCcsIHRoaXMuaWRzKTtcbiAgICB0aGlzLmFja3NbdGhpcy5pZHNdID0gYXJncy5wb3AoKTtcbiAgICBwYWNrZXQuaWQgPSB0aGlzLmlkcysrO1xuICB9XG5cbiAgaWYgKHRoaXMuY29ubmVjdGVkKSB7XG4gICAgdGhpcy5wYWNrZXQocGFja2V0KTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnNlbmRCdWZmZXIucHVzaChwYWNrZXQpO1xuICB9XG5cbiAgZGVsZXRlIHRoaXMuZmxhZ3M7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIGEgcGFja2V0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUucGFja2V0ID0gZnVuY3Rpb24ocGFja2V0KXtcbiAgcGFja2V0Lm5zcCA9IHRoaXMubnNwO1xuICB0aGlzLmlvLnBhY2tldChwYWNrZXQpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBlbmdpbmUgYG9wZW5gLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25vcGVuID0gZnVuY3Rpb24oKXtcbiAgZGVidWcoJ3RyYW5zcG9ydCBpcyBvcGVuIC0gY29ubmVjdGluZycpO1xuXG4gIC8vIHdyaXRlIGNvbm5lY3QgcGFja2V0IGlmIG5lY2Vzc2FyeVxuICBpZiAoJy8nICE9IHRoaXMubnNwKSB7XG4gICAgdGhpcy5wYWNrZXQoeyB0eXBlOiBwYXJzZXIuQ09OTkVDVCB9KTtcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBlbmdpbmUgYGNsb3NlYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcmVhc29uXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uY2xvc2UgPSBmdW5jdGlvbihyZWFzb24pe1xuICBkZWJ1ZygnY2xvc2UgKCVzKScsIHJlYXNvbik7XG4gIHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG4gIHRoaXMuZGlzY29ubmVjdGVkID0gdHJ1ZTtcbiAgZGVsZXRlIHRoaXMuaWQ7XG4gIHRoaXMuZW1pdCgnZGlzY29ubmVjdCcsIHJlYXNvbik7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIHNvY2tldCBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbnBhY2tldCA9IGZ1bmN0aW9uKHBhY2tldCl7XG4gIGlmIChwYWNrZXQubnNwICE9IHRoaXMubnNwKSByZXR1cm47XG5cbiAgc3dpdGNoIChwYWNrZXQudHlwZSkge1xuICAgIGNhc2UgcGFyc2VyLkNPTk5FQ1Q6XG4gICAgICB0aGlzLm9uY29ubmVjdCgpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5FVkVOVDpcbiAgICAgIHRoaXMub25ldmVudChwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5CSU5BUllfRVZFTlQ6XG4gICAgICB0aGlzLm9uZXZlbnQocGFja2V0KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBwYXJzZXIuQUNLOlxuICAgICAgdGhpcy5vbmFjayhwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5CSU5BUllfQUNLOlxuICAgICAgdGhpcy5vbmFjayhwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5ESVNDT05ORUNUOlxuICAgICAgdGhpcy5vbmRpc2Nvbm5lY3QoKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBwYXJzZXIuRVJST1I6XG4gICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgcGFja2V0LmRhdGEpO1xuICAgICAgYnJlYWs7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gYSBzZXJ2ZXIgZXZlbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmV2ZW50ID0gZnVuY3Rpb24ocGFja2V0KXtcbiAgdmFyIGFyZ3MgPSBwYWNrZXQuZGF0YSB8fCBbXTtcbiAgZGVidWcoJ2VtaXR0aW5nIGV2ZW50ICVqJywgYXJncyk7XG5cbiAgaWYgKG51bGwgIT0gcGFja2V0LmlkKSB7XG4gICAgZGVidWcoJ2F0dGFjaGluZyBhY2sgY2FsbGJhY2sgdG8gZXZlbnQnKTtcbiAgICBhcmdzLnB1c2godGhpcy5hY2socGFja2V0LmlkKSk7XG4gIH1cblxuICBpZiAodGhpcy5jb25uZWN0ZWQpIHtcbiAgICBlbWl0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucmVjZWl2ZUJ1ZmZlci5wdXNoKGFyZ3MpO1xuICB9XG59O1xuXG4vKipcbiAqIFByb2R1Y2VzIGFuIGFjayBjYWxsYmFjayB0byBlbWl0IHdpdGggYW4gZXZlbnQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5hY2sgPSBmdW5jdGlvbihpZCl7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHNlbnQgPSBmYWxzZTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCl7XG4gICAgLy8gcHJldmVudCBkb3VibGUgY2FsbGJhY2tzXG4gICAgaWYgKHNlbnQpIHJldHVybjtcbiAgICBzZW50ID0gdHJ1ZTtcbiAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgICBkZWJ1Zygnc2VuZGluZyBhY2sgJWonLCBhcmdzKTtcblxuICAgIHZhciB0eXBlID0gaGFzQmluKGFyZ3MpID8gcGFyc2VyLkJJTkFSWV9BQ0sgOiBwYXJzZXIuQUNLO1xuICAgIHNlbGYucGFja2V0KHtcbiAgICAgIHR5cGU6IHR5cGUsXG4gICAgICBpZDogaWQsXG4gICAgICBkYXRhOiBhcmdzXG4gICAgfSk7XG4gIH07XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgc2VydmVyIGFja25vd2xlZ2VtZW50LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25hY2sgPSBmdW5jdGlvbihwYWNrZXQpe1xuICB2YXIgYWNrID0gdGhpcy5hY2tzW3BhY2tldC5pZF07XG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBhY2spIHtcbiAgICBkZWJ1ZygnY2FsbGluZyBhY2sgJXMgd2l0aCAlaicsIHBhY2tldC5pZCwgcGFja2V0LmRhdGEpO1xuICAgIGFjay5hcHBseSh0aGlzLCBwYWNrZXQuZGF0YSk7XG4gICAgZGVsZXRlIHRoaXMuYWNrc1twYWNrZXQuaWRdO1xuICB9IGVsc2Uge1xuICAgIGRlYnVnKCdiYWQgYWNrICVzJywgcGFja2V0LmlkKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzZXJ2ZXIgY29ubmVjdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uY29ubmVjdCA9IGZ1bmN0aW9uKCl7XG4gIHRoaXMuY29ubmVjdGVkID0gdHJ1ZTtcbiAgdGhpcy5kaXNjb25uZWN0ZWQgPSBmYWxzZTtcbiAgdGhpcy5lbWl0KCdjb25uZWN0Jyk7XG4gIHRoaXMuZW1pdEJ1ZmZlcmVkKCk7XG59O1xuXG4vKipcbiAqIEVtaXQgYnVmZmVyZWQgZXZlbnRzIChyZWNlaXZlZCBhbmQgZW1pdHRlZCkuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5lbWl0QnVmZmVyZWQgPSBmdW5jdGlvbigpe1xuICB2YXIgaTtcbiAgZm9yIChpID0gMDsgaSA8IHRoaXMucmVjZWl2ZUJ1ZmZlci5sZW5ndGg7IGkrKykge1xuICAgIGVtaXQuYXBwbHkodGhpcywgdGhpcy5yZWNlaXZlQnVmZmVyW2ldKTtcbiAgfVxuICB0aGlzLnJlY2VpdmVCdWZmZXIgPSBbXTtcblxuICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5zZW5kQnVmZmVyLmxlbmd0aDsgaSsrKSB7XG4gICAgdGhpcy5wYWNrZXQodGhpcy5zZW5kQnVmZmVyW2ldKTtcbiAgfVxuICB0aGlzLnNlbmRCdWZmZXIgPSBbXTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gc2VydmVyIGRpc2Nvbm5lY3QuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmRpc2Nvbm5lY3QgPSBmdW5jdGlvbigpe1xuICBkZWJ1Zygnc2VydmVyIGRpc2Nvbm5lY3QgKCVzKScsIHRoaXMubnNwKTtcbiAgdGhpcy5kZXN0cm95KCk7XG4gIHRoaXMub25jbG9zZSgnaW8gc2VydmVyIGRpc2Nvbm5lY3QnKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZm9yY2VkIGNsaWVudC9zZXJ2ZXIgc2lkZSBkaXNjb25uZWN0aW9ucyxcbiAqIHRoaXMgbWV0aG9kIGVuc3VyZXMgdGhlIG1hbmFnZXIgc3RvcHMgdHJhY2tpbmcgdXMgYW5kXG4gKiB0aGF0IHJlY29ubmVjdGlvbnMgZG9uJ3QgZ2V0IHRyaWdnZXJlZCBmb3IgdGhpcy5cbiAqXG4gKiBAYXBpIHByaXZhdGUuXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKXtcbiAgaWYgKHRoaXMuc3Vicykge1xuICAgIC8vIGNsZWFuIHN1YnNjcmlwdGlvbnMgdG8gYXZvaWQgcmVjb25uZWN0aW9uc1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zdWJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLnN1YnNbaV0uZGVzdHJveSgpO1xuICAgIH1cbiAgICB0aGlzLnN1YnMgPSBudWxsO1xuICB9XG5cbiAgdGhpcy5pby5kZXN0cm95KHRoaXMpO1xufTtcblxuLyoqXG4gKiBEaXNjb25uZWN0cyB0aGUgc29ja2V0IG1hbnVhbGx5LlxuICpcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmNsb3NlID1cblNvY2tldC5wcm90b3R5cGUuZGlzY29ubmVjdCA9IGZ1bmN0aW9uKCl7XG4gIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgIGRlYnVnKCdwZXJmb3JtaW5nIGRpc2Nvbm5lY3QgKCVzKScsIHRoaXMubnNwKTtcbiAgICB0aGlzLnBhY2tldCh7IHR5cGU6IHBhcnNlci5ESVNDT05ORUNUIH0pO1xuICB9XG5cbiAgLy8gcmVtb3ZlIHNvY2tldCBmcm9tIHBvb2xcbiAgdGhpcy5kZXN0cm95KCk7XG5cbiAgaWYgKHRoaXMuY29ubmVjdGVkKSB7XG4gICAgLy8gZmlyZSBldmVudHNcbiAgICB0aGlzLm9uY2xvc2UoJ2lvIGNsaWVudCBkaXNjb25uZWN0Jyk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIGNvbXByZXNzIGZsYWcuXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSBpZiBgdHJ1ZWAsIGNvbXByZXNzZXMgdGhlIHNlbmRpbmcgZGF0YVxuICogQHJldHVybiB7U29ja2V0fSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUuY29tcHJlc3MgPSBmdW5jdGlvbihjb21wcmVzcyl7XG4gIHRoaXMuZmxhZ3MgPSB0aGlzLmZsYWdzIHx8IHt9O1xuICB0aGlzLmZsYWdzLmNvbXByZXNzID0gY29tcHJlc3M7XG4gIHJldHVybiB0aGlzO1xufTtcbiIsIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBwYXJzZXVyaSA9IHJlcXVpcmUoJ3BhcnNldXJpJyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdzb2NrZXQuaW8tY2xpZW50OnVybCcpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gdXJsO1xuXG4vKipcbiAqIFVSTCBwYXJzZXIuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVybFxuICogQHBhcmFtIHtPYmplY3R9IEFuIG9iamVjdCBtZWFudCB0byBtaW1pYyB3aW5kb3cubG9jYXRpb24uXG4gKiAgICAgICAgICAgICAgICAgRGVmYXVsdHMgdG8gd2luZG93LmxvY2F0aW9uLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiB1cmwodXJpLCBsb2Mpe1xuICB2YXIgb2JqID0gdXJpO1xuXG4gIC8vIGRlZmF1bHQgdG8gd2luZG93LmxvY2F0aW9uXG4gIHZhciBsb2MgPSBsb2MgfHwgZ2xvYmFsLmxvY2F0aW9uO1xuICBpZiAobnVsbCA9PSB1cmkpIHVyaSA9IGxvYy5wcm90b2NvbCArICcvLycgKyBsb2MuaG9zdDtcblxuICAvLyByZWxhdGl2ZSBwYXRoIHN1cHBvcnRcbiAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiB1cmkpIHtcbiAgICBpZiAoJy8nID09IHVyaS5jaGFyQXQoMCkpIHtcbiAgICAgIGlmICgnLycgPT0gdXJpLmNoYXJBdCgxKSkge1xuICAgICAgICB1cmkgPSBsb2MucHJvdG9jb2wgKyB1cmk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cmkgPSBsb2MuaG9zdCArIHVyaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIS9eKGh0dHBzP3x3c3M/KTpcXC9cXC8vLnRlc3QodXJpKSkge1xuICAgICAgZGVidWcoJ3Byb3RvY29sLWxlc3MgdXJsICVzJywgdXJpKTtcbiAgICAgIGlmICgndW5kZWZpbmVkJyAhPSB0eXBlb2YgbG9jKSB7XG4gICAgICAgIHVyaSA9IGxvYy5wcm90b2NvbCArICcvLycgKyB1cmk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cmkgPSAnaHR0cHM6Ly8nICsgdXJpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHBhcnNlXG4gICAgZGVidWcoJ3BhcnNlICVzJywgdXJpKTtcbiAgICBvYmogPSBwYXJzZXVyaSh1cmkpO1xuICB9XG5cbiAgLy8gbWFrZSBzdXJlIHdlIHRyZWF0IGBsb2NhbGhvc3Q6ODBgIGFuZCBgbG9jYWxob3N0YCBlcXVhbGx5XG4gIGlmICghb2JqLnBvcnQpIHtcbiAgICBpZiAoL14oaHR0cHx3cykkLy50ZXN0KG9iai5wcm90b2NvbCkpIHtcbiAgICAgIG9iai5wb3J0ID0gJzgwJztcbiAgICB9XG4gICAgZWxzZSBpZiAoL14oaHR0cHx3cylzJC8udGVzdChvYmoucHJvdG9jb2wpKSB7XG4gICAgICBvYmoucG9ydCA9ICc0NDMnO1xuICAgIH1cbiAgfVxuXG4gIG9iai5wYXRoID0gb2JqLnBhdGggfHwgJy8nO1xuXG4gIHZhciBpcHY2ID0gb2JqLmhvc3QuaW5kZXhPZignOicpICE9PSAtMTtcbiAgdmFyIGhvc3QgPSBpcHY2ID8gJ1snICsgb2JqLmhvc3QgKyAnXScgOiBvYmouaG9zdDtcblxuICAvLyBkZWZpbmUgdW5pcXVlIGlkXG4gIG9iai5pZCA9IG9iai5wcm90b2NvbCArICc6Ly8nICsgaG9zdCArICc6JyArIG9iai5wb3J0O1xuICAvLyBkZWZpbmUgaHJlZlxuICBvYmouaHJlZiA9IG9iai5wcm90b2NvbCArICc6Ly8nICsgaG9zdCArIChsb2MgJiYgbG9jLnBvcnQgPT0gb2JqLnBvcnQgPyAnJyA6ICgnOicgKyBvYmoucG9ydCkpO1xuXG4gIHJldHVybiBvYmo7XG59XG4iLCJcbi8qKlxuICogRXhwb3NlIGBFbWl0dGVyYC5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVtaXR0ZXI7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgRW1pdHRlcmAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBFbWl0dGVyKG9iaikge1xuICBpZiAob2JqKSByZXR1cm4gbWl4aW4ob2JqKTtcbn07XG5cbi8qKlxuICogTWl4aW4gdGhlIGVtaXR0ZXIgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBtaXhpbihvYmopIHtcbiAgZm9yICh2YXIga2V5IGluIEVtaXR0ZXIucHJvdG90eXBlKSB7XG4gICAgb2JqW2tleV0gPSBFbWl0dGVyLnByb3RvdHlwZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbi8qKlxuICogTGlzdGVuIG9uIHRoZSBnaXZlbiBgZXZlbnRgIHdpdGggYGZuYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbiA9XG5FbWl0dGVyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICAodGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XSA9IHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gfHwgW10pXG4gICAgLnB1c2goZm4pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXG4gKiB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgZm4pe1xuICBmdW5jdGlvbiBvbigpIHtcbiAgICB0aGlzLm9mZihldmVudCwgb24pO1xuICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBvbi5mbiA9IGZuO1xuICB0aGlzLm9uKGV2ZW50LCBvbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICogcmVnaXN0ZXJlZCBjYWxsYmFja3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub2ZmID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuXG4gIC8vIGFsbFxuICBpZiAoMCA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgdGhpcy5fY2FsbGJhY2tzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzcGVjaWZpYyBldmVudFxuICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcbiAgaWYgKCFjYWxsYmFja3MpIHJldHVybiB0aGlzO1xuXG4gIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnNcbiAgaWYgKDEgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIGRlbGV0ZSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcbiAgdmFyIGNiO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgIGNiID0gY2FsbGJhY2tzW2ldO1xuICAgIGlmIChjYiA9PT0gZm4gfHwgY2IuZm4gPT09IGZuKSB7XG4gICAgICBjYWxsYmFja3Muc3BsaWNlKGksIDEpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7TWl4ZWR9IC4uLlxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oZXZlbnQpe1xuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG4gIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpXG4gICAgLCBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdO1xuXG4gIGlmIChjYWxsYmFja3MpIHtcbiAgICBjYWxsYmFja3MgPSBjYWxsYmFja3Muc2xpY2UoMCk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgY2FsbGJhY2tzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYXJyYXkgb2YgY2FsbGJhY2tzIGZvciBgZXZlbnRgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7QXJyYXl9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XSB8fCBbXTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhpcyBlbWl0dGVyIGhhcyBgZXZlbnRgIGhhbmRsZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuaGFzTGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xuICByZXR1cm4gISEgdGhpcy5saXN0ZW5lcnMoZXZlbnQpLmxlbmd0aDtcbn07XG4iLCIvKmdsb2JhbCBCbG9iLEZpbGUqL1xuXG4vKipcbiAqIE1vZHVsZSByZXF1aXJlbWVudHNcbiAqL1xuXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKTtcbnZhciBpc0J1ZiA9IHJlcXVpcmUoJy4vaXMtYnVmZmVyJyk7XG5cbi8qKlxuICogUmVwbGFjZXMgZXZlcnkgQnVmZmVyIHwgQXJyYXlCdWZmZXIgaW4gcGFja2V0IHdpdGggYSBudW1iZXJlZCBwbGFjZWhvbGRlci5cbiAqIEFueXRoaW5nIHdpdGggYmxvYnMgb3IgZmlsZXMgc2hvdWxkIGJlIGZlZCB0aHJvdWdoIHJlbW92ZUJsb2JzIGJlZm9yZSBjb21pbmdcbiAqIGhlcmUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldCAtIHNvY2tldC5pbyBldmVudCBwYWNrZXRcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCBkZWNvbnN0cnVjdGVkIHBhY2tldCBhbmQgbGlzdCBvZiBidWZmZXJzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZGVjb25zdHJ1Y3RQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQpe1xuICB2YXIgYnVmZmVycyA9IFtdO1xuICB2YXIgcGFja2V0RGF0YSA9IHBhY2tldC5kYXRhO1xuXG4gIGZ1bmN0aW9uIF9kZWNvbnN0cnVjdFBhY2tldChkYXRhKSB7XG4gICAgaWYgKCFkYXRhKSByZXR1cm4gZGF0YTtcblxuICAgIGlmIChpc0J1ZihkYXRhKSkge1xuICAgICAgdmFyIHBsYWNlaG9sZGVyID0geyBfcGxhY2Vob2xkZXI6IHRydWUsIG51bTogYnVmZmVycy5sZW5ndGggfTtcbiAgICAgIGJ1ZmZlcnMucHVzaChkYXRhKTtcbiAgICAgIHJldHVybiBwbGFjZWhvbGRlcjtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIHZhciBuZXdEYXRhID0gbmV3IEFycmF5KGRhdGEubGVuZ3RoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBuZXdEYXRhW2ldID0gX2RlY29uc3RydWN0UGFja2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ld0RhdGE7XG4gICAgfSBlbHNlIGlmICgnb2JqZWN0JyA9PSB0eXBlb2YgZGF0YSAmJiAhKGRhdGEgaW5zdGFuY2VvZiBEYXRlKSkge1xuICAgICAgdmFyIG5ld0RhdGEgPSB7fTtcbiAgICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICAgIG5ld0RhdGFba2V5XSA9IF9kZWNvbnN0cnVjdFBhY2tldChkYXRhW2tleV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ld0RhdGE7XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgdmFyIHBhY2sgPSBwYWNrZXQ7XG4gIHBhY2suZGF0YSA9IF9kZWNvbnN0cnVjdFBhY2tldChwYWNrZXREYXRhKTtcbiAgcGFjay5hdHRhY2htZW50cyA9IGJ1ZmZlcnMubGVuZ3RoOyAvLyBudW1iZXIgb2YgYmluYXJ5ICdhdHRhY2htZW50cydcbiAgcmV0dXJuIHtwYWNrZXQ6IHBhY2ssIGJ1ZmZlcnM6IGJ1ZmZlcnN9O1xufTtcblxuLyoqXG4gKiBSZWNvbnN0cnVjdHMgYSBiaW5hcnkgcGFja2V0IGZyb20gaXRzIHBsYWNlaG9sZGVyIHBhY2tldCBhbmQgYnVmZmVyc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQgLSBldmVudCBwYWNrZXQgd2l0aCBwbGFjZWhvbGRlcnNcbiAqIEBwYXJhbSB7QXJyYXl9IGJ1ZmZlcnMgLSBiaW5hcnkgYnVmZmVycyB0byBwdXQgaW4gcGxhY2Vob2xkZXIgcG9zaXRpb25zXG4gKiBAcmV0dXJuIHtPYmplY3R9IHJlY29uc3RydWN0ZWQgcGFja2V0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMucmVjb25zdHJ1Y3RQYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQsIGJ1ZmZlcnMpIHtcbiAgdmFyIGN1clBsYWNlSG9sZGVyID0gMDtcblxuICBmdW5jdGlvbiBfcmVjb25zdHJ1Y3RQYWNrZXQoZGF0YSkge1xuICAgIGlmIChkYXRhICYmIGRhdGEuX3BsYWNlaG9sZGVyKSB7XG4gICAgICB2YXIgYnVmID0gYnVmZmVyc1tkYXRhLm51bV07IC8vIGFwcHJvcHJpYXRlIGJ1ZmZlciAoc2hvdWxkIGJlIG5hdHVyYWwgb3JkZXIgYW55d2F5KVxuICAgICAgcmV0dXJuIGJ1ZjtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICBkYXRhW2ldID0gX3JlY29uc3RydWN0UGFja2V0KGRhdGFbaV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSBlbHNlIGlmIChkYXRhICYmICdvYmplY3QnID09IHR5cGVvZiBkYXRhKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkge1xuICAgICAgICBkYXRhW2tleV0gPSBfcmVjb25zdHJ1Y3RQYWNrZXQoZGF0YVtrZXldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIHBhY2tldC5kYXRhID0gX3JlY29uc3RydWN0UGFja2V0KHBhY2tldC5kYXRhKTtcbiAgcGFja2V0LmF0dGFjaG1lbnRzID0gdW5kZWZpbmVkOyAvLyBubyBsb25nZXIgdXNlZnVsXG4gIHJldHVybiBwYWNrZXQ7XG59O1xuXG4vKipcbiAqIEFzeW5jaHJvbm91c2x5IHJlbW92ZXMgQmxvYnMgb3IgRmlsZXMgZnJvbSBkYXRhIHZpYVxuICogRmlsZVJlYWRlcidzIHJlYWRBc0FycmF5QnVmZmVyIG1ldGhvZC4gVXNlZCBiZWZvcmUgZW5jb2RpbmdcbiAqIGRhdGEgYXMgbXNncGFjay4gQ2FsbHMgY2FsbGJhY2sgd2l0aCB0aGUgYmxvYmxlc3MgZGF0YS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMucmVtb3ZlQmxvYnMgPSBmdW5jdGlvbihkYXRhLCBjYWxsYmFjaykge1xuICBmdW5jdGlvbiBfcmVtb3ZlQmxvYnMob2JqLCBjdXJLZXksIGNvbnRhaW5pbmdPYmplY3QpIHtcbiAgICBpZiAoIW9iaikgcmV0dXJuIG9iajtcblxuICAgIC8vIGNvbnZlcnQgYW55IGJsb2JcbiAgICBpZiAoKGdsb2JhbC5CbG9iICYmIG9iaiBpbnN0YW5jZW9mIEJsb2IpIHx8XG4gICAgICAgIChnbG9iYWwuRmlsZSAmJiBvYmogaW5zdGFuY2VvZiBGaWxlKSkge1xuICAgICAgcGVuZGluZ0Jsb2JzKys7XG5cbiAgICAgIC8vIGFzeW5jIGZpbGVyZWFkZXJcbiAgICAgIHZhciBmaWxlUmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gZnVuY3Rpb24oKSB7IC8vIHRoaXMucmVzdWx0ID09IGFycmF5YnVmZmVyXG4gICAgICAgIGlmIChjb250YWluaW5nT2JqZWN0KSB7XG4gICAgICAgICAgY29udGFpbmluZ09iamVjdFtjdXJLZXldID0gdGhpcy5yZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgYmxvYmxlc3NEYXRhID0gdGhpcy5yZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiBub3RoaW5nIHBlbmRpbmcgaXRzIGNhbGxiYWNrIHRpbWVcbiAgICAgICAgaWYoISAtLXBlbmRpbmdCbG9icykge1xuICAgICAgICAgIGNhbGxiYWNrKGJsb2JsZXNzRGF0YSk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIob2JqKTsgLy8gYmxvYiAtPiBhcnJheWJ1ZmZlclxuICAgIH0gZWxzZSBpZiAoaXNBcnJheShvYmopKSB7IC8vIGhhbmRsZSBhcnJheVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgX3JlbW92ZUJsb2JzKG9ialtpXSwgaSwgb2JqKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG9iaiAmJiAnb2JqZWN0JyA9PSB0eXBlb2Ygb2JqICYmICFpc0J1ZihvYmopKSB7IC8vIGFuZCBvYmplY3RcbiAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgX3JlbW92ZUJsb2JzKG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHBlbmRpbmdCbG9icyA9IDA7XG4gIHZhciBibG9ibGVzc0RhdGEgPSBkYXRhO1xuICBfcmVtb3ZlQmxvYnMoYmxvYmxlc3NEYXRhKTtcbiAgaWYgKCFwZW5kaW5nQmxvYnMpIHtcbiAgICBjYWxsYmFjayhibG9ibGVzc0RhdGEpO1xuICB9XG59O1xuIiwiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnc29ja2V0LmlvLXBhcnNlcicpO1xudmFyIGpzb24gPSByZXF1aXJlKCdqc29uMycpO1xudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5Jyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgYmluYXJ5ID0gcmVxdWlyZSgnLi9iaW5hcnknKTtcbnZhciBpc0J1ZiA9IHJlcXVpcmUoJy4vaXMtYnVmZmVyJyk7XG5cbi8qKlxuICogUHJvdG9jb2wgdmVyc2lvbi5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMucHJvdG9jb2wgPSA0O1xuXG4vKipcbiAqIFBhY2tldCB0eXBlcy5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMudHlwZXMgPSBbXG4gICdDT05ORUNUJyxcbiAgJ0RJU0NPTk5FQ1QnLFxuICAnRVZFTlQnLFxuICAnQUNLJyxcbiAgJ0VSUk9SJyxcbiAgJ0JJTkFSWV9FVkVOVCcsXG4gICdCSU5BUllfQUNLJ1xuXTtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgY29ubmVjdGAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkNPTk5FQ1QgPSAwO1xuXG4vKipcbiAqIFBhY2tldCB0eXBlIGBkaXNjb25uZWN0YC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuRElTQ09OTkVDVCA9IDE7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGV2ZW50YC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuRVZFTlQgPSAyO1xuXG4vKipcbiAqIFBhY2tldCB0eXBlIGBhY2tgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5BQ0sgPSAzO1xuXG4vKipcbiAqIFBhY2tldCB0eXBlIGBlcnJvcmAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkVSUk9SID0gNDtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSAnYmluYXJ5IGV2ZW50J1xuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5CSU5BUllfRVZFTlQgPSA1O1xuXG4vKipcbiAqIFBhY2tldCB0eXBlIGBiaW5hcnkgYWNrYC4gRm9yIGFja3Mgd2l0aCBiaW5hcnkgYXJndW1lbnRzLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5CSU5BUllfQUNLID0gNjtcblxuLyoqXG4gKiBFbmNvZGVyIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5FbmNvZGVyID0gRW5jb2RlcjtcblxuLyoqXG4gKiBEZWNvZGVyIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5EZWNvZGVyID0gRGVjb2RlcjtcblxuLyoqXG4gKiBBIHNvY2tldC5pbyBFbmNvZGVyIGluc3RhbmNlXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBFbmNvZGVyKCkge31cblxuLyoqXG4gKiBFbmNvZGUgYSBwYWNrZXQgYXMgYSBzaW5nbGUgc3RyaW5nIGlmIG5vbi1iaW5hcnksIG9yIGFzIGFcbiAqIGJ1ZmZlciBzZXF1ZW5jZSwgZGVwZW5kaW5nIG9uIHBhY2tldCB0eXBlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogLSBwYWNrZXQgb2JqZWN0XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayAtIGZ1bmN0aW9uIHRvIGhhbmRsZSBlbmNvZGluZ3MgKGxpa2VseSBlbmdpbmUud3JpdGUpXG4gKiBAcmV0dXJuIENhbGxzIGNhbGxiYWNrIHdpdGggQXJyYXkgb2YgZW5jb2RpbmdzXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVuY29kZXIucHJvdG90eXBlLmVuY29kZSA9IGZ1bmN0aW9uKG9iaiwgY2FsbGJhY2spe1xuICBkZWJ1ZygnZW5jb2RpbmcgcGFja2V0ICVqJywgb2JqKTtcblxuICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gb2JqLnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IG9iai50eXBlKSB7XG4gICAgZW5jb2RlQXNCaW5hcnkob2JqLCBjYWxsYmFjayk7XG4gIH1cbiAgZWxzZSB7XG4gICAgdmFyIGVuY29kaW5nID0gZW5jb2RlQXNTdHJpbmcob2JqKTtcbiAgICBjYWxsYmFjayhbZW5jb2RpbmddKTtcbiAgfVxufTtcblxuLyoqXG4gKiBFbmNvZGUgcGFja2V0IGFzIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFja2V0XG4gKiBAcmV0dXJuIHtTdHJpbmd9IGVuY29kZWRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGVuY29kZUFzU3RyaW5nKG9iaikge1xuICB2YXIgc3RyID0gJyc7XG4gIHZhciBuc3AgPSBmYWxzZTtcblxuICAvLyBmaXJzdCBpcyB0eXBlXG4gIHN0ciArPSBvYmoudHlwZTtcblxuICAvLyBhdHRhY2htZW50cyBpZiB3ZSBoYXZlIHRoZW1cbiAgaWYgKGV4cG9ydHMuQklOQVJZX0VWRU5UID09IG9iai50eXBlIHx8IGV4cG9ydHMuQklOQVJZX0FDSyA9PSBvYmoudHlwZSkge1xuICAgIHN0ciArPSBvYmouYXR0YWNobWVudHM7XG4gICAgc3RyICs9ICctJztcbiAgfVxuXG4gIC8vIGlmIHdlIGhhdmUgYSBuYW1lc3BhY2Ugb3RoZXIgdGhhbiBgL2BcbiAgLy8gd2UgYXBwZW5kIGl0IGZvbGxvd2VkIGJ5IGEgY29tbWEgYCxgXG4gIGlmIChvYmoubnNwICYmICcvJyAhPSBvYmoubnNwKSB7XG4gICAgbnNwID0gdHJ1ZTtcbiAgICBzdHIgKz0gb2JqLm5zcDtcbiAgfVxuXG4gIC8vIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IHRoZSBpZFxuICBpZiAobnVsbCAhPSBvYmouaWQpIHtcbiAgICBpZiAobnNwKSB7XG4gICAgICBzdHIgKz0gJywnO1xuICAgICAgbnNwID0gZmFsc2U7XG4gICAgfVxuICAgIHN0ciArPSBvYmouaWQ7XG4gIH1cblxuICAvLyBqc29uIGRhdGFcbiAgaWYgKG51bGwgIT0gb2JqLmRhdGEpIHtcbiAgICBpZiAobnNwKSBzdHIgKz0gJywnO1xuICAgIHN0ciArPSBqc29uLnN0cmluZ2lmeShvYmouZGF0YSk7XG4gIH1cblxuICBkZWJ1ZygnZW5jb2RlZCAlaiBhcyAlcycsIG9iaiwgc3RyKTtcbiAgcmV0dXJuIHN0cjtcbn1cblxuLyoqXG4gKiBFbmNvZGUgcGFja2V0IGFzICdidWZmZXIgc2VxdWVuY2UnIGJ5IHJlbW92aW5nIGJsb2JzLCBhbmRcbiAqIGRlY29uc3RydWN0aW5nIHBhY2tldCBpbnRvIG9iamVjdCB3aXRoIHBsYWNlaG9sZGVycyBhbmRcbiAqIGEgbGlzdCBvZiBidWZmZXJzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEByZXR1cm4ge0J1ZmZlcn0gZW5jb2RlZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gZW5jb2RlQXNCaW5hcnkob2JqLCBjYWxsYmFjaykge1xuXG4gIGZ1bmN0aW9uIHdyaXRlRW5jb2RpbmcoYmxvYmxlc3NEYXRhKSB7XG4gICAgdmFyIGRlY29uc3RydWN0aW9uID0gYmluYXJ5LmRlY29uc3RydWN0UGFja2V0KGJsb2JsZXNzRGF0YSk7XG4gICAgdmFyIHBhY2sgPSBlbmNvZGVBc1N0cmluZyhkZWNvbnN0cnVjdGlvbi5wYWNrZXQpO1xuICAgIHZhciBidWZmZXJzID0gZGVjb25zdHJ1Y3Rpb24uYnVmZmVycztcblxuICAgIGJ1ZmZlcnMudW5zaGlmdChwYWNrKTsgLy8gYWRkIHBhY2tldCBpbmZvIHRvIGJlZ2lubmluZyBvZiBkYXRhIGxpc3RcbiAgICBjYWxsYmFjayhidWZmZXJzKTsgLy8gd3JpdGUgYWxsIHRoZSBidWZmZXJzXG4gIH1cblxuICBiaW5hcnkucmVtb3ZlQmxvYnMob2JqLCB3cml0ZUVuY29kaW5nKTtcbn1cblxuLyoqXG4gKiBBIHNvY2tldC5pbyBEZWNvZGVyIGluc3RhbmNlXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSBkZWNvZGVyXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIERlY29kZXIoKSB7XG4gIHRoaXMucmVjb25zdHJ1Y3RvciA9IG51bGw7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYCB3aXRoIERlY29kZXIuXG4gKi9cblxuRW1pdHRlcihEZWNvZGVyLnByb3RvdHlwZSk7XG5cbi8qKlxuICogRGVjb2RlcyBhbiBlY29kZWQgcGFja2V0IHN0cmluZyBpbnRvIHBhY2tldCBKU09OLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBvYmogLSBlbmNvZGVkIHBhY2tldFxuICogQHJldHVybiB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRGVjb2Rlci5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24ob2JqKSB7XG4gIHZhciBwYWNrZXQ7XG4gIGlmICgnc3RyaW5nJyA9PSB0eXBlb2Ygb2JqKSB7XG4gICAgcGFja2V0ID0gZGVjb2RlU3RyaW5nKG9iaik7XG4gICAgaWYgKGV4cG9ydHMuQklOQVJZX0VWRU5UID09IHBhY2tldC50eXBlIHx8IGV4cG9ydHMuQklOQVJZX0FDSyA9PSBwYWNrZXQudHlwZSkgeyAvLyBiaW5hcnkgcGFja2V0J3MganNvblxuICAgICAgdGhpcy5yZWNvbnN0cnVjdG9yID0gbmV3IEJpbmFyeVJlY29uc3RydWN0b3IocGFja2V0KTtcblxuICAgICAgLy8gbm8gYXR0YWNobWVudHMsIGxhYmVsZWQgYmluYXJ5IGJ1dCBubyBiaW5hcnkgZGF0YSB0byBmb2xsb3dcbiAgICAgIGlmICh0aGlzLnJlY29uc3RydWN0b3IucmVjb25QYWNrLmF0dGFjaG1lbnRzID09PSAwKSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZGVjb2RlZCcsIHBhY2tldCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHsgLy8gbm9uLWJpbmFyeSBmdWxsIHBhY2tldFxuICAgICAgdGhpcy5lbWl0KCdkZWNvZGVkJywgcGFja2V0KTtcbiAgICB9XG4gIH1cbiAgZWxzZSBpZiAoaXNCdWYob2JqKSB8fCBvYmouYmFzZTY0KSB7IC8vIHJhdyBiaW5hcnkgZGF0YVxuICAgIGlmICghdGhpcy5yZWNvbnN0cnVjdG9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dvdCBiaW5hcnkgZGF0YSB3aGVuIG5vdCByZWNvbnN0cnVjdGluZyBhIHBhY2tldCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYWNrZXQgPSB0aGlzLnJlY29uc3RydWN0b3IudGFrZUJpbmFyeURhdGEob2JqKTtcbiAgICAgIGlmIChwYWNrZXQpIHsgLy8gcmVjZWl2ZWQgZmluYWwgYnVmZmVyXG4gICAgICAgIHRoaXMucmVjb25zdHJ1Y3RvciA9IG51bGw7XG4gICAgICAgIHRoaXMuZW1pdCgnZGVjb2RlZCcsIHBhY2tldCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biB0eXBlOiAnICsgb2JqKTtcbiAgfVxufTtcblxuLyoqXG4gKiBEZWNvZGUgYSBwYWNrZXQgU3RyaW5nIChKU09OIGRhdGEpXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGRlY29kZVN0cmluZyhzdHIpIHtcbiAgdmFyIHAgPSB7fTtcbiAgdmFyIGkgPSAwO1xuXG4gIC8vIGxvb2sgdXAgdHlwZVxuICBwLnR5cGUgPSBOdW1iZXIoc3RyLmNoYXJBdCgwKSk7XG4gIGlmIChudWxsID09IGV4cG9ydHMudHlwZXNbcC50eXBlXSkgcmV0dXJuIGVycm9yKCk7XG5cbiAgLy8gbG9vayB1cCBhdHRhY2htZW50cyBpZiB0eXBlIGJpbmFyeVxuICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gcC50eXBlIHx8IGV4cG9ydHMuQklOQVJZX0FDSyA9PSBwLnR5cGUpIHtcbiAgICB2YXIgYnVmID0gJyc7XG4gICAgd2hpbGUgKHN0ci5jaGFyQXQoKytpKSAhPSAnLScpIHtcbiAgICAgIGJ1ZiArPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKGkgPT0gc3RyLmxlbmd0aCkgYnJlYWs7XG4gICAgfVxuICAgIGlmIChidWYgIT0gTnVtYmVyKGJ1ZikgfHwgc3RyLmNoYXJBdChpKSAhPSAnLScpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSWxsZWdhbCBhdHRhY2htZW50cycpO1xuICAgIH1cbiAgICBwLmF0dGFjaG1lbnRzID0gTnVtYmVyKGJ1Zik7XG4gIH1cblxuICAvLyBsb29rIHVwIG5hbWVzcGFjZSAoaWYgYW55KVxuICBpZiAoJy8nID09IHN0ci5jaGFyQXQoaSArIDEpKSB7XG4gICAgcC5uc3AgPSAnJztcbiAgICB3aGlsZSAoKytpKSB7XG4gICAgICB2YXIgYyA9IHN0ci5jaGFyQXQoaSk7XG4gICAgICBpZiAoJywnID09IGMpIGJyZWFrO1xuICAgICAgcC5uc3AgKz0gYztcbiAgICAgIGlmIChpID09IHN0ci5sZW5ndGgpIGJyZWFrO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBwLm5zcCA9ICcvJztcbiAgfVxuXG4gIC8vIGxvb2sgdXAgaWRcbiAgdmFyIG5leHQgPSBzdHIuY2hhckF0KGkgKyAxKTtcbiAgaWYgKCcnICE9PSBuZXh0ICYmIE51bWJlcihuZXh0KSA9PSBuZXh0KSB7XG4gICAgcC5pZCA9ICcnO1xuICAgIHdoaWxlICgrK2kpIHtcbiAgICAgIHZhciBjID0gc3RyLmNoYXJBdChpKTtcbiAgICAgIGlmIChudWxsID09IGMgfHwgTnVtYmVyKGMpICE9IGMpIHtcbiAgICAgICAgLS1pO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHAuaWQgKz0gc3RyLmNoYXJBdChpKTtcbiAgICAgIGlmIChpID09IHN0ci5sZW5ndGgpIGJyZWFrO1xuICAgIH1cbiAgICBwLmlkID0gTnVtYmVyKHAuaWQpO1xuICB9XG5cbiAgLy8gbG9vayB1cCBqc29uIGRhdGFcbiAgaWYgKHN0ci5jaGFyQXQoKytpKSkge1xuICAgIHRyeSB7XG4gICAgICBwLmRhdGEgPSBqc29uLnBhcnNlKHN0ci5zdWJzdHIoaSkpO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICByZXR1cm4gZXJyb3IoKTtcbiAgICB9XG4gIH1cblxuICBkZWJ1ZygnZGVjb2RlZCAlcyBhcyAlaicsIHN0ciwgcCk7XG4gIHJldHVybiBwO1xufVxuXG4vKipcbiAqIERlYWxsb2NhdGVzIGEgcGFyc2VyJ3MgcmVzb3VyY2VzXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5EZWNvZGVyLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLnJlY29uc3RydWN0b3IpIHtcbiAgICB0aGlzLnJlY29uc3RydWN0b3IuZmluaXNoZWRSZWNvbnN0cnVjdGlvbigpO1xuICB9XG59O1xuXG4vKipcbiAqIEEgbWFuYWdlciBvZiBhIGJpbmFyeSBldmVudCdzICdidWZmZXIgc2VxdWVuY2UnLiBTaG91bGRcbiAqIGJlIGNvbnN0cnVjdGVkIHdoZW5ldmVyIGEgcGFja2V0IG9mIHR5cGUgQklOQVJZX0VWRU5UIGlzXG4gKiBkZWNvZGVkLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEByZXR1cm4ge0JpbmFyeVJlY29uc3RydWN0b3J9IGluaXRpYWxpemVkIHJlY29uc3RydWN0b3JcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIEJpbmFyeVJlY29uc3RydWN0b3IocGFja2V0KSB7XG4gIHRoaXMucmVjb25QYWNrID0gcGFja2V0O1xuICB0aGlzLmJ1ZmZlcnMgPSBbXTtcbn1cblxuLyoqXG4gKiBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYmluYXJ5IGRhdGEgcmVjZWl2ZWQgZnJvbSBjb25uZWN0aW9uXG4gKiBhZnRlciBhIEJJTkFSWV9FVkVOVCBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtCdWZmZXIgfCBBcnJheUJ1ZmZlcn0gYmluRGF0YSAtIHRoZSByYXcgYmluYXJ5IGRhdGEgcmVjZWl2ZWRcbiAqIEByZXR1cm4ge251bGwgfCBPYmplY3R9IHJldHVybnMgbnVsbCBpZiBtb3JlIGJpbmFyeSBkYXRhIGlzIGV4cGVjdGVkIG9yXG4gKiAgIGEgcmVjb25zdHJ1Y3RlZCBwYWNrZXQgb2JqZWN0IGlmIGFsbCBidWZmZXJzIGhhdmUgYmVlbiByZWNlaXZlZC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkJpbmFyeVJlY29uc3RydWN0b3IucHJvdG90eXBlLnRha2VCaW5hcnlEYXRhID0gZnVuY3Rpb24oYmluRGF0YSkge1xuICB0aGlzLmJ1ZmZlcnMucHVzaChiaW5EYXRhKTtcbiAgaWYgKHRoaXMuYnVmZmVycy5sZW5ndGggPT0gdGhpcy5yZWNvblBhY2suYXR0YWNobWVudHMpIHsgLy8gZG9uZSB3aXRoIGJ1ZmZlciBsaXN0XG4gICAgdmFyIHBhY2tldCA9IGJpbmFyeS5yZWNvbnN0cnVjdFBhY2tldCh0aGlzLnJlY29uUGFjaywgdGhpcy5idWZmZXJzKTtcbiAgICB0aGlzLmZpbmlzaGVkUmVjb25zdHJ1Y3Rpb24oKTtcbiAgICByZXR1cm4gcGFja2V0O1xuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxuLyoqXG4gKiBDbGVhbnMgdXAgYmluYXJ5IHBhY2tldCByZWNvbnN0cnVjdGlvbiB2YXJpYWJsZXMuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuQmluYXJ5UmVjb25zdHJ1Y3Rvci5wcm90b3R5cGUuZmluaXNoZWRSZWNvbnN0cnVjdGlvbiA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLnJlY29uUGFjayA9IG51bGw7XG4gIHRoaXMuYnVmZmVycyA9IFtdO1xufTtcblxuZnVuY3Rpb24gZXJyb3IoZGF0YSl7XG4gIHJldHVybiB7XG4gICAgdHlwZTogZXhwb3J0cy5FUlJPUixcbiAgICBkYXRhOiAncGFyc2VyIGVycm9yJ1xuICB9O1xufVxuIiwiXG5tb2R1bGUuZXhwb3J0cyA9IGlzQnVmO1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiBvYmogaXMgYSBidWZmZXIgb3IgYW4gYXJyYXlidWZmZXIuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaXNCdWYob2JqKSB7XG4gIHJldHVybiAoZ2xvYmFsLkJ1ZmZlciAmJiBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyKG9iaikpIHx8XG4gICAgICAgICAoZ2xvYmFsLkFycmF5QnVmZmVyICYmIG9iaiBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKTtcbn1cbiIsIi8qISBKU09OIHYzLjMuMiB8IGh0dHA6Ly9iZXN0aWVqcy5naXRodWIuaW8vanNvbjMgfCBDb3B5cmlnaHQgMjAxMi0yMDE0LCBLaXQgQ2FtYnJpZGdlIHwgaHR0cDovL2tpdC5taXQtbGljZW5zZS5vcmcgKi9cbjsoZnVuY3Rpb24gKCkge1xuICAvLyBEZXRlY3QgdGhlIGBkZWZpbmVgIGZ1bmN0aW9uIGV4cG9zZWQgYnkgYXN5bmNocm9ub3VzIG1vZHVsZSBsb2FkZXJzLiBUaGVcbiAgLy8gc3RyaWN0IGBkZWZpbmVgIGNoZWNrIGlzIG5lY2Vzc2FyeSBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIGByLmpzYC5cbiAgdmFyIGlzTG9hZGVyID0gdHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQ7XG5cbiAgLy8gQSBzZXQgb2YgdHlwZXMgdXNlZCB0byBkaXN0aW5ndWlzaCBvYmplY3RzIGZyb20gcHJpbWl0aXZlcy5cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgIFwiZnVuY3Rpb25cIjogdHJ1ZSxcbiAgICBcIm9iamVjdFwiOiB0cnVlXG4gIH07XG5cbiAgLy8gRGV0ZWN0IHRoZSBgZXhwb3J0c2Agb2JqZWN0IGV4cG9zZWQgYnkgQ29tbW9uSlMgaW1wbGVtZW50YXRpb25zLlxuICB2YXIgZnJlZUV4cG9ydHMgPSBvYmplY3RUeXBlc1t0eXBlb2YgZXhwb3J0c10gJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzO1xuXG4gIC8vIFVzZSB0aGUgYGdsb2JhbGAgb2JqZWN0IGV4cG9zZWQgYnkgTm9kZSAoaW5jbHVkaW5nIEJyb3dzZXJpZnkgdmlhXG4gIC8vIGBpbnNlcnQtbW9kdWxlLWdsb2JhbHNgKSwgTmFyd2hhbCwgYW5kIFJpbmdvIGFzIHRoZSBkZWZhdWx0IGNvbnRleHQsXG4gIC8vIGFuZCB0aGUgYHdpbmRvd2Agb2JqZWN0IGluIGJyb3dzZXJzLiBSaGlubyBleHBvcnRzIGEgYGdsb2JhbGAgZnVuY3Rpb25cbiAgLy8gaW5zdGVhZC5cbiAgdmFyIHJvb3QgPSBvYmplY3RUeXBlc1t0eXBlb2Ygd2luZG93XSAmJiB3aW5kb3cgfHwgdGhpcyxcbiAgICAgIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiB0eXBlb2YgZ2xvYmFsID09IFwib2JqZWN0XCIgJiYgZ2xvYmFsO1xuXG4gIGlmIChmcmVlR2xvYmFsICYmIChmcmVlR2xvYmFsW1wiZ2xvYmFsXCJdID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWxbXCJ3aW5kb3dcIl0gPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbFtcInNlbGZcIl0gPT09IGZyZWVHbG9iYWwpKSB7XG4gICAgcm9vdCA9IGZyZWVHbG9iYWw7XG4gIH1cblxuICAvLyBQdWJsaWM6IEluaXRpYWxpemVzIEpTT04gMyB1c2luZyB0aGUgZ2l2ZW4gYGNvbnRleHRgIG9iamVjdCwgYXR0YWNoaW5nIHRoZVxuICAvLyBgc3RyaW5naWZ5YCBhbmQgYHBhcnNlYCBmdW5jdGlvbnMgdG8gdGhlIHNwZWNpZmllZCBgZXhwb3J0c2Agb2JqZWN0LlxuICBmdW5jdGlvbiBydW5JbkNvbnRleHQoY29udGV4dCwgZXhwb3J0cykge1xuICAgIGNvbnRleHQgfHwgKGNvbnRleHQgPSByb290W1wiT2JqZWN0XCJdKCkpO1xuICAgIGV4cG9ydHMgfHwgKGV4cG9ydHMgPSByb290W1wiT2JqZWN0XCJdKCkpO1xuXG4gICAgLy8gTmF0aXZlIGNvbnN0cnVjdG9yIGFsaWFzZXMuXG4gICAgdmFyIE51bWJlciA9IGNvbnRleHRbXCJOdW1iZXJcIl0gfHwgcm9vdFtcIk51bWJlclwiXSxcbiAgICAgICAgU3RyaW5nID0gY29udGV4dFtcIlN0cmluZ1wiXSB8fCByb290W1wiU3RyaW5nXCJdLFxuICAgICAgICBPYmplY3QgPSBjb250ZXh0W1wiT2JqZWN0XCJdIHx8IHJvb3RbXCJPYmplY3RcIl0sXG4gICAgICAgIERhdGUgPSBjb250ZXh0W1wiRGF0ZVwiXSB8fCByb290W1wiRGF0ZVwiXSxcbiAgICAgICAgU3ludGF4RXJyb3IgPSBjb250ZXh0W1wiU3ludGF4RXJyb3JcIl0gfHwgcm9vdFtcIlN5bnRheEVycm9yXCJdLFxuICAgICAgICBUeXBlRXJyb3IgPSBjb250ZXh0W1wiVHlwZUVycm9yXCJdIHx8IHJvb3RbXCJUeXBlRXJyb3JcIl0sXG4gICAgICAgIE1hdGggPSBjb250ZXh0W1wiTWF0aFwiXSB8fCByb290W1wiTWF0aFwiXSxcbiAgICAgICAgbmF0aXZlSlNPTiA9IGNvbnRleHRbXCJKU09OXCJdIHx8IHJvb3RbXCJKU09OXCJdO1xuXG4gICAgLy8gRGVsZWdhdGUgdG8gdGhlIG5hdGl2ZSBgc3RyaW5naWZ5YCBhbmQgYHBhcnNlYCBpbXBsZW1lbnRhdGlvbnMuXG4gICAgaWYgKHR5cGVvZiBuYXRpdmVKU09OID09IFwib2JqZWN0XCIgJiYgbmF0aXZlSlNPTikge1xuICAgICAgZXhwb3J0cy5zdHJpbmdpZnkgPSBuYXRpdmVKU09OLnN0cmluZ2lmeTtcbiAgICAgIGV4cG9ydHMucGFyc2UgPSBuYXRpdmVKU09OLnBhcnNlO1xuICAgIH1cblxuICAgIC8vIENvbnZlbmllbmNlIGFsaWFzZXMuXG4gICAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZSxcbiAgICAgICAgZ2V0Q2xhc3MgPSBvYmplY3RQcm90by50b1N0cmluZyxcbiAgICAgICAgaXNQcm9wZXJ0eSwgZm9yRWFjaCwgdW5kZWY7XG5cbiAgICAvLyBUZXN0IHRoZSBgRGF0ZSNnZXRVVEMqYCBtZXRob2RzLiBCYXNlZCBvbiB3b3JrIGJ5IEBZYWZmbGUuXG4gICAgdmFyIGlzRXh0ZW5kZWQgPSBuZXcgRGF0ZSgtMzUwOTgyNzMzNDU3MzI5Mik7XG4gICAgdHJ5IHtcbiAgICAgIC8vIFRoZSBgZ2V0VVRDRnVsbFllYXJgLCBgTW9udGhgLCBhbmQgYERhdGVgIG1ldGhvZHMgcmV0dXJuIG5vbnNlbnNpY2FsXG4gICAgICAvLyByZXN1bHRzIGZvciBjZXJ0YWluIGRhdGVzIGluIE9wZXJhID49IDEwLjUzLlxuICAgICAgaXNFeHRlbmRlZCA9IGlzRXh0ZW5kZWQuZ2V0VVRDRnVsbFllYXIoKSA9PSAtMTA5MjUyICYmIGlzRXh0ZW5kZWQuZ2V0VVRDTW9udGgoKSA9PT0gMCAmJiBpc0V4dGVuZGVkLmdldFVUQ0RhdGUoKSA9PT0gMSAmJlxuICAgICAgICAvLyBTYWZhcmkgPCAyLjAuMiBzdG9yZXMgdGhlIGludGVybmFsIG1pbGxpc2Vjb25kIHRpbWUgdmFsdWUgY29ycmVjdGx5LFxuICAgICAgICAvLyBidXQgY2xpcHMgdGhlIHZhbHVlcyByZXR1cm5lZCBieSB0aGUgZGF0ZSBtZXRob2RzIHRvIHRoZSByYW5nZSBvZlxuICAgICAgICAvLyBzaWduZWQgMzItYml0IGludGVnZXJzIChbLTIgKiogMzEsIDIgKiogMzEgLSAxXSkuXG4gICAgICAgIGlzRXh0ZW5kZWQuZ2V0VVRDSG91cnMoKSA9PSAxMCAmJiBpc0V4dGVuZGVkLmdldFVUQ01pbnV0ZXMoKSA9PSAzNyAmJiBpc0V4dGVuZGVkLmdldFVUQ1NlY29uZHMoKSA9PSA2ICYmIGlzRXh0ZW5kZWQuZ2V0VVRDTWlsbGlzZWNvbmRzKCkgPT0gNzA4O1xuICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cblxuICAgIC8vIEludGVybmFsOiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIG5hdGl2ZSBgSlNPTi5zdHJpbmdpZnlgIGFuZCBgcGFyc2VgXG4gICAgLy8gaW1wbGVtZW50YXRpb25zIGFyZSBzcGVjLWNvbXBsaWFudC4gQmFzZWQgb24gd29yayBieSBLZW4gU255ZGVyLlxuICAgIGZ1bmN0aW9uIGhhcyhuYW1lKSB7XG4gICAgICBpZiAoaGFzW25hbWVdICE9PSB1bmRlZikge1xuICAgICAgICAvLyBSZXR1cm4gY2FjaGVkIGZlYXR1cmUgdGVzdCByZXN1bHQuXG4gICAgICAgIHJldHVybiBoYXNbbmFtZV07XG4gICAgICB9XG4gICAgICB2YXIgaXNTdXBwb3J0ZWQ7XG4gICAgICBpZiAobmFtZSA9PSBcImJ1Zy1zdHJpbmctY2hhci1pbmRleFwiKSB7XG4gICAgICAgIC8vIElFIDw9IDcgZG9lc24ndCBzdXBwb3J0IGFjY2Vzc2luZyBzdHJpbmcgY2hhcmFjdGVycyB1c2luZyBzcXVhcmVcbiAgICAgICAgLy8gYnJhY2tldCBub3RhdGlvbi4gSUUgOCBvbmx5IHN1cHBvcnRzIHRoaXMgZm9yIHByaW1pdGl2ZXMuXG4gICAgICAgIGlzU3VwcG9ydGVkID0gXCJhXCJbMF0gIT0gXCJhXCI7XG4gICAgICB9IGVsc2UgaWYgKG5hbWUgPT0gXCJqc29uXCIpIHtcbiAgICAgICAgLy8gSW5kaWNhdGVzIHdoZXRoZXIgYm90aCBgSlNPTi5zdHJpbmdpZnlgIGFuZCBgSlNPTi5wYXJzZWAgYXJlXG4gICAgICAgIC8vIHN1cHBvcnRlZC5cbiAgICAgICAgaXNTdXBwb3J0ZWQgPSBoYXMoXCJqc29uLXN0cmluZ2lmeVwiKSAmJiBoYXMoXCJqc29uLXBhcnNlXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHZhbHVlLCBzZXJpYWxpemVkID0gJ3tcImFcIjpbMSx0cnVlLGZhbHNlLG51bGwsXCJcXFxcdTAwMDBcXFxcYlxcXFxuXFxcXGZcXFxcclxcXFx0XCJdfSc7XG4gICAgICAgIC8vIFRlc3QgYEpTT04uc3RyaW5naWZ5YC5cbiAgICAgICAgaWYgKG5hbWUgPT0gXCJqc29uLXN0cmluZ2lmeVwiKSB7XG4gICAgICAgICAgdmFyIHN0cmluZ2lmeSA9IGV4cG9ydHMuc3RyaW5naWZ5LCBzdHJpbmdpZnlTdXBwb3J0ZWQgPSB0eXBlb2Ygc3RyaW5naWZ5ID09IFwiZnVuY3Rpb25cIiAmJiBpc0V4dGVuZGVkO1xuICAgICAgICAgIGlmIChzdHJpbmdpZnlTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgIC8vIEEgdGVzdCBmdW5jdGlvbiBvYmplY3Qgd2l0aCBhIGN1c3RvbSBgdG9KU09OYCBtZXRob2QuXG4gICAgICAgICAgICAodmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfSkudG9KU09OID0gdmFsdWU7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzdHJpbmdpZnlTdXBwb3J0ZWQgPVxuICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggMy4xYjEgYW5kIGIyIHNlcmlhbGl6ZSBzdHJpbmcsIG51bWJlciwgYW5kIGJvb2xlYW5cbiAgICAgICAgICAgICAgICAvLyBwcmltaXRpdmVzIGFzIG9iamVjdCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkoMCkgPT09IFwiMFwiICYmXG4gICAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIGIyLCBhbmQgSlNPTiAyIHNlcmlhbGl6ZSB3cmFwcGVkIHByaW1pdGl2ZXMgYXMgb2JqZWN0XG4gICAgICAgICAgICAgICAgLy8gbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBOdW1iZXIoKSkgPT09IFwiMFwiICYmXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBTdHJpbmcoKSkgPT0gJ1wiXCInICYmXG4gICAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIDIgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHZhbHVlIGlzIGBudWxsYCwgYHVuZGVmaW5lZGAsIG9yXG4gICAgICAgICAgICAgICAgLy8gZG9lcyBub3QgZGVmaW5lIGEgY2Fub25pY2FsIEpTT04gcmVwcmVzZW50YXRpb24gKHRoaXMgYXBwbGllcyB0b1xuICAgICAgICAgICAgICAgIC8vIG9iamVjdHMgd2l0aCBgdG9KU09OYCBwcm9wZXJ0aWVzIGFzIHdlbGwsICp1bmxlc3MqIHRoZXkgYXJlIG5lc3RlZFxuICAgICAgICAgICAgICAgIC8vIHdpdGhpbiBhbiBvYmplY3Qgb3IgYXJyYXkpLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShnZXRDbGFzcykgPT09IHVuZGVmICYmXG4gICAgICAgICAgICAgICAgLy8gSUUgOCBzZXJpYWxpemVzIGB1bmRlZmluZWRgIGFzIGBcInVuZGVmaW5lZFwiYC4gU2FmYXJpIDw9IDUuMS43IGFuZFxuICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIzIHBhc3MgdGhpcyB0ZXN0LlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeSh1bmRlZikgPT09IHVuZGVmICYmXG4gICAgICAgICAgICAgICAgLy8gU2FmYXJpIDw9IDUuMS43IGFuZCBGRiAzLjFiMyB0aHJvdyBgRXJyb3JgcyBhbmQgYFR5cGVFcnJvcmBzLFxuICAgICAgICAgICAgICAgIC8vIHJlc3BlY3RpdmVseSwgaWYgdGhlIHZhbHVlIGlzIG9taXR0ZWQgZW50aXJlbHkuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KCkgPT09IHVuZGVmICYmXG4gICAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIDIgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIG5vdCBhIG51bWJlcixcbiAgICAgICAgICAgICAgICAvLyBzdHJpbmcsIGFycmF5LCBvYmplY3QsIEJvb2xlYW4sIG9yIGBudWxsYCBsaXRlcmFsLiBUaGlzIGFwcGxpZXMgdG9cbiAgICAgICAgICAgICAgICAvLyBvYmplY3RzIHdpdGggY3VzdG9tIGB0b0pTT05gIG1ldGhvZHMgYXMgd2VsbCwgdW5sZXNzIHRoZXkgYXJlIG5lc3RlZFxuICAgICAgICAgICAgICAgIC8vIGluc2lkZSBvYmplY3Qgb3IgYXJyYXkgbGl0ZXJhbHMuIFlVSSAzLjAuMGIxIGlnbm9yZXMgY3VzdG9tIGB0b0pTT05gXG4gICAgICAgICAgICAgICAgLy8gbWV0aG9kcyBlbnRpcmVseS5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkodmFsdWUpID09PSBcIjFcIiAmJlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShbdmFsdWVdKSA9PSBcIlsxXVwiICYmXG4gICAgICAgICAgICAgICAgLy8gUHJvdG90eXBlIDw9IDEuNi4xIHNlcmlhbGl6ZXMgYFt1bmRlZmluZWRdYCBhcyBgXCJbXVwiYCBpbnN0ZWFkIG9mXG4gICAgICAgICAgICAgICAgLy8gYFwiW251bGxdXCJgLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShbdW5kZWZdKSA9PSBcIltudWxsXVwiICYmXG4gICAgICAgICAgICAgICAgLy8gWVVJIDMuMC4wYjEgZmFpbHMgdG8gc2VyaWFsaXplIGBudWxsYCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobnVsbCkgPT0gXCJudWxsXCIgJiZcbiAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgMiBoYWx0cyBzZXJpYWxpemF0aW9uIGlmIGFuIGFycmF5IGNvbnRhaW5zIGEgZnVuY3Rpb246XG4gICAgICAgICAgICAgICAgLy8gYFsxLCB0cnVlLCBnZXRDbGFzcywgMV1gIHNlcmlhbGl6ZXMgYXMgXCJbMSx0cnVlLF0sXCIuIEZGIDMuMWIzXG4gICAgICAgICAgICAgICAgLy8gZWxpZGVzIG5vbi1KU09OIHZhbHVlcyBmcm9tIG9iamVjdHMgYW5kIGFycmF5cywgdW5sZXNzIHRoZXlcbiAgICAgICAgICAgICAgICAvLyBkZWZpbmUgY3VzdG9tIGB0b0pTT05gIG1ldGhvZHMuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KFt1bmRlZiwgZ2V0Q2xhc3MsIG51bGxdKSA9PSBcIltudWxsLG51bGwsbnVsbF1cIiAmJlxuICAgICAgICAgICAgICAgIC8vIFNpbXBsZSBzZXJpYWxpemF0aW9uIHRlc3QuIEZGIDMuMWIxIHVzZXMgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2VzXG4gICAgICAgICAgICAgICAgLy8gd2hlcmUgY2hhcmFjdGVyIGVzY2FwZSBjb2RlcyBhcmUgZXhwZWN0ZWQgKGUuZy4sIGBcXGJgID0+IGBcXHUwMDA4YCkuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KHsgXCJhXCI6IFt2YWx1ZSwgdHJ1ZSwgZmFsc2UsIG51bGwsIFwiXFx4MDBcXGJcXG5cXGZcXHJcXHRcIl0gfSkgPT0gc2VyaWFsaXplZCAmJlxuICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIxIGFuZCBiMiBpZ25vcmUgdGhlIGBmaWx0ZXJgIGFuZCBgd2lkdGhgIGFyZ3VtZW50cy5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobnVsbCwgdmFsdWUpID09PSBcIjFcIiAmJlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShbMSwgMl0sIG51bGwsIDEpID09IFwiW1xcbiAxLFxcbiAyXFxuXVwiICYmXG4gICAgICAgICAgICAgICAgLy8gSlNPTiAyLCBQcm90b3R5cGUgPD0gMS43LCBhbmQgb2xkZXIgV2ViS2l0IGJ1aWxkcyBpbmNvcnJlY3RseVxuICAgICAgICAgICAgICAgIC8vIHNlcmlhbGl6ZSBleHRlbmRlZCB5ZWFycy5cbiAgICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoLTguNjRlMTUpKSA9PSAnXCItMjcxODIxLTA0LTIwVDAwOjAwOjAwLjAwMFpcIicgJiZcbiAgICAgICAgICAgICAgICAvLyBUaGUgbWlsbGlzZWNvbmRzIGFyZSBvcHRpb25hbCBpbiBFUyA1LCBidXQgcmVxdWlyZWQgaW4gNS4xLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgRGF0ZSg4LjY0ZTE1KSkgPT0gJ1wiKzI3NTc2MC0wOS0xM1QwMDowMDowMC4wMDBaXCInICYmXG4gICAgICAgICAgICAgICAgLy8gRmlyZWZveCA8PSAxMS4wIGluY29ycmVjdGx5IHNlcmlhbGl6ZXMgeWVhcnMgcHJpb3IgdG8gMCBhcyBuZWdhdGl2ZVxuICAgICAgICAgICAgICAgIC8vIGZvdXItZGlnaXQgeWVhcnMgaW5zdGVhZCBvZiBzaXgtZGlnaXQgeWVhcnMuIENyZWRpdHM6IEBZYWZmbGUuXG4gICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKC02MjE5ODc1NTJlNSkpID09ICdcIi0wMDAwMDEtMDEtMDFUMDA6MDA6MDAuMDAwWlwiJyAmJlxuICAgICAgICAgICAgICAgIC8vIFNhZmFyaSA8PSA1LjEuNSBhbmQgT3BlcmEgPj0gMTAuNTMgaW5jb3JyZWN0bHkgc2VyaWFsaXplIG1pbGxpc2Vjb25kXG4gICAgICAgICAgICAgICAgLy8gdmFsdWVzIGxlc3MgdGhhbiAxMDAwLiBDcmVkaXRzOiBAWWFmZmxlLlxuICAgICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgRGF0ZSgtMSkpID09ICdcIjE5NjktMTItMzFUMjM6NTk6NTkuOTk5WlwiJztcbiAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICBzdHJpbmdpZnlTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaXNTdXBwb3J0ZWQgPSBzdHJpbmdpZnlTdXBwb3J0ZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGVzdCBgSlNPTi5wYXJzZWAuXG4gICAgICAgIGlmIChuYW1lID09IFwianNvbi1wYXJzZVwiKSB7XG4gICAgICAgICAgdmFyIHBhcnNlID0gZXhwb3J0cy5wYXJzZTtcbiAgICAgICAgICBpZiAodHlwZW9mIHBhcnNlID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIGIyIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGEgYmFyZSBsaXRlcmFsIGlzIHByb3ZpZGVkLlxuICAgICAgICAgICAgICAvLyBDb25mb3JtaW5nIGltcGxlbWVudGF0aW9ucyBzaG91bGQgYWxzbyBjb2VyY2UgdGhlIGluaXRpYWwgYXJndW1lbnQgdG9cbiAgICAgICAgICAgICAgLy8gYSBzdHJpbmcgcHJpb3IgdG8gcGFyc2luZy5cbiAgICAgICAgICAgICAgaWYgKHBhcnNlKFwiMFwiKSA9PT0gMCAmJiAhcGFyc2UoZmFsc2UpKSB7XG4gICAgICAgICAgICAgICAgLy8gU2ltcGxlIHBhcnNpbmcgdGVzdC5cbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHBhcnNlKHNlcmlhbGl6ZWQpO1xuICAgICAgICAgICAgICAgIHZhciBwYXJzZVN1cHBvcnRlZCA9IHZhbHVlW1wiYVwiXS5sZW5ndGggPT0gNSAmJiB2YWx1ZVtcImFcIl1bMF0gPT09IDE7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnNlU3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgPD0gNS4xLjIgYW5kIEZGIDMuMWIxIGFsbG93IHVuZXNjYXBlZCB0YWJzIGluIHN0cmluZ3MuXG4gICAgICAgICAgICAgICAgICAgIHBhcnNlU3VwcG9ydGVkID0gIXBhcnNlKCdcIlxcdFwiJyk7XG4gICAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG4gICAgICAgICAgICAgICAgICBpZiAocGFyc2VTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBGRiA0LjAgYW5kIDQuMC4xIGFsbG93IGxlYWRpbmcgYCtgIHNpZ25zIGFuZCBsZWFkaW5nXG4gICAgICAgICAgICAgICAgICAgICAgLy8gZGVjaW1hbCBwb2ludHMuIEZGIDQuMCwgNC4wLjEsIGFuZCBJRSA5LTEwIGFsc28gYWxsb3dcbiAgICAgICAgICAgICAgICAgICAgICAvLyBjZXJ0YWluIG9jdGFsIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgICAgICAgIHBhcnNlU3VwcG9ydGVkID0gcGFyc2UoXCIwMVwiKSAhPT0gMTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlU3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gRkYgNC4wLCA0LjAuMSwgYW5kIFJoaW5vIDEuN1IzLVI0IGFsbG93IHRyYWlsaW5nIGRlY2ltYWxcbiAgICAgICAgICAgICAgICAgICAgICAvLyBwb2ludHMuIFRoZXNlIGVudmlyb25tZW50cywgYWxvbmcgd2l0aCBGRiAzLjFiMSBhbmQgMixcbiAgICAgICAgICAgICAgICAgICAgICAvLyBhbHNvIGFsbG93IHRyYWlsaW5nIGNvbW1hcyBpbiBKU09OIG9iamVjdHMgYW5kIGFycmF5cy5cbiAgICAgICAgICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9IHBhcnNlKFwiMS5cIikgIT09IDE7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpc1N1cHBvcnRlZCA9IHBhcnNlU3VwcG9ydGVkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gaGFzW25hbWVdID0gISFpc1N1cHBvcnRlZDtcbiAgICB9XG5cbiAgICBpZiAoIWhhcyhcImpzb25cIikpIHtcbiAgICAgIC8vIENvbW1vbiBgW1tDbGFzc11dYCBuYW1lIGFsaWFzZXMuXG4gICAgICB2YXIgZnVuY3Rpb25DbGFzcyA9IFwiW29iamVjdCBGdW5jdGlvbl1cIixcbiAgICAgICAgICBkYXRlQ2xhc3MgPSBcIltvYmplY3QgRGF0ZV1cIixcbiAgICAgICAgICBudW1iZXJDbGFzcyA9IFwiW29iamVjdCBOdW1iZXJdXCIsXG4gICAgICAgICAgc3RyaW5nQ2xhc3MgPSBcIltvYmplY3QgU3RyaW5nXVwiLFxuICAgICAgICAgIGFycmF5Q2xhc3MgPSBcIltvYmplY3QgQXJyYXldXCIsXG4gICAgICAgICAgYm9vbGVhbkNsYXNzID0gXCJbb2JqZWN0IEJvb2xlYW5dXCI7XG5cbiAgICAgIC8vIERldGVjdCBpbmNvbXBsZXRlIHN1cHBvcnQgZm9yIGFjY2Vzc2luZyBzdHJpbmcgY2hhcmFjdGVycyBieSBpbmRleC5cbiAgICAgIHZhciBjaGFySW5kZXhCdWdneSA9IGhhcyhcImJ1Zy1zdHJpbmctY2hhci1pbmRleFwiKTtcblxuICAgICAgLy8gRGVmaW5lIGFkZGl0aW9uYWwgdXRpbGl0eSBtZXRob2RzIGlmIHRoZSBgRGF0ZWAgbWV0aG9kcyBhcmUgYnVnZ3kuXG4gICAgICBpZiAoIWlzRXh0ZW5kZWQpIHtcbiAgICAgICAgdmFyIGZsb29yID0gTWF0aC5mbG9vcjtcbiAgICAgICAgLy8gQSBtYXBwaW5nIGJldHdlZW4gdGhlIG1vbnRocyBvZiB0aGUgeWVhciBhbmQgdGhlIG51bWJlciBvZiBkYXlzIGJldHdlZW5cbiAgICAgICAgLy8gSmFudWFyeSAxc3QgYW5kIHRoZSBmaXJzdCBvZiB0aGUgcmVzcGVjdGl2ZSBtb250aC5cbiAgICAgICAgdmFyIE1vbnRocyA9IFswLCAzMSwgNTksIDkwLCAxMjAsIDE1MSwgMTgxLCAyMTIsIDI0MywgMjczLCAzMDQsIDMzNF07XG4gICAgICAgIC8vIEludGVybmFsOiBDYWxjdWxhdGVzIHRoZSBudW1iZXIgb2YgZGF5cyBiZXR3ZWVuIHRoZSBVbml4IGVwb2NoIGFuZCB0aGVcbiAgICAgICAgLy8gZmlyc3QgZGF5IG9mIHRoZSBnaXZlbiBtb250aC5cbiAgICAgICAgdmFyIGdldERheSA9IGZ1bmN0aW9uICh5ZWFyLCBtb250aCkge1xuICAgICAgICAgIHJldHVybiBNb250aHNbbW9udGhdICsgMzY1ICogKHllYXIgLSAxOTcwKSArIGZsb29yKCh5ZWFyIC0gMTk2OSArIChtb250aCA9ICsobW9udGggPiAxKSkpIC8gNCkgLSBmbG9vcigoeWVhciAtIDE5MDEgKyBtb250aCkgLyAxMDApICsgZmxvb3IoKHllYXIgLSAxNjAxICsgbW9udGgpIC8gNDAwKTtcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgLy8gSW50ZXJuYWw6IERldGVybWluZXMgaWYgYSBwcm9wZXJ0eSBpcyBhIGRpcmVjdCBwcm9wZXJ0eSBvZiB0aGUgZ2l2ZW5cbiAgICAgIC8vIG9iamVjdC4gRGVsZWdhdGVzIHRvIHRoZSBuYXRpdmUgYE9iamVjdCNoYXNPd25Qcm9wZXJ0eWAgbWV0aG9kLlxuICAgICAgaWYgKCEoaXNQcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5KSkge1xuICAgICAgICBpc1Byb3BlcnR5ID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgdmFyIG1lbWJlcnMgPSB7fSwgY29uc3RydWN0b3I7XG4gICAgICAgICAgaWYgKChtZW1iZXJzLl9fcHJvdG9fXyA9IG51bGwsIG1lbWJlcnMuX19wcm90b19fID0ge1xuICAgICAgICAgICAgLy8gVGhlICpwcm90byogcHJvcGVydHkgY2Fubm90IGJlIHNldCBtdWx0aXBsZSB0aW1lcyBpbiByZWNlbnRcbiAgICAgICAgICAgIC8vIHZlcnNpb25zIG9mIEZpcmVmb3ggYW5kIFNlYU1vbmtleS5cbiAgICAgICAgICAgIFwidG9TdHJpbmdcIjogMVxuICAgICAgICAgIH0sIG1lbWJlcnMpLnRvU3RyaW5nICE9IGdldENsYXNzKSB7XG4gICAgICAgICAgICAvLyBTYWZhcmkgPD0gMi4wLjMgZG9lc24ndCBpbXBsZW1lbnQgYE9iamVjdCNoYXNPd25Qcm9wZXJ0eWAsIGJ1dFxuICAgICAgICAgICAgLy8gc3VwcG9ydHMgdGhlIG11dGFibGUgKnByb3RvKiBwcm9wZXJ0eS5cbiAgICAgICAgICAgIGlzUHJvcGVydHkgPSBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgLy8gQ2FwdHVyZSBhbmQgYnJlYWsgdGhlIG9iamVjdCdzIHByb3RvdHlwZSBjaGFpbiAoc2VlIHNlY3Rpb24gOC42LjJcbiAgICAgICAgICAgICAgLy8gb2YgdGhlIEVTIDUuMSBzcGVjKS4gVGhlIHBhcmVudGhlc2l6ZWQgZXhwcmVzc2lvbiBwcmV2ZW50cyBhblxuICAgICAgICAgICAgICAvLyB1bnNhZmUgdHJhbnNmb3JtYXRpb24gYnkgdGhlIENsb3N1cmUgQ29tcGlsZXIuXG4gICAgICAgICAgICAgIHZhciBvcmlnaW5hbCA9IHRoaXMuX19wcm90b19fLCByZXN1bHQgPSBwcm9wZXJ0eSBpbiAodGhpcy5fX3Byb3RvX18gPSBudWxsLCB0aGlzKTtcbiAgICAgICAgICAgICAgLy8gUmVzdG9yZSB0aGUgb3JpZ2luYWwgcHJvdG90eXBlIGNoYWluLlxuICAgICAgICAgICAgICB0aGlzLl9fcHJvdG9fXyA9IG9yaWdpbmFsO1xuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gQ2FwdHVyZSBhIHJlZmVyZW5jZSB0byB0aGUgdG9wLWxldmVsIGBPYmplY3RgIGNvbnN0cnVjdG9yLlxuICAgICAgICAgICAgY29uc3RydWN0b3IgPSBtZW1iZXJzLmNvbnN0cnVjdG9yO1xuICAgICAgICAgICAgLy8gVXNlIHRoZSBgY29uc3RydWN0b3JgIHByb3BlcnR5IHRvIHNpbXVsYXRlIGBPYmplY3QjaGFzT3duUHJvcGVydHlgIGluXG4gICAgICAgICAgICAvLyBvdGhlciBlbnZpcm9ubWVudHMuXG4gICAgICAgICAgICBpc1Byb3BlcnR5ID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgIHZhciBwYXJlbnQgPSAodGhpcy5jb25zdHJ1Y3RvciB8fCBjb25zdHJ1Y3RvcikucHJvdG90eXBlO1xuICAgICAgICAgICAgICByZXR1cm4gcHJvcGVydHkgaW4gdGhpcyAmJiAhKHByb3BlcnR5IGluIHBhcmVudCAmJiB0aGlzW3Byb3BlcnR5XSA9PT0gcGFyZW50W3Byb3BlcnR5XSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBtZW1iZXJzID0gbnVsbDtcbiAgICAgICAgICByZXR1cm4gaXNQcm9wZXJ0eS5jYWxsKHRoaXMsIHByb3BlcnR5KTtcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgLy8gSW50ZXJuYWw6IE5vcm1hbGl6ZXMgdGhlIGBmb3IuLi5pbmAgaXRlcmF0aW9uIGFsZ29yaXRobSBhY3Jvc3NcbiAgICAgIC8vIGVudmlyb25tZW50cy4gRWFjaCBlbnVtZXJhdGVkIGtleSBpcyB5aWVsZGVkIHRvIGEgYGNhbGxiYWNrYCBmdW5jdGlvbi5cbiAgICAgIGZvckVhY2ggPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgc2l6ZSA9IDAsIFByb3BlcnRpZXMsIG1lbWJlcnMsIHByb3BlcnR5O1xuXG4gICAgICAgIC8vIFRlc3RzIGZvciBidWdzIGluIHRoZSBjdXJyZW50IGVudmlyb25tZW50J3MgYGZvci4uLmluYCBhbGdvcml0aG0uIFRoZVxuICAgICAgICAvLyBgdmFsdWVPZmAgcHJvcGVydHkgaW5oZXJpdHMgdGhlIG5vbi1lbnVtZXJhYmxlIGZsYWcgZnJvbVxuICAgICAgICAvLyBgT2JqZWN0LnByb3RvdHlwZWAgaW4gb2xkZXIgdmVyc2lvbnMgb2YgSUUsIE5ldHNjYXBlLCBhbmQgTW96aWxsYS5cbiAgICAgICAgKFByb3BlcnRpZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdGhpcy52YWx1ZU9mID0gMDtcbiAgICAgICAgfSkucHJvdG90eXBlLnZhbHVlT2YgPSAwO1xuXG4gICAgICAgIC8vIEl0ZXJhdGUgb3ZlciBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgYFByb3BlcnRpZXNgIGNsYXNzLlxuICAgICAgICBtZW1iZXJzID0gbmV3IFByb3BlcnRpZXMoKTtcbiAgICAgICAgZm9yIChwcm9wZXJ0eSBpbiBtZW1iZXJzKSB7XG4gICAgICAgICAgLy8gSWdub3JlIGFsbCBwcm9wZXJ0aWVzIGluaGVyaXRlZCBmcm9tIGBPYmplY3QucHJvdG90eXBlYC5cbiAgICAgICAgICBpZiAoaXNQcm9wZXJ0eS5jYWxsKG1lbWJlcnMsIHByb3BlcnR5KSkge1xuICAgICAgICAgICAgc2l6ZSsrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBQcm9wZXJ0aWVzID0gbWVtYmVycyA9IG51bGw7XG5cbiAgICAgICAgLy8gTm9ybWFsaXplIHRoZSBpdGVyYXRpb24gYWxnb3JpdGhtLlxuICAgICAgICBpZiAoIXNpemUpIHtcbiAgICAgICAgICAvLyBBIGxpc3Qgb2Ygbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyBpbmhlcml0ZWQgZnJvbSBgT2JqZWN0LnByb3RvdHlwZWAuXG4gICAgICAgICAgbWVtYmVycyA9IFtcInZhbHVlT2ZcIiwgXCJ0b1N0cmluZ1wiLCBcInRvTG9jYWxlU3RyaW5nXCIsIFwicHJvcGVydHlJc0VudW1lcmFibGVcIiwgXCJpc1Byb3RvdHlwZU9mXCIsIFwiaGFzT3duUHJvcGVydHlcIiwgXCJjb25zdHJ1Y3RvclwiXTtcbiAgICAgICAgICAvLyBJRSA8PSA4LCBNb3ppbGxhIDEuMCwgYW5kIE5ldHNjYXBlIDYuMiBpZ25vcmUgc2hhZG93ZWQgbm9uLWVudW1lcmFibGVcbiAgICAgICAgICAvLyBwcm9wZXJ0aWVzLlxuICAgICAgICAgIGZvckVhY2ggPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgdmFyIGlzRnVuY3Rpb24gPSBnZXRDbGFzcy5jYWxsKG9iamVjdCkgPT0gZnVuY3Rpb25DbGFzcywgcHJvcGVydHksIGxlbmd0aDtcbiAgICAgICAgICAgIHZhciBoYXNQcm9wZXJ0eSA9ICFpc0Z1bmN0aW9uICYmIHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IgIT0gXCJmdW5jdGlvblwiICYmIG9iamVjdFR5cGVzW3R5cGVvZiBvYmplY3QuaGFzT3duUHJvcGVydHldICYmIG9iamVjdC5oYXNPd25Qcm9wZXJ0eSB8fCBpc1Byb3BlcnR5O1xuICAgICAgICAgICAgZm9yIChwcm9wZXJ0eSBpbiBvYmplY3QpIHtcbiAgICAgICAgICAgICAgLy8gR2Vja28gPD0gMS4wIGVudW1lcmF0ZXMgdGhlIGBwcm90b3R5cGVgIHByb3BlcnR5IG9mIGZ1bmN0aW9ucyB1bmRlclxuICAgICAgICAgICAgICAvLyBjZXJ0YWluIGNvbmRpdGlvbnM7IElFIGRvZXMgbm90LlxuICAgICAgICAgICAgICBpZiAoIShpc0Z1bmN0aW9uICYmIHByb3BlcnR5ID09IFwicHJvdG90eXBlXCIpICYmIGhhc1Byb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSkpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhwcm9wZXJ0eSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIE1hbnVhbGx5IGludm9rZSB0aGUgY2FsbGJhY2sgZm9yIGVhY2ggbm9uLWVudW1lcmFibGUgcHJvcGVydHkuXG4gICAgICAgICAgICBmb3IgKGxlbmd0aCA9IG1lbWJlcnMubGVuZ3RoOyBwcm9wZXJ0eSA9IG1lbWJlcnNbLS1sZW5ndGhdOyBoYXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpICYmIGNhbGxiYWNrKHByb3BlcnR5KSk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmIChzaXplID09IDIpIHtcbiAgICAgICAgICAvLyBTYWZhcmkgPD0gMi4wLjQgZW51bWVyYXRlcyBzaGFkb3dlZCBwcm9wZXJ0aWVzIHR3aWNlLlxuICAgICAgICAgIGZvckVhY2ggPSBmdW5jdGlvbiAob2JqZWN0LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgLy8gQ3JlYXRlIGEgc2V0IG9mIGl0ZXJhdGVkIHByb3BlcnRpZXMuXG4gICAgICAgICAgICB2YXIgbWVtYmVycyA9IHt9LCBpc0Z1bmN0aW9uID0gZ2V0Q2xhc3MuY2FsbChvYmplY3QpID09IGZ1bmN0aW9uQ2xhc3MsIHByb3BlcnR5O1xuICAgICAgICAgICAgZm9yIChwcm9wZXJ0eSBpbiBvYmplY3QpIHtcbiAgICAgICAgICAgICAgLy8gU3RvcmUgZWFjaCBwcm9wZXJ0eSBuYW1lIHRvIHByZXZlbnQgZG91YmxlIGVudW1lcmF0aW9uLiBUaGVcbiAgICAgICAgICAgICAgLy8gYHByb3RvdHlwZWAgcHJvcGVydHkgb2YgZnVuY3Rpb25zIGlzIG5vdCBlbnVtZXJhdGVkIGR1ZSB0byBjcm9zcy1cbiAgICAgICAgICAgICAgLy8gZW52aXJvbm1lbnQgaW5jb25zaXN0ZW5jaWVzLlxuICAgICAgICAgICAgICBpZiAoIShpc0Z1bmN0aW9uICYmIHByb3BlcnR5ID09IFwicHJvdG90eXBlXCIpICYmICFpc1Byb3BlcnR5LmNhbGwobWVtYmVycywgcHJvcGVydHkpICYmIChtZW1iZXJzW3Byb3BlcnR5XSA9IDEpICYmIGlzUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gTm8gYnVncyBkZXRlY3RlZDsgdXNlIHRoZSBzdGFuZGFyZCBgZm9yLi4uaW5gIGFsZ29yaXRobS5cbiAgICAgICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHZhciBpc0Z1bmN0aW9uID0gZ2V0Q2xhc3MuY2FsbChvYmplY3QpID09IGZ1bmN0aW9uQ2xhc3MsIHByb3BlcnR5LCBpc0NvbnN0cnVjdG9yO1xuICAgICAgICAgICAgZm9yIChwcm9wZXJ0eSBpbiBvYmplY3QpIHtcbiAgICAgICAgICAgICAgaWYgKCEoaXNGdW5jdGlvbiAmJiBwcm9wZXJ0eSA9PSBcInByb3RvdHlwZVwiKSAmJiBpc1Byb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSkgJiYgIShpc0NvbnN0cnVjdG9yID0gcHJvcGVydHkgPT09IFwiY29uc3RydWN0b3JcIikpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhwcm9wZXJ0eSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIE1hbnVhbGx5IGludm9rZSB0aGUgY2FsbGJhY2sgZm9yIHRoZSBgY29uc3RydWN0b3JgIHByb3BlcnR5IGR1ZSB0b1xuICAgICAgICAgICAgLy8gY3Jvc3MtZW52aXJvbm1lbnQgaW5jb25zaXN0ZW5jaWVzLlxuICAgICAgICAgICAgaWYgKGlzQ29uc3RydWN0b3IgfHwgaXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgKHByb3BlcnR5ID0gXCJjb25zdHJ1Y3RvclwiKSkpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2socHJvcGVydHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvckVhY2gob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgICB9O1xuXG4gICAgICAvLyBQdWJsaWM6IFNlcmlhbGl6ZXMgYSBKYXZhU2NyaXB0IGB2YWx1ZWAgYXMgYSBKU09OIHN0cmluZy4gVGhlIG9wdGlvbmFsXG4gICAgICAvLyBgZmlsdGVyYCBhcmd1bWVudCBtYXkgc3BlY2lmeSBlaXRoZXIgYSBmdW5jdGlvbiB0aGF0IGFsdGVycyBob3cgb2JqZWN0IGFuZFxuICAgICAgLy8gYXJyYXkgbWVtYmVycyBhcmUgc2VyaWFsaXplZCwgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncyBhbmQgbnVtYmVycyB0aGF0XG4gICAgICAvLyBpbmRpY2F0ZXMgd2hpY2ggcHJvcGVydGllcyBzaG91bGQgYmUgc2VyaWFsaXplZC4gVGhlIG9wdGlvbmFsIGB3aWR0aGBcbiAgICAgIC8vIGFyZ3VtZW50IG1heSBiZSBlaXRoZXIgYSBzdHJpbmcgb3IgbnVtYmVyIHRoYXQgc3BlY2lmaWVzIHRoZSBpbmRlbnRhdGlvblxuICAgICAgLy8gbGV2ZWwgb2YgdGhlIG91dHB1dC5cbiAgICAgIGlmICghaGFzKFwianNvbi1zdHJpbmdpZnlcIikpIHtcbiAgICAgICAgLy8gSW50ZXJuYWw6IEEgbWFwIG9mIGNvbnRyb2wgY2hhcmFjdGVycyBhbmQgdGhlaXIgZXNjYXBlZCBlcXVpdmFsZW50cy5cbiAgICAgICAgdmFyIEVzY2FwZXMgPSB7XG4gICAgICAgICAgOTI6IFwiXFxcXFxcXFxcIixcbiAgICAgICAgICAzNDogJ1xcXFxcIicsXG4gICAgICAgICAgODogXCJcXFxcYlwiLFxuICAgICAgICAgIDEyOiBcIlxcXFxmXCIsXG4gICAgICAgICAgMTA6IFwiXFxcXG5cIixcbiAgICAgICAgICAxMzogXCJcXFxcclwiLFxuICAgICAgICAgIDk6IFwiXFxcXHRcIlxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBDb252ZXJ0cyBgdmFsdWVgIGludG8gYSB6ZXJvLXBhZGRlZCBzdHJpbmcgc3VjaCB0aGF0IGl0c1xuICAgICAgICAvLyBsZW5ndGggaXMgYXQgbGVhc3QgZXF1YWwgdG8gYHdpZHRoYC4gVGhlIGB3aWR0aGAgbXVzdCBiZSA8PSA2LlxuICAgICAgICB2YXIgbGVhZGluZ1plcm9lcyA9IFwiMDAwMDAwXCI7XG4gICAgICAgIHZhciB0b1BhZGRlZFN0cmluZyA9IGZ1bmN0aW9uICh3aWR0aCwgdmFsdWUpIHtcbiAgICAgICAgICAvLyBUaGUgYHx8IDBgIGV4cHJlc3Npb24gaXMgbmVjZXNzYXJ5IHRvIHdvcmsgYXJvdW5kIGEgYnVnIGluXG4gICAgICAgICAgLy8gT3BlcmEgPD0gNy41NHUyIHdoZXJlIGAwID09IC0wYCwgYnV0IGBTdHJpbmcoLTApICE9PSBcIjBcImAuXG4gICAgICAgICAgcmV0dXJuIChsZWFkaW5nWmVyb2VzICsgKHZhbHVlIHx8IDApKS5zbGljZSgtd2lkdGgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBEb3VibGUtcXVvdGVzIGEgc3RyaW5nIGB2YWx1ZWAsIHJlcGxhY2luZyBhbGwgQVNDSUkgY29udHJvbFxuICAgICAgICAvLyBjaGFyYWN0ZXJzIChjaGFyYWN0ZXJzIHdpdGggY29kZSB1bml0IHZhbHVlcyBiZXR3ZWVuIDAgYW5kIDMxKSB3aXRoXG4gICAgICAgIC8vIHRoZWlyIGVzY2FwZWQgZXF1aXZhbGVudHMuIFRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlXG4gICAgICAgIC8vIGBRdW90ZSh2YWx1ZSlgIG9wZXJhdGlvbiBkZWZpbmVkIGluIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjMuXG4gICAgICAgIHZhciB1bmljb2RlUHJlZml4ID0gXCJcXFxcdTAwXCI7XG4gICAgICAgIHZhciBxdW90ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgIHZhciByZXN1bHQgPSAnXCInLCBpbmRleCA9IDAsIGxlbmd0aCA9IHZhbHVlLmxlbmd0aCwgdXNlQ2hhckluZGV4ID0gIWNoYXJJbmRleEJ1Z2d5IHx8IGxlbmd0aCA+IDEwO1xuICAgICAgICAgIHZhciBzeW1ib2xzID0gdXNlQ2hhckluZGV4ICYmIChjaGFySW5kZXhCdWdneSA/IHZhbHVlLnNwbGl0KFwiXCIpIDogdmFsdWUpO1xuICAgICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgdmFyIGNoYXJDb2RlID0gdmFsdWUuY2hhckNvZGVBdChpbmRleCk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgY2hhcmFjdGVyIGlzIGEgY29udHJvbCBjaGFyYWN0ZXIsIGFwcGVuZCBpdHMgVW5pY29kZSBvclxuICAgICAgICAgICAgLy8gc2hvcnRoYW5kIGVzY2FwZSBzZXF1ZW5jZTsgb3RoZXJ3aXNlLCBhcHBlbmQgdGhlIGNoYXJhY3RlciBhcy1pcy5cbiAgICAgICAgICAgIHN3aXRjaCAoY2hhckNvZGUpIHtcbiAgICAgICAgICAgICAgY2FzZSA4OiBjYXNlIDk6IGNhc2UgMTA6IGNhc2UgMTI6IGNhc2UgMTM6IGNhc2UgMzQ6IGNhc2UgOTI6XG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IEVzY2FwZXNbY2hhckNvZGVdO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA8IDMyKSB7XG4gICAgICAgICAgICAgICAgICByZXN1bHQgKz0gdW5pY29kZVByZWZpeCArIHRvUGFkZGVkU3RyaW5nKDIsIGNoYXJDb2RlLnRvU3RyaW5nKDE2KSk7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IHVzZUNoYXJJbmRleCA/IHN5bWJvbHNbaW5kZXhdIDogdmFsdWUuY2hhckF0KGluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdCArICdcIic7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZXMgYW4gb2JqZWN0LiBJbXBsZW1lbnRzIHRoZVxuICAgICAgICAvLyBgU3RyKGtleSwgaG9sZGVyKWAsIGBKTyh2YWx1ZSlgLCBhbmQgYEpBKHZhbHVlKWAgb3BlcmF0aW9ucy5cbiAgICAgICAgdmFyIHNlcmlhbGl6ZSA9IGZ1bmN0aW9uIChwcm9wZXJ0eSwgb2JqZWN0LCBjYWxsYmFjaywgcHJvcGVydGllcywgd2hpdGVzcGFjZSwgaW5kZW50YXRpb24sIHN0YWNrKSB7XG4gICAgICAgICAgdmFyIHZhbHVlLCBjbGFzc05hbWUsIHllYXIsIG1vbnRoLCBkYXRlLCB0aW1lLCBob3VycywgbWludXRlcywgc2Vjb25kcywgbWlsbGlzZWNvbmRzLCByZXN1bHRzLCBlbGVtZW50LCBpbmRleCwgbGVuZ3RoLCBwcmVmaXgsIHJlc3VsdDtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gTmVjZXNzYXJ5IGZvciBob3N0IG9iamVjdCBzdXBwb3J0LlxuICAgICAgICAgICAgdmFsdWUgPSBvYmplY3RbcHJvcGVydHldO1xuICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09IFwib2JqZWN0XCIgJiYgdmFsdWUpIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwodmFsdWUpO1xuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBkYXRlQ2xhc3MgJiYgIWlzUHJvcGVydHkuY2FsbCh2YWx1ZSwgXCJ0b0pTT05cIikpIHtcbiAgICAgICAgICAgICAgaWYgKHZhbHVlID4gLTEgLyAwICYmIHZhbHVlIDwgMSAvIDApIHtcbiAgICAgICAgICAgICAgICAvLyBEYXRlcyBhcmUgc2VyaWFsaXplZCBhY2NvcmRpbmcgdG8gdGhlIGBEYXRlI3RvSlNPTmAgbWV0aG9kXG4gICAgICAgICAgICAgICAgLy8gc3BlY2lmaWVkIGluIEVTIDUuMSBzZWN0aW9uIDE1LjkuNS40NC4gU2VlIHNlY3Rpb24gMTUuOS4xLjE1XG4gICAgICAgICAgICAgICAgLy8gZm9yIHRoZSBJU08gODYwMSBkYXRlIHRpbWUgc3RyaW5nIGZvcm1hdC5cbiAgICAgICAgICAgICAgICBpZiAoZ2V0RGF5KSB7XG4gICAgICAgICAgICAgICAgICAvLyBNYW51YWxseSBjb21wdXRlIHRoZSB5ZWFyLCBtb250aCwgZGF0ZSwgaG91cnMsIG1pbnV0ZXMsXG4gICAgICAgICAgICAgICAgICAvLyBzZWNvbmRzLCBhbmQgbWlsbGlzZWNvbmRzIGlmIHRoZSBgZ2V0VVRDKmAgbWV0aG9kcyBhcmVcbiAgICAgICAgICAgICAgICAgIC8vIGJ1Z2d5LiBBZGFwdGVkIGZyb20gQFlhZmZsZSdzIGBkYXRlLXNoaW1gIHByb2plY3QuXG4gICAgICAgICAgICAgICAgICBkYXRlID0gZmxvb3IodmFsdWUgLyA4NjRlNSk7XG4gICAgICAgICAgICAgICAgICBmb3IgKHllYXIgPSBmbG9vcihkYXRlIC8gMzY1LjI0MjUpICsgMTk3MCAtIDE7IGdldERheSh5ZWFyICsgMSwgMCkgPD0gZGF0ZTsgeWVhcisrKTtcbiAgICAgICAgICAgICAgICAgIGZvciAobW9udGggPSBmbG9vcigoZGF0ZSAtIGdldERheSh5ZWFyLCAwKSkgLyAzMC40Mik7IGdldERheSh5ZWFyLCBtb250aCArIDEpIDw9IGRhdGU7IG1vbnRoKyspO1xuICAgICAgICAgICAgICAgICAgZGF0ZSA9IDEgKyBkYXRlIC0gZ2V0RGF5KHllYXIsIG1vbnRoKTtcbiAgICAgICAgICAgICAgICAgIC8vIFRoZSBgdGltZWAgdmFsdWUgc3BlY2lmaWVzIHRoZSB0aW1lIHdpdGhpbiB0aGUgZGF5IChzZWUgRVNcbiAgICAgICAgICAgICAgICAgIC8vIDUuMSBzZWN0aW9uIDE1LjkuMS4yKS4gVGhlIGZvcm11bGEgYChBICUgQiArIEIpICUgQmAgaXMgdXNlZFxuICAgICAgICAgICAgICAgICAgLy8gdG8gY29tcHV0ZSBgQSBtb2R1bG8gQmAsIGFzIHRoZSBgJWAgb3BlcmF0b3IgZG9lcyBub3RcbiAgICAgICAgICAgICAgICAgIC8vIGNvcnJlc3BvbmQgdG8gdGhlIGBtb2R1bG9gIG9wZXJhdGlvbiBmb3IgbmVnYXRpdmUgbnVtYmVycy5cbiAgICAgICAgICAgICAgICAgIHRpbWUgPSAodmFsdWUgJSA4NjRlNSArIDg2NGU1KSAlIDg2NGU1O1xuICAgICAgICAgICAgICAgICAgLy8gVGhlIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzLCBhbmQgbWlsbGlzZWNvbmRzIGFyZSBvYnRhaW5lZCBieVxuICAgICAgICAgICAgICAgICAgLy8gZGVjb21wb3NpbmcgdGhlIHRpbWUgd2l0aGluIHRoZSBkYXkuIFNlZSBzZWN0aW9uIDE1LjkuMS4xMC5cbiAgICAgICAgICAgICAgICAgIGhvdXJzID0gZmxvb3IodGltZSAvIDM2ZTUpICUgMjQ7XG4gICAgICAgICAgICAgICAgICBtaW51dGVzID0gZmxvb3IodGltZSAvIDZlNCkgJSA2MDtcbiAgICAgICAgICAgICAgICAgIHNlY29uZHMgPSBmbG9vcih0aW1lIC8gMWUzKSAlIDYwO1xuICAgICAgICAgICAgICAgICAgbWlsbGlzZWNvbmRzID0gdGltZSAlIDFlMztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgeWVhciA9IHZhbHVlLmdldFVUQ0Z1bGxZZWFyKCk7XG4gICAgICAgICAgICAgICAgICBtb250aCA9IHZhbHVlLmdldFVUQ01vbnRoKCk7XG4gICAgICAgICAgICAgICAgICBkYXRlID0gdmFsdWUuZ2V0VVRDRGF0ZSgpO1xuICAgICAgICAgICAgICAgICAgaG91cnMgPSB2YWx1ZS5nZXRVVENIb3VycygpO1xuICAgICAgICAgICAgICAgICAgbWludXRlcyA9IHZhbHVlLmdldFVUQ01pbnV0ZXMoKTtcbiAgICAgICAgICAgICAgICAgIHNlY29uZHMgPSB2YWx1ZS5nZXRVVENTZWNvbmRzKCk7XG4gICAgICAgICAgICAgICAgICBtaWxsaXNlY29uZHMgPSB2YWx1ZS5nZXRVVENNaWxsaXNlY29uZHMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gU2VyaWFsaXplIGV4dGVuZGVkIHllYXJzIGNvcnJlY3RseS5cbiAgICAgICAgICAgICAgICB2YWx1ZSA9ICh5ZWFyIDw9IDAgfHwgeWVhciA+PSAxZTQgPyAoeWVhciA8IDAgPyBcIi1cIiA6IFwiK1wiKSArIHRvUGFkZGVkU3RyaW5nKDYsIHllYXIgPCAwID8gLXllYXIgOiB5ZWFyKSA6IHRvUGFkZGVkU3RyaW5nKDQsIHllYXIpKSArXG4gICAgICAgICAgICAgICAgICBcIi1cIiArIHRvUGFkZGVkU3RyaW5nKDIsIG1vbnRoICsgMSkgKyBcIi1cIiArIHRvUGFkZGVkU3RyaW5nKDIsIGRhdGUpICtcbiAgICAgICAgICAgICAgICAgIC8vIE1vbnRocywgZGF0ZXMsIGhvdXJzLCBtaW51dGVzLCBhbmQgc2Vjb25kcyBzaG91bGQgaGF2ZSB0d29cbiAgICAgICAgICAgICAgICAgIC8vIGRpZ2l0czsgbWlsbGlzZWNvbmRzIHNob3VsZCBoYXZlIHRocmVlLlxuICAgICAgICAgICAgICAgICAgXCJUXCIgKyB0b1BhZGRlZFN0cmluZygyLCBob3VycykgKyBcIjpcIiArIHRvUGFkZGVkU3RyaW5nKDIsIG1pbnV0ZXMpICsgXCI6XCIgKyB0b1BhZGRlZFN0cmluZygyLCBzZWNvbmRzKSArXG4gICAgICAgICAgICAgICAgICAvLyBNaWxsaXNlY29uZHMgYXJlIG9wdGlvbmFsIGluIEVTIDUuMCwgYnV0IHJlcXVpcmVkIGluIDUuMS5cbiAgICAgICAgICAgICAgICAgIFwiLlwiICsgdG9QYWRkZWRTdHJpbmcoMywgbWlsbGlzZWNvbmRzKSArIFwiWlwiO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUudG9KU09OID09IFwiZnVuY3Rpb25cIiAmJiAoKGNsYXNzTmFtZSAhPSBudW1iZXJDbGFzcyAmJiBjbGFzc05hbWUgIT0gc3RyaW5nQ2xhc3MgJiYgY2xhc3NOYW1lICE9IGFycmF5Q2xhc3MpIHx8IGlzUHJvcGVydHkuY2FsbCh2YWx1ZSwgXCJ0b0pTT05cIikpKSB7XG4gICAgICAgICAgICAgIC8vIFByb3RvdHlwZSA8PSAxLjYuMSBhZGRzIG5vbi1zdGFuZGFyZCBgdG9KU09OYCBtZXRob2RzIHRvIHRoZVxuICAgICAgICAgICAgICAvLyBgTnVtYmVyYCwgYFN0cmluZ2AsIGBEYXRlYCwgYW5kIGBBcnJheWAgcHJvdG90eXBlcy4gSlNPTiAzXG4gICAgICAgICAgICAgIC8vIGlnbm9yZXMgYWxsIGB0b0pTT05gIG1ldGhvZHMgb24gdGhlc2Ugb2JqZWN0cyB1bmxlc3MgdGhleSBhcmVcbiAgICAgICAgICAgICAgLy8gZGVmaW5lZCBkaXJlY3RseSBvbiBhbiBpbnN0YW5jZS5cbiAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS50b0pTT04ocHJvcGVydHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgIC8vIElmIGEgcmVwbGFjZW1lbnQgZnVuY3Rpb24gd2FzIHByb3ZpZGVkLCBjYWxsIGl0IHRvIG9idGFpbiB0aGUgdmFsdWVcbiAgICAgICAgICAgIC8vIGZvciBzZXJpYWxpemF0aW9uLlxuICAgICAgICAgICAgdmFsdWUgPSBjYWxsYmFjay5jYWxsKG9iamVjdCwgcHJvcGVydHksIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJudWxsXCI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwodmFsdWUpO1xuICAgICAgICAgIGlmIChjbGFzc05hbWUgPT0gYm9vbGVhbkNsYXNzKSB7XG4gICAgICAgICAgICAvLyBCb29sZWFucyBhcmUgcmVwcmVzZW50ZWQgbGl0ZXJhbGx5LlxuICAgICAgICAgICAgcmV0dXJuIFwiXCIgKyB2YWx1ZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTmFtZSA9PSBudW1iZXJDbGFzcykge1xuICAgICAgICAgICAgLy8gSlNPTiBudW1iZXJzIG11c3QgYmUgZmluaXRlLiBgSW5maW5pdHlgIGFuZCBgTmFOYCBhcmUgc2VyaWFsaXplZCBhc1xuICAgICAgICAgICAgLy8gYFwibnVsbFwiYC5cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZSA+IC0xIC8gMCAmJiB2YWx1ZSA8IDEgLyAwID8gXCJcIiArIHZhbHVlIDogXCJudWxsXCI7XG4gICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gc3RyaW5nQ2xhc3MpIHtcbiAgICAgICAgICAgIC8vIFN0cmluZ3MgYXJlIGRvdWJsZS1xdW90ZWQgYW5kIGVzY2FwZWQuXG4gICAgICAgICAgICByZXR1cm4gcXVvdGUoXCJcIiArIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gUmVjdXJzaXZlbHkgc2VyaWFsaXplIG9iamVjdHMgYW5kIGFycmF5cy5cbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGZvciBjeWNsaWMgc3RydWN0dXJlcy4gVGhpcyBpcyBhIGxpbmVhciBzZWFyY2g7IHBlcmZvcm1hbmNlXG4gICAgICAgICAgICAvLyBpcyBpbnZlcnNlbHkgcHJvcG9ydGlvbmFsIHRvIHRoZSBudW1iZXIgb2YgdW5pcXVlIG5lc3RlZCBvYmplY3RzLlxuICAgICAgICAgICAgZm9yIChsZW5ndGggPSBzdGFjay5sZW5ndGg7IGxlbmd0aC0tOykge1xuICAgICAgICAgICAgICBpZiAoc3RhY2tbbGVuZ3RoXSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBDeWNsaWMgc3RydWN0dXJlcyBjYW5ub3QgYmUgc2VyaWFsaXplZCBieSBgSlNPTi5zdHJpbmdpZnlgLlxuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBBZGQgdGhlIG9iamVjdCB0byB0aGUgc3RhY2sgb2YgdHJhdmVyc2VkIG9iamVjdHMuXG4gICAgICAgICAgICBzdGFjay5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIC8vIFNhdmUgdGhlIGN1cnJlbnQgaW5kZW50YXRpb24gbGV2ZWwgYW5kIGluZGVudCBvbmUgYWRkaXRpb25hbCBsZXZlbC5cbiAgICAgICAgICAgIHByZWZpeCA9IGluZGVudGF0aW9uO1xuICAgICAgICAgICAgaW5kZW50YXRpb24gKz0gd2hpdGVzcGFjZTtcbiAgICAgICAgICAgIGlmIChjbGFzc05hbWUgPT0gYXJyYXlDbGFzcykge1xuICAgICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXJpYWxpemUgYXJyYXkgZWxlbWVudHMuXG4gICAgICAgICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSB2YWx1ZS5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICAgICAgZWxlbWVudCA9IHNlcmlhbGl6ZShpbmRleCwgdmFsdWUsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCB3aGl0ZXNwYWNlLCBpbmRlbnRhdGlvbiwgc3RhY2spO1xuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChlbGVtZW50ID09PSB1bmRlZiA/IFwibnVsbFwiIDogZWxlbWVudCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0cy5sZW5ndGggPyAod2hpdGVzcGFjZSA/IFwiW1xcblwiICsgaW5kZW50YXRpb24gKyByZXN1bHRzLmpvaW4oXCIsXFxuXCIgKyBpbmRlbnRhdGlvbikgKyBcIlxcblwiICsgcHJlZml4ICsgXCJdXCIgOiAoXCJbXCIgKyByZXN1bHRzLmpvaW4oXCIsXCIpICsgXCJdXCIpKSA6IFwiW11cIjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZSBvYmplY3QgbWVtYmVycy4gTWVtYmVycyBhcmUgc2VsZWN0ZWQgZnJvbVxuICAgICAgICAgICAgICAvLyBlaXRoZXIgYSB1c2VyLXNwZWNpZmllZCBsaXN0IG9mIHByb3BlcnR5IG5hbWVzLCBvciB0aGUgb2JqZWN0XG4gICAgICAgICAgICAgIC8vIGl0c2VsZi5cbiAgICAgICAgICAgICAgZm9yRWFjaChwcm9wZXJ0aWVzIHx8IHZhbHVlLCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICB2YXIgZWxlbWVudCA9IHNlcmlhbGl6ZShwcm9wZXJ0eSwgdmFsdWUsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCB3aGl0ZXNwYWNlLCBpbmRlbnRhdGlvbiwgc3RhY2spO1xuICAgICAgICAgICAgICAgIGlmIChlbGVtZW50ICE9PSB1bmRlZikge1xuICAgICAgICAgICAgICAgICAgLy8gQWNjb3JkaW5nIHRvIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjM6IFwiSWYgYGdhcGAge3doaXRlc3BhY2V9XG4gICAgICAgICAgICAgICAgICAvLyBpcyBub3QgdGhlIGVtcHR5IHN0cmluZywgbGV0IGBtZW1iZXJgIHtxdW90ZShwcm9wZXJ0eSkgKyBcIjpcIn1cbiAgICAgICAgICAgICAgICAgIC8vIGJlIHRoZSBjb25jYXRlbmF0aW9uIG9mIGBtZW1iZXJgIGFuZCB0aGUgYHNwYWNlYCBjaGFyYWN0ZXIuXCJcbiAgICAgICAgICAgICAgICAgIC8vIFRoZSBcImBzcGFjZWAgY2hhcmFjdGVyXCIgcmVmZXJzIHRvIHRoZSBsaXRlcmFsIHNwYWNlXG4gICAgICAgICAgICAgICAgICAvLyBjaGFyYWN0ZXIsIG5vdCB0aGUgYHNwYWNlYCB7d2lkdGh9IGFyZ3VtZW50IHByb3ZpZGVkIHRvXG4gICAgICAgICAgICAgICAgICAvLyBgSlNPTi5zdHJpbmdpZnlgLlxuICAgICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHF1b3RlKHByb3BlcnR5KSArIFwiOlwiICsgKHdoaXRlc3BhY2UgPyBcIiBcIiA6IFwiXCIpICsgZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0cy5sZW5ndGggPyAod2hpdGVzcGFjZSA/IFwie1xcblwiICsgaW5kZW50YXRpb24gKyByZXN1bHRzLmpvaW4oXCIsXFxuXCIgKyBpbmRlbnRhdGlvbikgKyBcIlxcblwiICsgcHJlZml4ICsgXCJ9XCIgOiAoXCJ7XCIgKyByZXN1bHRzLmpvaW4oXCIsXCIpICsgXCJ9XCIpKSA6IFwie31cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgb2JqZWN0IGZyb20gdGhlIHRyYXZlcnNlZCBvYmplY3Qgc3RhY2suXG4gICAgICAgICAgICBzdGFjay5wb3AoKTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFB1YmxpYzogYEpTT04uc3RyaW5naWZ5YC4gU2VlIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjMuXG4gICAgICAgIGV4cG9ydHMuc3RyaW5naWZ5ID0gZnVuY3Rpb24gKHNvdXJjZSwgZmlsdGVyLCB3aWR0aCkge1xuICAgICAgICAgIHZhciB3aGl0ZXNwYWNlLCBjYWxsYmFjaywgcHJvcGVydGllcywgY2xhc3NOYW1lO1xuICAgICAgICAgIGlmIChvYmplY3RUeXBlc1t0eXBlb2YgZmlsdGVyXSAmJiBmaWx0ZXIpIHtcbiAgICAgICAgICAgIGlmICgoY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbChmaWx0ZXIpKSA9PSBmdW5jdGlvbkNsYXNzKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrID0gZmlsdGVyO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gYXJyYXlDbGFzcykge1xuICAgICAgICAgICAgICAvLyBDb252ZXJ0IHRoZSBwcm9wZXJ0eSBuYW1lcyBhcnJheSBpbnRvIGEgbWFrZXNoaWZ0IHNldC5cbiAgICAgICAgICAgICAgcHJvcGVydGllcyA9IHt9O1xuICAgICAgICAgICAgICBmb3IgKHZhciBpbmRleCA9IDAsIGxlbmd0aCA9IGZpbHRlci5sZW5ndGgsIHZhbHVlOyBpbmRleCA8IGxlbmd0aDsgdmFsdWUgPSBmaWx0ZXJbaW5kZXgrK10sICgoY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbCh2YWx1ZSkpLCBjbGFzc05hbWUgPT0gc3RyaW5nQ2xhc3MgfHwgY2xhc3NOYW1lID09IG51bWJlckNsYXNzKSAmJiAocHJvcGVydGllc1t2YWx1ZV0gPSAxKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh3aWR0aCkge1xuICAgICAgICAgICAgaWYgKChjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKHdpZHRoKSkgPT0gbnVtYmVyQ2xhc3MpIHtcbiAgICAgICAgICAgICAgLy8gQ29udmVydCB0aGUgYHdpZHRoYCB0byBhbiBpbnRlZ2VyIGFuZCBjcmVhdGUgYSBzdHJpbmcgY29udGFpbmluZ1xuICAgICAgICAgICAgICAvLyBgd2lkdGhgIG51bWJlciBvZiBzcGFjZSBjaGFyYWN0ZXJzLlxuICAgICAgICAgICAgICBpZiAoKHdpZHRoIC09IHdpZHRoICUgMSkgPiAwKSB7XG4gICAgICAgICAgICAgICAgZm9yICh3aGl0ZXNwYWNlID0gXCJcIiwgd2lkdGggPiAxMCAmJiAod2lkdGggPSAxMCk7IHdoaXRlc3BhY2UubGVuZ3RoIDwgd2lkdGg7IHdoaXRlc3BhY2UgKz0gXCIgXCIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNsYXNzTmFtZSA9PSBzdHJpbmdDbGFzcykge1xuICAgICAgICAgICAgICB3aGl0ZXNwYWNlID0gd2lkdGgubGVuZ3RoIDw9IDEwID8gd2lkdGggOiB3aWR0aC5zbGljZSgwLCAxMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIE9wZXJhIDw9IDcuNTR1MiBkaXNjYXJkcyB0aGUgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBlbXB0eSBzdHJpbmcga2V5c1xuICAgICAgICAgIC8vIChgXCJcImApIG9ubHkgaWYgdGhleSBhcmUgdXNlZCBkaXJlY3RseSB3aXRoaW4gYW4gb2JqZWN0IG1lbWJlciBsaXN0XG4gICAgICAgICAgLy8gKGUuZy4sIGAhKFwiXCIgaW4geyBcIlwiOiAxfSlgKS5cbiAgICAgICAgICByZXR1cm4gc2VyaWFsaXplKFwiXCIsICh2YWx1ZSA9IHt9LCB2YWx1ZVtcIlwiXSA9IHNvdXJjZSwgdmFsdWUpLCBjYWxsYmFjaywgcHJvcGVydGllcywgd2hpdGVzcGFjZSwgXCJcIiwgW10pO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBQdWJsaWM6IFBhcnNlcyBhIEpTT04gc291cmNlIHN0cmluZy5cbiAgICAgIGlmICghaGFzKFwianNvbi1wYXJzZVwiKSkge1xuICAgICAgICB2YXIgZnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogQSBtYXAgb2YgZXNjYXBlZCBjb250cm9sIGNoYXJhY3RlcnMgYW5kIHRoZWlyIHVuZXNjYXBlZFxuICAgICAgICAvLyBlcXVpdmFsZW50cy5cbiAgICAgICAgdmFyIFVuZXNjYXBlcyA9IHtcbiAgICAgICAgICA5MjogXCJcXFxcXCIsXG4gICAgICAgICAgMzQ6ICdcIicsXG4gICAgICAgICAgNDc6IFwiL1wiLFxuICAgICAgICAgIDk4OiBcIlxcYlwiLFxuICAgICAgICAgIDExNjogXCJcXHRcIixcbiAgICAgICAgICAxMTA6IFwiXFxuXCIsXG4gICAgICAgICAgMTAyOiBcIlxcZlwiLFxuICAgICAgICAgIDExNDogXCJcXHJcIlxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBTdG9yZXMgdGhlIHBhcnNlciBzdGF0ZS5cbiAgICAgICAgdmFyIEluZGV4LCBTb3VyY2U7XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFJlc2V0cyB0aGUgcGFyc2VyIHN0YXRlIGFuZCB0aHJvd3MgYSBgU3ludGF4RXJyb3JgLlxuICAgICAgICB2YXIgYWJvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgSW5kZXggPSBTb3VyY2UgPSBudWxsO1xuICAgICAgICAgIHRocm93IFN5bnRheEVycm9yKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFJldHVybnMgdGhlIG5leHQgdG9rZW4sIG9yIGBcIiRcImAgaWYgdGhlIHBhcnNlciBoYXMgcmVhY2hlZFxuICAgICAgICAvLyB0aGUgZW5kIG9mIHRoZSBzb3VyY2Ugc3RyaW5nLiBBIHRva2VuIG1heSBiZSBhIHN0cmluZywgbnVtYmVyLCBgbnVsbGBcbiAgICAgICAgLy8gbGl0ZXJhbCwgb3IgQm9vbGVhbiBsaXRlcmFsLlxuICAgICAgICB2YXIgbGV4ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBzb3VyY2UgPSBTb3VyY2UsIGxlbmd0aCA9IHNvdXJjZS5sZW5ndGgsIHZhbHVlLCBiZWdpbiwgcG9zaXRpb24sIGlzU2lnbmVkLCBjaGFyQ29kZTtcbiAgICAgICAgICB3aGlsZSAoSW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpO1xuICAgICAgICAgICAgc3dpdGNoIChjaGFyQ29kZSkge1xuICAgICAgICAgICAgICBjYXNlIDk6IGNhc2UgMTA6IGNhc2UgMTM6IGNhc2UgMzI6XG4gICAgICAgICAgICAgICAgLy8gU2tpcCB3aGl0ZXNwYWNlIHRva2VucywgaW5jbHVkaW5nIHRhYnMsIGNhcnJpYWdlIHJldHVybnMsIGxpbmVcbiAgICAgICAgICAgICAgICAvLyBmZWVkcywgYW5kIHNwYWNlIGNoYXJhY3RlcnMuXG4gICAgICAgICAgICAgICAgSW5kZXgrKztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAxMjM6IGNhc2UgMTI1OiBjYXNlIDkxOiBjYXNlIDkzOiBjYXNlIDU4OiBjYXNlIDQ0OlxuICAgICAgICAgICAgICAgIC8vIFBhcnNlIGEgcHVuY3R1YXRvciB0b2tlbiAoYHtgLCBgfWAsIGBbYCwgYF1gLCBgOmAsIG9yIGAsYCkgYXRcbiAgICAgICAgICAgICAgICAvLyB0aGUgY3VycmVudCBwb3NpdGlvbi5cbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGNoYXJJbmRleEJ1Z2d5ID8gc291cmNlLmNoYXJBdChJbmRleCkgOiBzb3VyY2VbSW5kZXhdO1xuICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICBjYXNlIDM0OlxuICAgICAgICAgICAgICAgIC8vIGBcImAgZGVsaW1pdHMgYSBKU09OIHN0cmluZzsgYWR2YW5jZSB0byB0aGUgbmV4dCBjaGFyYWN0ZXIgYW5kXG4gICAgICAgICAgICAgICAgLy8gYmVnaW4gcGFyc2luZyB0aGUgc3RyaW5nLiBTdHJpbmcgdG9rZW5zIGFyZSBwcmVmaXhlZCB3aXRoIHRoZVxuICAgICAgICAgICAgICAgIC8vIHNlbnRpbmVsIGBAYCBjaGFyYWN0ZXIgdG8gZGlzdGluZ3Vpc2ggdGhlbSBmcm9tIHB1bmN0dWF0b3JzIGFuZFxuICAgICAgICAgICAgICAgIC8vIGVuZC1vZi1zdHJpbmcgdG9rZW5zLlxuICAgICAgICAgICAgICAgIGZvciAodmFsdWUgPSBcIkBcIiwgSW5kZXgrKzsgSW5kZXggPCBsZW5ndGg7KSB7XG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA8IDMyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFVuZXNjYXBlZCBBU0NJSSBjb250cm9sIGNoYXJhY3RlcnMgKHRob3NlIHdpdGggYSBjb2RlIHVuaXRcbiAgICAgICAgICAgICAgICAgICAgLy8gbGVzcyB0aGFuIHRoZSBzcGFjZSBjaGFyYWN0ZXIpIGFyZSBub3QgcGVybWl0dGVkLlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGFyQ29kZSA9PSA5Mikge1xuICAgICAgICAgICAgICAgICAgICAvLyBBIHJldmVyc2Ugc29saWR1cyAoYFxcYCkgbWFya3MgdGhlIGJlZ2lubmluZyBvZiBhbiBlc2NhcGVkXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnRyb2wgY2hhcmFjdGVyIChpbmNsdWRpbmcgYFwiYCwgYFxcYCwgYW5kIGAvYCkgb3IgVW5pY29kZVxuICAgICAgICAgICAgICAgICAgICAvLyBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoY2hhckNvZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjYXNlIDkyOiBjYXNlIDM0OiBjYXNlIDQ3OiBjYXNlIDk4OiBjYXNlIDExNjogY2FzZSAxMTA6IGNhc2UgMTAyOiBjYXNlIDExNDpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldml2ZSBlc2NhcGVkIGNvbnRyb2wgY2hhcmFjdGVycy5cbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlICs9IFVuZXNjYXBlc1tjaGFyQ29kZV07XG4gICAgICAgICAgICAgICAgICAgICAgICBJbmRleCsrO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMTc6XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBgXFx1YCBtYXJrcyB0aGUgYmVnaW5uaW5nIG9mIGEgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBBZHZhbmNlIHRvIHRoZSBmaXJzdCBjaGFyYWN0ZXIgYW5kIHZhbGlkYXRlIHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm91ci1kaWdpdCBjb2RlIHBvaW50LlxuICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW4gPSArK0luZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwb3NpdGlvbiA9IEluZGV4ICsgNDsgSW5kZXggPCBwb3NpdGlvbjsgSW5kZXgrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSB2YWxpZCBzZXF1ZW5jZSBjb21wcmlzZXMgZm91ciBoZXhkaWdpdHMgKGNhc2UtXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluc2Vuc2l0aXZlKSB0aGF0IGZvcm0gYSBzaW5nbGUgaGV4YWRlY2ltYWwgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3IHx8IGNoYXJDb2RlID49IDk3ICYmIGNoYXJDb2RlIDw9IDEwMiB8fCBjaGFyQ29kZSA+PSA2NSAmJiBjaGFyQ29kZSA8PSA3MCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnZhbGlkIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldml2ZSB0aGUgZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSArPSBmcm9tQ2hhckNvZGUoXCIweFwiICsgc291cmNlLnNsaWNlKGJlZ2luLCBJbmRleCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEludmFsaWQgZXNjYXBlIHNlcXVlbmNlLlxuICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDM0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gQW4gdW5lc2NhcGVkIGRvdWJsZS1xdW90ZSBjaGFyYWN0ZXIgbWFya3MgdGhlIGVuZCBvZiB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAvLyBzdHJpbmcuXG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIGJlZ2luID0gSW5kZXg7XG4gICAgICAgICAgICAgICAgICAgIC8vIE9wdGltaXplIGZvciB0aGUgY29tbW9uIGNhc2Ugd2hlcmUgYSBzdHJpbmcgaXMgdmFsaWQuXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChjaGFyQ29kZSA+PSAzMiAmJiBjaGFyQ29kZSAhPSA5MiAmJiBjaGFyQ29kZSAhPSAzNCkge1xuICAgICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gQXBwZW5kIHRoZSBzdHJpbmcgYXMtaXMuXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlICs9IHNvdXJjZS5zbGljZShiZWdpbiwgSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpID09IDM0KSB7XG4gICAgICAgICAgICAgICAgICAvLyBBZHZhbmNlIHRvIHRoZSBuZXh0IGNoYXJhY3RlciBhbmQgcmV0dXJuIHRoZSByZXZpdmVkIHN0cmluZy5cbiAgICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFVudGVybWluYXRlZCBzdHJpbmcuXG4gICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAvLyBQYXJzZSBudW1iZXJzIGFuZCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBiZWdpbiA9IEluZGV4O1xuICAgICAgICAgICAgICAgIC8vIEFkdmFuY2UgcGFzdCB0aGUgbmVnYXRpdmUgc2lnbiwgaWYgb25lIGlzIHNwZWNpZmllZC5cbiAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gNDUpIHtcbiAgICAgICAgICAgICAgICAgIGlzU2lnbmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFBhcnNlIGFuIGludGVnZXIgb3IgZmxvYXRpbmctcG9pbnQgdmFsdWUuXG4gICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KSB7XG4gICAgICAgICAgICAgICAgICAvLyBMZWFkaW5nIHplcm9lcyBhcmUgaW50ZXJwcmV0ZWQgYXMgb2N0YWwgbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gNDggJiYgKChjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4ICsgMSkpLCBjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1NykpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWxsZWdhbCBvY3RhbCBsaXRlcmFsLlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgaXNTaWduZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBpbnRlZ2VyIGNvbXBvbmVudC5cbiAgICAgICAgICAgICAgICAgIGZvciAoOyBJbmRleCA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBJbmRleCsrKTtcbiAgICAgICAgICAgICAgICAgIC8vIEZsb2F0cyBjYW5ub3QgY29udGFpbiBhIGxlYWRpbmcgZGVjaW1hbCBwb2ludDsgaG93ZXZlciwgdGhpc1xuICAgICAgICAgICAgICAgICAgLy8gY2FzZSBpcyBhbHJlYWR5IGFjY291bnRlZCBmb3IgYnkgdGhlIHBhcnNlci5cbiAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuY2hhckNvZGVBdChJbmRleCkgPT0gNDYpIHtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb24gPSArK0luZGV4O1xuICAgICAgICAgICAgICAgICAgICAvLyBQYXJzZSB0aGUgZGVjaW1hbCBjb21wb25lbnQuXG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBwb3NpdGlvbiA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQocG9zaXRpb24pKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBwb3NpdGlvbisrKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gSWxsZWdhbCB0cmFpbGluZyBkZWNpbWFsLlxuICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgSW5kZXggPSBwb3NpdGlvbjtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIGV4cG9uZW50cy4gVGhlIGBlYCBkZW5vdGluZyB0aGUgZXhwb25lbnQgaXNcbiAgICAgICAgICAgICAgICAgIC8vIGNhc2UtaW5zZW5zaXRpdmUuXG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSAxMDEgfHwgY2hhckNvZGUgPT0gNjkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdCgrK0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2tpcCBwYXN0IHRoZSBzaWduIGZvbGxvd2luZyB0aGUgZXhwb25lbnQsIGlmIG9uZSBpc1xuICAgICAgICAgICAgICAgICAgICAvLyBzcGVjaWZpZWQuXG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSA0MyB8fCBjaGFyQ29kZSA9PSA0NSkge1xuICAgICAgICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgdGhlIGV4cG9uZW50aWFsIGNvbXBvbmVudC5cbiAgICAgICAgICAgICAgICAgICAgZm9yIChwb3NpdGlvbiA9IEluZGV4OyBwb3NpdGlvbiA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQocG9zaXRpb24pKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBwb3NpdGlvbisrKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uID09IEluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gSWxsZWdhbCBlbXB0eSBleHBvbmVudC5cbiAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEluZGV4ID0gcG9zaXRpb247XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAvLyBDb2VyY2UgdGhlIHBhcnNlZCB2YWx1ZSB0byBhIEphdmFTY3JpcHQgbnVtYmVyLlxuICAgICAgICAgICAgICAgICAgcmV0dXJuICtzb3VyY2Uuc2xpY2UoYmVnaW4sIEluZGV4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gQSBuZWdhdGl2ZSBzaWduIG1heSBvbmx5IHByZWNlZGUgbnVtYmVycy5cbiAgICAgICAgICAgICAgICBpZiAoaXNTaWduZWQpIHtcbiAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIGB0cnVlYCwgYGZhbHNlYCwgYW5kIGBudWxsYCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09IFwidHJ1ZVwiKSB7XG4gICAgICAgICAgICAgICAgICBJbmRleCArPSA0O1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2Uuc2xpY2UoSW5kZXgsIEluZGV4ICsgNSkgPT0gXCJmYWxzZVwiKSB7XG4gICAgICAgICAgICAgICAgICBJbmRleCArPSA1O1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09IFwibnVsbFwiKSB7XG4gICAgICAgICAgICAgICAgICBJbmRleCArPSA0O1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFVucmVjb2duaXplZCB0b2tlbi5cbiAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBSZXR1cm4gdGhlIHNlbnRpbmVsIGAkYCBjaGFyYWN0ZXIgaWYgdGhlIHBhcnNlciBoYXMgcmVhY2hlZCB0aGUgZW5kXG4gICAgICAgICAgLy8gb2YgdGhlIHNvdXJjZSBzdHJpbmcuXG4gICAgICAgICAgcmV0dXJuIFwiJFwiO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEludGVybmFsOiBQYXJzZXMgYSBKU09OIGB2YWx1ZWAgdG9rZW4uXG4gICAgICAgIHZhciBnZXQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICB2YXIgcmVzdWx0cywgaGFzTWVtYmVycztcbiAgICAgICAgICBpZiAodmFsdWUgPT0gXCIkXCIpIHtcbiAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgZW5kIG9mIGlucHV0LlxuICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBpZiAoKGNoYXJJbmRleEJ1Z2d5ID8gdmFsdWUuY2hhckF0KDApIDogdmFsdWVbMF0pID09IFwiQFwiKSB7XG4gICAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgc2VudGluZWwgYEBgIGNoYXJhY3Rlci5cbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLnNsaWNlKDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gUGFyc2Ugb2JqZWN0IGFuZCBhcnJheSBsaXRlcmFscy5cbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIltcIikge1xuICAgICAgICAgICAgICAvLyBQYXJzZXMgYSBKU09OIGFycmF5LCByZXR1cm5pbmcgYSBuZXcgSmF2YVNjcmlwdCBhcnJheS5cbiAgICAgICAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgICBmb3IgKDs7IGhhc01lbWJlcnMgfHwgKGhhc01lbWJlcnMgPSB0cnVlKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gbGV4KCk7XG4gICAgICAgICAgICAgICAgLy8gQSBjbG9zaW5nIHNxdWFyZSBicmFja2V0IG1hcmtzIHRoZSBlbmQgb2YgdGhlIGFycmF5IGxpdGVyYWwuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiXVwiKSB7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIGFycmF5IGxpdGVyYWwgY29udGFpbnMgZWxlbWVudHMsIHRoZSBjdXJyZW50IHRva2VuXG4gICAgICAgICAgICAgICAgLy8gc2hvdWxkIGJlIGEgY29tbWEgc2VwYXJhdGluZyB0aGUgcHJldmlvdXMgZWxlbWVudCBmcm9tIHRoZVxuICAgICAgICAgICAgICAgIC8vIG5leHQuXG4gICAgICAgICAgICAgICAgaWYgKGhhc01lbWJlcnMpIHtcbiAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIixcIikge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJdXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBVbmV4cGVjdGVkIHRyYWlsaW5nIGAsYCBpbiBhcnJheSBsaXRlcmFsLlxuICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEEgYCxgIG11c3Qgc2VwYXJhdGUgZWFjaCBhcnJheSBlbGVtZW50LlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBFbGlzaW9ucyBhbmQgbGVhZGluZyBjb21tYXMgYXJlIG5vdCBwZXJtaXR0ZWQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiKSB7XG4gICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goZ2V0KHZhbHVlKSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID09IFwie1wiKSB7XG4gICAgICAgICAgICAgIC8vIFBhcnNlcyBhIEpTT04gb2JqZWN0LCByZXR1cm5pbmcgYSBuZXcgSmF2YVNjcmlwdCBvYmplY3QuXG4gICAgICAgICAgICAgIHJlc3VsdHMgPSB7fTtcbiAgICAgICAgICAgICAgZm9yICg7OyBoYXNNZW1iZXJzIHx8IChoYXNNZW1iZXJzID0gdHJ1ZSkpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgIC8vIEEgY2xvc2luZyBjdXJseSBicmFjZSBtYXJrcyB0aGUgZW5kIG9mIHRoZSBvYmplY3QgbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJ9XCIpIHtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgb2JqZWN0IGxpdGVyYWwgY29udGFpbnMgbWVtYmVycywgdGhlIGN1cnJlbnQgdG9rZW5cbiAgICAgICAgICAgICAgICAvLyBzaG91bGQgYmUgYSBjb21tYSBzZXBhcmF0b3IuXG4gICAgICAgICAgICAgICAgaWYgKGhhc01lbWJlcnMpIHtcbiAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIixcIikge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJ9XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBVbmV4cGVjdGVkIHRyYWlsaW5nIGAsYCBpbiBvYmplY3QgbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBBIGAsYCBtdXN0IHNlcGFyYXRlIGVhY2ggb2JqZWN0IG1lbWJlci5cbiAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gTGVhZGluZyBjb21tYXMgYXJlIG5vdCBwZXJtaXR0ZWQsIG9iamVjdCBwcm9wZXJ0eSBuYW1lcyBtdXN0IGJlXG4gICAgICAgICAgICAgICAgLy8gZG91YmxlLXF1b3RlZCBzdHJpbmdzLCBhbmQgYSBgOmAgbXVzdCBzZXBhcmF0ZSBlYWNoIHByb3BlcnR5XG4gICAgICAgICAgICAgICAgLy8gbmFtZSBhbmQgdmFsdWUuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiIHx8IHR5cGVvZiB2YWx1ZSAhPSBcInN0cmluZ1wiIHx8IChjaGFySW5kZXhCdWdneSA/IHZhbHVlLmNoYXJBdCgwKSA6IHZhbHVlWzBdKSAhPSBcIkBcIiB8fCBsZXgoKSAhPSBcIjpcIikge1xuICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmVzdWx0c1t2YWx1ZS5zbGljZSgxKV0gPSBnZXQobGV4KCkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gVW5leHBlY3RlZCB0b2tlbiBlbmNvdW50ZXJlZC5cbiAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBJbnRlcm5hbDogVXBkYXRlcyBhIHRyYXZlcnNlZCBvYmplY3QgbWVtYmVyLlxuICAgICAgICB2YXIgdXBkYXRlID0gZnVuY3Rpb24gKHNvdXJjZSwgcHJvcGVydHksIGNhbGxiYWNrKSB7XG4gICAgICAgICAgdmFyIGVsZW1lbnQgPSB3YWxrKHNvdXJjZSwgcHJvcGVydHksIGNhbGxiYWNrKTtcbiAgICAgICAgICBpZiAoZWxlbWVudCA9PT0gdW5kZWYpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBzb3VyY2VbcHJvcGVydHldO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzb3VyY2VbcHJvcGVydHldID0gZWxlbWVudDtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gSW50ZXJuYWw6IFJlY3Vyc2l2ZWx5IHRyYXZlcnNlcyBhIHBhcnNlZCBKU09OIG9iamVjdCwgaW52b2tpbmcgdGhlXG4gICAgICAgIC8vIGBjYWxsYmFja2AgZnVuY3Rpb24gZm9yIGVhY2ggdmFsdWUuIFRoaXMgaXMgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlXG4gICAgICAgIC8vIGBXYWxrKGhvbGRlciwgbmFtZSlgIG9wZXJhdGlvbiBkZWZpbmVkIGluIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjIuXG4gICAgICAgIHZhciB3YWxrID0gZnVuY3Rpb24gKHNvdXJjZSwgcHJvcGVydHksIGNhbGxiYWNrKSB7XG4gICAgICAgICAgdmFyIHZhbHVlID0gc291cmNlW3Byb3BlcnR5XSwgbGVuZ3RoO1xuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIiAmJiB2YWx1ZSkge1xuICAgICAgICAgICAgLy8gYGZvckVhY2hgIGNhbid0IGJlIHVzZWQgdG8gdHJhdmVyc2UgYW4gYXJyYXkgaW4gT3BlcmEgPD0gOC41NFxuICAgICAgICAgICAgLy8gYmVjYXVzZSBpdHMgYE9iamVjdCNoYXNPd25Qcm9wZXJ0eWAgaW1wbGVtZW50YXRpb24gcmV0dXJucyBgZmFsc2VgXG4gICAgICAgICAgICAvLyBmb3IgYXJyYXkgaW5kaWNlcyAoZS5nLiwgYCFbMSwgMiwgM10uaGFzT3duUHJvcGVydHkoXCIwXCIpYCkuXG4gICAgICAgICAgICBpZiAoZ2V0Q2xhc3MuY2FsbCh2YWx1ZSkgPT0gYXJyYXlDbGFzcykge1xuICAgICAgICAgICAgICBmb3IgKGxlbmd0aCA9IHZhbHVlLmxlbmd0aDsgbGVuZ3RoLS07KSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlKHZhbHVlLCBsZW5ndGgsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZm9yRWFjaCh2YWx1ZSwgZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlKHZhbHVlLCBwcm9wZXJ0eSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmNhbGwoc291cmNlLCBwcm9wZXJ0eSwgdmFsdWUpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFB1YmxpYzogYEpTT04ucGFyc2VgLiBTZWUgRVMgNS4xIHNlY3Rpb24gMTUuMTIuMi5cbiAgICAgICAgZXhwb3J0cy5wYXJzZSA9IGZ1bmN0aW9uIChzb3VyY2UsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgdmFyIHJlc3VsdCwgdmFsdWU7XG4gICAgICAgICAgSW5kZXggPSAwO1xuICAgICAgICAgIFNvdXJjZSA9IFwiXCIgKyBzb3VyY2U7XG4gICAgICAgICAgcmVzdWx0ID0gZ2V0KGxleCgpKTtcbiAgICAgICAgICAvLyBJZiBhIEpTT04gc3RyaW5nIGNvbnRhaW5zIG11bHRpcGxlIHRva2VucywgaXQgaXMgaW52YWxpZC5cbiAgICAgICAgICBpZiAobGV4KCkgIT0gXCIkXCIpIHtcbiAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFJlc2V0IHRoZSBwYXJzZXIgc3RhdGUuXG4gICAgICAgICAgSW5kZXggPSBTb3VyY2UgPSBudWxsO1xuICAgICAgICAgIHJldHVybiBjYWxsYmFjayAmJiBnZXRDbGFzcy5jYWxsKGNhbGxiYWNrKSA9PSBmdW5jdGlvbkNsYXNzID8gd2FsaygodmFsdWUgPSB7fSwgdmFsdWVbXCJcIl0gPSByZXN1bHQsIHZhbHVlKSwgXCJcIiwgY2FsbGJhY2spIDogcmVzdWx0O1xuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIGV4cG9ydHNbXCJydW5JbkNvbnRleHRcIl0gPSBydW5JbkNvbnRleHQ7XG4gICAgcmV0dXJuIGV4cG9ydHM7XG4gIH1cblxuICBpZiAoZnJlZUV4cG9ydHMgJiYgIWlzTG9hZGVyKSB7XG4gICAgLy8gRXhwb3J0IGZvciBDb21tb25KUyBlbnZpcm9ubWVudHMuXG4gICAgcnVuSW5Db250ZXh0KHJvb3QsIGZyZWVFeHBvcnRzKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBFeHBvcnQgZm9yIHdlYiBicm93c2VycyBhbmQgSmF2YVNjcmlwdCBlbmdpbmVzLlxuICAgIHZhciBuYXRpdmVKU09OID0gcm9vdC5KU09OLFxuICAgICAgICBwcmV2aW91c0pTT04gPSByb290W1wiSlNPTjNcIl0sXG4gICAgICAgIGlzUmVzdG9yZWQgPSBmYWxzZTtcblxuICAgIHZhciBKU09OMyA9IHJ1bkluQ29udGV4dChyb290LCAocm9vdFtcIkpTT04zXCJdID0ge1xuICAgICAgLy8gUHVibGljOiBSZXN0b3JlcyB0aGUgb3JpZ2luYWwgdmFsdWUgb2YgdGhlIGdsb2JhbCBgSlNPTmAgb2JqZWN0IGFuZFxuICAgICAgLy8gcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGUgYEpTT04zYCBvYmplY3QuXG4gICAgICBcIm5vQ29uZmxpY3RcIjogZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIWlzUmVzdG9yZWQpIHtcbiAgICAgICAgICBpc1Jlc3RvcmVkID0gdHJ1ZTtcbiAgICAgICAgICByb290LkpTT04gPSBuYXRpdmVKU09OO1xuICAgICAgICAgIHJvb3RbXCJKU09OM1wiXSA9IHByZXZpb3VzSlNPTjtcbiAgICAgICAgICBuYXRpdmVKU09OID0gcHJldmlvdXNKU09OID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gSlNPTjM7XG4gICAgICB9XG4gICAgfSkpO1xuXG4gICAgcm9vdC5KU09OID0ge1xuICAgICAgXCJwYXJzZVwiOiBKU09OMy5wYXJzZSxcbiAgICAgIFwic3RyaW5naWZ5XCI6IEpTT04zLnN0cmluZ2lmeVxuICAgIH07XG4gIH1cblxuICAvLyBFeHBvcnQgZm9yIGFzeW5jaHJvbm91cyBtb2R1bGUgbG9hZGVycy5cbiAgaWYgKGlzTG9hZGVyKSB7XG4gICAgZGVmaW5lKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBKU09OMztcbiAgICB9KTtcbiAgfVxufSkuY2FsbCh0aGlzKTtcbiIsIm1vZHVsZS5leHBvcnRzID0gdG9BcnJheVxuXG5mdW5jdGlvbiB0b0FycmF5KGxpc3QsIGluZGV4KSB7XG4gICAgdmFyIGFycmF5ID0gW11cblxuICAgIGluZGV4ID0gaW5kZXggfHwgMFxuXG4gICAgZm9yICh2YXIgaSA9IGluZGV4IHx8IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGFycmF5W2kgLSBpbmRleF0gPSBsaXN0W2ldXG4gICAgfVxuXG4gICAgcmV0dXJuIGFycmF5XG59XG4iLCIvKiEgaHR0cHM6Ly9tdGhzLmJlL3V0ZjhqcyB2Mi4wLjAgYnkgQG1hdGhpYXMgKi9cbjsoZnVuY3Rpb24ocm9vdCkge1xuXG5cdC8vIERldGVjdCBmcmVlIHZhcmlhYmxlcyBgZXhwb3J0c2Bcblx0dmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cztcblxuXHQvLyBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYFxuXHR2YXIgZnJlZU1vZHVsZSA9IHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmXG5cdFx0bW9kdWxlLmV4cG9ydHMgPT0gZnJlZUV4cG9ydHMgJiYgbW9kdWxlO1xuXG5cdC8vIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgLCBmcm9tIE5vZGUuanMgb3IgQnJvd3NlcmlmaWVkIGNvZGUsXG5cdC8vIGFuZCB1c2UgaXQgYXMgYHJvb3RgXG5cdHZhciBmcmVlR2xvYmFsID0gdHlwZW9mIGdsb2JhbCA9PSAnb2JqZWN0JyAmJiBnbG9iYWw7XG5cdGlmIChmcmVlR2xvYmFsLmdsb2JhbCA9PT0gZnJlZUdsb2JhbCB8fCBmcmVlR2xvYmFsLndpbmRvdyA9PT0gZnJlZUdsb2JhbCkge1xuXHRcdHJvb3QgPSBmcmVlR2xvYmFsO1xuXHR9XG5cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0dmFyIHN0cmluZ0Zyb21DaGFyQ29kZSA9IFN0cmluZy5mcm9tQ2hhckNvZGU7XG5cblx0Ly8gVGFrZW4gZnJvbSBodHRwczovL210aHMuYmUvcHVueWNvZGVcblx0ZnVuY3Rpb24gdWNzMmRlY29kZShzdHJpbmcpIHtcblx0XHR2YXIgb3V0cHV0ID0gW107XG5cdFx0dmFyIGNvdW50ZXIgPSAwO1xuXHRcdHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoO1xuXHRcdHZhciB2YWx1ZTtcblx0XHR2YXIgZXh0cmE7XG5cdFx0d2hpbGUgKGNvdW50ZXIgPCBsZW5ndGgpIHtcblx0XHRcdHZhbHVlID0gc3RyaW5nLmNoYXJDb2RlQXQoY291bnRlcisrKTtcblx0XHRcdGlmICh2YWx1ZSA+PSAweEQ4MDAgJiYgdmFsdWUgPD0gMHhEQkZGICYmIGNvdW50ZXIgPCBsZW5ndGgpIHtcblx0XHRcdFx0Ly8gaGlnaCBzdXJyb2dhdGUsIGFuZCB0aGVyZSBpcyBhIG5leHQgY2hhcmFjdGVyXG5cdFx0XHRcdGV4dHJhID0gc3RyaW5nLmNoYXJDb2RlQXQoY291bnRlcisrKTtcblx0XHRcdFx0aWYgKChleHRyYSAmIDB4RkMwMCkgPT0gMHhEQzAwKSB7IC8vIGxvdyBzdXJyb2dhdGVcblx0XHRcdFx0XHRvdXRwdXQucHVzaCgoKHZhbHVlICYgMHgzRkYpIDw8IDEwKSArIChleHRyYSAmIDB4M0ZGKSArIDB4MTAwMDApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIHVubWF0Y2hlZCBzdXJyb2dhdGU7IG9ubHkgYXBwZW5kIHRoaXMgY29kZSB1bml0LCBpbiBjYXNlIHRoZSBuZXh0XG5cdFx0XHRcdFx0Ly8gY29kZSB1bml0IGlzIHRoZSBoaWdoIHN1cnJvZ2F0ZSBvZiBhIHN1cnJvZ2F0ZSBwYWlyXG5cdFx0XHRcdFx0b3V0cHV0LnB1c2godmFsdWUpO1xuXHRcdFx0XHRcdGNvdW50ZXItLTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0b3V0cHV0LnB1c2godmFsdWUpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gb3V0cHV0O1xuXHR9XG5cblx0Ly8gVGFrZW4gZnJvbSBodHRwczovL210aHMuYmUvcHVueWNvZGVcblx0ZnVuY3Rpb24gdWNzMmVuY29kZShhcnJheSkge1xuXHRcdHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cdFx0dmFyIGluZGV4ID0gLTE7XG5cdFx0dmFyIHZhbHVlO1xuXHRcdHZhciBvdXRwdXQgPSAnJztcblx0XHR3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuXHRcdFx0dmFsdWUgPSBhcnJheVtpbmRleF07XG5cdFx0XHRpZiAodmFsdWUgPiAweEZGRkYpIHtcblx0XHRcdFx0dmFsdWUgLT0gMHgxMDAwMDtcblx0XHRcdFx0b3V0cHV0ICs9IHN0cmluZ0Zyb21DaGFyQ29kZSh2YWx1ZSA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMCk7XG5cdFx0XHRcdHZhbHVlID0gMHhEQzAwIHwgdmFsdWUgJiAweDNGRjtcblx0XHRcdH1cblx0XHRcdG91dHB1dCArPSBzdHJpbmdGcm9tQ2hhckNvZGUodmFsdWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gb3V0cHV0O1xuXHR9XG5cblx0ZnVuY3Rpb24gY2hlY2tTY2FsYXJWYWx1ZShjb2RlUG9pbnQpIHtcblx0XHRpZiAoY29kZVBvaW50ID49IDB4RDgwMCAmJiBjb2RlUG9pbnQgPD0gMHhERkZGKSB7XG5cdFx0XHR0aHJvdyBFcnJvcihcblx0XHRcdFx0J0xvbmUgc3Vycm9nYXRlIFUrJyArIGNvZGVQb2ludC50b1N0cmluZygxNikudG9VcHBlckNhc2UoKSArXG5cdFx0XHRcdCcgaXMgbm90IGEgc2NhbGFyIHZhbHVlJ1xuXHRcdFx0KTtcblx0XHR9XG5cdH1cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0ZnVuY3Rpb24gY3JlYXRlQnl0ZShjb2RlUG9pbnQsIHNoaWZ0KSB7XG5cdFx0cmV0dXJuIHN0cmluZ0Zyb21DaGFyQ29kZSgoKGNvZGVQb2ludCA+PiBzaGlmdCkgJiAweDNGKSB8IDB4ODApO1xuXHR9XG5cblx0ZnVuY3Rpb24gZW5jb2RlQ29kZVBvaW50KGNvZGVQb2ludCkge1xuXHRcdGlmICgoY29kZVBvaW50ICYgMHhGRkZGRkY4MCkgPT0gMCkgeyAvLyAxLWJ5dGUgc2VxdWVuY2Vcblx0XHRcdHJldHVybiBzdHJpbmdGcm9tQ2hhckNvZGUoY29kZVBvaW50KTtcblx0XHR9XG5cdFx0dmFyIHN5bWJvbCA9ICcnO1xuXHRcdGlmICgoY29kZVBvaW50ICYgMHhGRkZGRjgwMCkgPT0gMCkgeyAvLyAyLWJ5dGUgc2VxdWVuY2Vcblx0XHRcdHN5bWJvbCA9IHN0cmluZ0Zyb21DaGFyQ29kZSgoKGNvZGVQb2ludCA+PiA2KSAmIDB4MUYpIHwgMHhDMCk7XG5cdFx0fVxuXHRcdGVsc2UgaWYgKChjb2RlUG9pbnQgJiAweEZGRkYwMDAwKSA9PSAwKSB7IC8vIDMtYnl0ZSBzZXF1ZW5jZVxuXHRcdFx0Y2hlY2tTY2FsYXJWYWx1ZShjb2RlUG9pbnQpO1xuXHRcdFx0c3ltYm9sID0gc3RyaW5nRnJvbUNoYXJDb2RlKCgoY29kZVBvaW50ID4+IDEyKSAmIDB4MEYpIHwgMHhFMCk7XG5cdFx0XHRzeW1ib2wgKz0gY3JlYXRlQnl0ZShjb2RlUG9pbnQsIDYpO1xuXHRcdH1cblx0XHRlbHNlIGlmICgoY29kZVBvaW50ICYgMHhGRkUwMDAwMCkgPT0gMCkgeyAvLyA0LWJ5dGUgc2VxdWVuY2Vcblx0XHRcdHN5bWJvbCA9IHN0cmluZ0Zyb21DaGFyQ29kZSgoKGNvZGVQb2ludCA+PiAxOCkgJiAweDA3KSB8IDB4RjApO1xuXHRcdFx0c3ltYm9sICs9IGNyZWF0ZUJ5dGUoY29kZVBvaW50LCAxMik7XG5cdFx0XHRzeW1ib2wgKz0gY3JlYXRlQnl0ZShjb2RlUG9pbnQsIDYpO1xuXHRcdH1cblx0XHRzeW1ib2wgKz0gc3RyaW5nRnJvbUNoYXJDb2RlKChjb2RlUG9pbnQgJiAweDNGKSB8IDB4ODApO1xuXHRcdHJldHVybiBzeW1ib2w7XG5cdH1cblxuXHRmdW5jdGlvbiB1dGY4ZW5jb2RlKHN0cmluZykge1xuXHRcdHZhciBjb2RlUG9pbnRzID0gdWNzMmRlY29kZShzdHJpbmcpO1xuXHRcdHZhciBsZW5ndGggPSBjb2RlUG9pbnRzLmxlbmd0aDtcblx0XHR2YXIgaW5kZXggPSAtMTtcblx0XHR2YXIgY29kZVBvaW50O1xuXHRcdHZhciBieXRlU3RyaW5nID0gJyc7XG5cdFx0d2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcblx0XHRcdGNvZGVQb2ludCA9IGNvZGVQb2ludHNbaW5kZXhdO1xuXHRcdFx0Ynl0ZVN0cmluZyArPSBlbmNvZGVDb2RlUG9pbnQoY29kZVBvaW50KTtcblx0XHR9XG5cdFx0cmV0dXJuIGJ5dGVTdHJpbmc7XG5cdH1cblxuXHQvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuXHRmdW5jdGlvbiByZWFkQ29udGludWF0aW9uQnl0ZSgpIHtcblx0XHRpZiAoYnl0ZUluZGV4ID49IGJ5dGVDb3VudCkge1xuXHRcdFx0dGhyb3cgRXJyb3IoJ0ludmFsaWQgYnl0ZSBpbmRleCcpO1xuXHRcdH1cblxuXHRcdHZhciBjb250aW51YXRpb25CeXRlID0gYnl0ZUFycmF5W2J5dGVJbmRleF0gJiAweEZGO1xuXHRcdGJ5dGVJbmRleCsrO1xuXG5cdFx0aWYgKChjb250aW51YXRpb25CeXRlICYgMHhDMCkgPT0gMHg4MCkge1xuXHRcdFx0cmV0dXJuIGNvbnRpbnVhdGlvbkJ5dGUgJiAweDNGO1xuXHRcdH1cblxuXHRcdC8vIElmIHdlIGVuZCB1cCBoZXJlLCBpdOKAmXMgbm90IGEgY29udGludWF0aW9uIGJ5dGVcblx0XHR0aHJvdyBFcnJvcignSW52YWxpZCBjb250aW51YXRpb24gYnl0ZScpO1xuXHR9XG5cblx0ZnVuY3Rpb24gZGVjb2RlU3ltYm9sKCkge1xuXHRcdHZhciBieXRlMTtcblx0XHR2YXIgYnl0ZTI7XG5cdFx0dmFyIGJ5dGUzO1xuXHRcdHZhciBieXRlNDtcblx0XHR2YXIgY29kZVBvaW50O1xuXG5cdFx0aWYgKGJ5dGVJbmRleCA+IGJ5dGVDb3VudCkge1xuXHRcdFx0dGhyb3cgRXJyb3IoJ0ludmFsaWQgYnl0ZSBpbmRleCcpO1xuXHRcdH1cblxuXHRcdGlmIChieXRlSW5kZXggPT0gYnl0ZUNvdW50KSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gUmVhZCBmaXJzdCBieXRlXG5cdFx0Ynl0ZTEgPSBieXRlQXJyYXlbYnl0ZUluZGV4XSAmIDB4RkY7XG5cdFx0Ynl0ZUluZGV4Kys7XG5cblx0XHQvLyAxLWJ5dGUgc2VxdWVuY2UgKG5vIGNvbnRpbnVhdGlvbiBieXRlcylcblx0XHRpZiAoKGJ5dGUxICYgMHg4MCkgPT0gMCkge1xuXHRcdFx0cmV0dXJuIGJ5dGUxO1xuXHRcdH1cblxuXHRcdC8vIDItYnl0ZSBzZXF1ZW5jZVxuXHRcdGlmICgoYnl0ZTEgJiAweEUwKSA9PSAweEMwKSB7XG5cdFx0XHR2YXIgYnl0ZTIgPSByZWFkQ29udGludWF0aW9uQnl0ZSgpO1xuXHRcdFx0Y29kZVBvaW50ID0gKChieXRlMSAmIDB4MUYpIDw8IDYpIHwgYnl0ZTI7XG5cdFx0XHRpZiAoY29kZVBvaW50ID49IDB4ODApIHtcblx0XHRcdFx0cmV0dXJuIGNvZGVQb2ludDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRocm93IEVycm9yKCdJbnZhbGlkIGNvbnRpbnVhdGlvbiBieXRlJyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gMy1ieXRlIHNlcXVlbmNlIChtYXkgaW5jbHVkZSB1bnBhaXJlZCBzdXJyb2dhdGVzKVxuXHRcdGlmICgoYnl0ZTEgJiAweEYwKSA9PSAweEUwKSB7XG5cdFx0XHRieXRlMiA9IHJlYWRDb250aW51YXRpb25CeXRlKCk7XG5cdFx0XHRieXRlMyA9IHJlYWRDb250aW51YXRpb25CeXRlKCk7XG5cdFx0XHRjb2RlUG9pbnQgPSAoKGJ5dGUxICYgMHgwRikgPDwgMTIpIHwgKGJ5dGUyIDw8IDYpIHwgYnl0ZTM7XG5cdFx0XHRpZiAoY29kZVBvaW50ID49IDB4MDgwMCkge1xuXHRcdFx0XHRjaGVja1NjYWxhclZhbHVlKGNvZGVQb2ludCk7XG5cdFx0XHRcdHJldHVybiBjb2RlUG9pbnQ7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aHJvdyBFcnJvcignSW52YWxpZCBjb250aW51YXRpb24gYnl0ZScpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIDQtYnl0ZSBzZXF1ZW5jZVxuXHRcdGlmICgoYnl0ZTEgJiAweEY4KSA9PSAweEYwKSB7XG5cdFx0XHRieXRlMiA9IHJlYWRDb250aW51YXRpb25CeXRlKCk7XG5cdFx0XHRieXRlMyA9IHJlYWRDb250aW51YXRpb25CeXRlKCk7XG5cdFx0XHRieXRlNCA9IHJlYWRDb250aW51YXRpb25CeXRlKCk7XG5cdFx0XHRjb2RlUG9pbnQgPSAoKGJ5dGUxICYgMHgwRikgPDwgMHgxMikgfCAoYnl0ZTIgPDwgMHgwQykgfFxuXHRcdFx0XHQoYnl0ZTMgPDwgMHgwNikgfCBieXRlNDtcblx0XHRcdGlmIChjb2RlUG9pbnQgPj0gMHgwMTAwMDAgJiYgY29kZVBvaW50IDw9IDB4MTBGRkZGKSB7XG5cdFx0XHRcdHJldHVybiBjb2RlUG9pbnQ7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0dGhyb3cgRXJyb3IoJ0ludmFsaWQgVVRGLTggZGV0ZWN0ZWQnKTtcblx0fVxuXG5cdHZhciBieXRlQXJyYXk7XG5cdHZhciBieXRlQ291bnQ7XG5cdHZhciBieXRlSW5kZXg7XG5cdGZ1bmN0aW9uIHV0ZjhkZWNvZGUoYnl0ZVN0cmluZykge1xuXHRcdGJ5dGVBcnJheSA9IHVjczJkZWNvZGUoYnl0ZVN0cmluZyk7XG5cdFx0Ynl0ZUNvdW50ID0gYnl0ZUFycmF5Lmxlbmd0aDtcblx0XHRieXRlSW5kZXggPSAwO1xuXHRcdHZhciBjb2RlUG9pbnRzID0gW107XG5cdFx0dmFyIHRtcDtcblx0XHR3aGlsZSAoKHRtcCA9IGRlY29kZVN5bWJvbCgpKSAhPT0gZmFsc2UpIHtcblx0XHRcdGNvZGVQb2ludHMucHVzaCh0bXApO1xuXHRcdH1cblx0XHRyZXR1cm4gdWNzMmVuY29kZShjb2RlUG9pbnRzKTtcblx0fVxuXG5cdC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5cdHZhciB1dGY4ID0ge1xuXHRcdCd2ZXJzaW9uJzogJzIuMC4wJyxcblx0XHQnZW5jb2RlJzogdXRmOGVuY29kZSxcblx0XHQnZGVjb2RlJzogdXRmOGRlY29kZVxuXHR9O1xuXG5cdC8vIFNvbWUgQU1EIGJ1aWxkIG9wdGltaXplcnMsIGxpa2Ugci5qcywgY2hlY2sgZm9yIHNwZWNpZmljIGNvbmRpdGlvbiBwYXR0ZXJuc1xuXHQvLyBsaWtlIHRoZSBmb2xsb3dpbmc6XG5cdGlmIChcblx0XHR0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiZcblx0XHR0eXBlb2YgZGVmaW5lLmFtZCA9PSAnb2JqZWN0JyAmJlxuXHRcdGRlZmluZS5hbWRcblx0KSB7XG5cdFx0ZGVmaW5lKGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHV0Zjg7XG5cdFx0fSk7XG5cdH1cdGVsc2UgaWYgKGZyZWVFeHBvcnRzICYmICFmcmVlRXhwb3J0cy5ub2RlVHlwZSkge1xuXHRcdGlmIChmcmVlTW9kdWxlKSB7IC8vIGluIE5vZGUuanMgb3IgUmluZ29KUyB2MC44LjArXG5cdFx0XHRmcmVlTW9kdWxlLmV4cG9ydHMgPSB1dGY4O1xuXHRcdH0gZWxzZSB7IC8vIGluIE5hcndoYWwgb3IgUmluZ29KUyB2MC43LjAtXG5cdFx0XHR2YXIgb2JqZWN0ID0ge307XG5cdFx0XHR2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3QuaGFzT3duUHJvcGVydHk7XG5cdFx0XHRmb3IgKHZhciBrZXkgaW4gdXRmOCkge1xuXHRcdFx0XHRoYXNPd25Qcm9wZXJ0eS5jYWxsKHV0ZjgsIGtleSkgJiYgKGZyZWVFeHBvcnRzW2tleV0gPSB1dGY4W2tleV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0fSBlbHNlIHsgLy8gaW4gUmhpbm8gb3IgYSB3ZWIgYnJvd3NlclxuXHRcdHJvb3QudXRmOCA9IHV0Zjg7XG5cdH1cblxufSh0aGlzKSk7XG4iLCJ2YXIgVnVlIC8vIGxhdGUgYmluZFxudmFyIG1hcCA9IE9iamVjdC5jcmVhdGUobnVsbClcbnZhciBzaGltbWVkID0gZmFsc2VcbnZhciBpc0Jyb3dzZXJpZnkgPSBmYWxzZVxuXG4vKipcbiAqIERldGVybWluZSBjb21wYXRpYmlsaXR5IGFuZCBhcHBseSBwYXRjaC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB2dWVcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gYnJvd3NlcmlmeVxuICovXG5cbmV4cG9ydHMuaW5zdGFsbCA9IGZ1bmN0aW9uICh2dWUsIGJyb3dzZXJpZnkpIHtcbiAgaWYgKHNoaW1tZWQpIHJldHVyblxuICBzaGltbWVkID0gdHJ1ZVxuXG4gIFZ1ZSA9IHZ1ZVxuICBpc0Jyb3dzZXJpZnkgPSBicm93c2VyaWZ5XG5cbiAgZXhwb3J0cy5jb21wYXRpYmxlID0gISFWdWUuaW50ZXJuYWxEaXJlY3RpdmVzXG4gIGlmICghZXhwb3J0cy5jb21wYXRpYmxlKSB7XG4gICAgY29uc29sZS53YXJuKFxuICAgICAgJ1tITVJdIHZ1ZS1sb2FkZXIgaG90IHJlbG9hZCBpcyBvbmx5IGNvbXBhdGlibGUgd2l0aCAnICtcbiAgICAgICdWdWUuanMgMS4wLjArLidcbiAgICApXG4gICAgcmV0dXJuXG4gIH1cblxuICAvLyBwYXRjaCB2aWV3IGRpcmVjdGl2ZVxuICBwYXRjaFZpZXcoVnVlLmludGVybmFsRGlyZWN0aXZlcy5jb21wb25lbnQpXG4gIGNvbnNvbGUubG9nKCdbSE1SXSBWdWUgY29tcG9uZW50IGhvdCByZWxvYWQgc2hpbSBhcHBsaWVkLicpXG4gIC8vIHNoaW0gcm91dGVyLXZpZXcgaWYgcHJlc2VudFxuICB2YXIgcm91dGVyVmlldyA9IFZ1ZS5lbGVtZW50RGlyZWN0aXZlKCdyb3V0ZXItdmlldycpXG4gIGlmIChyb3V0ZXJWaWV3KSB7XG4gICAgcGF0Y2hWaWV3KHJvdXRlclZpZXcpXG4gICAgY29uc29sZS5sb2coJ1tITVJdIHZ1ZS1yb3V0ZXIgPHJvdXRlci12aWV3PiBob3QgcmVsb2FkIHNoaW0gYXBwbGllZC4nKVxuICB9XG59XG5cbi8qKlxuICogU2hpbSB0aGUgdmlldyBkaXJlY3RpdmUgKGNvbXBvbmVudCBvciByb3V0ZXItdmlldykuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFZpZXdcbiAqL1xuXG5mdW5jdGlvbiBwYXRjaFZpZXcgKFZpZXcpIHtcbiAgdmFyIHVuYnVpbGQgPSBWaWV3LnVuYnVpbGRcbiAgVmlldy51bmJ1aWxkID0gZnVuY3Rpb24gKGRlZmVyKSB7XG4gICAgaWYgKCF0aGlzLmhvdFVwZGF0aW5nKSB7XG4gICAgICB2YXIgcHJldkNvbXBvbmVudCA9IHRoaXMuY2hpbGRWTSAmJiB0aGlzLmNoaWxkVk0uY29uc3RydWN0b3JcbiAgICAgIHJlbW92ZVZpZXcocHJldkNvbXBvbmVudCwgdGhpcylcbiAgICAgIC8vIGRlZmVyID0gdHJ1ZSBtZWFucyB3ZSBhcmUgdHJhbnNpdGlvbmluZyB0byBhIG5ld1xuICAgICAgLy8gQ29tcG9uZW50LiBSZWdpc3RlciB0aGlzIG5ldyBjb21wb25lbnQgdG8gdGhlIGxpc3QuXG4gICAgICBpZiAoZGVmZXIpIHtcbiAgICAgICAgYWRkVmlldyh0aGlzLkNvbXBvbmVudCwgdGhpcylcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gY2FsbCBvcmlnaW5hbFxuICAgIHJldHVybiB1bmJ1aWxkLmNhbGwodGhpcywgZGVmZXIpXG4gIH1cbn1cblxuLyoqXG4gKiBBZGQgYSBjb21wb25lbnQgdmlldyB0byBhIENvbXBvbmVudCdzIGhvdCBsaXN0XG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gQ29tcG9uZW50XG4gKiBAcGFyYW0ge0RpcmVjdGl2ZX0gdmlldyAtIHZpZXcgZGlyZWN0aXZlIGluc3RhbmNlXG4gKi9cblxuZnVuY3Rpb24gYWRkVmlldyAoQ29tcG9uZW50LCB2aWV3KSB7XG4gIHZhciBpZCA9IENvbXBvbmVudCAmJiBDb21wb25lbnQub3B0aW9ucy5ob3RJRFxuICBpZiAoaWQpIHtcbiAgICBpZiAoIW1hcFtpZF0pIHtcbiAgICAgIG1hcFtpZF0gPSB7XG4gICAgICAgIENvbXBvbmVudDogQ29tcG9uZW50LFxuICAgICAgICB2aWV3czogW10sXG4gICAgICAgIGluc3RhbmNlczogW11cbiAgICAgIH1cbiAgICB9XG4gICAgbWFwW2lkXS52aWV3cy5wdXNoKHZpZXcpXG4gIH1cbn1cblxuLyoqXG4gKiBSZW1vdmUgYSBjb21wb25lbnQgdmlldyBmcm9tIGEgQ29tcG9uZW50J3MgaG90IGxpc3RcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBDb21wb25lbnRcbiAqIEBwYXJhbSB7RGlyZWN0aXZlfSB2aWV3IC0gdmlldyBkaXJlY3RpdmUgaW5zdGFuY2VcbiAqL1xuXG5mdW5jdGlvbiByZW1vdmVWaWV3IChDb21wb25lbnQsIHZpZXcpIHtcbiAgdmFyIGlkID0gQ29tcG9uZW50ICYmIENvbXBvbmVudC5vcHRpb25zLmhvdElEXG4gIGlmIChpZCkge1xuICAgIG1hcFtpZF0udmlld3MuJHJlbW92ZSh2aWV3KVxuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgcmVjb3JkIGZvciBhIGhvdCBtb2R1bGUsIHdoaWNoIGtlZXBzIHRyYWNrIG9mIGl0cyBjb25zdHJ1Y290cixcbiAqIGluc3RuYWNlcyBhbmQgdmlld3MgKGNvbXBvbmVudCBkaXJlY3RpdmVzIG9yIHJvdXRlci12aWV3cykuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGlkXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICovXG5cbmV4cG9ydHMuY3JlYXRlUmVjb3JkID0gZnVuY3Rpb24gKGlkLCBvcHRpb25zKSB7XG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zLm9wdGlvbnNcbiAgfVxuICBpZiAodHlwZW9mIG9wdGlvbnMuZWwgIT09ICdzdHJpbmcnICYmIHR5cGVvZiBvcHRpb25zLmRhdGEgIT09ICdvYmplY3QnKSB7XG4gICAgbWFrZU9wdGlvbnNIb3QoaWQsIG9wdGlvbnMpXG4gICAgbWFwW2lkXSA9IHtcbiAgICAgIENvbXBvbmVudDogbnVsbCxcbiAgICAgIHZpZXdzOiBbXSxcbiAgICAgIGluc3RhbmNlczogW11cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBNYWtlIGEgQ29tcG9uZW50IG9wdGlvbnMgb2JqZWN0IGhvdC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gaWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKi9cblxuZnVuY3Rpb24gbWFrZU9wdGlvbnNIb3QgKGlkLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMuaG90SUQgPSBpZFxuICBpbmplY3RIb29rKG9wdGlvbnMsICdjcmVhdGVkJywgZnVuY3Rpb24gKCkge1xuICAgIHZhciByZWNvcmQgPSBtYXBbaWRdXG4gICAgaWYgKCFyZWNvcmQuQ29tcG9uZW50KSB7XG4gICAgICByZWNvcmQuQ29tcG9uZW50ID0gdGhpcy5jb25zdHJ1Y3RvclxuICAgIH1cbiAgICByZWNvcmQuaW5zdGFuY2VzLnB1c2godGhpcylcbiAgfSlcbiAgaW5qZWN0SG9vayhvcHRpb25zLCAnYmVmb3JlRGVzdHJveScsIGZ1bmN0aW9uICgpIHtcbiAgICBtYXBbaWRdLmluc3RhbmNlcy4kcmVtb3ZlKHRoaXMpXG4gIH0pXG59XG5cbi8qKlxuICogSW5qZWN0IGEgaG9vayB0byBhIGhvdCByZWxvYWRhYmxlIGNvbXBvbmVudCBzbyB0aGF0XG4gKiB3ZSBjYW4ga2VlcCB0cmFjayBvZiBpdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGhvb2tcbiAqL1xuXG5mdW5jdGlvbiBpbmplY3RIb29rIChvcHRpb25zLCBuYW1lLCBob29rKSB7XG4gIHZhciBleGlzdGluZyA9IG9wdGlvbnNbbmFtZV1cbiAgb3B0aW9uc1tuYW1lXSA9IGV4aXN0aW5nXG4gICAgPyBBcnJheS5pc0FycmF5KGV4aXN0aW5nKVxuICAgICAgPyBleGlzdGluZy5jb25jYXQoaG9vaylcbiAgICAgIDogW2V4aXN0aW5nLCBob29rXVxuICAgIDogW2hvb2tdXG59XG5cbi8qKlxuICogVXBkYXRlIGEgaG90IGNvbXBvbmVudC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gaWRcbiAqIEBwYXJhbSB7T2JqZWN0fG51bGx9IG5ld09wdGlvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfG51bGx9IG5ld1RlbXBsYXRlXG4gKi9cblxuZXhwb3J0cy51cGRhdGUgPSBmdW5jdGlvbiAoaWQsIG5ld09wdGlvbnMsIG5ld1RlbXBsYXRlKSB7XG4gIHZhciByZWNvcmQgPSBtYXBbaWRdXG4gIC8vIGZvcmNlIGZ1bGwtcmVsb2FkIGlmIGFuIGluc3RhbmNlIG9mIHRoZSBjb21wb25lbnQgaXMgYWN0aXZlIGJ1dCBpcyBub3RcbiAgLy8gbWFuYWdlZCBieSBhIHZpZXdcbiAgaWYgKCFyZWNvcmQgfHwgKHJlY29yZC5pbnN0YW5jZXMubGVuZ3RoICYmICFyZWNvcmQudmlld3MubGVuZ3RoKSkge1xuICAgIGNvbnNvbGUubG9nKCdbSE1SXSBSb290IG9yIG1hbnVhbGx5LW1vdW50ZWQgaW5zdGFuY2UgbW9kaWZpZWQuIEZ1bGwgcmVsb2FkIG1heSBiZSByZXF1aXJlZC4nKVxuICAgIGlmICghaXNCcm93c2VyaWZ5KSB7XG4gICAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKClcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gYnJvd3NlcmlmeS1obXIgc29tZWhvdyBzZW5kcyBpbmNvbXBsZXRlIGJ1bmRsZSBpZiB3ZSByZWxvYWQgaGVyZVxuICAgICAgcmV0dXJuXG4gICAgfVxuICB9XG4gIGlmICghaXNCcm93c2VyaWZ5KSB7XG4gICAgLy8gYnJvd3NlcmlmeS1obXIgYWxyZWFkeSBsb2dzIHRoaXNcbiAgICBjb25zb2xlLmxvZygnW0hNUl0gVXBkYXRpbmcgY29tcG9uZW50OiAnICsgZm9ybWF0KGlkKSlcbiAgfVxuICB2YXIgQ29tcG9uZW50ID0gcmVjb3JkLkNvbXBvbmVudFxuICAvLyB1cGRhdGUgY29uc3RydWN0b3JcbiAgaWYgKG5ld09wdGlvbnMpIHtcbiAgICAvLyBpbiBjYXNlIHRoZSB1c2VyIGV4cG9ydHMgYSBjb25zdHJ1Y3RvclxuICAgIENvbXBvbmVudCA9IHJlY29yZC5Db21wb25lbnQgPSB0eXBlb2YgbmV3T3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgPyBuZXdPcHRpb25zXG4gICAgICA6IFZ1ZS5leHRlbmQobmV3T3B0aW9ucylcbiAgICBtYWtlT3B0aW9uc0hvdChpZCwgQ29tcG9uZW50Lm9wdGlvbnMpXG4gIH1cbiAgaWYgKG5ld1RlbXBsYXRlKSB7XG4gICAgQ29tcG9uZW50Lm9wdGlvbnMudGVtcGxhdGUgPSBuZXdUZW1wbGF0ZVxuICB9XG4gIC8vIGhhbmRsZSByZWN1cnNpdmUgbG9va3VwXG4gIGlmIChDb21wb25lbnQub3B0aW9ucy5uYW1lKSB7XG4gICAgQ29tcG9uZW50Lm9wdGlvbnMuY29tcG9uZW50c1tDb21wb25lbnQub3B0aW9ucy5uYW1lXSA9IENvbXBvbmVudFxuICB9XG4gIC8vIHJlc2V0IGNvbnN0cnVjdG9yIGNhY2hlZCBsaW5rZXJcbiAgQ29tcG9uZW50LmxpbmtlciA9IG51bGxcbiAgLy8gcmVsb2FkIGFsbCB2aWV3c1xuICByZWNvcmQudmlld3MuZm9yRWFjaChmdW5jdGlvbiAodmlldykge1xuICAgIHVwZGF0ZVZpZXcodmlldywgQ29tcG9uZW50KVxuICB9KVxuICAvLyBmbHVzaCBkZXZ0b29sc1xuICBpZiAod2luZG93Ll9fVlVFX0RFVlRPT0xTX0dMT0JBTF9IT09LX18pIHtcbiAgICB3aW5kb3cuX19WVUVfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5lbWl0KCdmbHVzaCcpXG4gIH1cbn1cblxuLyoqXG4gKiBVcGRhdGUgYSBjb21wb25lbnQgdmlldyBpbnN0YW5jZVxuICpcbiAqIEBwYXJhbSB7RGlyZWN0aXZlfSB2aWV3XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBDb21wb25lbnRcbiAqL1xuXG5mdW5jdGlvbiB1cGRhdGVWaWV3ICh2aWV3LCBDb21wb25lbnQpIHtcbiAgaWYgKCF2aWV3Ll9ib3VuZCkge1xuICAgIHJldHVyblxuICB9XG4gIHZpZXcuQ29tcG9uZW50ID0gQ29tcG9uZW50XG4gIHZpZXcuaG90VXBkYXRpbmcgPSB0cnVlXG4gIC8vIGRpc2FibGUgdHJhbnNpdGlvbnNcbiAgdmlldy52bS5faXNDb21waWxlZCA9IGZhbHNlXG4gIC8vIHNhdmUgc3RhdGVcbiAgdmFyIHN0YXRlID0gZXh0cmFjdFN0YXRlKHZpZXcuY2hpbGRWTSlcbiAgLy8gcmVtb3VudCwgbWFrZSBzdXJlIHRvIGRpc2FibGUga2VlcC1hbGl2ZVxuICB2YXIga2VlcEFsaXZlID0gdmlldy5rZWVwQWxpdmVcbiAgdmlldy5rZWVwQWxpdmUgPSBmYWxzZVxuICB2aWV3Lm1vdW50Q29tcG9uZW50KClcbiAgdmlldy5rZWVwQWxpdmUgPSBrZWVwQWxpdmVcbiAgLy8gcmVzdG9yZSBzdGF0ZVxuICByZXN0b3JlU3RhdGUodmlldy5jaGlsZFZNLCBzdGF0ZSwgdHJ1ZSlcbiAgLy8gcmUtZWFuYmxlIHRyYW5zaXRpb25zXG4gIHZpZXcudm0uX2lzQ29tcGlsZWQgPSB0cnVlXG4gIHZpZXcuaG90VXBkYXRpbmcgPSBmYWxzZVxufVxuXG4vKipcbiAqIEV4dHJhY3Qgc3RhdGUgZnJvbSBhIFZ1ZSBpbnN0YW5jZS5cbiAqXG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuXG5mdW5jdGlvbiBleHRyYWN0U3RhdGUgKHZtKSB7XG4gIHJldHVybiB7XG4gICAgY2lkOiB2bS5jb25zdHJ1Y3Rvci5jaWQsXG4gICAgZGF0YTogdm0uJGRhdGEsXG4gICAgY2hpbGRyZW46IHZtLiRjaGlsZHJlbi5tYXAoZXh0cmFjdFN0YXRlKVxuICB9XG59XG5cbi8qKlxuICogUmVzdG9yZSBzdGF0ZSB0byBhIHJlbG9hZGVkIFZ1ZSBpbnN0YW5jZS5cbiAqXG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGF0ZVxuICovXG5cbmZ1bmN0aW9uIHJlc3RvcmVTdGF0ZSAodm0sIHN0YXRlLCBpc1Jvb3QpIHtcbiAgdmFyIG9sZEFzeW5jQ29uZmlnXG4gIGlmIChpc1Jvb3QpIHtcbiAgICAvLyBzZXQgVnVlIGludG8gc3luYyBtb2RlIGR1cmluZyBzdGF0ZSByZWh5ZHJhdGlvblxuICAgIG9sZEFzeW5jQ29uZmlnID0gVnVlLmNvbmZpZy5hc3luY1xuICAgIFZ1ZS5jb25maWcuYXN5bmMgPSBmYWxzZVxuICB9XG4gIC8vIGFjdHVhbCByZXN0b3JlXG4gIGlmIChpc1Jvb3QgfHwgIXZtLl9wcm9wcykge1xuICAgIHZtLiRkYXRhID0gc3RhdGUuZGF0YVxuICB9IGVsc2Uge1xuICAgIE9iamVjdC5rZXlzKHN0YXRlLmRhdGEpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgaWYgKCF2bS5fcHJvcHNba2V5XSkge1xuICAgICAgICAvLyBmb3Igbm9uLXJvb3QsIG9ubHkgcmVzdG9yZSBub24tcHJvcHMgZmllbGRzXG4gICAgICAgIHZtLiRkYXRhW2tleV0gPSBzdGF0ZS5kYXRhW2tleV1cbiAgICAgIH1cbiAgICB9KVxuICB9XG4gIC8vIHZlcmlmeSBjaGlsZCBjb25zaXN0ZW5jeVxuICB2YXIgaGFzU2FtZUNoaWxkcmVuID0gdm0uJGNoaWxkcmVuLmV2ZXJ5KGZ1bmN0aW9uIChjLCBpKSB7XG4gICAgcmV0dXJuIHN0YXRlLmNoaWxkcmVuW2ldICYmIHN0YXRlLmNoaWxkcmVuW2ldLmNpZCA9PT0gYy5jb25zdHJ1Y3Rvci5jaWRcbiAgfSlcbiAgaWYgKGhhc1NhbWVDaGlsZHJlbikge1xuICAgIC8vIHJlaHlkcmF0ZSBjaGlsZHJlblxuICAgIHZtLiRjaGlsZHJlbi5mb3JFYWNoKGZ1bmN0aW9uIChjLCBpKSB7XG4gICAgICByZXN0b3JlU3RhdGUoYywgc3RhdGUuY2hpbGRyZW5baV0pXG4gICAgfSlcbiAgfVxuICBpZiAoaXNSb290KSB7XG4gICAgVnVlLmNvbmZpZy5hc3luYyA9IG9sZEFzeW5jQ29uZmlnXG4gIH1cbn1cblxuZnVuY3Rpb24gZm9ybWF0IChpZCkge1xuICByZXR1cm4gaWQubWF0Y2goL1teXFwvXStcXC52dWUkLylbMF1cbn1cbiIsIi8qIVxuICogVnVlLmpzIHYxLjAuMTdcbiAqIChjKSAyMDE2IEV2YW4gWW91XG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gc2V0KG9iaiwga2V5LCB2YWwpIHtcbiAgaWYgKGhhc093bihvYmosIGtleSkpIHtcbiAgICBvYmpba2V5XSA9IHZhbDtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKG9iai5faXNWdWUpIHtcbiAgICBzZXQob2JqLl9kYXRhLCBrZXksIHZhbCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBvYiA9IG9iai5fX29iX187XG4gIGlmICghb2IpIHtcbiAgICBvYmpba2V5XSA9IHZhbDtcbiAgICByZXR1cm47XG4gIH1cbiAgb2IuY29udmVydChrZXksIHZhbCk7XG4gIG9iLmRlcC5ub3RpZnkoKTtcbiAgaWYgKG9iLnZtcykge1xuICAgIHZhciBpID0gb2Iudm1zLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICB2YXIgdm0gPSBvYi52bXNbaV07XG4gICAgICB2bS5fcHJveHkoa2V5KTtcbiAgICAgIHZtLl9kaWdlc3QoKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHZhbDtcbn1cblxuLyoqXG4gKiBEZWxldGUgYSBwcm9wZXJ0eSBhbmQgdHJpZ2dlciBjaGFuZ2UgaWYgbmVjZXNzYXJ5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqL1xuXG5mdW5jdGlvbiBkZWwob2JqLCBrZXkpIHtcbiAgaWYgKCFoYXNPd24ob2JqLCBrZXkpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGRlbGV0ZSBvYmpba2V5XTtcbiAgdmFyIG9iID0gb2JqLl9fb2JfXztcbiAgaWYgKCFvYikge1xuICAgIHJldHVybjtcbiAgfVxuICBvYi5kZXAubm90aWZ5KCk7XG4gIGlmIChvYi52bXMpIHtcbiAgICB2YXIgaSA9IG9iLnZtcy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgdmFyIHZtID0gb2Iudm1zW2ldO1xuICAgICAgdm0uX3VucHJveHkoa2V5KTtcbiAgICAgIHZtLl9kaWdlc3QoKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbi8qKlxuICogQ2hlY2sgd2hldGhlciB0aGUgb2JqZWN0IGhhcyB0aGUgcHJvcGVydHkuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuXG5mdW5jdGlvbiBoYXNPd24ob2JqLCBrZXkpIHtcbiAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGFuIGV4cHJlc3Npb24gaXMgYSBsaXRlcmFsIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBleHBcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cblxudmFyIGxpdGVyYWxWYWx1ZVJFID0gL15cXHM/KHRydWV8ZmFsc2V8LT9bXFxkXFwuXSt8J1teJ10qJ3xcIlteXCJdKlwiKVxccz8kLztcblxuZnVuY3Rpb24gaXNMaXRlcmFsKGV4cCkge1xuICByZXR1cm4gbGl0ZXJhbFZhbHVlUkUudGVzdChleHApO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgc3RyaW5nIHN0YXJ0cyB3aXRoICQgb3IgX1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cblxuZnVuY3Rpb24gaXNSZXNlcnZlZChzdHIpIHtcbiAgdmFyIGMgPSAoc3RyICsgJycpLmNoYXJDb2RlQXQoMCk7XG4gIHJldHVybiBjID09PSAweDI0IHx8IGMgPT09IDB4NUY7XG59XG5cbi8qKlxuICogR3VhcmQgdGV4dCBvdXRwdXQsIG1ha2Ugc3VyZSB1bmRlZmluZWQgb3V0cHV0c1xuICogZW1wdHkgc3RyaW5nXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5cbmZ1bmN0aW9uIF90b1N0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICcnIDogdmFsdWUudG9TdHJpbmcoKTtcbn1cblxuLyoqXG4gKiBDaGVjayBhbmQgY29udmVydCBwb3NzaWJsZSBudW1lcmljIHN0cmluZ3MgdG8gbnVtYmVyc1xuICogYmVmb3JlIHNldHRpbmcgYmFjayB0byBkYXRhXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHJldHVybiB7KnxOdW1iZXJ9XG4gKi9cblxuZnVuY3Rpb24gdG9OdW1iZXIodmFsdWUpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgdmFyIHBhcnNlZCA9IE51bWJlcih2YWx1ZSk7XG4gICAgcmV0dXJuIGlzTmFOKHBhcnNlZCkgPyB2YWx1ZSA6IHBhcnNlZDtcbiAgfVxufVxuXG4vKipcbiAqIENvbnZlcnQgc3RyaW5nIGJvb2xlYW4gbGl0ZXJhbHMgaW50byByZWFsIGJvb2xlYW5zLlxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm4geyp8Qm9vbGVhbn1cbiAqL1xuXG5mdW5jdGlvbiB0b0Jvb2xlYW4odmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlID09PSAndHJ1ZScgPyB0cnVlIDogdmFsdWUgPT09ICdmYWxzZScgPyBmYWxzZSA6IHZhbHVlO1xufVxuXG4vKipcbiAqIFN0cmlwIHF1b3RlcyBmcm9tIGEgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7U3RyaW5nIHwgZmFsc2V9XG4gKi9cblxuZnVuY3Rpb24gc3RyaXBRdW90ZXMoc3RyKSB7XG4gIHZhciBhID0gc3RyLmNoYXJDb2RlQXQoMCk7XG4gIHZhciBiID0gc3RyLmNoYXJDb2RlQXQoc3RyLmxlbmd0aCAtIDEpO1xuICByZXR1cm4gYSA9PT0gYiAmJiAoYSA9PT0gMHgyMiB8fCBhID09PSAweDI3KSA/IHN0ci5zbGljZSgxLCAtMSkgOiBzdHI7XG59XG5cbi8qKlxuICogQ2FtZWxpemUgYSBoeXBoZW4tZGVsbWl0ZWQgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuXG52YXIgY2FtZWxpemVSRSA9IC8tKFxcdykvZztcblxuZnVuY3Rpb24gY2FtZWxpemUoc3RyKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZShjYW1lbGl6ZVJFLCB0b1VwcGVyKTtcbn1cblxuZnVuY3Rpb24gdG9VcHBlcihfLCBjKSB7XG4gIHJldHVybiBjID8gYy50b1VwcGVyQ2FzZSgpIDogJyc7XG59XG5cbi8qKlxuICogSHlwaGVuYXRlIGEgY2FtZWxDYXNlIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cblxudmFyIGh5cGhlbmF0ZVJFID0gLyhbYS16XFxkXSkoW0EtWl0pL2c7XG5cbmZ1bmN0aW9uIGh5cGhlbmF0ZShzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKGh5cGhlbmF0ZVJFLCAnJDEtJDInKS50b0xvd2VyQ2FzZSgpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGh5cGhlbi91bmRlcnNjb3JlL3NsYXNoIGRlbGltaXRlcmVkIG5hbWVzIGludG9cbiAqIGNhbWVsaXplZCBjbGFzc05hbWVzLlxuICpcbiAqIGUuZy4gbXktY29tcG9uZW50ID0+IE15Q29tcG9uZW50XG4gKiAgICAgIHNvbWVfZWxzZSAgICA9PiBTb21lRWxzZVxuICogICAgICBzb21lL2NvbXAgICAgPT4gU29tZUNvbXBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cblxudmFyIGNsYXNzaWZ5UkUgPSAvKD86XnxbLV9cXC9dKShcXHcpL2c7XG5cbmZ1bmN0aW9uIGNsYXNzaWZ5KHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoY2xhc3NpZnlSRSwgdG9VcHBlcik7XG59XG5cbi8qKlxuICogU2ltcGxlIGJpbmQsIGZhc3RlciB0aGFuIG5hdGl2ZVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0ge09iamVjdH0gY3R4XG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5mdW5jdGlvbiBiaW5kKGZuLCBjdHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChhKSB7XG4gICAgdmFyIGwgPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHJldHVybiBsID8gbCA+IDEgPyBmbi5hcHBseShjdHgsIGFyZ3VtZW50cykgOiBmbi5jYWxsKGN0eCwgYSkgOiBmbi5jYWxsKGN0eCk7XG4gIH07XG59XG5cbi8qKlxuICogQ29udmVydCBhbiBBcnJheS1saWtlIG9iamVjdCB0byBhIHJlYWwgQXJyYXkuXG4gKlxuICogQHBhcmFtIHtBcnJheS1saWtlfSBsaXN0XG4gKiBAcGFyYW0ge051bWJlcn0gW3N0YXJ0XSAtIHN0YXJ0IGluZGV4XG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuXG5mdW5jdGlvbiB0b0FycmF5KGxpc3QsIHN0YXJ0KSB7XG4gIHN0YXJ0ID0gc3RhcnQgfHwgMDtcbiAgdmFyIGkgPSBsaXN0Lmxlbmd0aCAtIHN0YXJ0O1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGkpO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgcmV0W2ldID0gbGlzdFtpICsgc3RhcnRdO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogTWl4IHByb3BlcnRpZXMgaW50byB0YXJnZXQgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0b1xuICogQHBhcmFtIHtPYmplY3R9IGZyb21cbiAqL1xuXG5mdW5jdGlvbiBleHRlbmQodG8sIGZyb20pIHtcbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhmcm9tKTtcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIHRvW2tleXNbaV1dID0gZnJvbVtrZXlzW2ldXTtcbiAgfVxuICByZXR1cm4gdG87XG59XG5cbi8qKlxuICogUXVpY2sgb2JqZWN0IGNoZWNrIC0gdGhpcyBpcyBwcmltYXJpbHkgdXNlZCB0byB0ZWxsXG4gKiBPYmplY3RzIGZyb20gcHJpbWl0aXZlIHZhbHVlcyB3aGVuIHdlIGtub3cgdGhlIHZhbHVlXG4gKiBpcyBhIEpTT04tY29tcGxpYW50IHR5cGUuXG4gKlxuICogQHBhcmFtIHsqfSBvYmpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cblxuZnVuY3Rpb24gaXNPYmplY3Qob2JqKSB7XG4gIHJldHVybiBvYmogIT09IG51bGwgJiYgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCc7XG59XG5cbi8qKlxuICogU3RyaWN0IG9iamVjdCB0eXBlIGNoZWNrLiBPbmx5IHJldHVybnMgdHJ1ZVxuICogZm9yIHBsYWluIEphdmFTY3JpcHQgb2JqZWN0cy5cbiAqXG4gKiBAcGFyYW0geyp9IG9ialxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIE9CSkVDVF9TVFJJTkcgPSAnW29iamVjdCBPYmplY3RdJztcblxuZnVuY3Rpb24gaXNQbGFpbk9iamVjdChvYmopIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwob2JqKSA9PT0gT0JKRUNUX1NUUklORztcbn1cblxuLyoqXG4gKiBBcnJheSB0eXBlIGNoZWNrLlxuICpcbiAqIEBwYXJhbSB7Kn0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcblxuLyoqXG4gKiBEZWZpbmUgYSBub24tZW51bWVyYWJsZSBwcm9wZXJ0eVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFtlbnVtZXJhYmxlXVxuICovXG5cbmZ1bmN0aW9uIGRlZihvYmosIGtleSwgdmFsLCBlbnVtZXJhYmxlKSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgIHZhbHVlOiB2YWwsXG4gICAgZW51bWVyYWJsZTogISFlbnVtZXJhYmxlLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICB9KTtcbn1cblxuLyoqXG4gKiBEZWJvdW5jZSBhIGZ1bmN0aW9uIHNvIGl0IG9ubHkgZ2V0cyBjYWxsZWQgYWZ0ZXIgdGhlXG4gKiBpbnB1dCBzdG9wcyBhcnJpdmluZyBhZnRlciB0aGUgZ2l2ZW4gd2FpdCBwZXJpb2QuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY1xuICogQHBhcmFtIHtOdW1iZXJ9IHdhaXRcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSAtIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb25cbiAqL1xuXG5mdW5jdGlvbiBfZGVib3VuY2UoZnVuYywgd2FpdCkge1xuICB2YXIgdGltZW91dCwgYXJncywgY29udGV4dCwgdGltZXN0YW1wLCByZXN1bHQ7XG4gIHZhciBsYXRlciA9IGZ1bmN0aW9uIGxhdGVyKCkge1xuICAgIHZhciBsYXN0ID0gRGF0ZS5ub3coKSAtIHRpbWVzdGFtcDtcbiAgICBpZiAobGFzdCA8IHdhaXQgJiYgbGFzdCA+PSAwKSB7XG4gICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgd2FpdCAtIGxhc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aW1lb3V0ID0gbnVsbDtcbiAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgICBpZiAoIXRpbWVvdXQpIGNvbnRleHQgPSBhcmdzID0gbnVsbDtcbiAgICB9XG4gIH07XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgY29udGV4dCA9IHRoaXM7XG4gICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgIGlmICghdGltZW91dCkge1xuICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHdhaXQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufVxuXG4vKipcbiAqIE1hbnVhbCBpbmRleE9mIGJlY2F1c2UgaXQncyBzbGlnaHRseSBmYXN0ZXIgdGhhblxuICogbmF0aXZlLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGFyclxuICogQHBhcmFtIHsqfSBvYmpcbiAqL1xuXG5mdW5jdGlvbiBpbmRleE9mKGFyciwgb2JqKSB7XG4gIHZhciBpID0gYXJyLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIGlmIChhcnJbaV0gPT09IG9iaikgcmV0dXJuIGk7XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG4vKipcbiAqIE1ha2UgYSBjYW5jZWxsYWJsZSB2ZXJzaW9uIG9mIGFuIGFzeW5jIGNhbGxiYWNrLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5mdW5jdGlvbiBjYW5jZWxsYWJsZShmbikge1xuICB2YXIgY2IgPSBmdW5jdGlvbiBjYigpIHtcbiAgICBpZiAoIWNiLmNhbmNlbGxlZCkge1xuICAgICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuICB9O1xuICBjYi5jYW5jZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgY2IuY2FuY2VsbGVkID0gdHJ1ZTtcbiAgfTtcbiAgcmV0dXJuIGNiO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIHR3byB2YWx1ZXMgYXJlIGxvb3NlbHkgZXF1YWwgLSB0aGF0IGlzLFxuICogaWYgdGhleSBhcmUgcGxhaW4gb2JqZWN0cywgZG8gdGhleSBoYXZlIHRoZSBzYW1lIHNoYXBlP1xuICpcbiAqIEBwYXJhbSB7Kn0gYVxuICogQHBhcmFtIHsqfSBiXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbmZ1bmN0aW9uIGxvb3NlRXF1YWwoYSwgYikge1xuICAvKiBlc2xpbnQtZGlzYWJsZSBlcWVxZXEgKi9cbiAgcmV0dXJuIGEgPT0gYiB8fCAoaXNPYmplY3QoYSkgJiYgaXNPYmplY3QoYikgPyBKU09OLnN0cmluZ2lmeShhKSA9PT0gSlNPTi5zdHJpbmdpZnkoYikgOiBmYWxzZSk7XG4gIC8qIGVzbGludC1lbmFibGUgZXFlcWVxICovXG59XG5cbnZhciBoYXNQcm90byA9ICgnX19wcm90b19fJyBpbiB7fSk7XG5cbi8vIEJyb3dzZXIgZW52aXJvbm1lbnQgc25pZmZpbmdcbnZhciBpbkJyb3dzZXIgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwod2luZG93KSAhPT0gJ1tvYmplY3QgT2JqZWN0XSc7XG5cbi8vIGRldGVjdCBkZXZ0b29sc1xudmFyIGRldnRvb2xzID0gaW5Ccm93c2VyICYmIHdpbmRvdy5fX1ZVRV9ERVZUT09MU19HTE9CQUxfSE9PS19fO1xuXG4vLyBVQSBzbmlmZmluZyBmb3Igd29ya2luZyBhcm91bmQgYnJvd3Nlci1zcGVjaWZpYyBxdWlya3NcbnZhciBVQSA9IGluQnJvd3NlciAmJiB3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpO1xudmFyIGlzSUU5ID0gVUEgJiYgVUEuaW5kZXhPZignbXNpZSA5LjAnKSA+IDA7XG52YXIgaXNBbmRyb2lkID0gVUEgJiYgVUEuaW5kZXhPZignYW5kcm9pZCcpID4gMDtcblxudmFyIHRyYW5zaXRpb25Qcm9wID0gdW5kZWZpbmVkO1xudmFyIHRyYW5zaXRpb25FbmRFdmVudCA9IHVuZGVmaW5lZDtcbnZhciBhbmltYXRpb25Qcm9wID0gdW5kZWZpbmVkO1xudmFyIGFuaW1hdGlvbkVuZEV2ZW50ID0gdW5kZWZpbmVkO1xuXG4vLyBUcmFuc2l0aW9uIHByb3BlcnR5L2V2ZW50IHNuaWZmaW5nXG5pZiAoaW5Ccm93c2VyICYmICFpc0lFOSkge1xuICB2YXIgaXNXZWJraXRUcmFucyA9IHdpbmRvdy5vbnRyYW5zaXRpb25lbmQgPT09IHVuZGVmaW5lZCAmJiB3aW5kb3cub253ZWJraXR0cmFuc2l0aW9uZW5kICE9PSB1bmRlZmluZWQ7XG4gIHZhciBpc1dlYmtpdEFuaW0gPSB3aW5kb3cub25hbmltYXRpb25lbmQgPT09IHVuZGVmaW5lZCAmJiB3aW5kb3cub253ZWJraXRhbmltYXRpb25lbmQgIT09IHVuZGVmaW5lZDtcbiAgdHJhbnNpdGlvblByb3AgPSBpc1dlYmtpdFRyYW5zID8gJ1dlYmtpdFRyYW5zaXRpb24nIDogJ3RyYW5zaXRpb24nO1xuICB0cmFuc2l0aW9uRW5kRXZlbnQgPSBpc1dlYmtpdFRyYW5zID8gJ3dlYmtpdFRyYW5zaXRpb25FbmQnIDogJ3RyYW5zaXRpb25lbmQnO1xuICBhbmltYXRpb25Qcm9wID0gaXNXZWJraXRBbmltID8gJ1dlYmtpdEFuaW1hdGlvbicgOiAnYW5pbWF0aW9uJztcbiAgYW5pbWF0aW9uRW5kRXZlbnQgPSBpc1dlYmtpdEFuaW0gPyAnd2Via2l0QW5pbWF0aW9uRW5kJyA6ICdhbmltYXRpb25lbmQnO1xufVxuXG4vKipcbiAqIERlZmVyIGEgdGFzayB0byBleGVjdXRlIGl0IGFzeW5jaHJvbm91c2x5LiBJZGVhbGx5IHRoaXNcbiAqIHNob3VsZCBiZSBleGVjdXRlZCBhcyBhIG1pY3JvdGFzaywgc28gd2UgbGV2ZXJhZ2VcbiAqIE11dGF0aW9uT2JzZXJ2ZXIgaWYgaXQncyBhdmFpbGFibGUsIGFuZCBmYWxsYmFjayB0b1xuICogc2V0VGltZW91dCgwKS5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYlxuICogQHBhcmFtIHtPYmplY3R9IGN0eFxuICovXG5cbnZhciBuZXh0VGljayA9IChmdW5jdGlvbiAoKSB7XG4gIHZhciBjYWxsYmFja3MgPSBbXTtcbiAgdmFyIHBlbmRpbmcgPSBmYWxzZTtcbiAgdmFyIHRpbWVyRnVuYztcbiAgZnVuY3Rpb24gbmV4dFRpY2tIYW5kbGVyKCkge1xuICAgIHBlbmRpbmcgPSBmYWxzZTtcbiAgICB2YXIgY29waWVzID0gY2FsbGJhY2tzLnNsaWNlKDApO1xuICAgIGNhbGxiYWNrcyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY29waWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb3BpZXNbaV0oKTtcbiAgICB9XG4gIH1cblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKHR5cGVvZiBNdXRhdGlvbk9ic2VydmVyICE9PSAndW5kZWZpbmVkJykge1xuICAgIHZhciBjb3VudGVyID0gMTtcbiAgICB2YXIgb2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihuZXh0VGlja0hhbmRsZXIpO1xuICAgIHZhciB0ZXh0Tm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNvdW50ZXIpO1xuICAgIG9ic2VydmVyLm9ic2VydmUodGV4dE5vZGUsIHtcbiAgICAgIGNoYXJhY3RlckRhdGE6IHRydWVcbiAgICB9KTtcbiAgICB0aW1lckZ1bmMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBjb3VudGVyID0gKGNvdW50ZXIgKyAxKSAlIDI7XG4gICAgICB0ZXh0Tm9kZS5kYXRhID0gY291bnRlcjtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIC8vIHdlYnBhY2sgYXR0ZW1wdHMgdG8gaW5qZWN0IGEgc2hpbSBmb3Igc2V0SW1tZWRpYXRlXG4gICAgLy8gaWYgaXQgaXMgdXNlZCBhcyBhIGdsb2JhbCwgc28gd2UgaGF2ZSB0byB3b3JrIGFyb3VuZCB0aGF0IHRvXG4gICAgLy8gYXZvaWQgYnVuZGxpbmcgdW5uZWNlc3NhcnkgY29kZS5cbiAgICB2YXIgY29udGV4dCA9IGluQnJvd3NlciA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsIDoge307XG4gICAgdGltZXJGdW5jID0gY29udGV4dC5zZXRJbW1lZGlhdGUgfHwgc2V0VGltZW91dDtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24gKGNiLCBjdHgpIHtcbiAgICB2YXIgZnVuYyA9IGN0eCA/IGZ1bmN0aW9uICgpIHtcbiAgICAgIGNiLmNhbGwoY3R4KTtcbiAgICB9IDogY2I7XG4gICAgY2FsbGJhY2tzLnB1c2goZnVuYyk7XG4gICAgaWYgKHBlbmRpbmcpIHJldHVybjtcbiAgICBwZW5kaW5nID0gdHJ1ZTtcbiAgICB0aW1lckZ1bmMobmV4dFRpY2tIYW5kbGVyLCAwKTtcbiAgfTtcbn0pKCk7XG5cbmZ1bmN0aW9uIENhY2hlKGxpbWl0KSB7XG4gIHRoaXMuc2l6ZSA9IDA7XG4gIHRoaXMubGltaXQgPSBsaW1pdDtcbiAgdGhpcy5oZWFkID0gdGhpcy50YWlsID0gdW5kZWZpbmVkO1xuICB0aGlzLl9rZXltYXAgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xufVxuXG52YXIgcCA9IENhY2hlLnByb3RvdHlwZTtcblxuLyoqXG4gKiBQdXQgPHZhbHVlPiBpbnRvIHRoZSBjYWNoZSBhc3NvY2lhdGVkIHdpdGggPGtleT4uXG4gKiBSZXR1cm5zIHRoZSBlbnRyeSB3aGljaCB3YXMgcmVtb3ZlZCB0byBtYWtlIHJvb20gZm9yXG4gKiB0aGUgbmV3IGVudHJ5LiBPdGhlcndpc2UgdW5kZWZpbmVkIGlzIHJldHVybmVkLlxuICogKGkuZS4gaWYgdGhlcmUgd2FzIGVub3VnaCByb29tIGFscmVhZHkpLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEByZXR1cm4ge0VudHJ5fHVuZGVmaW5lZH1cbiAqL1xuXG5wLnB1dCA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gIHZhciByZW1vdmVkO1xuICBpZiAodGhpcy5zaXplID09PSB0aGlzLmxpbWl0KSB7XG4gICAgcmVtb3ZlZCA9IHRoaXMuc2hpZnQoKTtcbiAgfVxuXG4gIHZhciBlbnRyeSA9IHRoaXMuZ2V0KGtleSwgdHJ1ZSk7XG4gIGlmICghZW50cnkpIHtcbiAgICBlbnRyeSA9IHtcbiAgICAgIGtleToga2V5XG4gICAgfTtcbiAgICB0aGlzLl9rZXltYXBba2V5XSA9IGVudHJ5O1xuICAgIGlmICh0aGlzLnRhaWwpIHtcbiAgICAgIHRoaXMudGFpbC5uZXdlciA9IGVudHJ5O1xuICAgICAgZW50cnkub2xkZXIgPSB0aGlzLnRhaWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaGVhZCA9IGVudHJ5O1xuICAgIH1cbiAgICB0aGlzLnRhaWwgPSBlbnRyeTtcbiAgICB0aGlzLnNpemUrKztcbiAgfVxuICBlbnRyeS52YWx1ZSA9IHZhbHVlO1xuXG4gIHJldHVybiByZW1vdmVkO1xufTtcblxuLyoqXG4gKiBQdXJnZSB0aGUgbGVhc3QgcmVjZW50bHkgdXNlZCAob2xkZXN0KSBlbnRyeSBmcm9tIHRoZVxuICogY2FjaGUuIFJldHVybnMgdGhlIHJlbW92ZWQgZW50cnkgb3IgdW5kZWZpbmVkIGlmIHRoZVxuICogY2FjaGUgd2FzIGVtcHR5LlxuICovXG5cbnAuc2hpZnQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBlbnRyeSA9IHRoaXMuaGVhZDtcbiAgaWYgKGVudHJ5KSB7XG4gICAgdGhpcy5oZWFkID0gdGhpcy5oZWFkLm5ld2VyO1xuICAgIHRoaXMuaGVhZC5vbGRlciA9IHVuZGVmaW5lZDtcbiAgICBlbnRyeS5uZXdlciA9IGVudHJ5Lm9sZGVyID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2tleW1hcFtlbnRyeS5rZXldID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuc2l6ZS0tO1xuICB9XG4gIHJldHVybiBlbnRyeTtcbn07XG5cbi8qKlxuICogR2V0IGFuZCByZWdpc3RlciByZWNlbnQgdXNlIG9mIDxrZXk+LiBSZXR1cm5zIHRoZSB2YWx1ZVxuICogYXNzb2NpYXRlZCB3aXRoIDxrZXk+IG9yIHVuZGVmaW5lZCBpZiBub3QgaW4gY2FjaGUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHtCb29sZWFufSByZXR1cm5FbnRyeVxuICogQHJldHVybiB7RW50cnl8Kn1cbiAqL1xuXG5wLmdldCA9IGZ1bmN0aW9uIChrZXksIHJldHVybkVudHJ5KSB7XG4gIHZhciBlbnRyeSA9IHRoaXMuX2tleW1hcFtrZXldO1xuICBpZiAoZW50cnkgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICBpZiAoZW50cnkgPT09IHRoaXMudGFpbCkge1xuICAgIHJldHVybiByZXR1cm5FbnRyeSA/IGVudHJ5IDogZW50cnkudmFsdWU7XG4gIH1cbiAgLy8gSEVBRC0tLS0tLS0tLS0tLS0tVEFJTFxuICAvLyAgIDwub2xkZXIgICAubmV3ZXI+XG4gIC8vICA8LS0tIGFkZCBkaXJlY3Rpb24gLS1cbiAgLy8gICBBICBCICBDICA8RD4gIEVcbiAgaWYgKGVudHJ5Lm5ld2VyKSB7XG4gICAgaWYgKGVudHJ5ID09PSB0aGlzLmhlYWQpIHtcbiAgICAgIHRoaXMuaGVhZCA9IGVudHJ5Lm5ld2VyO1xuICAgIH1cbiAgICBlbnRyeS5uZXdlci5vbGRlciA9IGVudHJ5Lm9sZGVyOyAvLyBDIDwtLSBFLlxuICB9XG4gIGlmIChlbnRyeS5vbGRlcikge1xuICAgIGVudHJ5Lm9sZGVyLm5ld2VyID0gZW50cnkubmV3ZXI7IC8vIEMuIC0tPiBFXG4gIH1cbiAgZW50cnkubmV3ZXIgPSB1bmRlZmluZWQ7IC8vIEQgLS14XG4gIGVudHJ5Lm9sZGVyID0gdGhpcy50YWlsOyAvLyBELiAtLT4gRVxuICBpZiAodGhpcy50YWlsKSB7XG4gICAgdGhpcy50YWlsLm5ld2VyID0gZW50cnk7IC8vIEUuIDwtLSBEXG4gIH1cbiAgdGhpcy50YWlsID0gZW50cnk7XG4gIHJldHVybiByZXR1cm5FbnRyeSA/IGVudHJ5IDogZW50cnkudmFsdWU7XG59O1xuXG52YXIgY2FjaGUkMSA9IG5ldyBDYWNoZSgxMDAwKTtcbnZhciBmaWx0ZXJUb2tlblJFID0gL1teXFxzJ1wiXSt8J1teJ10qJ3xcIlteXCJdKlwiL2c7XG52YXIgcmVzZXJ2ZWRBcmdSRSA9IC9eaW4kfF4tP1xcZCsvO1xuXG4vKipcbiAqIFBhcnNlciBzdGF0ZVxuICovXG5cbnZhciBzdHI7XG52YXIgZGlyO1xudmFyIGM7XG52YXIgcHJldjtcbnZhciBpO1xudmFyIGw7XG52YXIgbGFzdEZpbHRlckluZGV4O1xudmFyIGluU2luZ2xlO1xudmFyIGluRG91YmxlO1xudmFyIGN1cmx5O1xudmFyIHNxdWFyZTtcbnZhciBwYXJlbjtcbi8qKlxuICogUHVzaCBhIGZpbHRlciB0byB0aGUgY3VycmVudCBkaXJlY3RpdmUgb2JqZWN0XG4gKi9cblxuZnVuY3Rpb24gcHVzaEZpbHRlcigpIHtcbiAgdmFyIGV4cCA9IHN0ci5zbGljZShsYXN0RmlsdGVySW5kZXgsIGkpLnRyaW0oKTtcbiAgdmFyIGZpbHRlcjtcbiAgaWYgKGV4cCkge1xuICAgIGZpbHRlciA9IHt9O1xuICAgIHZhciB0b2tlbnMgPSBleHAubWF0Y2goZmlsdGVyVG9rZW5SRSk7XG4gICAgZmlsdGVyLm5hbWUgPSB0b2tlbnNbMF07XG4gICAgaWYgKHRva2Vucy5sZW5ndGggPiAxKSB7XG4gICAgICBmaWx0ZXIuYXJncyA9IHRva2Vucy5zbGljZSgxKS5tYXAocHJvY2Vzc0ZpbHRlckFyZyk7XG4gICAgfVxuICB9XG4gIGlmIChmaWx0ZXIpIHtcbiAgICAoZGlyLmZpbHRlcnMgPSBkaXIuZmlsdGVycyB8fCBbXSkucHVzaChmaWx0ZXIpO1xuICB9XG4gIGxhc3RGaWx0ZXJJbmRleCA9IGkgKyAxO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGFuIGFyZ3VtZW50IGlzIGR5bmFtaWMgYW5kIHN0cmlwIHF1b3Rlcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gYXJnXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cblxuZnVuY3Rpb24gcHJvY2Vzc0ZpbHRlckFyZyhhcmcpIHtcbiAgaWYgKHJlc2VydmVkQXJnUkUudGVzdChhcmcpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbHVlOiB0b051bWJlcihhcmcpLFxuICAgICAgZHluYW1pYzogZmFsc2VcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHZhciBzdHJpcHBlZCA9IHN0cmlwUXVvdGVzKGFyZyk7XG4gICAgdmFyIGR5bmFtaWMgPSBzdHJpcHBlZCA9PT0gYXJnO1xuICAgIHJldHVybiB7XG4gICAgICB2YWx1ZTogZHluYW1pYyA/IGFyZyA6IHN0cmlwcGVkLFxuICAgICAgZHluYW1pYzogZHluYW1pY1xuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBQYXJzZSBhIGRpcmVjdGl2ZSB2YWx1ZSBhbmQgZXh0cmFjdCB0aGUgZXhwcmVzc2lvblxuICogYW5kIGl0cyBmaWx0ZXJzIGludG8gYSBkZXNjcmlwdG9yLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogXCJhICsgMSB8IHVwcGVyY2FzZVwiIHdpbGwgeWllbGQ6XG4gKiB7XG4gKiAgIGV4cHJlc3Npb246ICdhICsgMScsXG4gKiAgIGZpbHRlcnM6IFtcbiAqICAgICB7IG5hbWU6ICd1cHBlcmNhc2UnLCBhcmdzOiBudWxsIH1cbiAqICAgXVxuICogfVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuXG5mdW5jdGlvbiBwYXJzZURpcmVjdGl2ZShzKSB7XG4gIHZhciBoaXQgPSBjYWNoZSQxLmdldChzKTtcbiAgaWYgKGhpdCkge1xuICAgIHJldHVybiBoaXQ7XG4gIH1cblxuICAvLyByZXNldCBwYXJzZXIgc3RhdGVcbiAgc3RyID0gcztcbiAgaW5TaW5nbGUgPSBpbkRvdWJsZSA9IGZhbHNlO1xuICBjdXJseSA9IHNxdWFyZSA9IHBhcmVuID0gMDtcbiAgbGFzdEZpbHRlckluZGV4ID0gMDtcbiAgZGlyID0ge307XG5cbiAgZm9yIChpID0gMCwgbCA9IHN0ci5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBwcmV2ID0gYztcbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSk7XG4gICAgaWYgKGluU2luZ2xlKSB7XG4gICAgICAvLyBjaGVjayBzaW5nbGUgcXVvdGVcbiAgICAgIGlmIChjID09PSAweDI3ICYmIHByZXYgIT09IDB4NUMpIGluU2luZ2xlID0gIWluU2luZ2xlO1xuICAgIH0gZWxzZSBpZiAoaW5Eb3VibGUpIHtcbiAgICAgIC8vIGNoZWNrIGRvdWJsZSBxdW90ZVxuICAgICAgaWYgKGMgPT09IDB4MjIgJiYgcHJldiAhPT0gMHg1QykgaW5Eb3VibGUgPSAhaW5Eb3VibGU7XG4gICAgfSBlbHNlIGlmIChjID09PSAweDdDICYmIC8vIHBpcGVcbiAgICBzdHIuY2hhckNvZGVBdChpICsgMSkgIT09IDB4N0MgJiYgc3RyLmNoYXJDb2RlQXQoaSAtIDEpICE9PSAweDdDKSB7XG4gICAgICBpZiAoZGlyLmV4cHJlc3Npb24gPT0gbnVsbCkge1xuICAgICAgICAvLyBmaXJzdCBmaWx0ZXIsIGVuZCBvZiBleHByZXNzaW9uXG4gICAgICAgIGxhc3RGaWx0ZXJJbmRleCA9IGkgKyAxO1xuICAgICAgICBkaXIuZXhwcmVzc2lvbiA9IHN0ci5zbGljZSgwLCBpKS50cmltKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBhbHJlYWR5IGhhcyBmaWx0ZXJcbiAgICAgICAgcHVzaEZpbHRlcigpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzd2l0Y2ggKGMpIHtcbiAgICAgICAgY2FzZSAweDIyOlxuICAgICAgICAgIGluRG91YmxlID0gdHJ1ZTticmVhazsgLy8gXCJcbiAgICAgICAgY2FzZSAweDI3OlxuICAgICAgICAgIGluU2luZ2xlID0gdHJ1ZTticmVhazsgLy8gJ1xuICAgICAgICBjYXNlIDB4Mjg6XG4gICAgICAgICAgcGFyZW4rKzticmVhazsgLy8gKFxuICAgICAgICBjYXNlIDB4Mjk6XG4gICAgICAgICAgcGFyZW4tLTticmVhazsgLy8gKVxuICAgICAgICBjYXNlIDB4NUI6XG4gICAgICAgICAgc3F1YXJlKys7YnJlYWs7IC8vIFtcbiAgICAgICAgY2FzZSAweDVEOlxuICAgICAgICAgIHNxdWFyZS0tO2JyZWFrOyAvLyBdXG4gICAgICAgIGNhc2UgMHg3QjpcbiAgICAgICAgICBjdXJseSsrO2JyZWFrOyAvLyB7XG4gICAgICAgIGNhc2UgMHg3RDpcbiAgICAgICAgICBjdXJseS0tO2JyZWFrOyAvLyB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGRpci5leHByZXNzaW9uID09IG51bGwpIHtcbiAgICBkaXIuZXhwcmVzc2lvbiA9IHN0ci5zbGljZSgwLCBpKS50cmltKCk7XG4gIH0gZWxzZSBpZiAobGFzdEZpbHRlckluZGV4ICE9PSAwKSB7XG4gICAgcHVzaEZpbHRlcigpO1xuICB9XG5cbiAgY2FjaGUkMS5wdXQocywgZGlyKTtcbiAgcmV0dXJuIGRpcjtcbn1cblxudmFyIGRpcmVjdGl2ZSA9IE9iamVjdC5mcmVlemUoe1xuICBwYXJzZURpcmVjdGl2ZTogcGFyc2VEaXJlY3RpdmVcbn0pO1xuXG52YXIgcmVnZXhFc2NhcGVSRSA9IC9bLS4qKz9eJHt9KCl8W1xcXVxcL1xcXFxdL2c7XG52YXIgY2FjaGUgPSB1bmRlZmluZWQ7XG52YXIgdGFnUkUgPSB1bmRlZmluZWQ7XG52YXIgaHRtbFJFID0gdW5kZWZpbmVkO1xuLyoqXG4gKiBFc2NhcGUgYSBzdHJpbmcgc28gaXQgY2FuIGJlIHVzZWQgaW4gYSBSZWdFeHBcbiAqIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqL1xuXG5mdW5jdGlvbiBlc2NhcGVSZWdleChzdHIpIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKHJlZ2V4RXNjYXBlUkUsICdcXFxcJCYnKTtcbn1cblxuZnVuY3Rpb24gY29tcGlsZVJlZ2V4KCkge1xuICB2YXIgb3BlbiA9IGVzY2FwZVJlZ2V4KGNvbmZpZy5kZWxpbWl0ZXJzWzBdKTtcbiAgdmFyIGNsb3NlID0gZXNjYXBlUmVnZXgoY29uZmlnLmRlbGltaXRlcnNbMV0pO1xuICB2YXIgdW5zYWZlT3BlbiA9IGVzY2FwZVJlZ2V4KGNvbmZpZy51bnNhZmVEZWxpbWl0ZXJzWzBdKTtcbiAgdmFyIHVuc2FmZUNsb3NlID0gZXNjYXBlUmVnZXgoY29uZmlnLnVuc2FmZURlbGltaXRlcnNbMV0pO1xuICB0YWdSRSA9IG5ldyBSZWdFeHAodW5zYWZlT3BlbiArICcoLis/KScgKyB1bnNhZmVDbG9zZSArICd8JyArIG9wZW4gKyAnKC4rPyknICsgY2xvc2UsICdnJyk7XG4gIGh0bWxSRSA9IG5ldyBSZWdFeHAoJ14nICsgdW5zYWZlT3BlbiArICcuKicgKyB1bnNhZmVDbG9zZSArICckJyk7XG4gIC8vIHJlc2V0IGNhY2hlXG4gIGNhY2hlID0gbmV3IENhY2hlKDEwMDApO1xufVxuXG4vKipcbiAqIFBhcnNlIGEgdGVtcGxhdGUgdGV4dCBzdHJpbmcgaW50byBhbiBhcnJheSBvZiB0b2tlbnMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHRleHRcbiAqIEByZXR1cm4ge0FycmF5PE9iamVjdD4gfCBudWxsfVxuICogICAgICAgICAgICAgICAtIHtTdHJpbmd9IHR5cGVcbiAqICAgICAgICAgICAgICAgLSB7U3RyaW5nfSB2YWx1ZVxuICogICAgICAgICAgICAgICAtIHtCb29sZWFufSBbaHRtbF1cbiAqICAgICAgICAgICAgICAgLSB7Qm9vbGVhbn0gW29uZVRpbWVdXG4gKi9cblxuZnVuY3Rpb24gcGFyc2VUZXh0KHRleHQpIHtcbiAgaWYgKCFjYWNoZSkge1xuICAgIGNvbXBpbGVSZWdleCgpO1xuICB9XG4gIHZhciBoaXQgPSBjYWNoZS5nZXQodGV4dCk7XG4gIGlmIChoaXQpIHtcbiAgICByZXR1cm4gaGl0O1xuICB9XG4gIHRleHQgPSB0ZXh0LnJlcGxhY2UoL1xcbi9nLCAnJyk7XG4gIGlmICghdGFnUkUudGVzdCh0ZXh0KSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHZhciB0b2tlbnMgPSBbXTtcbiAgdmFyIGxhc3RJbmRleCA9IHRhZ1JFLmxhc3RJbmRleCA9IDA7XG4gIHZhciBtYXRjaCwgaW5kZXgsIGh0bWwsIHZhbHVlLCBmaXJzdCwgb25lVGltZTtcbiAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uZC1hc3NpZ24gKi9cbiAgd2hpbGUgKG1hdGNoID0gdGFnUkUuZXhlYyh0ZXh0KSkge1xuICAgIC8qIGVzbGludC1lbmFibGUgbm8tY29uZC1hc3NpZ24gKi9cbiAgICBpbmRleCA9IG1hdGNoLmluZGV4O1xuICAgIC8vIHB1c2ggdGV4dCB0b2tlblxuICAgIGlmIChpbmRleCA+IGxhc3RJbmRleCkge1xuICAgICAgdG9rZW5zLnB1c2goe1xuICAgICAgICB2YWx1ZTogdGV4dC5zbGljZShsYXN0SW5kZXgsIGluZGV4KVxuICAgICAgfSk7XG4gICAgfVxuICAgIC8vIHRhZyB0b2tlblxuICAgIGh0bWwgPSBodG1sUkUudGVzdChtYXRjaFswXSk7XG4gICAgdmFsdWUgPSBodG1sID8gbWF0Y2hbMV0gOiBtYXRjaFsyXTtcbiAgICBmaXJzdCA9IHZhbHVlLmNoYXJDb2RlQXQoMCk7XG4gICAgb25lVGltZSA9IGZpcnN0ID09PSA0MjsgLy8gKlxuICAgIHZhbHVlID0gb25lVGltZSA/IHZhbHVlLnNsaWNlKDEpIDogdmFsdWU7XG4gICAgdG9rZW5zLnB1c2goe1xuICAgICAgdGFnOiB0cnVlLFxuICAgICAgdmFsdWU6IHZhbHVlLnRyaW0oKSxcbiAgICAgIGh0bWw6IGh0bWwsXG4gICAgICBvbmVUaW1lOiBvbmVUaW1lXG4gICAgfSk7XG4gICAgbGFzdEluZGV4ID0gaW5kZXggKyBtYXRjaFswXS5sZW5ndGg7XG4gIH1cbiAgaWYgKGxhc3RJbmRleCA8IHRleHQubGVuZ3RoKSB7XG4gICAgdG9rZW5zLnB1c2goe1xuICAgICAgdmFsdWU6IHRleHQuc2xpY2UobGFzdEluZGV4KVxuICAgIH0pO1xuICB9XG4gIGNhY2hlLnB1dCh0ZXh0LCB0b2tlbnMpO1xuICByZXR1cm4gdG9rZW5zO1xufVxuXG4vKipcbiAqIEZvcm1hdCBhIGxpc3Qgb2YgdG9rZW5zIGludG8gYW4gZXhwcmVzc2lvbi5cbiAqIGUuZy4gdG9rZW5zIHBhcnNlZCBmcm9tICdhIHt7Yn19IGMnIGNhbiBiZSBzZXJpYWxpemVkXG4gKiBpbnRvIG9uZSBzaW5nbGUgZXhwcmVzc2lvbiBhcyAnXCJhIFwiICsgYiArIFwiIGNcIicuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gdG9rZW5zXG4gKiBAcGFyYW0ge1Z1ZX0gW3ZtXVxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5cbmZ1bmN0aW9uIHRva2Vuc1RvRXhwKHRva2Vucywgdm0pIHtcbiAgaWYgKHRva2Vucy5sZW5ndGggPiAxKSB7XG4gICAgcmV0dXJuIHRva2Vucy5tYXAoZnVuY3Rpb24gKHRva2VuKSB7XG4gICAgICByZXR1cm4gZm9ybWF0VG9rZW4odG9rZW4sIHZtKTtcbiAgICB9KS5qb2luKCcrJyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZvcm1hdFRva2VuKHRva2Vuc1swXSwgdm0sIHRydWUpO1xuICB9XG59XG5cbi8qKlxuICogRm9ybWF0IGEgc2luZ2xlIHRva2VuLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0b2tlblxuICogQHBhcmFtIHtWdWV9IFt2bV1cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW3NpbmdsZV1cbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBmb3JtYXRUb2tlbih0b2tlbiwgdm0sIHNpbmdsZSkge1xuICByZXR1cm4gdG9rZW4udGFnID8gdG9rZW4ub25lVGltZSAmJiB2bSA/ICdcIicgKyB2bS4kZXZhbCh0b2tlbi52YWx1ZSkgKyAnXCInIDogaW5saW5lRmlsdGVycyh0b2tlbi52YWx1ZSwgc2luZ2xlKSA6ICdcIicgKyB0b2tlbi52YWx1ZSArICdcIic7XG59XG5cbi8qKlxuICogRm9yIGFuIGF0dHJpYnV0ZSB3aXRoIG11bHRpcGxlIGludGVycG9sYXRpb24gdGFncyxcbiAqIGUuZy4gYXR0cj1cInNvbWUte3t0aGluZyB8IGZpbHRlcn19XCIsIGluIG9yZGVyIHRvIGNvbWJpbmVcbiAqIHRoZSB3aG9sZSB0aGluZyBpbnRvIGEgc2luZ2xlIHdhdGNoYWJsZSBleHByZXNzaW9uLCB3ZVxuICogaGF2ZSB0byBpbmxpbmUgdGhvc2UgZmlsdGVycy4gVGhpcyBmdW5jdGlvbiBkb2VzIGV4YWN0bHlcbiAqIHRoYXQuIFRoaXMgaXMgYSBiaXQgaGFja3kgYnV0IGl0IGF2b2lkcyBoZWF2eSBjaGFuZ2VzXG4gKiB0byBkaXJlY3RpdmUgcGFyc2VyIGFuZCB3YXRjaGVyIG1lY2hhbmlzbS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXhwXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHNpbmdsZVxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5cbnZhciBmaWx0ZXJSRSA9IC9bXnxdXFx8W158XS87XG5mdW5jdGlvbiBpbmxpbmVGaWx0ZXJzKGV4cCwgc2luZ2xlKSB7XG4gIGlmICghZmlsdGVyUkUudGVzdChleHApKSB7XG4gICAgcmV0dXJuIHNpbmdsZSA/IGV4cCA6ICcoJyArIGV4cCArICcpJztcbiAgfSBlbHNlIHtcbiAgICB2YXIgZGlyID0gcGFyc2VEaXJlY3RpdmUoZXhwKTtcbiAgICBpZiAoIWRpci5maWx0ZXJzKSB7XG4gICAgICByZXR1cm4gJygnICsgZXhwICsgJyknO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gJ3RoaXMuX2FwcGx5RmlsdGVycygnICsgZGlyLmV4cHJlc3Npb24gKyAvLyB2YWx1ZVxuICAgICAgJyxudWxsLCcgKyAvLyBvbGRWYWx1ZSAobnVsbCBmb3IgcmVhZClcbiAgICAgIEpTT04uc3RyaW5naWZ5KGRpci5maWx0ZXJzKSArIC8vIGZpbHRlciBkZXNjcmlwdG9yc1xuICAgICAgJyxmYWxzZSknOyAvLyB3cml0ZT9cbiAgICB9XG4gIH1cbn1cblxudmFyIHRleHQgPSBPYmplY3QuZnJlZXplKHtcbiAgY29tcGlsZVJlZ2V4OiBjb21waWxlUmVnZXgsXG4gIHBhcnNlVGV4dDogcGFyc2VUZXh0LFxuICB0b2tlbnNUb0V4cDogdG9rZW5zVG9FeHBcbn0pO1xuXG52YXIgZGVsaW1pdGVycyA9IFsne3snLCAnfX0nXTtcbnZhciB1bnNhZmVEZWxpbWl0ZXJzID0gWyd7e3snLCAnfX19J107XG5cbnZhciBjb25maWcgPSBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gcHJpbnQgZGVidWcgbWVzc2FnZXMuXG4gICAqIEFsc28gZW5hYmxlcyBzdGFjayB0cmFjZSBmb3Igd2FybmluZ3MuXG4gICAqXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKi9cblxuICBkZWJ1ZzogZmFsc2UsXG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gc3VwcHJlc3Mgd2FybmluZ3MuXG4gICAqXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKi9cblxuICBzaWxlbnQ6IGZhbHNlLFxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHVzZSBhc3luYyByZW5kZXJpbmcuXG4gICAqL1xuXG4gIGFzeW5jOiB0cnVlLFxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHdhcm4gYWdhaW5zdCBlcnJvcnMgY2F1Z2h0IHdoZW4gZXZhbHVhdGluZ1xuICAgKiBleHByZXNzaW9ucy5cbiAgICovXG5cbiAgd2FybkV4cHJlc3Npb25FcnJvcnM6IHRydWUsXG5cbiAgLyoqXG4gICAqIEludGVybmFsIGZsYWcgdG8gaW5kaWNhdGUgdGhlIGRlbGltaXRlcnMgaGF2ZSBiZWVuXG4gICAqIGNoYW5nZWQuXG4gICAqXG4gICAqIEB0eXBlIHtCb29sZWFufVxuICAgKi9cblxuICBfZGVsaW1pdGVyc0NoYW5nZWQ6IHRydWUsXG5cbiAgLyoqXG4gICAqIExpc3Qgb2YgYXNzZXQgdHlwZXMgdGhhdCBhIGNvbXBvbmVudCBjYW4gb3duLlxuICAgKlxuICAgKiBAdHlwZSB7QXJyYXl9XG4gICAqL1xuXG4gIF9hc3NldFR5cGVzOiBbJ2NvbXBvbmVudCcsICdkaXJlY3RpdmUnLCAnZWxlbWVudERpcmVjdGl2ZScsICdmaWx0ZXInLCAndHJhbnNpdGlvbicsICdwYXJ0aWFsJ10sXG5cbiAgLyoqXG4gICAqIHByb3AgYmluZGluZyBtb2Rlc1xuICAgKi9cblxuICBfcHJvcEJpbmRpbmdNb2Rlczoge1xuICAgIE9ORV9XQVk6IDAsXG4gICAgVFdPX1dBWTogMSxcbiAgICBPTkVfVElNRTogMlxuICB9LFxuXG4gIC8qKlxuICAgKiBNYXggY2lyY3VsYXIgdXBkYXRlcyBhbGxvd2VkIGluIGEgYmF0Y2hlciBmbHVzaCBjeWNsZS5cbiAgICovXG5cbiAgX21heFVwZGF0ZUNvdW50OiAxMDBcblxufSwge1xuICBkZWxpbWl0ZXJzOiB7IC8qKlxuICAgICAgICAgICAgICAgICAqIEludGVycG9sYXRpb24gZGVsaW1pdGVycy4gQ2hhbmdpbmcgdGhlc2Ugd291bGQgdHJpZ2dlclxuICAgICAgICAgICAgICAgICAqIHRoZSB0ZXh0IHBhcnNlciB0byByZS1jb21waWxlIHRoZSByZWd1bGFyIGV4cHJlc3Npb25zLlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogQHR5cGUge0FycmF5PFN0cmluZz59XG4gICAgICAgICAgICAgICAgICovXG5cbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiBkZWxpbWl0ZXJzO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbiBzZXQodmFsKSB7XG4gICAgICBkZWxpbWl0ZXJzID0gdmFsO1xuICAgICAgY29tcGlsZVJlZ2V4KCk7XG4gICAgfSxcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZW51bWVyYWJsZTogdHJ1ZVxuICB9LFxuICB1bnNhZmVEZWxpbWl0ZXJzOiB7XG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdW5zYWZlRGVsaW1pdGVycztcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24gc2V0KHZhbCkge1xuICAgICAgdW5zYWZlRGVsaW1pdGVycyA9IHZhbDtcbiAgICAgIGNvbXBpbGVSZWdleCgpO1xuICAgIH0sXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGVudW1lcmFibGU6IHRydWVcbiAgfVxufSk7XG5cbnZhciB3YXJuID0gdW5kZWZpbmVkO1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBoYXNDb25zb2xlID0gdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnO1xuICAgIHdhcm4gPSBmdW5jdGlvbiAobXNnLCBlKSB7XG4gICAgICBpZiAoaGFzQ29uc29sZSAmJiAoIWNvbmZpZy5zaWxlbnQgfHwgY29uZmlnLmRlYnVnKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oJ1tWdWUgd2Fybl06ICcgKyBtc2cpO1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgICAgICAgIGlmIChlKSB7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4obmV3IEVycm9yKCdXYXJuaW5nIFN0YWNrIFRyYWNlJykuc3RhY2spO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH0pKCk7XG59XG5cbi8qKlxuICogQXBwZW5kIHdpdGggdHJhbnNpdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldFxuICogQHBhcmFtIHtWdWV9IHZtXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2JdXG4gKi9cblxuZnVuY3Rpb24gYXBwZW5kV2l0aFRyYW5zaXRpb24oZWwsIHRhcmdldCwgdm0sIGNiKSB7XG4gIGFwcGx5VHJhbnNpdGlvbihlbCwgMSwgZnVuY3Rpb24gKCkge1xuICAgIHRhcmdldC5hcHBlbmRDaGlsZChlbCk7XG4gIH0sIHZtLCBjYik7XG59XG5cbi8qKlxuICogSW5zZXJ0QmVmb3JlIHdpdGggdHJhbnNpdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldFxuICogQHBhcmFtIHtWdWV9IHZtXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2JdXG4gKi9cblxuZnVuY3Rpb24gYmVmb3JlV2l0aFRyYW5zaXRpb24oZWwsIHRhcmdldCwgdm0sIGNiKSB7XG4gIGFwcGx5VHJhbnNpdGlvbihlbCwgMSwgZnVuY3Rpb24gKCkge1xuICAgIGJlZm9yZShlbCwgdGFyZ2V0KTtcbiAgfSwgdm0sIGNiKTtcbn1cblxuLyoqXG4gKiBSZW1vdmUgd2l0aCB0cmFuc2l0aW9uLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7VnVlfSB2bVxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NiXVxuICovXG5cbmZ1bmN0aW9uIHJlbW92ZVdpdGhUcmFuc2l0aW9uKGVsLCB2bSwgY2IpIHtcbiAgYXBwbHlUcmFuc2l0aW9uKGVsLCAtMSwgZnVuY3Rpb24gKCkge1xuICAgIHJlbW92ZShlbCk7XG4gIH0sIHZtLCBjYik7XG59XG5cbi8qKlxuICogQXBwbHkgdHJhbnNpdGlvbnMgd2l0aCBhbiBvcGVyYXRpb24gY2FsbGJhY2suXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtOdW1iZXJ9IGRpcmVjdGlvblxuICogICAgICAgICAgICAgICAgICAxOiBlbnRlclxuICogICAgICAgICAgICAgICAgIC0xOiBsZWF2ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gb3AgLSB0aGUgYWN0dWFsIERPTSBvcGVyYXRpb25cbiAqIEBwYXJhbSB7VnVlfSB2bVxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NiXVxuICovXG5cbmZ1bmN0aW9uIGFwcGx5VHJhbnNpdGlvbihlbCwgZGlyZWN0aW9uLCBvcCwgdm0sIGNiKSB7XG4gIHZhciB0cmFuc2l0aW9uID0gZWwuX192X3RyYW5zO1xuICBpZiAoIXRyYW5zaXRpb24gfHxcbiAgLy8gc2tpcCBpZiB0aGVyZSBhcmUgbm8ganMgaG9va3MgYW5kIENTUyB0cmFuc2l0aW9uIGlzXG4gIC8vIG5vdCBzdXBwb3J0ZWRcbiAgIXRyYW5zaXRpb24uaG9va3MgJiYgIXRyYW5zaXRpb25FbmRFdmVudCB8fFxuICAvLyBza2lwIHRyYW5zaXRpb25zIGZvciBpbml0aWFsIGNvbXBpbGVcbiAgIXZtLl9pc0NvbXBpbGVkIHx8XG4gIC8vIGlmIHRoZSB2bSBpcyBiZWluZyBtYW5pcHVsYXRlZCBieSBhIHBhcmVudCBkaXJlY3RpdmVcbiAgLy8gZHVyaW5nIHRoZSBwYXJlbnQncyBjb21waWxhdGlvbiBwaGFzZSwgc2tpcCB0aGVcbiAgLy8gYW5pbWF0aW9uLlxuICB2bS4kcGFyZW50ICYmICF2bS4kcGFyZW50Ll9pc0NvbXBpbGVkKSB7XG4gICAgb3AoKTtcbiAgICBpZiAoY2IpIGNiKCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBhY3Rpb24gPSBkaXJlY3Rpb24gPiAwID8gJ2VudGVyJyA6ICdsZWF2ZSc7XG4gIHRyYW5zaXRpb25bYWN0aW9uXShvcCwgY2IpO1xufVxuXG52YXIgdHJhbnNpdGlvbiA9IE9iamVjdC5mcmVlemUoe1xuICBhcHBlbmRXaXRoVHJhbnNpdGlvbjogYXBwZW5kV2l0aFRyYW5zaXRpb24sXG4gIGJlZm9yZVdpdGhUcmFuc2l0aW9uOiBiZWZvcmVXaXRoVHJhbnNpdGlvbixcbiAgcmVtb3ZlV2l0aFRyYW5zaXRpb246IHJlbW92ZVdpdGhUcmFuc2l0aW9uLFxuICBhcHBseVRyYW5zaXRpb246IGFwcGx5VHJhbnNpdGlvblxufSk7XG5cbi8qKlxuICogUXVlcnkgYW4gZWxlbWVudCBzZWxlY3RvciBpZiBpdCdzIG5vdCBhbiBlbGVtZW50IGFscmVhZHkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8RWxlbWVudH0gZWxcbiAqIEByZXR1cm4ge0VsZW1lbnR9XG4gKi9cblxuZnVuY3Rpb24gcXVlcnkoZWwpIHtcbiAgaWYgKHR5cGVvZiBlbCA9PT0gJ3N0cmluZycpIHtcbiAgICB2YXIgc2VsZWN0b3IgPSBlbDtcbiAgICBlbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWwpO1xuICAgIGlmICghZWwpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybignQ2Fubm90IGZpbmQgZWxlbWVudDogJyArIHNlbGVjdG9yKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGVsO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGEgbm9kZSBpcyBpbiB0aGUgZG9jdW1lbnQuXG4gKiBOb3RlOiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY29udGFpbnMgc2hvdWxkIHdvcmsgaGVyZVxuICogYnV0IGFsd2F5cyByZXR1cm5zIGZhbHNlIGZvciBjb21tZW50IG5vZGVzIGluIHBoYW50b21qcyxcbiAqIG1ha2luZyB1bml0IHRlc3RzIGRpZmZpY3VsdC4gVGhpcyBpcyBmaXhlZCBieSBkb2luZyB0aGVcbiAqIGNvbnRhaW5zKCkgY2hlY2sgb24gdGhlIG5vZGUncyBwYXJlbnROb2RlIGluc3RlYWQgb2ZcbiAqIHRoZSBub2RlIGl0c2VsZi5cbiAqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cblxuZnVuY3Rpb24gaW5Eb2Mobm9kZSkge1xuICB2YXIgZG9jID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICB2YXIgcGFyZW50ID0gbm9kZSAmJiBub2RlLnBhcmVudE5vZGU7XG4gIHJldHVybiBkb2MgPT09IG5vZGUgfHwgZG9jID09PSBwYXJlbnQgfHwgISEocGFyZW50ICYmIHBhcmVudC5ub2RlVHlwZSA9PT0gMSAmJiBkb2MuY29udGFpbnMocGFyZW50KSk7XG59XG5cbi8qKlxuICogR2V0IGFuZCByZW1vdmUgYW4gYXR0cmlidXRlIGZyb20gYSBub2RlLlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICogQHBhcmFtIHtTdHJpbmd9IF9hdHRyXG4gKi9cblxuZnVuY3Rpb24gZ2V0QXR0cihub2RlLCBfYXR0cikge1xuICB2YXIgdmFsID0gbm9kZS5nZXRBdHRyaWJ1dGUoX2F0dHIpO1xuICBpZiAodmFsICE9PSBudWxsKSB7XG4gICAgbm9kZS5yZW1vdmVBdHRyaWJ1dGUoX2F0dHIpO1xuICB9XG4gIHJldHVybiB2YWw7XG59XG5cbi8qKlxuICogR2V0IGFuIGF0dHJpYnV0ZSB3aXRoIGNvbG9uIG9yIHYtYmluZDogcHJlZml4LlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEByZXR1cm4ge1N0cmluZ3xudWxsfVxuICovXG5cbmZ1bmN0aW9uIGdldEJpbmRBdHRyKG5vZGUsIG5hbWUpIHtcbiAgdmFyIHZhbCA9IGdldEF0dHIobm9kZSwgJzonICsgbmFtZSk7XG4gIGlmICh2YWwgPT09IG51bGwpIHtcbiAgICB2YWwgPSBnZXRBdHRyKG5vZGUsICd2LWJpbmQ6JyArIG5hbWUpO1xuICB9XG4gIHJldHVybiB2YWw7XG59XG5cbi8qKlxuICogQ2hlY2sgdGhlIHByZXNlbmNlIG9mIGEgYmluZCBhdHRyaWJ1dGUuXG4gKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuXG5mdW5jdGlvbiBoYXNCaW5kQXR0cihub2RlLCBuYW1lKSB7XG4gIHJldHVybiBub2RlLmhhc0F0dHJpYnV0ZShuYW1lKSB8fCBub2RlLmhhc0F0dHJpYnV0ZSgnOicgKyBuYW1lKSB8fCBub2RlLmhhc0F0dHJpYnV0ZSgndi1iaW5kOicgKyBuYW1lKTtcbn1cblxuLyoqXG4gKiBJbnNlcnQgZWwgYmVmb3JlIHRhcmdldFxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0XG4gKi9cblxuZnVuY3Rpb24gYmVmb3JlKGVsLCB0YXJnZXQpIHtcbiAgdGFyZ2V0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVsLCB0YXJnZXQpO1xufVxuXG4vKipcbiAqIEluc2VydCBlbCBhZnRlciB0YXJnZXRcbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldFxuICovXG5cbmZ1bmN0aW9uIGFmdGVyKGVsLCB0YXJnZXQpIHtcbiAgaWYgKHRhcmdldC5uZXh0U2libGluZykge1xuICAgIGJlZm9yZShlbCwgdGFyZ2V0Lm5leHRTaWJsaW5nKTtcbiAgfSBlbHNlIHtcbiAgICB0YXJnZXQucGFyZW50Tm9kZS5hcHBlbmRDaGlsZChlbCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZW1vdmUgZWwgZnJvbSBET01cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKi9cblxuZnVuY3Rpb24gcmVtb3ZlKGVsKSB7XG4gIGVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWwpO1xufVxuXG4vKipcbiAqIFByZXBlbmQgZWwgdG8gdGFyZ2V0XG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtFbGVtZW50fSB0YXJnZXRcbiAqL1xuXG5mdW5jdGlvbiBwcmVwZW5kKGVsLCB0YXJnZXQpIHtcbiAgaWYgKHRhcmdldC5maXJzdENoaWxkKSB7XG4gICAgYmVmb3JlKGVsLCB0YXJnZXQuZmlyc3RDaGlsZCk7XG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0LmFwcGVuZENoaWxkKGVsKTtcbiAgfVxufVxuXG4vKipcbiAqIFJlcGxhY2UgdGFyZ2V0IHdpdGggZWxcbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldFxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICovXG5cbmZ1bmN0aW9uIHJlcGxhY2UodGFyZ2V0LCBlbCkge1xuICB2YXIgcGFyZW50ID0gdGFyZ2V0LnBhcmVudE5vZGU7XG4gIGlmIChwYXJlbnQpIHtcbiAgICBwYXJlbnQucmVwbGFjZUNoaWxkKGVsLCB0YXJnZXQpO1xuICB9XG59XG5cbi8qKlxuICogQWRkIGV2ZW50IGxpc3RlbmVyIHNob3J0aGFuZC5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNiXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFt1c2VDYXB0dXJlXVxuICovXG5cbmZ1bmN0aW9uIG9uKGVsLCBldmVudCwgY2IsIHVzZUNhcHR1cmUpIHtcbiAgZWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgY2IsIHVzZUNhcHR1cmUpO1xufVxuXG4vKipcbiAqIFJlbW92ZSBldmVudCBsaXN0ZW5lciBzaG9ydGhhbmQuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYlxuICovXG5cbmZ1bmN0aW9uIG9mZihlbCwgZXZlbnQsIGNiKSB7XG4gIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGNiKTtcbn1cblxuLyoqXG4gKiBJbiBJRTksIHNldEF0dHJpYnV0ZSgnY2xhc3MnKSB3aWxsIHJlc3VsdCBpbiBlbXB0eSBjbGFzc1xuICogaWYgdGhlIGVsZW1lbnQgYWxzbyBoYXMgdGhlIDpjbGFzcyBhdHRyaWJ1dGU7IEhvd2V2ZXIgaW5cbiAqIFBoYW50b21KUywgc2V0dGluZyBgY2xhc3NOYW1lYCBkb2VzIG5vdCB3b3JrIG9uIFNWRyBlbGVtZW50cy4uLlxuICogU28gd2UgaGF2ZSB0byBkbyBhIGNvbmRpdGlvbmFsIGNoZWNrIGhlcmUuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtTdHJpbmd9IGNsc1xuICovXG5cbmZ1bmN0aW9uIHNldENsYXNzKGVsLCBjbHMpIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChpc0lFOSAmJiAhL3N2ZyQvLnRlc3QoZWwubmFtZXNwYWNlVVJJKSkge1xuICAgIGVsLmNsYXNzTmFtZSA9IGNscztcbiAgfSBlbHNlIHtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgY2xzKTtcbiAgfVxufVxuXG4vKipcbiAqIEFkZCBjbGFzcyB3aXRoIGNvbXBhdGliaWxpdHkgZm9yIElFICYgU1ZHXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtTdHJpbmd9IGNsc1xuICovXG5cbmZ1bmN0aW9uIGFkZENsYXNzKGVsLCBjbHMpIHtcbiAgaWYgKGVsLmNsYXNzTGlzdCkge1xuICAgIGVsLmNsYXNzTGlzdC5hZGQoY2xzKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgY3VyID0gJyAnICsgKGVsLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSB8fCAnJykgKyAnICc7XG4gICAgaWYgKGN1ci5pbmRleE9mKCcgJyArIGNscyArICcgJykgPCAwKSB7XG4gICAgICBzZXRDbGFzcyhlbCwgKGN1ciArIGNscykudHJpbSgpKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZW1vdmUgY2xhc3Mgd2l0aCBjb21wYXRpYmlsaXR5IGZvciBJRSAmIFNWR1xuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSBjbHNcbiAqL1xuXG5mdW5jdGlvbiByZW1vdmVDbGFzcyhlbCwgY2xzKSB7XG4gIGlmIChlbC5jbGFzc0xpc3QpIHtcbiAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKGNscyk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGN1ciA9ICcgJyArIChlbC5nZXRBdHRyaWJ1dGUoJ2NsYXNzJykgfHwgJycpICsgJyAnO1xuICAgIHZhciB0YXIgPSAnICcgKyBjbHMgKyAnICc7XG4gICAgd2hpbGUgKGN1ci5pbmRleE9mKHRhcikgPj0gMCkge1xuICAgICAgY3VyID0gY3VyLnJlcGxhY2UodGFyLCAnICcpO1xuICAgIH1cbiAgICBzZXRDbGFzcyhlbCwgY3VyLnRyaW0oKSk7XG4gIH1cbiAgaWYgKCFlbC5jbGFzc05hbWUpIHtcbiAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoJ2NsYXNzJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBFeHRyYWN0IHJhdyBjb250ZW50IGluc2lkZSBhbiBlbGVtZW50IGludG8gYSB0ZW1wb3JhcnlcbiAqIGNvbnRhaW5lciBkaXZcbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGFzRnJhZ21lbnRcbiAqIEByZXR1cm4ge0VsZW1lbnR8RG9jdW1lbnRGcmFnbWVudH1cbiAqL1xuXG5mdW5jdGlvbiBleHRyYWN0Q29udGVudChlbCwgYXNGcmFnbWVudCkge1xuICB2YXIgY2hpbGQ7XG4gIHZhciByYXdDb250ZW50O1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKGlzVGVtcGxhdGUoZWwpICYmIGlzRnJhZ21lbnQoZWwuY29udGVudCkpIHtcbiAgICBlbCA9IGVsLmNvbnRlbnQ7XG4gIH1cbiAgaWYgKGVsLmhhc0NoaWxkTm9kZXMoKSkge1xuICAgIHRyaW1Ob2RlKGVsKTtcbiAgICByYXdDb250ZW50ID0gYXNGcmFnbWVudCA/IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSA6IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbmQtYXNzaWduICovXG4gICAgd2hpbGUgKGNoaWxkID0gZWwuZmlyc3RDaGlsZCkge1xuICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25kLWFzc2lnbiAqL1xuICAgICAgcmF3Q29udGVudC5hcHBlbmRDaGlsZChjaGlsZCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByYXdDb250ZW50O1xufVxuXG4vKipcbiAqIFRyaW0gcG9zc2libGUgZW1wdHkgaGVhZC90YWlsIHRleHQgYW5kIGNvbW1lbnRcbiAqIG5vZGVzIGluc2lkZSBhIHBhcmVudC5cbiAqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAqL1xuXG5mdW5jdGlvbiB0cmltTm9kZShub2RlKSB7XG4gIHZhciBjaGlsZDtcbiAgLyogZXNsaW50LWRpc2FibGUgbm8tc2VxdWVuY2VzICovXG4gIHdoaWxlICgoY2hpbGQgPSBub2RlLmZpcnN0Q2hpbGQsIGlzVHJpbW1hYmxlKGNoaWxkKSkpIHtcbiAgICBub2RlLnJlbW92ZUNoaWxkKGNoaWxkKTtcbiAgfVxuICB3aGlsZSAoKGNoaWxkID0gbm9kZS5sYXN0Q2hpbGQsIGlzVHJpbW1hYmxlKGNoaWxkKSkpIHtcbiAgICBub2RlLnJlbW92ZUNoaWxkKGNoaWxkKTtcbiAgfVxuICAvKiBlc2xpbnQtZW5hYmxlIG5vLXNlcXVlbmNlcyAqL1xufVxuXG5mdW5jdGlvbiBpc1RyaW1tYWJsZShub2RlKSB7XG4gIHJldHVybiBub2RlICYmIChub2RlLm5vZGVUeXBlID09PSAzICYmICFub2RlLmRhdGEudHJpbSgpIHx8IG5vZGUubm9kZVR5cGUgPT09IDgpO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIGFuIGVsZW1lbnQgaXMgYSB0ZW1wbGF0ZSB0YWcuXG4gKiBOb3RlIGlmIHRoZSB0ZW1wbGF0ZSBhcHBlYXJzIGluc2lkZSBhbiBTVkcgaXRzIHRhZ05hbWVcbiAqIHdpbGwgYmUgaW4gbG93ZXJjYXNlLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqL1xuXG5mdW5jdGlvbiBpc1RlbXBsYXRlKGVsKSB7XG4gIHJldHVybiBlbC50YWdOYW1lICYmIGVsLnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gJ3RlbXBsYXRlJztcbn1cblxuLyoqXG4gKiBDcmVhdGUgYW4gXCJhbmNob3JcIiBmb3IgcGVyZm9ybWluZyBkb20gaW5zZXJ0aW9uL3JlbW92YWxzLlxuICogVGhpcyBpcyB1c2VkIGluIGEgbnVtYmVyIG9mIHNjZW5hcmlvczpcbiAqIC0gZnJhZ21lbnQgaW5zdGFuY2VcbiAqIC0gdi1odG1sXG4gKiAtIHYtaWZcbiAqIC0gdi1mb3JcbiAqIC0gY29tcG9uZW50XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGNvbnRlbnRcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gcGVyc2lzdCAtIElFIHRyYXNoZXMgZW1wdHkgdGV4dE5vZGVzIG9uXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9uZU5vZGUodHJ1ZSksIHNvIGluIGNlcnRhaW5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2VzIHRoZSBhbmNob3IgbmVlZHMgdG8gYmVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vbi1lbXB0eSB0byBiZSBwZXJzaXN0ZWQgaW5cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlcy5cbiAqIEByZXR1cm4ge0NvbW1lbnR8VGV4dH1cbiAqL1xuXG5mdW5jdGlvbiBjcmVhdGVBbmNob3IoY29udGVudCwgcGVyc2lzdCkge1xuICB2YXIgYW5jaG9yID0gY29uZmlnLmRlYnVnID8gZG9jdW1lbnQuY3JlYXRlQ29tbWVudChjb250ZW50KSA6IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHBlcnNpc3QgPyAnICcgOiAnJyk7XG4gIGFuY2hvci5fX3ZfYW5jaG9yID0gdHJ1ZTtcbiAgcmV0dXJuIGFuY2hvcjtcbn1cblxuLyoqXG4gKiBGaW5kIGEgY29tcG9uZW50IHJlZiBhdHRyaWJ1dGUgdGhhdCBzdGFydHMgd2l0aCAkLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gbm9kZVxuICogQHJldHVybiB7U3RyaW5nfHVuZGVmaW5lZH1cbiAqL1xuXG52YXIgcmVmUkUgPSAvXnYtcmVmOi87XG5cbmZ1bmN0aW9uIGZpbmRSZWYobm9kZSkge1xuICBpZiAobm9kZS5oYXNBdHRyaWJ1dGVzKCkpIHtcbiAgICB2YXIgYXR0cnMgPSBub2RlLmF0dHJpYnV0ZXM7XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBhdHRycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHZhciBuYW1lID0gYXR0cnNbaV0ubmFtZTtcbiAgICAgIGlmIChyZWZSRS50ZXN0KG5hbWUpKSB7XG4gICAgICAgIHJldHVybiBjYW1lbGl6ZShuYW1lLnJlcGxhY2UocmVmUkUsICcnKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogTWFwIGEgZnVuY3Rpb24gdG8gYSByYW5nZSBvZiBub2RlcyAuXG4gKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKiBAcGFyYW0ge05vZGV9IGVuZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gb3BcbiAqL1xuXG5mdW5jdGlvbiBtYXBOb2RlUmFuZ2Uobm9kZSwgZW5kLCBvcCkge1xuICB2YXIgbmV4dDtcbiAgd2hpbGUgKG5vZGUgIT09IGVuZCkge1xuICAgIG5leHQgPSBub2RlLm5leHRTaWJsaW5nO1xuICAgIG9wKG5vZGUpO1xuICAgIG5vZGUgPSBuZXh0O1xuICB9XG4gIG9wKGVuZCk7XG59XG5cbi8qKlxuICogUmVtb3ZlIGEgcmFuZ2Ugb2Ygbm9kZXMgd2l0aCB0cmFuc2l0aW9uLCBzdG9yZVxuICogdGhlIG5vZGVzIGluIGEgZnJhZ21lbnQgd2l0aCBjb3JyZWN0IG9yZGVyaW5nLFxuICogYW5kIGNhbGwgY2FsbGJhY2sgd2hlbiBkb25lLlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gc3RhcnRcbiAqIEBwYXJhbSB7Tm9kZX0gZW5kXG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqIEBwYXJhbSB7RG9jdW1lbnRGcmFnbWVudH0gZnJhZ1xuICogQHBhcmFtIHtGdW5jdGlvbn0gY2JcbiAqL1xuXG5mdW5jdGlvbiByZW1vdmVOb2RlUmFuZ2Uoc3RhcnQsIGVuZCwgdm0sIGZyYWcsIGNiKSB7XG4gIHZhciBkb25lID0gZmFsc2U7XG4gIHZhciByZW1vdmVkID0gMDtcbiAgdmFyIG5vZGVzID0gW107XG4gIG1hcE5vZGVSYW5nZShzdGFydCwgZW5kLCBmdW5jdGlvbiAobm9kZSkge1xuICAgIGlmIChub2RlID09PSBlbmQpIGRvbmUgPSB0cnVlO1xuICAgIG5vZGVzLnB1c2gobm9kZSk7XG4gICAgcmVtb3ZlV2l0aFRyYW5zaXRpb24obm9kZSwgdm0sIG9uUmVtb3ZlZCk7XG4gIH0pO1xuICBmdW5jdGlvbiBvblJlbW92ZWQoKSB7XG4gICAgcmVtb3ZlZCsrO1xuICAgIGlmIChkb25lICYmIHJlbW92ZWQgPj0gbm9kZXMubGVuZ3RoKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGZyYWcuYXBwZW5kQ2hpbGQobm9kZXNbaV0pO1xuICAgICAgfVxuICAgICAgY2IgJiYgY2IoKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhIG5vZGUgaXMgYSBEb2N1bWVudEZyYWdtZW50LlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuXG5mdW5jdGlvbiBpc0ZyYWdtZW50KG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUgJiYgbm9kZS5ub2RlVHlwZSA9PT0gMTE7XG59XG5cbi8qKlxuICogR2V0IG91dGVySFRNTCBvZiBlbGVtZW50cywgdGFraW5nIGNhcmVcbiAqIG9mIFNWRyBlbGVtZW50cyBpbiBJRSBhcyB3ZWxsLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBnZXRPdXRlckhUTUwoZWwpIHtcbiAgaWYgKGVsLm91dGVySFRNTCkge1xuICAgIHJldHVybiBlbC5vdXRlckhUTUw7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChlbC5jbG9uZU5vZGUodHJ1ZSkpO1xuICAgIHJldHVybiBjb250YWluZXIuaW5uZXJIVE1MO1xuICB9XG59XG5cbnZhciBjb21tb25UYWdSRSA9IC9eKGRpdnxwfHNwYW58aW1nfGF8YnxpfGJyfHVsfG9sfGxpfGgxfGgyfGgzfGg0fGg1fGg2fGNvZGV8cHJlfHRhYmxlfHRofHRkfHRyfGZvcm18bGFiZWx8aW5wdXR8c2VsZWN0fG9wdGlvbnxuYXZ8YXJ0aWNsZXxzZWN0aW9ufGhlYWRlcnxmb290ZXIpJC87XG52YXIgcmVzZXJ2ZWRUYWdSRSA9IC9eKHNsb3R8cGFydGlhbHxjb21wb25lbnQpJC87XG5cbnZhciBpc1Vua25vd25FbGVtZW50ID0gdW5kZWZpbmVkO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgaXNVbmtub3duRWxlbWVudCA9IGZ1bmN0aW9uIChlbCwgdGFnKSB7XG4gICAgaWYgKHRhZy5pbmRleE9mKCctJykgPiAtMSkge1xuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjgyMTAzNjQvMTA3MDI0NFxuICAgICAgcmV0dXJuIGVsLmNvbnN0cnVjdG9yID09PSB3aW5kb3cuSFRNTFVua25vd25FbGVtZW50IHx8IGVsLmNvbnN0cnVjdG9yID09PSB3aW5kb3cuSFRNTEVsZW1lbnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAoL0hUTUxVbmtub3duRWxlbWVudC8udGVzdChlbC50b1N0cmluZygpKSAmJlxuICAgICAgICAvLyBDaHJvbWUgcmV0dXJucyB1bmtub3duIGZvciBzZXZlcmFsIEhUTUw1IGVsZW1lbnRzLlxuICAgICAgICAvLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NTQwNTI2XG4gICAgICAgICEvXihkYXRhfHRpbWV8cnRjfHJiKSQvLnRlc3QodGFnKVxuICAgICAgKTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYW4gZWxlbWVudCBpcyBhIGNvbXBvbmVudCwgaWYgeWVzIHJldHVybiBpdHNcbiAqIGNvbXBvbmVudCBpZC5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH1cbiAqL1xuXG5mdW5jdGlvbiBjaGVja0NvbXBvbmVudEF0dHIoZWwsIG9wdGlvbnMpIHtcbiAgdmFyIHRhZyA9IGVsLnRhZ05hbWUudG9Mb3dlckNhc2UoKTtcbiAgdmFyIGhhc0F0dHJzID0gZWwuaGFzQXR0cmlidXRlcygpO1xuICBpZiAoIWNvbW1vblRhZ1JFLnRlc3QodGFnKSAmJiAhcmVzZXJ2ZWRUYWdSRS50ZXN0KHRhZykpIHtcbiAgICBpZiAocmVzb2x2ZUFzc2V0KG9wdGlvbnMsICdjb21wb25lbnRzJywgdGFnKSkge1xuICAgICAgcmV0dXJuIHsgaWQ6IHRhZyB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgaXMgPSBoYXNBdHRycyAmJiBnZXRJc0JpbmRpbmcoZWwpO1xuICAgICAgaWYgKGlzKSB7XG4gICAgICAgIHJldHVybiBpcztcbiAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICB2YXIgZXhwZWN0ZWRUYWcgPSBvcHRpb25zLl9jb21wb25lbnROYW1lTWFwICYmIG9wdGlvbnMuX2NvbXBvbmVudE5hbWVNYXBbdGFnXTtcbiAgICAgICAgaWYgKGV4cGVjdGVkVGFnKSB7XG4gICAgICAgICAgd2FybignVW5rbm93biBjdXN0b20gZWxlbWVudDogPCcgKyB0YWcgKyAnPiAtICcgKyAnZGlkIHlvdSBtZWFuIDwnICsgZXhwZWN0ZWRUYWcgKyAnPj8gJyArICdIVE1MIGlzIGNhc2UtaW5zZW5zaXRpdmUsIHJlbWVtYmVyIHRvIHVzZSBrZWJhYi1jYXNlIGluIHRlbXBsYXRlcy4nKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc1Vua25vd25FbGVtZW50KGVsLCB0YWcpKSB7XG4gICAgICAgICAgd2FybignVW5rbm93biBjdXN0b20gZWxlbWVudDogPCcgKyB0YWcgKyAnPiAtIGRpZCB5b3UgJyArICdyZWdpc3RlciB0aGUgY29tcG9uZW50IGNvcnJlY3RseT8gRm9yIHJlY3Vyc2l2ZSBjb21wb25lbnRzLCAnICsgJ21ha2Ugc3VyZSB0byBwcm92aWRlIHRoZSBcIm5hbWVcIiBvcHRpb24uJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoaGFzQXR0cnMpIHtcbiAgICByZXR1cm4gZ2V0SXNCaW5kaW5nKGVsKTtcbiAgfVxufVxuXG4vKipcbiAqIEdldCBcImlzXCIgYmluZGluZyBmcm9tIGFuIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHJldHVybiB7T2JqZWN0fHVuZGVmaW5lZH1cbiAqL1xuXG5mdW5jdGlvbiBnZXRJc0JpbmRpbmcoZWwpIHtcbiAgLy8gZHluYW1pYyBzeW50YXhcbiAgdmFyIGV4cCA9IGdldEF0dHIoZWwsICdpcycpO1xuICBpZiAoZXhwICE9IG51bGwpIHtcbiAgICByZXR1cm4geyBpZDogZXhwIH07XG4gIH0gZWxzZSB7XG4gICAgZXhwID0gZ2V0QmluZEF0dHIoZWwsICdpcycpO1xuICAgIGlmIChleHAgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHsgaWQ6IGV4cCwgZHluYW1pYzogdHJ1ZSB9O1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFNldCBhIHByb3AncyBpbml0aWFsIHZhbHVlIG9uIGEgdm0gYW5kIGl0cyBkYXRhIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm9wXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKi9cblxuZnVuY3Rpb24gaW5pdFByb3Aodm0sIHByb3AsIHZhbHVlKSB7XG4gIHZhciBrZXkgPSBwcm9wLnBhdGg7XG4gIHZhbHVlID0gY29lcmNlUHJvcChwcm9wLCB2YWx1ZSk7XG4gIHZtW2tleV0gPSB2bS5fZGF0YVtrZXldID0gYXNzZXJ0UHJvcChwcm9wLCB2YWx1ZSkgPyB2YWx1ZSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBBc3NlcnQgd2hldGhlciBhIHByb3AgaXMgdmFsaWQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHByb3BcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqL1xuXG5mdW5jdGlvbiBhc3NlcnRQcm9wKHByb3AsIHZhbHVlKSB7XG4gIGlmICghcHJvcC5vcHRpb25zLnJlcXVpcmVkICYmICggLy8gbm9uLXJlcXVpcmVkXG4gIHByb3AucmF3ID09PSBudWxsIHx8IC8vIGFic2NlbnRcbiAgdmFsdWUgPT0gbnVsbCkgLy8gbnVsbCBvciB1bmRlZmluZWRcbiAgKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIHZhciBvcHRpb25zID0gcHJvcC5vcHRpb25zO1xuICB2YXIgdHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgdmFyIHZhbGlkID0gdHJ1ZTtcbiAgdmFyIGV4cGVjdGVkVHlwZTtcbiAgaWYgKHR5cGUpIHtcbiAgICBpZiAodHlwZSA9PT0gU3RyaW5nKSB7XG4gICAgICBleHBlY3RlZFR5cGUgPSAnc3RyaW5nJztcbiAgICAgIHZhbGlkID0gdHlwZW9mIHZhbHVlID09PSBleHBlY3RlZFR5cGU7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBOdW1iZXIpIHtcbiAgICAgIGV4cGVjdGVkVHlwZSA9ICdudW1iZXInO1xuICAgICAgdmFsaWQgPSB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gQm9vbGVhbikge1xuICAgICAgZXhwZWN0ZWRUeXBlID0gJ2Jvb2xlYW4nO1xuICAgICAgdmFsaWQgPSB0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJztcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IEZ1bmN0aW9uKSB7XG4gICAgICBleHBlY3RlZFR5cGUgPSAnZnVuY3Rpb24nO1xuICAgICAgdmFsaWQgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbic7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSBPYmplY3QpIHtcbiAgICAgIGV4cGVjdGVkVHlwZSA9ICdvYmplY3QnO1xuICAgICAgdmFsaWQgPSBpc1BsYWluT2JqZWN0KHZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IEFycmF5KSB7XG4gICAgICBleHBlY3RlZFR5cGUgPSAnYXJyYXknO1xuICAgICAgdmFsaWQgPSBpc0FycmF5KHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsaWQgPSB2YWx1ZSBpbnN0YW5jZW9mIHR5cGU7XG4gICAgfVxuICB9XG4gIGlmICghdmFsaWQpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oJ0ludmFsaWQgcHJvcDogdHlwZSBjaGVjayBmYWlsZWQgZm9yICcgKyBwcm9wLnBhdGggKyAnPVwiJyArIHByb3AucmF3ICsgJ1wiLicgKyAnIEV4cGVjdGVkICcgKyBmb3JtYXRUeXBlKGV4cGVjdGVkVHlwZSkgKyAnLCBnb3QgJyArIGZvcm1hdFZhbHVlKHZhbHVlKSArICcuJyk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciB2YWxpZGF0b3IgPSBvcHRpb25zLnZhbGlkYXRvcjtcbiAgaWYgKHZhbGlkYXRvcikge1xuICAgIGlmICghdmFsaWRhdG9yKHZhbHVlKSkge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKCdJbnZhbGlkIHByb3A6IGN1c3RvbSB2YWxpZGF0b3IgY2hlY2sgZmFpbGVkIGZvciAnICsgcHJvcC5wYXRoICsgJz1cIicgKyBwcm9wLnJhdyArICdcIicpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBGb3JjZSBwYXJzaW5nIHZhbHVlIHdpdGggY29lcmNlIG9wdGlvbi5cbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHJldHVybiB7Kn1cbiAqL1xuXG5mdW5jdGlvbiBjb2VyY2VQcm9wKHByb3AsIHZhbHVlKSB7XG4gIHZhciBjb2VyY2UgPSBwcm9wLm9wdGlvbnMuY29lcmNlO1xuICBpZiAoIWNvZXJjZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICAvLyBjb2VyY2UgaXMgYSBmdW5jdGlvblxuICByZXR1cm4gY29lcmNlKHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VHlwZSh2YWwpIHtcbiAgcmV0dXJuIHZhbCA/IHZhbC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHZhbC5zbGljZSgxKSA6ICdjdXN0b20gdHlwZSc7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFZhbHVlKHZhbCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbCkuc2xpY2UoOCwgLTEpO1xufVxuXG4vKipcbiAqIE9wdGlvbiBvdmVyd3JpdGluZyBzdHJhdGVnaWVzIGFyZSBmdW5jdGlvbnMgdGhhdCBoYW5kbGVcbiAqIGhvdyB0byBtZXJnZSBhIHBhcmVudCBvcHRpb24gdmFsdWUgYW5kIGEgY2hpbGQgb3B0aW9uXG4gKiB2YWx1ZSBpbnRvIHRoZSBmaW5hbCB2YWx1ZS5cbiAqXG4gKiBBbGwgc3RyYXRlZ3kgZnVuY3Rpb25zIGZvbGxvdyB0aGUgc2FtZSBzaWduYXR1cmU6XG4gKlxuICogQHBhcmFtIHsqfSBwYXJlbnRWYWxcbiAqIEBwYXJhbSB7Kn0gY2hpbGRWYWxcbiAqIEBwYXJhbSB7VnVlfSBbdm1dXG4gKi9cblxudmFyIHN0cmF0cyA9IGNvbmZpZy5vcHRpb25NZXJnZVN0cmF0ZWdpZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4vKipcbiAqIEhlbHBlciB0aGF0IHJlY3Vyc2l2ZWx5IG1lcmdlcyB0d28gZGF0YSBvYmplY3RzIHRvZ2V0aGVyLlxuICovXG5cbmZ1bmN0aW9uIG1lcmdlRGF0YSh0bywgZnJvbSkge1xuICB2YXIga2V5LCB0b1ZhbCwgZnJvbVZhbDtcbiAgZm9yIChrZXkgaW4gZnJvbSkge1xuICAgIHRvVmFsID0gdG9ba2V5XTtcbiAgICBmcm9tVmFsID0gZnJvbVtrZXldO1xuICAgIGlmICghaGFzT3duKHRvLCBrZXkpKSB7XG4gICAgICBzZXQodG8sIGtleSwgZnJvbVZhbCk7XG4gICAgfSBlbHNlIGlmIChpc09iamVjdCh0b1ZhbCkgJiYgaXNPYmplY3QoZnJvbVZhbCkpIHtcbiAgICAgIG1lcmdlRGF0YSh0b1ZhbCwgZnJvbVZhbCk7XG4gICAgfVxuICB9XG4gIHJldHVybiB0bztcbn1cblxuLyoqXG4gKiBEYXRhXG4gKi9cblxuc3RyYXRzLmRhdGEgPSBmdW5jdGlvbiAocGFyZW50VmFsLCBjaGlsZFZhbCwgdm0pIHtcbiAgaWYgKCF2bSkge1xuICAgIC8vIGluIGEgVnVlLmV4dGVuZCBtZXJnZSwgYm90aCBzaG91bGQgYmUgZnVuY3Rpb25zXG4gICAgaWYgKCFjaGlsZFZhbCkge1xuICAgICAgcmV0dXJuIHBhcmVudFZhbDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBjaGlsZFZhbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKCdUaGUgXCJkYXRhXCIgb3B0aW9uIHNob3VsZCBiZSBhIGZ1bmN0aW9uICcgKyAndGhhdCByZXR1cm5zIGEgcGVyLWluc3RhbmNlIHZhbHVlIGluIGNvbXBvbmVudCAnICsgJ2RlZmluaXRpb25zLicpO1xuICAgICAgcmV0dXJuIHBhcmVudFZhbDtcbiAgICB9XG4gICAgaWYgKCFwYXJlbnRWYWwpIHtcbiAgICAgIHJldHVybiBjaGlsZFZhbDtcbiAgICB9XG4gICAgLy8gd2hlbiBwYXJlbnRWYWwgJiBjaGlsZFZhbCBhcmUgYm90aCBwcmVzZW50LFxuICAgIC8vIHdlIG5lZWQgdG8gcmV0dXJuIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZVxuICAgIC8vIG1lcmdlZCByZXN1bHQgb2YgYm90aCBmdW5jdGlvbnMuLi4gbm8gbmVlZCB0b1xuICAgIC8vIGNoZWNrIGlmIHBhcmVudFZhbCBpcyBhIGZ1bmN0aW9uIGhlcmUgYmVjYXVzZVxuICAgIC8vIGl0IGhhcyB0byBiZSBhIGZ1bmN0aW9uIHRvIHBhc3MgcHJldmlvdXMgbWVyZ2VzLlxuICAgIHJldHVybiBmdW5jdGlvbiBtZXJnZWREYXRhRm4oKSB7XG4gICAgICByZXR1cm4gbWVyZ2VEYXRhKGNoaWxkVmFsLmNhbGwodGhpcyksIHBhcmVudFZhbC5jYWxsKHRoaXMpKTtcbiAgICB9O1xuICB9IGVsc2UgaWYgKHBhcmVudFZhbCB8fCBjaGlsZFZhbCkge1xuICAgIHJldHVybiBmdW5jdGlvbiBtZXJnZWRJbnN0YW5jZURhdGFGbigpIHtcbiAgICAgIC8vIGluc3RhbmNlIG1lcmdlXG4gICAgICB2YXIgaW5zdGFuY2VEYXRhID0gdHlwZW9mIGNoaWxkVmFsID09PSAnZnVuY3Rpb24nID8gY2hpbGRWYWwuY2FsbCh2bSkgOiBjaGlsZFZhbDtcbiAgICAgIHZhciBkZWZhdWx0RGF0YSA9IHR5cGVvZiBwYXJlbnRWYWwgPT09ICdmdW5jdGlvbicgPyBwYXJlbnRWYWwuY2FsbCh2bSkgOiB1bmRlZmluZWQ7XG4gICAgICBpZiAoaW5zdGFuY2VEYXRhKSB7XG4gICAgICAgIHJldHVybiBtZXJnZURhdGEoaW5zdGFuY2VEYXRhLCBkZWZhdWx0RGF0YSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZGVmYXVsdERhdGE7XG4gICAgICB9XG4gICAgfTtcbiAgfVxufTtcblxuLyoqXG4gKiBFbFxuICovXG5cbnN0cmF0cy5lbCA9IGZ1bmN0aW9uIChwYXJlbnRWYWwsIGNoaWxkVmFsLCB2bSkge1xuICBpZiAoIXZtICYmIGNoaWxkVmFsICYmIHR5cGVvZiBjaGlsZFZhbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybignVGhlIFwiZWxcIiBvcHRpb24gc2hvdWxkIGJlIGEgZnVuY3Rpb24gJyArICd0aGF0IHJldHVybnMgYSBwZXItaW5zdGFuY2UgdmFsdWUgaW4gY29tcG9uZW50ICcgKyAnZGVmaW5pdGlvbnMuJyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciByZXQgPSBjaGlsZFZhbCB8fCBwYXJlbnRWYWw7XG4gIC8vIGludm9rZSB0aGUgZWxlbWVudCBmYWN0b3J5IGlmIHRoaXMgaXMgaW5zdGFuY2UgbWVyZ2VcbiAgcmV0dXJuIHZtICYmIHR5cGVvZiByZXQgPT09ICdmdW5jdGlvbicgPyByZXQuY2FsbCh2bSkgOiByZXQ7XG59O1xuXG4vKipcbiAqIEhvb2tzIGFuZCBwYXJhbSBhdHRyaWJ1dGVzIGFyZSBtZXJnZWQgYXMgYXJyYXlzLlxuICovXG5cbnN0cmF0cy5pbml0ID0gc3RyYXRzLmNyZWF0ZWQgPSBzdHJhdHMucmVhZHkgPSBzdHJhdHMuYXR0YWNoZWQgPSBzdHJhdHMuZGV0YWNoZWQgPSBzdHJhdHMuYmVmb3JlQ29tcGlsZSA9IHN0cmF0cy5jb21waWxlZCA9IHN0cmF0cy5iZWZvcmVEZXN0cm95ID0gc3RyYXRzLmRlc3Ryb3llZCA9IHN0cmF0cy5hY3RpdmF0ZSA9IGZ1bmN0aW9uIChwYXJlbnRWYWwsIGNoaWxkVmFsKSB7XG4gIHJldHVybiBjaGlsZFZhbCA/IHBhcmVudFZhbCA/IHBhcmVudFZhbC5jb25jYXQoY2hpbGRWYWwpIDogaXNBcnJheShjaGlsZFZhbCkgPyBjaGlsZFZhbCA6IFtjaGlsZFZhbF0gOiBwYXJlbnRWYWw7XG59O1xuXG4vKipcbiAqIDAuMTEgZGVwcmVjYXRpb24gd2FybmluZ1xuICovXG5cbnN0cmF0cy5wYXJhbUF0dHJpYnV0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybignXCJwYXJhbUF0dHJpYnV0ZXNcIiBvcHRpb24gaGFzIGJlZW4gZGVwcmVjYXRlZCBpbiAwLjEyLiAnICsgJ1VzZSBcInByb3BzXCIgaW5zdGVhZC4nKTtcbn07XG5cbi8qKlxuICogQXNzZXRzXG4gKlxuICogV2hlbiBhIHZtIGlzIHByZXNlbnQgKGluc3RhbmNlIGNyZWF0aW9uKSwgd2UgbmVlZCB0byBkb1xuICogYSB0aHJlZS13YXkgbWVyZ2UgYmV0d2VlbiBjb25zdHJ1Y3RvciBvcHRpb25zLCBpbnN0YW5jZVxuICogb3B0aW9ucyBhbmQgcGFyZW50IG9wdGlvbnMuXG4gKi9cblxuZnVuY3Rpb24gbWVyZ2VBc3NldHMocGFyZW50VmFsLCBjaGlsZFZhbCkge1xuICB2YXIgcmVzID0gT2JqZWN0LmNyZWF0ZShwYXJlbnRWYWwpO1xuICByZXR1cm4gY2hpbGRWYWwgPyBleHRlbmQocmVzLCBndWFyZEFycmF5QXNzZXRzKGNoaWxkVmFsKSkgOiByZXM7XG59XG5cbmNvbmZpZy5fYXNzZXRUeXBlcy5mb3JFYWNoKGZ1bmN0aW9uICh0eXBlKSB7XG4gIHN0cmF0c1t0eXBlICsgJ3MnXSA9IG1lcmdlQXNzZXRzO1xufSk7XG5cbi8qKlxuICogRXZlbnRzICYgV2F0Y2hlcnMuXG4gKlxuICogRXZlbnRzICYgd2F0Y2hlcnMgaGFzaGVzIHNob3VsZCBub3Qgb3ZlcndyaXRlIG9uZVxuICogYW5vdGhlciwgc28gd2UgbWVyZ2UgdGhlbSBhcyBhcnJheXMuXG4gKi9cblxuc3RyYXRzLndhdGNoID0gc3RyYXRzLmV2ZW50cyA9IGZ1bmN0aW9uIChwYXJlbnRWYWwsIGNoaWxkVmFsKSB7XG4gIGlmICghY2hpbGRWYWwpIHJldHVybiBwYXJlbnRWYWw7XG4gIGlmICghcGFyZW50VmFsKSByZXR1cm4gY2hpbGRWYWw7XG4gIHZhciByZXQgPSB7fTtcbiAgZXh0ZW5kKHJldCwgcGFyZW50VmFsKTtcbiAgZm9yICh2YXIga2V5IGluIGNoaWxkVmFsKSB7XG4gICAgdmFyIHBhcmVudCA9IHJldFtrZXldO1xuICAgIHZhciBjaGlsZCA9IGNoaWxkVmFsW2tleV07XG4gICAgaWYgKHBhcmVudCAmJiAhaXNBcnJheShwYXJlbnQpKSB7XG4gICAgICBwYXJlbnQgPSBbcGFyZW50XTtcbiAgICB9XG4gICAgcmV0W2tleV0gPSBwYXJlbnQgPyBwYXJlbnQuY29uY2F0KGNoaWxkKSA6IFtjaGlsZF07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn07XG5cbi8qKlxuICogT3RoZXIgb2JqZWN0IGhhc2hlcy5cbiAqL1xuXG5zdHJhdHMucHJvcHMgPSBzdHJhdHMubWV0aG9kcyA9IHN0cmF0cy5jb21wdXRlZCA9IGZ1bmN0aW9uIChwYXJlbnRWYWwsIGNoaWxkVmFsKSB7XG4gIGlmICghY2hpbGRWYWwpIHJldHVybiBwYXJlbnRWYWw7XG4gIGlmICghcGFyZW50VmFsKSByZXR1cm4gY2hpbGRWYWw7XG4gIHZhciByZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICBleHRlbmQocmV0LCBwYXJlbnRWYWwpO1xuICBleHRlbmQocmV0LCBjaGlsZFZhbCk7XG4gIHJldHVybiByZXQ7XG59O1xuXG4vKipcbiAqIERlZmF1bHQgc3RyYXRlZ3kuXG4gKi9cblxudmFyIGRlZmF1bHRTdHJhdCA9IGZ1bmN0aW9uIGRlZmF1bHRTdHJhdChwYXJlbnRWYWwsIGNoaWxkVmFsKSB7XG4gIHJldHVybiBjaGlsZFZhbCA9PT0gdW5kZWZpbmVkID8gcGFyZW50VmFsIDogY2hpbGRWYWw7XG59O1xuXG4vKipcbiAqIE1ha2Ugc3VyZSBjb21wb25lbnQgb3B0aW9ucyBnZXQgY29udmVydGVkIHRvIGFjdHVhbFxuICogY29uc3RydWN0b3JzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKi9cblxuZnVuY3Rpb24gZ3VhcmRDb21wb25lbnRzKG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMuY29tcG9uZW50cykge1xuICAgIHZhciBjb21wb25lbnRzID0gb3B0aW9ucy5jb21wb25lbnRzID0gZ3VhcmRBcnJheUFzc2V0cyhvcHRpb25zLmNvbXBvbmVudHMpO1xuICAgIHZhciBpZHMgPSBPYmplY3Qua2V5cyhjb21wb25lbnRzKTtcbiAgICB2YXIgZGVmO1xuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICB2YXIgbWFwID0gb3B0aW9ucy5fY29tcG9uZW50TmFtZU1hcCA9IHt9O1xuICAgIH1cbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGlkcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHZhciBrZXkgPSBpZHNbaV07XG4gICAgICBpZiAoY29tbW9uVGFnUkUudGVzdChrZXkpIHx8IHJlc2VydmVkVGFnUkUudGVzdChrZXkpKSB7XG4gICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybignRG8gbm90IHVzZSBidWlsdC1pbiBvciByZXNlcnZlZCBIVE1MIGVsZW1lbnRzIGFzIGNvbXBvbmVudCAnICsgJ2lkOiAnICsga2V5KTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICAvLyByZWNvcmQgYSBhbGwgbG93ZXJjYXNlIDwtPiBrZWJhYi1jYXNlIG1hcHBpbmcgZm9yXG4gICAgICAvLyBwb3NzaWJsZSBjdXN0b20gZWxlbWVudCBjYXNlIGVycm9yIHdhcm5pbmdcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIG1hcFtrZXkucmVwbGFjZSgvLS9nLCAnJykudG9Mb3dlckNhc2UoKV0gPSBoeXBoZW5hdGUoa2V5KTtcbiAgICAgIH1cbiAgICAgIGRlZiA9IGNvbXBvbmVudHNba2V5XTtcbiAgICAgIGlmIChpc1BsYWluT2JqZWN0KGRlZikpIHtcbiAgICAgICAgY29tcG9uZW50c1trZXldID0gVnVlLmV4dGVuZChkZWYpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEVuc3VyZSBhbGwgcHJvcHMgb3B0aW9uIHN5bnRheCBhcmUgbm9ybWFsaXplZCBpbnRvIHRoZVxuICogT2JqZWN0LWJhc2VkIGZvcm1hdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICovXG5cbmZ1bmN0aW9uIGd1YXJkUHJvcHMob3B0aW9ucykge1xuICB2YXIgcHJvcHMgPSBvcHRpb25zLnByb3BzO1xuICB2YXIgaSwgdmFsO1xuICBpZiAoaXNBcnJheShwcm9wcykpIHtcbiAgICBvcHRpb25zLnByb3BzID0ge307XG4gICAgaSA9IHByb3BzLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICB2YWwgPSBwcm9wc1tpXTtcbiAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgICAgICBvcHRpb25zLnByb3BzW3ZhbF0gPSBudWxsO1xuICAgICAgfSBlbHNlIGlmICh2YWwubmFtZSkge1xuICAgICAgICBvcHRpb25zLnByb3BzW3ZhbC5uYW1lXSA9IHZhbDtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSBpZiAoaXNQbGFpbk9iamVjdChwcm9wcykpIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BzKTtcbiAgICBpID0ga2V5cy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgdmFsID0gcHJvcHNba2V5c1tpXV07XG4gICAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwcm9wc1trZXlzW2ldXSA9IHsgdHlwZTogdmFsIH07XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogR3VhcmQgYW4gQXJyYXktZm9ybWF0IGFzc2V0cyBvcHRpb24gYW5kIGNvbnZlcnRlZCBpdFxuICogaW50byB0aGUga2V5LXZhbHVlIE9iamVjdCBmb3JtYXQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8QXJyYXl9IGFzc2V0c1xuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5cbmZ1bmN0aW9uIGd1YXJkQXJyYXlBc3NldHMoYXNzZXRzKSB7XG4gIGlmIChpc0FycmF5KGFzc2V0cykpIHtcbiAgICB2YXIgcmVzID0ge307XG4gICAgdmFyIGkgPSBhc3NldHMubGVuZ3RoO1xuICAgIHZhciBhc3NldDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICBhc3NldCA9IGFzc2V0c1tpXTtcbiAgICAgIHZhciBpZCA9IHR5cGVvZiBhc3NldCA9PT0gJ2Z1bmN0aW9uJyA/IGFzc2V0Lm9wdGlvbnMgJiYgYXNzZXQub3B0aW9ucy5uYW1lIHx8IGFzc2V0LmlkIDogYXNzZXQubmFtZSB8fCBhc3NldC5pZDtcbiAgICAgIGlmICghaWQpIHtcbiAgICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKCdBcnJheS1zeW50YXggYXNzZXRzIG11c3QgcHJvdmlkZSBhIFwibmFtZVwiIG9yIFwiaWRcIiBmaWVsZC4nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc1tpZF0gPSBhc3NldDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuICByZXR1cm4gYXNzZXRzO1xufVxuXG4vKipcbiAqIE1lcmdlIHR3byBvcHRpb24gb2JqZWN0cyBpbnRvIGEgbmV3IG9uZS5cbiAqIENvcmUgdXRpbGl0eSB1c2VkIGluIGJvdGggaW5zdGFudGlhdGlvbiBhbmQgaW5oZXJpdGFuY2UuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhcmVudFxuICogQHBhcmFtIHtPYmplY3R9IGNoaWxkXG4gKiBAcGFyYW0ge1Z1ZX0gW3ZtXSAtIGlmIHZtIGlzIHByZXNlbnQsIGluZGljYXRlcyB0aGlzIGlzXG4gKiAgICAgICAgICAgICAgICAgICAgIGFuIGluc3RhbnRpYXRpb24gbWVyZ2UuXG4gKi9cblxuZnVuY3Rpb24gbWVyZ2VPcHRpb25zKHBhcmVudCwgY2hpbGQsIHZtKSB7XG4gIGd1YXJkQ29tcG9uZW50cyhjaGlsZCk7XG4gIGd1YXJkUHJvcHMoY2hpbGQpO1xuICB2YXIgb3B0aW9ucyA9IHt9O1xuICB2YXIga2V5O1xuICBpZiAoY2hpbGQubWl4aW5zKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjaGlsZC5taXhpbnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBwYXJlbnQgPSBtZXJnZU9wdGlvbnMocGFyZW50LCBjaGlsZC5taXhpbnNbaV0sIHZtKTtcbiAgICB9XG4gIH1cbiAgZm9yIChrZXkgaW4gcGFyZW50KSB7XG4gICAgbWVyZ2VGaWVsZChrZXkpO1xuICB9XG4gIGZvciAoa2V5IGluIGNoaWxkKSB7XG4gICAgaWYgKCFoYXNPd24ocGFyZW50LCBrZXkpKSB7XG4gICAgICBtZXJnZUZpZWxkKGtleSk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIG1lcmdlRmllbGQoa2V5KSB7XG4gICAgdmFyIHN0cmF0ID0gc3RyYXRzW2tleV0gfHwgZGVmYXVsdFN0cmF0O1xuICAgIG9wdGlvbnNba2V5XSA9IHN0cmF0KHBhcmVudFtrZXldLCBjaGlsZFtrZXldLCB2bSwga2V5KTtcbiAgfVxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGFuIGFzc2V0LlxuICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGJlY2F1c2UgY2hpbGQgaW5zdGFuY2VzIG5lZWQgYWNjZXNzXG4gKiB0byBhc3NldHMgZGVmaW5lZCBpbiBpdHMgYW5jZXN0b3IgY2hhaW4uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge1N0cmluZ30gaWRcbiAqIEByZXR1cm4ge09iamVjdHxGdW5jdGlvbn1cbiAqL1xuXG5mdW5jdGlvbiByZXNvbHZlQXNzZXQob3B0aW9ucywgdHlwZSwgaWQpIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmICh0eXBlb2YgaWQgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBhc3NldHMgPSBvcHRpb25zW3R5cGVdO1xuICB2YXIgY2FtZWxpemVkSWQ7XG4gIHJldHVybiBhc3NldHNbaWRdIHx8XG4gIC8vIGNhbWVsQ2FzZSBJRFxuICBhc3NldHNbY2FtZWxpemVkSWQgPSBjYW1lbGl6ZShpZCldIHx8XG4gIC8vIFBhc2NhbCBDYXNlIElEXG4gIGFzc2V0c1tjYW1lbGl6ZWRJZC5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIGNhbWVsaXplZElkLnNsaWNlKDEpXTtcbn1cblxuLyoqXG4gKiBBc3NlcnQgYXNzZXQgZXhpc3RzXG4gKi9cblxuZnVuY3Rpb24gYXNzZXJ0QXNzZXQodmFsLCB0eXBlLCBpZCkge1xuICBpZiAoIXZhbCkge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybignRmFpbGVkIHRvIHJlc29sdmUgJyArIHR5cGUgKyAnOiAnICsgaWQpO1xuICB9XG59XG5cbnZhciB1aWQkMSA9IDA7XG5cbi8qKlxuICogQSBkZXAgaXMgYW4gb2JzZXJ2YWJsZSB0aGF0IGNhbiBoYXZlIG11bHRpcGxlXG4gKiBkaXJlY3RpdmVzIHN1YnNjcmliaW5nIHRvIGl0LlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBEZXAoKSB7XG4gIHRoaXMuaWQgPSB1aWQkMSsrO1xuICB0aGlzLnN1YnMgPSBbXTtcbn1cblxuLy8gdGhlIGN1cnJlbnQgdGFyZ2V0IHdhdGNoZXIgYmVpbmcgZXZhbHVhdGVkLlxuLy8gdGhpcyBpcyBnbG9iYWxseSB1bmlxdWUgYmVjYXVzZSB0aGVyZSBjb3VsZCBiZSBvbmx5IG9uZVxuLy8gd2F0Y2hlciBiZWluZyBldmFsdWF0ZWQgYXQgYW55IHRpbWUuXG5EZXAudGFyZ2V0ID0gbnVsbDtcblxuLyoqXG4gKiBBZGQgYSBkaXJlY3RpdmUgc3Vic2NyaWJlci5cbiAqXG4gKiBAcGFyYW0ge0RpcmVjdGl2ZX0gc3ViXG4gKi9cblxuRGVwLnByb3RvdHlwZS5hZGRTdWIgPSBmdW5jdGlvbiAoc3ViKSB7XG4gIHRoaXMuc3Vicy5wdXNoKHN1Yik7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBhIGRpcmVjdGl2ZSBzdWJzY3JpYmVyLlxuICpcbiAqIEBwYXJhbSB7RGlyZWN0aXZlfSBzdWJcbiAqL1xuXG5EZXAucHJvdG90eXBlLnJlbW92ZVN1YiA9IGZ1bmN0aW9uIChzdWIpIHtcbiAgdGhpcy5zdWJzLiRyZW1vdmUoc3ViKTtcbn07XG5cbi8qKlxuICogQWRkIHNlbGYgYXMgYSBkZXBlbmRlbmN5IHRvIHRoZSB0YXJnZXQgd2F0Y2hlci5cbiAqL1xuXG5EZXAucHJvdG90eXBlLmRlcGVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgRGVwLnRhcmdldC5hZGREZXAodGhpcyk7XG59O1xuXG4vKipcbiAqIE5vdGlmeSBhbGwgc3Vic2NyaWJlcnMgb2YgYSBuZXcgdmFsdWUuXG4gKi9cblxuRGVwLnByb3RvdHlwZS5ub3RpZnkgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIHN0YWJsaXplIHRoZSBzdWJzY3JpYmVyIGxpc3QgZmlyc3RcbiAgdmFyIHN1YnMgPSB0b0FycmF5KHRoaXMuc3Vicyk7XG4gIGZvciAodmFyIGkgPSAwLCBsID0gc3Vicy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBzdWJzW2ldLnVwZGF0ZSgpO1xuICB9XG59O1xuXG52YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTtcbnZhciBhcnJheU1ldGhvZHMgPSBPYmplY3QuY3JlYXRlKGFycmF5UHJvdG8pXG5cbi8qKlxuICogSW50ZXJjZXB0IG11dGF0aW5nIG1ldGhvZHMgYW5kIGVtaXQgZXZlbnRzXG4gKi9cblxuO1sncHVzaCcsICdwb3AnLCAnc2hpZnQnLCAndW5zaGlmdCcsICdzcGxpY2UnLCAnc29ydCcsICdyZXZlcnNlJ10uZm9yRWFjaChmdW5jdGlvbiAobWV0aG9kKSB7XG4gIC8vIGNhY2hlIG9yaWdpbmFsIG1ldGhvZFxuICB2YXIgb3JpZ2luYWwgPSBhcnJheVByb3RvW21ldGhvZF07XG4gIGRlZihhcnJheU1ldGhvZHMsIG1ldGhvZCwgZnVuY3Rpb24gbXV0YXRvcigpIHtcbiAgICAvLyBhdm9pZCBsZWFraW5nIGFyZ3VtZW50czpcbiAgICAvLyBodHRwOi8vanNwZXJmLmNvbS9jbG9zdXJlLXdpdGgtYXJndW1lbnRzXG4gICAgdmFyIGkgPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGkpO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGFyZ3NbaV0gPSBhcmd1bWVudHNbaV07XG4gICAgfVxuICAgIHZhciByZXN1bHQgPSBvcmlnaW5hbC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB2YXIgb2IgPSB0aGlzLl9fb2JfXztcbiAgICB2YXIgaW5zZXJ0ZWQ7XG4gICAgc3dpdGNoIChtZXRob2QpIHtcbiAgICAgIGNhc2UgJ3B1c2gnOlxuICAgICAgICBpbnNlcnRlZCA9IGFyZ3M7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndW5zaGlmdCc6XG4gICAgICAgIGluc2VydGVkID0gYXJncztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdzcGxpY2UnOlxuICAgICAgICBpbnNlcnRlZCA9IGFyZ3Muc2xpY2UoMik7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBpZiAoaW5zZXJ0ZWQpIG9iLm9ic2VydmVBcnJheShpbnNlcnRlZCk7XG4gICAgLy8gbm90aWZ5IGNoYW5nZVxuICAgIG9iLmRlcC5ub3RpZnkoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9KTtcbn0pO1xuXG4vKipcbiAqIFN3YXAgdGhlIGVsZW1lbnQgYXQgdGhlIGdpdmVuIGluZGV4IHdpdGggYSBuZXcgdmFsdWVcbiAqIGFuZCBlbWl0cyBjb3JyZXNwb25kaW5nIGV2ZW50LlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxuICogQHBhcmFtIHsqfSB2YWxcbiAqIEByZXR1cm4geyp9IC0gcmVwbGFjZWQgZWxlbWVudFxuICovXG5cbmRlZihhcnJheVByb3RvLCAnJHNldCcsIGZ1bmN0aW9uICRzZXQoaW5kZXgsIHZhbCkge1xuICBpZiAoaW5kZXggPj0gdGhpcy5sZW5ndGgpIHtcbiAgICB0aGlzLmxlbmd0aCA9IE51bWJlcihpbmRleCkgKyAxO1xuICB9XG4gIHJldHVybiB0aGlzLnNwbGljZShpbmRleCwgMSwgdmFsKVswXTtcbn0pO1xuXG4vKipcbiAqIENvbnZlbmllbmNlIG1ldGhvZCB0byByZW1vdmUgdGhlIGVsZW1lbnQgYXQgZ2l2ZW4gaW5kZXguXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4XG4gKiBAcGFyYW0geyp9IHZhbFxuICovXG5cbmRlZihhcnJheVByb3RvLCAnJHJlbW92ZScsIGZ1bmN0aW9uICRyZW1vdmUoaXRlbSkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKCF0aGlzLmxlbmd0aCkgcmV0dXJuO1xuICB2YXIgaW5kZXggPSBpbmRleE9mKHRoaXMsIGl0ZW0pO1xuICBpZiAoaW5kZXggPiAtMSkge1xuICAgIHJldHVybiB0aGlzLnNwbGljZShpbmRleCwgMSk7XG4gIH1cbn0pO1xuXG52YXIgYXJyYXlLZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoYXJyYXlNZXRob2RzKTtcblxuLyoqXG4gKiBPYnNlcnZlciBjbGFzcyB0aGF0IGFyZSBhdHRhY2hlZCB0byBlYWNoIG9ic2VydmVkXG4gKiBvYmplY3QuIE9uY2UgYXR0YWNoZWQsIHRoZSBvYnNlcnZlciBjb252ZXJ0cyB0YXJnZXRcbiAqIG9iamVjdCdzIHByb3BlcnR5IGtleXMgaW50byBnZXR0ZXIvc2V0dGVycyB0aGF0XG4gKiBjb2xsZWN0IGRlcGVuZGVuY2llcyBhbmQgZGlzcGF0Y2hlcyB1cGRhdGVzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSB2YWx1ZVxuICogQGNvbnN0cnVjdG9yXG4gKi9cblxuZnVuY3Rpb24gT2JzZXJ2ZXIodmFsdWUpIHtcbiAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICB0aGlzLmRlcCA9IG5ldyBEZXAoKTtcbiAgZGVmKHZhbHVlLCAnX19vYl9fJywgdGhpcyk7XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIHZhciBhdWdtZW50ID0gaGFzUHJvdG8gPyBwcm90b0F1Z21lbnQgOiBjb3B5QXVnbWVudDtcbiAgICBhdWdtZW50KHZhbHVlLCBhcnJheU1ldGhvZHMsIGFycmF5S2V5cyk7XG4gICAgdGhpcy5vYnNlcnZlQXJyYXkodmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMud2Fsayh2YWx1ZSk7XG4gIH1cbn1cblxuLy8gSW5zdGFuY2UgbWV0aG9kc1xuXG4vKipcbiAqIFdhbGsgdGhyb3VnaCBlYWNoIHByb3BlcnR5IGFuZCBjb252ZXJ0IHRoZW0gaW50b1xuICogZ2V0dGVyL3NldHRlcnMuIFRoaXMgbWV0aG9kIHNob3VsZCBvbmx5IGJlIGNhbGxlZCB3aGVuXG4gKiB2YWx1ZSB0eXBlIGlzIE9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKi9cblxuT2JzZXJ2ZXIucHJvdG90eXBlLndhbGsgPSBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqKTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBrZXlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIHRoaXMuY29udmVydChrZXlzW2ldLCBvYmpba2V5c1tpXV0pO1xuICB9XG59O1xuXG4vKipcbiAqIE9ic2VydmUgYSBsaXN0IG9mIEFycmF5IGl0ZW1zLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGl0ZW1zXG4gKi9cblxuT2JzZXJ2ZXIucHJvdG90eXBlLm9ic2VydmVBcnJheSA9IGZ1bmN0aW9uIChpdGVtcykge1xuICBmb3IgKHZhciBpID0gMCwgbCA9IGl0ZW1zLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIG9ic2VydmUoaXRlbXNbaV0pO1xuICB9XG59O1xuXG4vKipcbiAqIENvbnZlcnQgYSBwcm9wZXJ0eSBpbnRvIGdldHRlci9zZXR0ZXIgc28gd2UgY2FuIGVtaXRcbiAqIHRoZSBldmVudHMgd2hlbiB0aGUgcHJvcGVydHkgaXMgYWNjZXNzZWQvY2hhbmdlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gKiBAcGFyYW0geyp9IHZhbFxuICovXG5cbk9ic2VydmVyLnByb3RvdHlwZS5jb252ZXJ0ID0gZnVuY3Rpb24gKGtleSwgdmFsKSB7XG4gIGRlZmluZVJlYWN0aXZlKHRoaXMudmFsdWUsIGtleSwgdmFsKTtcbn07XG5cbi8qKlxuICogQWRkIGFuIG93bmVyIHZtLCBzbyB0aGF0IHdoZW4gJHNldC8kZGVsZXRlIG11dGF0aW9uc1xuICogaGFwcGVuIHdlIGNhbiBub3RpZnkgb3duZXIgdm1zIHRvIHByb3h5IHRoZSBrZXlzIGFuZFxuICogZGlnZXN0IHRoZSB3YXRjaGVycy4gVGhpcyBpcyBvbmx5IGNhbGxlZCB3aGVuIHRoZSBvYmplY3RcbiAqIGlzIG9ic2VydmVkIGFzIGFuIGluc3RhbmNlJ3Mgcm9vdCAkZGF0YS5cbiAqXG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqL1xuXG5PYnNlcnZlci5wcm90b3R5cGUuYWRkVm0gPSBmdW5jdGlvbiAodm0pIHtcbiAgKHRoaXMudm1zIHx8ICh0aGlzLnZtcyA9IFtdKSkucHVzaCh2bSk7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBhbiBvd25lciB2bS4gVGhpcyBpcyBjYWxsZWQgd2hlbiB0aGUgb2JqZWN0IGlzXG4gKiBzd2FwcGVkIG91dCBhcyBhbiBpbnN0YW5jZSdzICRkYXRhIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqL1xuXG5PYnNlcnZlci5wcm90b3R5cGUucmVtb3ZlVm0gPSBmdW5jdGlvbiAodm0pIHtcbiAgdGhpcy52bXMuJHJlbW92ZSh2bSk7XG59O1xuXG4vLyBoZWxwZXJzXG5cbi8qKlxuICogQXVnbWVudCBhbiB0YXJnZXQgT2JqZWN0IG9yIEFycmF5IGJ5IGludGVyY2VwdGluZ1xuICogdGhlIHByb3RvdHlwZSBjaGFpbiB1c2luZyBfX3Byb3RvX19cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxBcnJheX0gdGFyZ2V0XG4gKiBAcGFyYW0ge09iamVjdH0gcHJvdG9cbiAqL1xuXG5mdW5jdGlvbiBwcm90b0F1Z21lbnQodGFyZ2V0LCBzcmMpIHtcbiAgLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cbiAgdGFyZ2V0Ll9fcHJvdG9fXyA9IHNyYztcbiAgLyogZXNsaW50LWVuYWJsZSBuby1wcm90byAqL1xufVxuXG4vKipcbiAqIEF1Z21lbnQgYW4gdGFyZ2V0IE9iamVjdCBvciBBcnJheSBieSBkZWZpbmluZ1xuICogaGlkZGVuIHByb3BlcnRpZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8QXJyYXl9IHRhcmdldFxuICogQHBhcmFtIHtPYmplY3R9IHByb3RvXG4gKi9cblxuZnVuY3Rpb24gY29weUF1Z21lbnQodGFyZ2V0LCBzcmMsIGtleXMpIHtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBrZXlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgIGRlZih0YXJnZXQsIGtleSwgc3JjW2tleV0pO1xuICB9XG59XG5cbi8qKlxuICogQXR0ZW1wdCB0byBjcmVhdGUgYW4gb2JzZXJ2ZXIgaW5zdGFuY2UgZm9yIGEgdmFsdWUsXG4gKiByZXR1cm5zIHRoZSBuZXcgb2JzZXJ2ZXIgaWYgc3VjY2Vzc2Z1bGx5IG9ic2VydmVkLFxuICogb3IgdGhlIGV4aXN0aW5nIG9ic2VydmVyIGlmIHRoZSB2YWx1ZSBhbHJlYWR5IGhhcyBvbmUuXG4gKlxuICogQHBhcmFtIHsqfSB2YWx1ZVxuICogQHBhcmFtIHtWdWV9IFt2bV1cbiAqIEByZXR1cm4ge09ic2VydmVyfHVuZGVmaW5lZH1cbiAqIEBzdGF0aWNcbiAqL1xuXG5mdW5jdGlvbiBvYnNlcnZlKHZhbHVlLCB2bSkge1xuICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIG9iO1xuICBpZiAoaGFzT3duKHZhbHVlLCAnX19vYl9fJykgJiYgdmFsdWUuX19vYl9fIGluc3RhbmNlb2YgT2JzZXJ2ZXIpIHtcbiAgICBvYiA9IHZhbHVlLl9fb2JfXztcbiAgfSBlbHNlIGlmICgoaXNBcnJheSh2YWx1ZSkgfHwgaXNQbGFpbk9iamVjdCh2YWx1ZSkpICYmIE9iamVjdC5pc0V4dGVuc2libGUodmFsdWUpICYmICF2YWx1ZS5faXNWdWUpIHtcbiAgICBvYiA9IG5ldyBPYnNlcnZlcih2YWx1ZSk7XG4gIH1cbiAgaWYgKG9iICYmIHZtKSB7XG4gICAgb2IuYWRkVm0odm0pO1xuICB9XG4gIHJldHVybiBvYjtcbn1cblxuLyoqXG4gKiBEZWZpbmUgYSByZWFjdGl2ZSBwcm9wZXJ0eSBvbiBhbiBPYmplY3QuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICogQHBhcmFtIHsqfSB2YWxcbiAqL1xuXG5mdW5jdGlvbiBkZWZpbmVSZWFjdGl2ZShvYmosIGtleSwgdmFsKSB7XG4gIHZhciBkZXAgPSBuZXcgRGVwKCk7XG5cbiAgdmFyIHByb3BlcnR5ID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihvYmosIGtleSk7XG4gIGlmIChwcm9wZXJ0eSAmJiBwcm9wZXJ0eS5jb25maWd1cmFibGUgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gY2F0ZXIgZm9yIHByZS1kZWZpbmVkIGdldHRlci9zZXR0ZXJzXG4gIHZhciBnZXR0ZXIgPSBwcm9wZXJ0eSAmJiBwcm9wZXJ0eS5nZXQ7XG4gIHZhciBzZXR0ZXIgPSBwcm9wZXJ0eSAmJiBwcm9wZXJ0eS5zZXQ7XG5cbiAgdmFyIGNoaWxkT2IgPSBvYnNlcnZlKHZhbCk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIGdldDogZnVuY3Rpb24gcmVhY3RpdmVHZXR0ZXIoKSB7XG4gICAgICB2YXIgdmFsdWUgPSBnZXR0ZXIgPyBnZXR0ZXIuY2FsbChvYmopIDogdmFsO1xuICAgICAgaWYgKERlcC50YXJnZXQpIHtcbiAgICAgICAgZGVwLmRlcGVuZCgpO1xuICAgICAgICBpZiAoY2hpbGRPYikge1xuICAgICAgICAgIGNoaWxkT2IuZGVwLmRlcGVuZCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIGZvciAodmFyIGUsIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICBlID0gdmFsdWVbaV07XG4gICAgICAgICAgICBlICYmIGUuX19vYl9fICYmIGUuX19vYl9fLmRlcC5kZXBlbmQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24gcmVhY3RpdmVTZXR0ZXIobmV3VmFsKSB7XG4gICAgICB2YXIgdmFsdWUgPSBnZXR0ZXIgPyBnZXR0ZXIuY2FsbChvYmopIDogdmFsO1xuICAgICAgaWYgKG5ld1ZhbCA9PT0gdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHNldHRlcikge1xuICAgICAgICBzZXR0ZXIuY2FsbChvYmosIG5ld1ZhbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWwgPSBuZXdWYWw7XG4gICAgICB9XG4gICAgICBjaGlsZE9iID0gb2JzZXJ2ZShuZXdWYWwpO1xuICAgICAgZGVwLm5vdGlmeSgpO1xuICAgIH1cbiAgfSk7XG59XG5cblxuXG52YXIgdXRpbCA9IE9iamVjdC5mcmVlemUoe1xuXHRkZWZpbmVSZWFjdGl2ZTogZGVmaW5lUmVhY3RpdmUsXG5cdHNldDogc2V0LFxuXHRkZWw6IGRlbCxcblx0aGFzT3duOiBoYXNPd24sXG5cdGlzTGl0ZXJhbDogaXNMaXRlcmFsLFxuXHRpc1Jlc2VydmVkOiBpc1Jlc2VydmVkLFxuXHRfdG9TdHJpbmc6IF90b1N0cmluZyxcblx0dG9OdW1iZXI6IHRvTnVtYmVyLFxuXHR0b0Jvb2xlYW46IHRvQm9vbGVhbixcblx0c3RyaXBRdW90ZXM6IHN0cmlwUXVvdGVzLFxuXHRjYW1lbGl6ZTogY2FtZWxpemUsXG5cdGh5cGhlbmF0ZTogaHlwaGVuYXRlLFxuXHRjbGFzc2lmeTogY2xhc3NpZnksXG5cdGJpbmQ6IGJpbmQsXG5cdHRvQXJyYXk6IHRvQXJyYXksXG5cdGV4dGVuZDogZXh0ZW5kLFxuXHRpc09iamVjdDogaXNPYmplY3QsXG5cdGlzUGxhaW5PYmplY3Q6IGlzUGxhaW5PYmplY3QsXG5cdGRlZjogZGVmLFxuXHRkZWJvdW5jZTogX2RlYm91bmNlLFxuXHRpbmRleE9mOiBpbmRleE9mLFxuXHRjYW5jZWxsYWJsZTogY2FuY2VsbGFibGUsXG5cdGxvb3NlRXF1YWw6IGxvb3NlRXF1YWwsXG5cdGlzQXJyYXk6IGlzQXJyYXksXG5cdGhhc1Byb3RvOiBoYXNQcm90byxcblx0aW5Ccm93c2VyOiBpbkJyb3dzZXIsXG5cdGRldnRvb2xzOiBkZXZ0b29scyxcblx0aXNJRTk6IGlzSUU5LFxuXHRpc0FuZHJvaWQ6IGlzQW5kcm9pZCxcblx0Z2V0IHRyYW5zaXRpb25Qcm9wICgpIHsgcmV0dXJuIHRyYW5zaXRpb25Qcm9wOyB9LFxuXHRnZXQgdHJhbnNpdGlvbkVuZEV2ZW50ICgpIHsgcmV0dXJuIHRyYW5zaXRpb25FbmRFdmVudDsgfSxcblx0Z2V0IGFuaW1hdGlvblByb3AgKCkgeyByZXR1cm4gYW5pbWF0aW9uUHJvcDsgfSxcblx0Z2V0IGFuaW1hdGlvbkVuZEV2ZW50ICgpIHsgcmV0dXJuIGFuaW1hdGlvbkVuZEV2ZW50OyB9LFxuXHRuZXh0VGljazogbmV4dFRpY2ssXG5cdHF1ZXJ5OiBxdWVyeSxcblx0aW5Eb2M6IGluRG9jLFxuXHRnZXRBdHRyOiBnZXRBdHRyLFxuXHRnZXRCaW5kQXR0cjogZ2V0QmluZEF0dHIsXG5cdGhhc0JpbmRBdHRyOiBoYXNCaW5kQXR0cixcblx0YmVmb3JlOiBiZWZvcmUsXG5cdGFmdGVyOiBhZnRlcixcblx0cmVtb3ZlOiByZW1vdmUsXG5cdHByZXBlbmQ6IHByZXBlbmQsXG5cdHJlcGxhY2U6IHJlcGxhY2UsXG5cdG9uOiBvbixcblx0b2ZmOiBvZmYsXG5cdHNldENsYXNzOiBzZXRDbGFzcyxcblx0YWRkQ2xhc3M6IGFkZENsYXNzLFxuXHRyZW1vdmVDbGFzczogcmVtb3ZlQ2xhc3MsXG5cdGV4dHJhY3RDb250ZW50OiBleHRyYWN0Q29udGVudCxcblx0dHJpbU5vZGU6IHRyaW1Ob2RlLFxuXHRpc1RlbXBsYXRlOiBpc1RlbXBsYXRlLFxuXHRjcmVhdGVBbmNob3I6IGNyZWF0ZUFuY2hvcixcblx0ZmluZFJlZjogZmluZFJlZixcblx0bWFwTm9kZVJhbmdlOiBtYXBOb2RlUmFuZ2UsXG5cdHJlbW92ZU5vZGVSYW5nZTogcmVtb3ZlTm9kZVJhbmdlLFxuXHRpc0ZyYWdtZW50OiBpc0ZyYWdtZW50LFxuXHRnZXRPdXRlckhUTUw6IGdldE91dGVySFRNTCxcblx0bWVyZ2VPcHRpb25zOiBtZXJnZU9wdGlvbnMsXG5cdHJlc29sdmVBc3NldDogcmVzb2x2ZUFzc2V0LFxuXHRhc3NlcnRBc3NldDogYXNzZXJ0QXNzZXQsXG5cdGNoZWNrQ29tcG9uZW50QXR0cjogY2hlY2tDb21wb25lbnRBdHRyLFxuXHRpbml0UHJvcDogaW5pdFByb3AsXG5cdGFzc2VydFByb3A6IGFzc2VydFByb3AsXG5cdGNvZXJjZVByb3A6IGNvZXJjZVByb3AsXG5cdGNvbW1vblRhZ1JFOiBjb21tb25UYWdSRSxcblx0cmVzZXJ2ZWRUYWdSRTogcmVzZXJ2ZWRUYWdSRSxcblx0Z2V0IHdhcm4gKCkgeyByZXR1cm4gd2FybjsgfVxufSk7XG5cbnZhciB1aWQgPSAwO1xuXG5mdW5jdGlvbiBpbml0TWl4aW4gKFZ1ZSkge1xuICAvKipcbiAgICogVGhlIG1haW4gaW5pdCBzZXF1ZW5jZS4gVGhpcyBpcyBjYWxsZWQgZm9yIGV2ZXJ5XG4gICAqIGluc3RhbmNlLCBpbmNsdWRpbmcgb25lcyB0aGF0IGFyZSBjcmVhdGVkIGZyb20gZXh0ZW5kZWRcbiAgICogY29uc3RydWN0b3JzLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIHRoaXMgb3B0aW9ucyBvYmplY3Qgc2hvdWxkIGJlXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIHJlc3VsdCBvZiBtZXJnaW5nIGNsYXNzXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyBhbmQgdGhlIG9wdGlvbnMgcGFzc2VkXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgaW4gdG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgIHRoaXMuJGVsID0gbnVsbDtcbiAgICB0aGlzLiRwYXJlbnQgPSBvcHRpb25zLnBhcmVudDtcbiAgICB0aGlzLiRyb290ID0gdGhpcy4kcGFyZW50ID8gdGhpcy4kcGFyZW50LiRyb290IDogdGhpcztcbiAgICB0aGlzLiRjaGlsZHJlbiA9IFtdO1xuICAgIHRoaXMuJHJlZnMgPSB7fTsgLy8gY2hpbGQgdm0gcmVmZXJlbmNlc1xuICAgIHRoaXMuJGVscyA9IHt9OyAvLyBlbGVtZW50IHJlZmVyZW5jZXNcbiAgICB0aGlzLl93YXRjaGVycyA9IFtdOyAvLyBhbGwgd2F0Y2hlcnMgYXMgYW4gYXJyYXlcbiAgICB0aGlzLl9kaXJlY3RpdmVzID0gW107IC8vIGFsbCBkaXJlY3RpdmVzXG5cbiAgICAvLyBhIHVpZFxuICAgIHRoaXMuX3VpZCA9IHVpZCsrO1xuXG4gICAgLy8gYSBmbGFnIHRvIGF2b2lkIHRoaXMgYmVpbmcgb2JzZXJ2ZWRcbiAgICB0aGlzLl9pc1Z1ZSA9IHRydWU7XG5cbiAgICAvLyBldmVudHMgYm9va2tlZXBpbmdcbiAgICB0aGlzLl9ldmVudHMgPSB7fTsgLy8gcmVnaXN0ZXJlZCBjYWxsYmFja3NcbiAgICB0aGlzLl9ldmVudHNDb3VudCA9IHt9OyAvLyBmb3IgJGJyb2FkY2FzdCBvcHRpbWl6YXRpb25cblxuICAgIC8vIGZyYWdtZW50IGluc3RhbmNlIHByb3BlcnRpZXNcbiAgICB0aGlzLl9pc0ZyYWdtZW50ID0gZmFsc2U7XG4gICAgdGhpcy5fZnJhZ21lbnQgPSAvLyBAdHlwZSB7RG9jdW1lbnRGcmFnbWVudH1cbiAgICB0aGlzLl9mcmFnbWVudFN0YXJ0ID0gLy8gQHR5cGUge1RleHR8Q29tbWVudH1cbiAgICB0aGlzLl9mcmFnbWVudEVuZCA9IG51bGw7IC8vIEB0eXBlIHtUZXh0fENvbW1lbnR9XG5cbiAgICAvLyBsaWZlY3ljbGUgc3RhdGVcbiAgICB0aGlzLl9pc0NvbXBpbGVkID0gdGhpcy5faXNEZXN0cm95ZWQgPSB0aGlzLl9pc1JlYWR5ID0gdGhpcy5faXNBdHRhY2hlZCA9IHRoaXMuX2lzQmVpbmdEZXN0cm95ZWQgPSB0aGlzLl92Rm9yUmVtb3ZpbmcgPSBmYWxzZTtcbiAgICB0aGlzLl91bmxpbmtGbiA9IG51bGw7XG5cbiAgICAvLyBjb250ZXh0OlxuICAgIC8vIGlmIHRoaXMgaXMgYSB0cmFuc2NsdWRlZCBjb21wb25lbnQsIGNvbnRleHRcbiAgICAvLyB3aWxsIGJlIHRoZSBjb21tb24gcGFyZW50IHZtIG9mIHRoaXMgaW5zdGFuY2VcbiAgICAvLyBhbmQgaXRzIGhvc3QuXG4gICAgdGhpcy5fY29udGV4dCA9IG9wdGlvbnMuX2NvbnRleHQgfHwgdGhpcy4kcGFyZW50O1xuXG4gICAgLy8gc2NvcGU6XG4gICAgLy8gaWYgdGhpcyBpcyBpbnNpZGUgYW4gaW5saW5lIHYtZm9yLCB0aGUgc2NvcGVcbiAgICAvLyB3aWxsIGJlIHRoZSBpbnRlcm1lZGlhdGUgc2NvcGUgY3JlYXRlZCBmb3IgdGhpc1xuICAgIC8vIHJlcGVhdCBmcmFnbWVudC4gdGhpcyBpcyB1c2VkIGZvciBsaW5raW5nIHByb3BzXG4gICAgLy8gYW5kIGNvbnRhaW5lciBkaXJlY3RpdmVzLlxuICAgIHRoaXMuX3Njb3BlID0gb3B0aW9ucy5fc2NvcGU7XG5cbiAgICAvLyBmcmFnbWVudDpcbiAgICAvLyBpZiB0aGlzIGluc3RhbmNlIGlzIGNvbXBpbGVkIGluc2lkZSBhIEZyYWdtZW50LCBpdFxuICAgIC8vIG5lZWRzIHRvIHJlaWdzdGVyIGl0c2VsZiBhcyBhIGNoaWxkIG9mIHRoYXQgZnJhZ21lbnRcbiAgICAvLyBmb3IgYXR0YWNoL2RldGFjaCB0byB3b3JrIHByb3Blcmx5LlxuICAgIHRoaXMuX2ZyYWcgPSBvcHRpb25zLl9mcmFnO1xuICAgIGlmICh0aGlzLl9mcmFnKSB7XG4gICAgICB0aGlzLl9mcmFnLmNoaWxkcmVuLnB1c2godGhpcyk7XG4gICAgfVxuXG4gICAgLy8gcHVzaCBzZWxmIGludG8gcGFyZW50IC8gdHJhbnNjbHVzaW9uIGhvc3RcbiAgICBpZiAodGhpcy4kcGFyZW50KSB7XG4gICAgICB0aGlzLiRwYXJlbnQuJGNoaWxkcmVuLnB1c2godGhpcyk7XG4gICAgfVxuXG4gICAgLy8gc2F2ZSByYXcgY29uc3RydWN0b3IgZGF0YSBiZWZvcmUgbWVyZ2VcbiAgICAvLyBzbyB0aGF0IHdlIGtub3cgd2hpY2ggcHJvcGVydGllcyBhcmUgcHJvdmlkZWQgYXRcbiAgICAvLyBpbnN0YW50aWF0aW9uLlxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICB0aGlzLl9ydW50aW1lRGF0YSA9IG9wdGlvbnMuZGF0YTtcbiAgICB9XG5cbiAgICAvLyBtZXJnZSBvcHRpb25zLlxuICAgIG9wdGlvbnMgPSB0aGlzLiRvcHRpb25zID0gbWVyZ2VPcHRpb25zKHRoaXMuY29uc3RydWN0b3Iub3B0aW9ucywgb3B0aW9ucywgdGhpcyk7XG5cbiAgICAvLyBzZXQgcmVmXG4gICAgdGhpcy5fdXBkYXRlUmVmKCk7XG5cbiAgICAvLyBpbml0aWFsaXplIGRhdGEgYXMgZW1wdHkgb2JqZWN0LlxuICAgIC8vIGl0IHdpbGwgYmUgZmlsbGVkIHVwIGluIF9pbml0U2NvcGUoKS5cbiAgICB0aGlzLl9kYXRhID0ge307XG5cbiAgICAvLyBjYWxsIGluaXQgaG9va1xuICAgIHRoaXMuX2NhbGxIb29rKCdpbml0Jyk7XG5cbiAgICAvLyBpbml0aWFsaXplIGRhdGEgb2JzZXJ2YXRpb24gYW5kIHNjb3BlIGluaGVyaXRhbmNlLlxuICAgIHRoaXMuX2luaXRTdGF0ZSgpO1xuXG4gICAgLy8gc2V0dXAgZXZlbnQgc3lzdGVtIGFuZCBvcHRpb24gZXZlbnRzLlxuICAgIHRoaXMuX2luaXRFdmVudHMoKTtcblxuICAgIC8vIGNhbGwgY3JlYXRlZCBob29rXG4gICAgdGhpcy5fY2FsbEhvb2soJ2NyZWF0ZWQnKTtcblxuICAgIC8vIGlmIGBlbGAgb3B0aW9uIGlzIHBhc3NlZCwgc3RhcnQgY29tcGlsYXRpb24uXG4gICAgaWYgKG9wdGlvbnMuZWwpIHtcbiAgICAgIHRoaXMuJG1vdW50KG9wdGlvbnMuZWwpO1xuICAgIH1cbiAgfTtcbn1cblxudmFyIHBhdGhDYWNoZSA9IG5ldyBDYWNoZSgxMDAwKTtcblxuLy8gYWN0aW9uc1xudmFyIEFQUEVORCA9IDA7XG52YXIgUFVTSCA9IDE7XG52YXIgSU5DX1NVQl9QQVRIX0RFUFRIID0gMjtcbnZhciBQVVNIX1NVQl9QQVRIID0gMztcblxuLy8gc3RhdGVzXG52YXIgQkVGT1JFX1BBVEggPSAwO1xudmFyIElOX1BBVEggPSAxO1xudmFyIEJFRk9SRV9JREVOVCA9IDI7XG52YXIgSU5fSURFTlQgPSAzO1xudmFyIElOX1NVQl9QQVRIID0gNDtcbnZhciBJTl9TSU5HTEVfUVVPVEUgPSA1O1xudmFyIElOX0RPVUJMRV9RVU9URSA9IDY7XG52YXIgQUZURVJfUEFUSCA9IDc7XG52YXIgRVJST1IgPSA4O1xuXG52YXIgcGF0aFN0YXRlTWFjaGluZSA9IFtdO1xuXG5wYXRoU3RhdGVNYWNoaW5lW0JFRk9SRV9QQVRIXSA9IHtcbiAgJ3dzJzogW0JFRk9SRV9QQVRIXSxcbiAgJ2lkZW50JzogW0lOX0lERU5ULCBBUFBFTkRdLFxuICAnWyc6IFtJTl9TVUJfUEFUSF0sXG4gICdlb2YnOiBbQUZURVJfUEFUSF1cbn07XG5cbnBhdGhTdGF0ZU1hY2hpbmVbSU5fUEFUSF0gPSB7XG4gICd3cyc6IFtJTl9QQVRIXSxcbiAgJy4nOiBbQkVGT1JFX0lERU5UXSxcbiAgJ1snOiBbSU5fU1VCX1BBVEhdLFxuICAnZW9mJzogW0FGVEVSX1BBVEhdXG59O1xuXG5wYXRoU3RhdGVNYWNoaW5lW0JFRk9SRV9JREVOVF0gPSB7XG4gICd3cyc6IFtCRUZPUkVfSURFTlRdLFxuICAnaWRlbnQnOiBbSU5fSURFTlQsIEFQUEVORF1cbn07XG5cbnBhdGhTdGF0ZU1hY2hpbmVbSU5fSURFTlRdID0ge1xuICAnaWRlbnQnOiBbSU5fSURFTlQsIEFQUEVORF0sXG4gICcwJzogW0lOX0lERU5ULCBBUFBFTkRdLFxuICAnbnVtYmVyJzogW0lOX0lERU5ULCBBUFBFTkRdLFxuICAnd3MnOiBbSU5fUEFUSCwgUFVTSF0sXG4gICcuJzogW0JFRk9SRV9JREVOVCwgUFVTSF0sXG4gICdbJzogW0lOX1NVQl9QQVRILCBQVVNIXSxcbiAgJ2VvZic6IFtBRlRFUl9QQVRILCBQVVNIXVxufTtcblxucGF0aFN0YXRlTWFjaGluZVtJTl9TVUJfUEFUSF0gPSB7XG4gIFwiJ1wiOiBbSU5fU0lOR0xFX1FVT1RFLCBBUFBFTkRdLFxuICAnXCInOiBbSU5fRE9VQkxFX1FVT1RFLCBBUFBFTkRdLFxuICAnWyc6IFtJTl9TVUJfUEFUSCwgSU5DX1NVQl9QQVRIX0RFUFRIXSxcbiAgJ10nOiBbSU5fUEFUSCwgUFVTSF9TVUJfUEFUSF0sXG4gICdlb2YnOiBFUlJPUixcbiAgJ2Vsc2UnOiBbSU5fU1VCX1BBVEgsIEFQUEVORF1cbn07XG5cbnBhdGhTdGF0ZU1hY2hpbmVbSU5fU0lOR0xFX1FVT1RFXSA9IHtcbiAgXCInXCI6IFtJTl9TVUJfUEFUSCwgQVBQRU5EXSxcbiAgJ2VvZic6IEVSUk9SLFxuICAnZWxzZSc6IFtJTl9TSU5HTEVfUVVPVEUsIEFQUEVORF1cbn07XG5cbnBhdGhTdGF0ZU1hY2hpbmVbSU5fRE9VQkxFX1FVT1RFXSA9IHtcbiAgJ1wiJzogW0lOX1NVQl9QQVRILCBBUFBFTkRdLFxuICAnZW9mJzogRVJST1IsXG4gICdlbHNlJzogW0lOX0RPVUJMRV9RVU9URSwgQVBQRU5EXVxufTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgdGhlIHR5cGUgb2YgYSBjaGFyYWN0ZXIgaW4gYSBrZXlwYXRoLlxuICpcbiAqIEBwYXJhbSB7Q2hhcn0gY2hcbiAqIEByZXR1cm4ge1N0cmluZ30gdHlwZVxuICovXG5cbmZ1bmN0aW9uIGdldFBhdGhDaGFyVHlwZShjaCkge1xuICBpZiAoY2ggPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiAnZW9mJztcbiAgfVxuXG4gIHZhciBjb2RlID0gY2guY2hhckNvZGVBdCgwKTtcblxuICBzd2l0Y2ggKGNvZGUpIHtcbiAgICBjYXNlIDB4NUI6IC8vIFtcbiAgICBjYXNlIDB4NUQ6IC8vIF1cbiAgICBjYXNlIDB4MkU6IC8vIC5cbiAgICBjYXNlIDB4MjI6IC8vIFwiXG4gICAgY2FzZSAweDI3OiAvLyAnXG4gICAgY2FzZSAweDMwOlxuICAgICAgLy8gMFxuICAgICAgcmV0dXJuIGNoO1xuXG4gICAgY2FzZSAweDVGOiAvLyBfXG4gICAgY2FzZSAweDI0OlxuICAgICAgLy8gJFxuICAgICAgcmV0dXJuICdpZGVudCc7XG5cbiAgICBjYXNlIDB4MjA6IC8vIFNwYWNlXG4gICAgY2FzZSAweDA5OiAvLyBUYWJcbiAgICBjYXNlIDB4MEE6IC8vIE5ld2xpbmVcbiAgICBjYXNlIDB4MEQ6IC8vIFJldHVyblxuICAgIGNhc2UgMHhBMDogLy8gTm8tYnJlYWsgc3BhY2VcbiAgICBjYXNlIDB4RkVGRjogLy8gQnl0ZSBPcmRlciBNYXJrXG4gICAgY2FzZSAweDIwMjg6IC8vIExpbmUgU2VwYXJhdG9yXG4gICAgY2FzZSAweDIwMjk6XG4gICAgICAvLyBQYXJhZ3JhcGggU2VwYXJhdG9yXG4gICAgICByZXR1cm4gJ3dzJztcbiAgfVxuXG4gIC8vIGEteiwgQS1aXG4gIGlmIChjb2RlID49IDB4NjEgJiYgY29kZSA8PSAweDdBIHx8IGNvZGUgPj0gMHg0MSAmJiBjb2RlIDw9IDB4NUEpIHtcbiAgICByZXR1cm4gJ2lkZW50JztcbiAgfVxuXG4gIC8vIDEtOVxuICBpZiAoY29kZSA+PSAweDMxICYmIGNvZGUgPD0gMHgzOSkge1xuICAgIHJldHVybiAnbnVtYmVyJztcbiAgfVxuXG4gIHJldHVybiAnZWxzZSc7XG59XG5cbi8qKlxuICogRm9ybWF0IGEgc3ViUGF0aCwgcmV0dXJuIGl0cyBwbGFpbiBmb3JtIGlmIGl0IGlzXG4gKiBhIGxpdGVyYWwgc3RyaW5nIG9yIG51bWJlci4gT3RoZXJ3aXNlIHByZXBlbmQgdGhlXG4gKiBkeW5hbWljIGluZGljYXRvciAoKikuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhdGhcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBmb3JtYXRTdWJQYXRoKHBhdGgpIHtcbiAgdmFyIHRyaW1tZWQgPSBwYXRoLnRyaW0oKTtcbiAgLy8gaW52YWxpZCBsZWFkaW5nIDBcbiAgaWYgKHBhdGguY2hhckF0KDApID09PSAnMCcgJiYgaXNOYU4ocGF0aCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIGlzTGl0ZXJhbCh0cmltbWVkKSA/IHN0cmlwUXVvdGVzKHRyaW1tZWQpIDogJyonICsgdHJpbW1lZDtcbn1cblxuLyoqXG4gKiBQYXJzZSBhIHN0cmluZyBwYXRoIGludG8gYW4gYXJyYXkgb2Ygc2VnbWVudHNcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcGF0aFxuICogQHJldHVybiB7QXJyYXl8dW5kZWZpbmVkfVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlKHBhdGgpIHtcbiAgdmFyIGtleXMgPSBbXTtcbiAgdmFyIGluZGV4ID0gLTE7XG4gIHZhciBtb2RlID0gQkVGT1JFX1BBVEg7XG4gIHZhciBzdWJQYXRoRGVwdGggPSAwO1xuICB2YXIgYywgbmV3Q2hhciwga2V5LCB0eXBlLCB0cmFuc2l0aW9uLCBhY3Rpb24sIHR5cGVNYXA7XG5cbiAgdmFyIGFjdGlvbnMgPSBbXTtcblxuICBhY3Rpb25zW1BVU0hdID0gZnVuY3Rpb24gKCkge1xuICAgIGlmIChrZXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgICBrZXkgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9O1xuXG4gIGFjdGlvbnNbQVBQRU5EXSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGtleSA9IG5ld0NoYXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGtleSArPSBuZXdDaGFyO1xuICAgIH1cbiAgfTtcblxuICBhY3Rpb25zW0lOQ19TVUJfUEFUSF9ERVBUSF0gPSBmdW5jdGlvbiAoKSB7XG4gICAgYWN0aW9uc1tBUFBFTkRdKCk7XG4gICAgc3ViUGF0aERlcHRoKys7XG4gIH07XG5cbiAgYWN0aW9uc1tQVVNIX1NVQl9QQVRIXSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoc3ViUGF0aERlcHRoID4gMCkge1xuICAgICAgc3ViUGF0aERlcHRoLS07XG4gICAgICBtb2RlID0gSU5fU1VCX1BBVEg7XG4gICAgICBhY3Rpb25zW0FQUEVORF0oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3ViUGF0aERlcHRoID0gMDtcbiAgICAgIGtleSA9IGZvcm1hdFN1YlBhdGgoa2V5KTtcbiAgICAgIGlmIChrZXkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFjdGlvbnNbUFVTSF0oKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgZnVuY3Rpb24gbWF5YmVVbmVzY2FwZVF1b3RlKCkge1xuICAgIHZhciBuZXh0Q2hhciA9IHBhdGhbaW5kZXggKyAxXTtcbiAgICBpZiAobW9kZSA9PT0gSU5fU0lOR0xFX1FVT1RFICYmIG5leHRDaGFyID09PSBcIidcIiB8fCBtb2RlID09PSBJTl9ET1VCTEVfUVVPVEUgJiYgbmV4dENoYXIgPT09ICdcIicpIHtcbiAgICAgIGluZGV4Kys7XG4gICAgICBuZXdDaGFyID0gJ1xcXFwnICsgbmV4dENoYXI7XG4gICAgICBhY3Rpb25zW0FQUEVORF0oKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHdoaWxlIChtb2RlICE9IG51bGwpIHtcbiAgICBpbmRleCsrO1xuICAgIGMgPSBwYXRoW2luZGV4XTtcblxuICAgIGlmIChjID09PSAnXFxcXCcgJiYgbWF5YmVVbmVzY2FwZVF1b3RlKCkpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIHR5cGUgPSBnZXRQYXRoQ2hhclR5cGUoYyk7XG4gICAgdHlwZU1hcCA9IHBhdGhTdGF0ZU1hY2hpbmVbbW9kZV07XG4gICAgdHJhbnNpdGlvbiA9IHR5cGVNYXBbdHlwZV0gfHwgdHlwZU1hcFsnZWxzZSddIHx8IEVSUk9SO1xuXG4gICAgaWYgKHRyYW5zaXRpb24gPT09IEVSUk9SKSB7XG4gICAgICByZXR1cm47IC8vIHBhcnNlIGVycm9yXG4gICAgfVxuXG4gICAgbW9kZSA9IHRyYW5zaXRpb25bMF07XG4gICAgYWN0aW9uID0gYWN0aW9uc1t0cmFuc2l0aW9uWzFdXTtcbiAgICBpZiAoYWN0aW9uKSB7XG4gICAgICBuZXdDaGFyID0gdHJhbnNpdGlvblsyXTtcbiAgICAgIG5ld0NoYXIgPSBuZXdDaGFyID09PSB1bmRlZmluZWQgPyBjIDogbmV3Q2hhcjtcbiAgICAgIGlmIChhY3Rpb24oKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtb2RlID09PSBBRlRFUl9QQVRIKSB7XG4gICAgICBrZXlzLnJhdyA9IHBhdGg7XG4gICAgICByZXR1cm4ga2V5cztcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBFeHRlcm5hbCBwYXJzZSB0aGF0IGNoZWNrIGZvciBhIGNhY2hlIGhpdCBmaXJzdFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoXG4gKiBAcmV0dXJuIHtBcnJheXx1bmRlZmluZWR9XG4gKi9cblxuZnVuY3Rpb24gcGFyc2VQYXRoKHBhdGgpIHtcbiAgdmFyIGhpdCA9IHBhdGhDYWNoZS5nZXQocGF0aCk7XG4gIGlmICghaGl0KSB7XG4gICAgaGl0ID0gcGFyc2UocGF0aCk7XG4gICAgaWYgKGhpdCkge1xuICAgICAgcGF0aENhY2hlLnB1dChwYXRoLCBoaXQpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gaGl0O1xufVxuXG4vKipcbiAqIEdldCBmcm9tIGFuIG9iamVjdCBmcm9tIGEgcGF0aCBzdHJpbmdcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcGFyYW0ge1N0cmluZ30gcGF0aFxuICovXG5cbmZ1bmN0aW9uIGdldFBhdGgob2JqLCBwYXRoKSB7XG4gIHJldHVybiBwYXJzZUV4cHJlc3Npb24ocGF0aCkuZ2V0KG9iaik7XG59XG5cbi8qKlxuICogV2FybiBhZ2FpbnN0IHNldHRpbmcgbm9uLWV4aXN0ZW50IHJvb3QgcGF0aCBvbiBhIHZtLlxuICovXG5cbnZhciB3YXJuTm9uRXhpc3RlbnQ7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICB3YXJuTm9uRXhpc3RlbnQgPSBmdW5jdGlvbiAocGF0aCkge1xuICAgIHdhcm4oJ1lvdSBhcmUgc2V0dGluZyBhIG5vbi1leGlzdGVudCBwYXRoIFwiJyArIHBhdGgucmF3ICsgJ1wiICcgKyAnb24gYSB2bSBpbnN0YW5jZS4gQ29uc2lkZXIgcHJlLWluaXRpYWxpemluZyB0aGUgcHJvcGVydHkgJyArICd3aXRoIHRoZSBcImRhdGFcIiBvcHRpb24gZm9yIG1vcmUgcmVsaWFibGUgcmVhY3Rpdml0eSAnICsgJ2FuZCBiZXR0ZXIgcGVyZm9ybWFuY2UuJyk7XG4gIH07XG59XG5cbi8qKlxuICogU2V0IG9uIGFuIG9iamVjdCBmcm9tIGEgcGF0aFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEBwYXJhbSB7U3RyaW5nIHwgQXJyYXl9IHBhdGhcbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKi9cblxuZnVuY3Rpb24gc2V0UGF0aChvYmosIHBhdGgsIHZhbCkge1xuICB2YXIgb3JpZ2luYWwgPSBvYmo7XG4gIGlmICh0eXBlb2YgcGF0aCA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXRoID0gcGFyc2UocGF0aCk7XG4gIH1cbiAgaWYgKCFwYXRoIHx8ICFpc09iamVjdChvYmopKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBsYXN0LCBrZXk7XG4gIGZvciAodmFyIGkgPSAwLCBsID0gcGF0aC5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICBsYXN0ID0gb2JqO1xuICAgIGtleSA9IHBhdGhbaV07XG4gICAgaWYgKGtleS5jaGFyQXQoMCkgPT09ICcqJykge1xuICAgICAga2V5ID0gcGFyc2VFeHByZXNzaW9uKGtleS5zbGljZSgxKSkuZ2V0LmNhbGwob3JpZ2luYWwsIG9yaWdpbmFsKTtcbiAgICB9XG4gICAgaWYgKGkgPCBsIC0gMSkge1xuICAgICAgb2JqID0gb2JqW2tleV07XG4gICAgICBpZiAoIWlzT2JqZWN0KG9iaikpIHtcbiAgICAgICAgb2JqID0ge307XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIGxhc3QuX2lzVnVlKSB7XG4gICAgICAgICAgd2Fybk5vbkV4aXN0ZW50KHBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIHNldChsYXN0LCBrZXksIG9iaik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgb2JqLiRzZXQoa2V5LCB2YWwpO1xuICAgICAgfSBlbHNlIGlmIChrZXkgaW4gb2JqKSB7XG4gICAgICAgIG9ialtrZXldID0gdmFsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgb2JqLl9pc1Z1ZSkge1xuICAgICAgICAgIHdhcm5Ob25FeGlzdGVudChwYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBzZXQob2JqLCBrZXksIHZhbCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG52YXIgcGF0aCA9IE9iamVjdC5mcmVlemUoe1xuICBwYXJzZVBhdGg6IHBhcnNlUGF0aCxcbiAgZ2V0UGF0aDogZ2V0UGF0aCxcbiAgc2V0UGF0aDogc2V0UGF0aFxufSk7XG5cbnZhciBleHByZXNzaW9uQ2FjaGUgPSBuZXcgQ2FjaGUoMTAwMCk7XG5cbnZhciBhbGxvd2VkS2V5d29yZHMgPSAnTWF0aCxEYXRlLHRoaXMsdHJ1ZSxmYWxzZSxudWxsLHVuZGVmaW5lZCxJbmZpbml0eSxOYU4sJyArICdpc05hTixpc0Zpbml0ZSxkZWNvZGVVUkksZGVjb2RlVVJJQ29tcG9uZW50LGVuY29kZVVSSSwnICsgJ2VuY29kZVVSSUNvbXBvbmVudCxwYXJzZUludCxwYXJzZUZsb2F0JztcbnZhciBhbGxvd2VkS2V5d29yZHNSRSA9IG5ldyBSZWdFeHAoJ14oJyArIGFsbG93ZWRLZXl3b3Jkcy5yZXBsYWNlKC8sL2csICdcXFxcYnwnKSArICdcXFxcYiknKTtcblxuLy8ga2V5d29yZHMgdGhhdCBkb24ndCBtYWtlIHNlbnNlIGluc2lkZSBleHByZXNzaW9uc1xudmFyIGltcHJvcGVyS2V5d29yZHMgPSAnYnJlYWssY2FzZSxjbGFzcyxjYXRjaCxjb25zdCxjb250aW51ZSxkZWJ1Z2dlcixkZWZhdWx0LCcgKyAnZGVsZXRlLGRvLGVsc2UsZXhwb3J0LGV4dGVuZHMsZmluYWxseSxmb3IsZnVuY3Rpb24saWYsJyArICdpbXBvcnQsaW4saW5zdGFuY2VvZixsZXQscmV0dXJuLHN1cGVyLHN3aXRjaCx0aHJvdyx0cnksJyArICd2YXIsd2hpbGUsd2l0aCx5aWVsZCxlbnVtLGF3YWl0LGltcGxlbWVudHMscGFja2FnZSwnICsgJ3Byb2N0ZWN0ZWQsc3RhdGljLGludGVyZmFjZSxwcml2YXRlLHB1YmxpYyc7XG52YXIgaW1wcm9wZXJLZXl3b3Jkc1JFID0gbmV3IFJlZ0V4cCgnXignICsgaW1wcm9wZXJLZXl3b3Jkcy5yZXBsYWNlKC8sL2csICdcXFxcYnwnKSArICdcXFxcYiknKTtcblxudmFyIHdzUkUgPSAvXFxzL2c7XG52YXIgbmV3bGluZVJFID0gL1xcbi9nO1xudmFyIHNhdmVSRSA9IC9bXFx7LF1cXHMqW1xcd1xcJF9dK1xccyo6fCgnKD86W14nXFxcXF18XFxcXC4pKid8XCIoPzpbXlwiXFxcXF18XFxcXC4pKlwifGAoPzpbXmBcXFxcXXxcXFxcLikqXFwkXFx7fFxcfSg/OlteYFxcXFxdfFxcXFwuKSpgfGAoPzpbXmBcXFxcXXxcXFxcLikqYCl8bmV3IHx0eXBlb2YgfHZvaWQgL2c7XG52YXIgcmVzdG9yZVJFID0gL1wiKFxcZCspXCIvZztcbnZhciBwYXRoVGVzdFJFID0gL15bQS1aYS16XyRdW1xcdyRdKig/OlxcLltBLVphLXpfJF1bXFx3JF0qfFxcWycuKj8nXFxdfFxcW1wiLio/XCJcXF18XFxbXFxkK1xcXXxcXFtbQS1aYS16XyRdW1xcdyRdKlxcXSkqJC87XG52YXIgaWRlbnRSRSA9IC9bXlxcdyRcXC5dKD86W0EtWmEtel8kXVtcXHckXSopL2c7XG52YXIgYm9vbGVhbkxpdGVyYWxSRSA9IC9eKD86dHJ1ZXxmYWxzZSkkLztcblxuLyoqXG4gKiBTYXZlIC8gUmV3cml0ZSAvIFJlc3RvcmVcbiAqXG4gKiBXaGVuIHJld3JpdGluZyBwYXRocyBmb3VuZCBpbiBhbiBleHByZXNzaW9uLCBpdCBpc1xuICogcG9zc2libGUgZm9yIHRoZSBzYW1lIGxldHRlciBzZXF1ZW5jZXMgdG8gYmUgZm91bmQgaW5cbiAqIHN0cmluZ3MgYW5kIE9iamVjdCBsaXRlcmFsIHByb3BlcnR5IGtleXMuIFRoZXJlZm9yZSB3ZVxuICogcmVtb3ZlIGFuZCBzdG9yZSB0aGVzZSBwYXJ0cyBpbiBhIHRlbXBvcmFyeSBhcnJheSwgYW5kXG4gKiByZXN0b3JlIHRoZW0gYWZ0ZXIgdGhlIHBhdGggcmV3cml0ZS5cbiAqL1xuXG52YXIgc2F2ZWQgPSBbXTtcblxuLyoqXG4gKiBTYXZlIHJlcGxhY2VyXG4gKlxuICogVGhlIHNhdmUgcmVnZXggY2FuIG1hdGNoIHR3byBwb3NzaWJsZSBjYXNlczpcbiAqIDEuIEFuIG9wZW5pbmcgb2JqZWN0IGxpdGVyYWxcbiAqIDIuIEEgc3RyaW5nXG4gKiBJZiBtYXRjaGVkIGFzIGEgcGxhaW4gc3RyaW5nLCB3ZSBuZWVkIHRvIGVzY2FwZSBpdHNcbiAqIG5ld2xpbmVzLCBzaW5jZSB0aGUgc3RyaW5nIG5lZWRzIHRvIGJlIHByZXNlcnZlZCB3aGVuXG4gKiBnZW5lcmF0aW5nIHRoZSBmdW5jdGlvbiBib2R5LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBpc1N0cmluZyAtIHN0ciBpZiBtYXRjaGVkIGFzIGEgc3RyaW5nXG4gKiBAcmV0dXJuIHtTdHJpbmd9IC0gcGxhY2Vob2xkZXIgd2l0aCBpbmRleFxuICovXG5cbmZ1bmN0aW9uIHNhdmUoc3RyLCBpc1N0cmluZykge1xuICB2YXIgaSA9IHNhdmVkLmxlbmd0aDtcbiAgc2F2ZWRbaV0gPSBpc1N0cmluZyA/IHN0ci5yZXBsYWNlKG5ld2xpbmVSRSwgJ1xcXFxuJykgOiBzdHI7XG4gIHJldHVybiAnXCInICsgaSArICdcIic7XG59XG5cbi8qKlxuICogUGF0aCByZXdyaXRlIHJlcGxhY2VyXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJhd1xuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5cbmZ1bmN0aW9uIHJld3JpdGUocmF3KSB7XG4gIHZhciBjID0gcmF3LmNoYXJBdCgwKTtcbiAgdmFyIHBhdGggPSByYXcuc2xpY2UoMSk7XG4gIGlmIChhbGxvd2VkS2V5d29yZHNSRS50ZXN0KHBhdGgpKSB7XG4gICAgcmV0dXJuIHJhdztcbiAgfSBlbHNlIHtcbiAgICBwYXRoID0gcGF0aC5pbmRleE9mKCdcIicpID4gLTEgPyBwYXRoLnJlcGxhY2UocmVzdG9yZVJFLCByZXN0b3JlKSA6IHBhdGg7XG4gICAgcmV0dXJuIGMgKyAnc2NvcGUuJyArIHBhdGg7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXN0b3JlIHJlcGxhY2VyXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHBhcmFtIHtTdHJpbmd9IGkgLSBtYXRjaGVkIHNhdmUgaW5kZXhcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiByZXN0b3JlKHN0ciwgaSkge1xuICByZXR1cm4gc2F2ZWRbaV07XG59XG5cbi8qKlxuICogUmV3cml0ZSBhbiBleHByZXNzaW9uLCBwcmVmaXhpbmcgYWxsIHBhdGggYWNjZXNzb3JzIHdpdGhcbiAqIGBzY29wZS5gIGFuZCBnZW5lcmF0ZSBnZXR0ZXIvc2V0dGVyIGZ1bmN0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXhwXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5mdW5jdGlvbiBjb21waWxlR2V0dGVyKGV4cCkge1xuICBpZiAoaW1wcm9wZXJLZXl3b3Jkc1JFLnRlc3QoZXhwKSkge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybignQXZvaWQgdXNpbmcgcmVzZXJ2ZWQga2V5d29yZHMgaW4gZXhwcmVzc2lvbjogJyArIGV4cCk7XG4gIH1cbiAgLy8gcmVzZXQgc3RhdGVcbiAgc2F2ZWQubGVuZ3RoID0gMDtcbiAgLy8gc2F2ZSBzdHJpbmdzIGFuZCBvYmplY3QgbGl0ZXJhbCBrZXlzXG4gIHZhciBib2R5ID0gZXhwLnJlcGxhY2Uoc2F2ZVJFLCBzYXZlKS5yZXBsYWNlKHdzUkUsICcnKTtcbiAgLy8gcmV3cml0ZSBhbGwgcGF0aHNcbiAgLy8gcGFkIDEgc3BhY2UgaGVyZSBiZWNhdWUgdGhlIHJlZ2V4IG1hdGNoZXMgMSBleHRyYSBjaGFyXG4gIGJvZHkgPSAoJyAnICsgYm9keSkucmVwbGFjZShpZGVudFJFLCByZXdyaXRlKS5yZXBsYWNlKHJlc3RvcmVSRSwgcmVzdG9yZSk7XG4gIHJldHVybiBtYWtlR2V0dGVyRm4oYm9keSk7XG59XG5cbi8qKlxuICogQnVpbGQgYSBnZXR0ZXIgZnVuY3Rpb24uIFJlcXVpcmVzIGV2YWwuXG4gKlxuICogV2UgaXNvbGF0ZSB0aGUgdHJ5L2NhdGNoIHNvIGl0IGRvZXNuJ3QgYWZmZWN0IHRoZVxuICogb3B0aW1pemF0aW9uIG9mIHRoZSBwYXJzZSBmdW5jdGlvbiB3aGVuIGl0IGlzIG5vdCBjYWxsZWQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGJvZHlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufHVuZGVmaW5lZH1cbiAqL1xuXG5mdW5jdGlvbiBtYWtlR2V0dGVyRm4oYm9keSkge1xuICB0cnkge1xuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLW5ldy1mdW5jICovXG4gICAgcmV0dXJuIG5ldyBGdW5jdGlvbignc2NvcGUnLCAncmV0dXJuICcgKyBib2R5ICsgJzsnKTtcbiAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLW5ldy1mdW5jICovXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oJ0ludmFsaWQgZXhwcmVzc2lvbi4gJyArICdHZW5lcmF0ZWQgZnVuY3Rpb24gYm9keTogJyArIGJvZHkpO1xuICB9XG59XG5cbi8qKlxuICogQ29tcGlsZSBhIHNldHRlciBmdW5jdGlvbiBmb3IgdGhlIGV4cHJlc3Npb24uXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV4cFxuICogQHJldHVybiB7RnVuY3Rpb258dW5kZWZpbmVkfVxuICovXG5cbmZ1bmN0aW9uIGNvbXBpbGVTZXR0ZXIoZXhwKSB7XG4gIHZhciBwYXRoID0gcGFyc2VQYXRoKGV4cCk7XG4gIGlmIChwYXRoKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChzY29wZSwgdmFsKSB7XG4gICAgICBzZXRQYXRoKHNjb3BlLCBwYXRoLCB2YWwpO1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKCdJbnZhbGlkIHNldHRlciBleHByZXNzaW9uOiAnICsgZXhwKTtcbiAgfVxufVxuXG4vKipcbiAqIFBhcnNlIGFuIGV4cHJlc3Npb24gaW50byByZS13cml0dGVuIGdldHRlci9zZXR0ZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBleHBcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gbmVlZFNldFxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cblxuZnVuY3Rpb24gcGFyc2VFeHByZXNzaW9uKGV4cCwgbmVlZFNldCkge1xuICBleHAgPSBleHAudHJpbSgpO1xuICAvLyB0cnkgY2FjaGVcbiAgdmFyIGhpdCA9IGV4cHJlc3Npb25DYWNoZS5nZXQoZXhwKTtcbiAgaWYgKGhpdCkge1xuICAgIGlmIChuZWVkU2V0ICYmICFoaXQuc2V0KSB7XG4gICAgICBoaXQuc2V0ID0gY29tcGlsZVNldHRlcihoaXQuZXhwKTtcbiAgICB9XG4gICAgcmV0dXJuIGhpdDtcbiAgfVxuICB2YXIgcmVzID0geyBleHA6IGV4cCB9O1xuICByZXMuZ2V0ID0gaXNTaW1wbGVQYXRoKGV4cCkgJiYgZXhwLmluZGV4T2YoJ1snKSA8IDBcbiAgLy8gb3B0aW1pemVkIHN1cGVyIHNpbXBsZSBnZXR0ZXJcbiAgPyBtYWtlR2V0dGVyRm4oJ3Njb3BlLicgKyBleHApXG4gIC8vIGR5bmFtaWMgZ2V0dGVyXG4gIDogY29tcGlsZUdldHRlcihleHApO1xuICBpZiAobmVlZFNldCkge1xuICAgIHJlcy5zZXQgPSBjb21waWxlU2V0dGVyKGV4cCk7XG4gIH1cbiAgZXhwcmVzc2lvbkNhY2hlLnB1dChleHAsIHJlcyk7XG4gIHJldHVybiByZXM7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYW4gZXhwcmVzc2lvbiBpcyBhIHNpbXBsZSBwYXRoLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBleHBcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cblxuZnVuY3Rpb24gaXNTaW1wbGVQYXRoKGV4cCkge1xuICByZXR1cm4gcGF0aFRlc3RSRS50ZXN0KGV4cCkgJiZcbiAgLy8gZG9uJ3QgdHJlYXQgdHJ1ZS9mYWxzZSBhcyBwYXRoc1xuICAhYm9vbGVhbkxpdGVyYWxSRS50ZXN0KGV4cCkgJiZcbiAgLy8gTWF0aCBjb25zdGFudHMgZS5nLiBNYXRoLlBJLCBNYXRoLkUgZXRjLlxuICBleHAuc2xpY2UoMCwgNSkgIT09ICdNYXRoLic7XG59XG5cbnZhciBleHByZXNzaW9uID0gT2JqZWN0LmZyZWV6ZSh7XG4gIHBhcnNlRXhwcmVzc2lvbjogcGFyc2VFeHByZXNzaW9uLFxuICBpc1NpbXBsZVBhdGg6IGlzU2ltcGxlUGF0aFxufSk7XG5cbi8vIHdlIGhhdmUgdHdvIHNlcGFyYXRlIHF1ZXVlczogb25lIGZvciBkaXJlY3RpdmUgdXBkYXRlc1xuLy8gYW5kIG9uZSBmb3IgdXNlciB3YXRjaGVyIHJlZ2lzdGVyZWQgdmlhICR3YXRjaCgpLlxuLy8gd2Ugd2FudCB0byBndWFyYW50ZWUgZGlyZWN0aXZlIHVwZGF0ZXMgdG8gYmUgY2FsbGVkXG4vLyBiZWZvcmUgdXNlciB3YXRjaGVycyBzbyB0aGF0IHdoZW4gdXNlciB3YXRjaGVycyBhcmVcbi8vIHRyaWdnZXJlZCwgdGhlIERPTSB3b3VsZCBoYXZlIGFscmVhZHkgYmVlbiBpbiB1cGRhdGVkXG4vLyBzdGF0ZS5cbnZhciBxdWV1ZSA9IFtdO1xudmFyIHVzZXJRdWV1ZSA9IFtdO1xudmFyIGhhcyA9IHt9O1xudmFyIGNpcmN1bGFyID0ge307XG52YXIgd2FpdGluZyA9IGZhbHNlO1xudmFyIGludGVybmFsUXVldWVEZXBsZXRlZCA9IGZhbHNlO1xuXG4vKipcbiAqIFJlc2V0IHRoZSBiYXRjaGVyJ3Mgc3RhdGUuXG4gKi9cblxuZnVuY3Rpb24gcmVzZXRCYXRjaGVyU3RhdGUoKSB7XG4gIHF1ZXVlID0gW107XG4gIHVzZXJRdWV1ZSA9IFtdO1xuICBoYXMgPSB7fTtcbiAgY2lyY3VsYXIgPSB7fTtcbiAgd2FpdGluZyA9IGludGVybmFsUXVldWVEZXBsZXRlZCA9IGZhbHNlO1xufVxuXG4vKipcbiAqIEZsdXNoIGJvdGggcXVldWVzIGFuZCBydW4gdGhlIHdhdGNoZXJzLlxuICovXG5cbmZ1bmN0aW9uIGZsdXNoQmF0Y2hlclF1ZXVlKCkge1xuICBydW5CYXRjaGVyUXVldWUocXVldWUpO1xuICBpbnRlcm5hbFF1ZXVlRGVwbGV0ZWQgPSB0cnVlO1xuICBydW5CYXRjaGVyUXVldWUodXNlclF1ZXVlKTtcbiAgLy8gZGV2IHRvb2wgaG9va1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKGRldnRvb2xzKSB7XG4gICAgZGV2dG9vbHMuZW1pdCgnZmx1c2gnKTtcbiAgfVxuICByZXNldEJhdGNoZXJTdGF0ZSgpO1xufVxuXG4vKipcbiAqIFJ1biB0aGUgd2F0Y2hlcnMgaW4gYSBzaW5nbGUgcXVldWUuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcXVldWVcbiAqL1xuXG5mdW5jdGlvbiBydW5CYXRjaGVyUXVldWUocXVldWUpIHtcbiAgLy8gZG8gbm90IGNhY2hlIGxlbmd0aCBiZWNhdXNlIG1vcmUgd2F0Y2hlcnMgbWlnaHQgYmUgcHVzaGVkXG4gIC8vIGFzIHdlIHJ1biBleGlzdGluZyB3YXRjaGVyc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHdhdGNoZXIgPSBxdWV1ZVtpXTtcbiAgICB2YXIgaWQgPSB3YXRjaGVyLmlkO1xuICAgIGhhc1tpZF0gPSBudWxsO1xuICAgIHdhdGNoZXIucnVuKCk7XG4gICAgLy8gaW4gZGV2IGJ1aWxkLCBjaGVjayBhbmQgc3RvcCBjaXJjdWxhciB1cGRhdGVzLlxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIGhhc1tpZF0gIT0gbnVsbCkge1xuICAgICAgY2lyY3VsYXJbaWRdID0gKGNpcmN1bGFyW2lkXSB8fCAwKSArIDE7XG4gICAgICBpZiAoY2lyY3VsYXJbaWRdID4gY29uZmlnLl9tYXhVcGRhdGVDb3VudCkge1xuICAgICAgICBxdWV1ZS5zcGxpY2UoaGFzW2lkXSwgMSk7XG4gICAgICAgIHdhcm4oJ1lvdSBtYXkgaGF2ZSBhbiBpbmZpbml0ZSB1cGRhdGUgbG9vcCBmb3Igd2F0Y2hlciAnICsgJ3dpdGggZXhwcmVzc2lvbjogJyArIHdhdGNoZXIuZXhwcmVzc2lvbik7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUHVzaCBhIHdhdGNoZXIgaW50byB0aGUgd2F0Y2hlciBxdWV1ZS5cbiAqIEpvYnMgd2l0aCBkdXBsaWNhdGUgSURzIHdpbGwgYmUgc2tpcHBlZCB1bmxlc3MgaXQnc1xuICogcHVzaGVkIHdoZW4gdGhlIHF1ZXVlIGlzIGJlaW5nIGZsdXNoZWQuXG4gKlxuICogQHBhcmFtIHtXYXRjaGVyfSB3YXRjaGVyXG4gKiAgIHByb3BlcnRpZXM6XG4gKiAgIC0ge051bWJlcn0gaWRcbiAqICAgLSB7RnVuY3Rpb259IHJ1blxuICovXG5cbmZ1bmN0aW9uIHB1c2hXYXRjaGVyKHdhdGNoZXIpIHtcbiAgdmFyIGlkID0gd2F0Y2hlci5pZDtcbiAgaWYgKGhhc1tpZF0gPT0gbnVsbCkge1xuICAgIC8vIGlmIGFuIGludGVybmFsIHdhdGNoZXIgaXMgcHVzaGVkLCBidXQgdGhlIGludGVybmFsXG4gICAgLy8gcXVldWUgaXMgYWxyZWFkeSBkZXBsZXRlZCwgd2UgcnVuIGl0IGltbWVkaWF0ZWx5LlxuICAgIGlmIChpbnRlcm5hbFF1ZXVlRGVwbGV0ZWQgJiYgIXdhdGNoZXIudXNlcikge1xuICAgICAgd2F0Y2hlci5ydW4oKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gcHVzaCB3YXRjaGVyIGludG8gYXBwcm9wcmlhdGUgcXVldWVcbiAgICB2YXIgcSA9IHdhdGNoZXIudXNlciA/IHVzZXJRdWV1ZSA6IHF1ZXVlO1xuICAgIGhhc1tpZF0gPSBxLmxlbmd0aDtcbiAgICBxLnB1c2god2F0Y2hlcik7XG4gICAgLy8gcXVldWUgdGhlIGZsdXNoXG4gICAgaWYgKCF3YWl0aW5nKSB7XG4gICAgICB3YWl0aW5nID0gdHJ1ZTtcbiAgICAgIG5leHRUaWNrKGZsdXNoQmF0Y2hlclF1ZXVlKTtcbiAgICB9XG4gIH1cbn1cblxudmFyIHVpZCQyID0gMDtcblxuLyoqXG4gKiBBIHdhdGNoZXIgcGFyc2VzIGFuIGV4cHJlc3Npb24sIGNvbGxlY3RzIGRlcGVuZGVuY2llcyxcbiAqIGFuZCBmaXJlcyBjYWxsYmFjayB3aGVuIHRoZSBleHByZXNzaW9uIHZhbHVlIGNoYW5nZXMuXG4gKiBUaGlzIGlzIHVzZWQgZm9yIGJvdGggdGhlICR3YXRjaCgpIGFwaSBhbmQgZGlyZWN0aXZlcy5cbiAqXG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqIEBwYXJhbSB7U3RyaW5nfSBleHByZXNzaW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqICAgICAgICAgICAgICAgICAtIHtBcnJheX0gZmlsdGVyc1xuICogICAgICAgICAgICAgICAgIC0ge0Jvb2xlYW59IHR3b1dheVxuICogICAgICAgICAgICAgICAgIC0ge0Jvb2xlYW59IGRlZXBcbiAqICAgICAgICAgICAgICAgICAtIHtCb29sZWFufSB1c2VyXG4gKiAgICAgICAgICAgICAgICAgLSB7Qm9vbGVhbn0gc3luY1xuICogICAgICAgICAgICAgICAgIC0ge0Jvb2xlYW59IGxhenlcbiAqICAgICAgICAgICAgICAgICAtIHtGdW5jdGlvbn0gW3ByZVByb2Nlc3NdXG4gKiAgICAgICAgICAgICAgICAgLSB7RnVuY3Rpb259IFtwb3N0UHJvY2Vzc11cbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBXYXRjaGVyKHZtLCBleHBPckZuLCBjYiwgb3B0aW9ucykge1xuICAvLyBtaXggaW4gb3B0aW9uc1xuICBpZiAob3B0aW9ucykge1xuICAgIGV4dGVuZCh0aGlzLCBvcHRpb25zKTtcbiAgfVxuICB2YXIgaXNGbiA9IHR5cGVvZiBleHBPckZuID09PSAnZnVuY3Rpb24nO1xuICB0aGlzLnZtID0gdm07XG4gIHZtLl93YXRjaGVycy5wdXNoKHRoaXMpO1xuICB0aGlzLmV4cHJlc3Npb24gPSBpc0ZuID8gZXhwT3JGbi50b1N0cmluZygpIDogZXhwT3JGbjtcbiAgdGhpcy5jYiA9IGNiO1xuICB0aGlzLmlkID0gKyt1aWQkMjsgLy8gdWlkIGZvciBiYXRjaGluZ1xuICB0aGlzLmFjdGl2ZSA9IHRydWU7XG4gIHRoaXMuZGlydHkgPSB0aGlzLmxhenk7IC8vIGZvciBsYXp5IHdhdGNoZXJzXG4gIHRoaXMuZGVwcyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIHRoaXMubmV3RGVwcyA9IG51bGw7XG4gIHRoaXMucHJldkVycm9yID0gbnVsbDsgLy8gZm9yIGFzeW5jIGVycm9yIHN0YWNrc1xuICAvLyBwYXJzZSBleHByZXNzaW9uIGZvciBnZXR0ZXIvc2V0dGVyXG4gIGlmIChpc0ZuKSB7XG4gICAgdGhpcy5nZXR0ZXIgPSBleHBPckZuO1xuICAgIHRoaXMuc2V0dGVyID0gdW5kZWZpbmVkO1xuICB9IGVsc2Uge1xuICAgIHZhciByZXMgPSBwYXJzZUV4cHJlc3Npb24oZXhwT3JGbiwgdGhpcy50d29XYXkpO1xuICAgIHRoaXMuZ2V0dGVyID0gcmVzLmdldDtcbiAgICB0aGlzLnNldHRlciA9IHJlcy5zZXQ7XG4gIH1cbiAgdGhpcy52YWx1ZSA9IHRoaXMubGF6eSA/IHVuZGVmaW5lZCA6IHRoaXMuZ2V0KCk7XG4gIC8vIHN0YXRlIGZvciBhdm9pZGluZyBmYWxzZSB0cmlnZ2VycyBmb3IgZGVlcCBhbmQgQXJyYXlcbiAgLy8gd2F0Y2hlcnMgZHVyaW5nIHZtLl9kaWdlc3QoKVxuICB0aGlzLnF1ZXVlZCA9IHRoaXMuc2hhbGxvdyA9IGZhbHNlO1xufVxuXG4vKipcbiAqIEFkZCBhIGRlcGVuZGVuY3kgdG8gdGhpcyBkaXJlY3RpdmUuXG4gKlxuICogQHBhcmFtIHtEZXB9IGRlcFxuICovXG5cbldhdGNoZXIucHJvdG90eXBlLmFkZERlcCA9IGZ1bmN0aW9uIChkZXApIHtcbiAgdmFyIGlkID0gZGVwLmlkO1xuICBpZiAoIXRoaXMubmV3RGVwc1tpZF0pIHtcbiAgICB0aGlzLm5ld0RlcHNbaWRdID0gZGVwO1xuICAgIGlmICghdGhpcy5kZXBzW2lkXSkge1xuICAgICAgdGhpcy5kZXBzW2lkXSA9IGRlcDtcbiAgICAgIGRlcC5hZGRTdWIodGhpcyk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIEV2YWx1YXRlIHRoZSBnZXR0ZXIsIGFuZCByZS1jb2xsZWN0IGRlcGVuZGVuY2llcy5cbiAqL1xuXG5XYXRjaGVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuYmVmb3JlR2V0KCk7XG4gIHZhciBzY29wZSA9IHRoaXMuc2NvcGUgfHwgdGhpcy52bTtcbiAgdmFyIHZhbHVlO1xuICB0cnkge1xuICAgIHZhbHVlID0gdGhpcy5nZXR0ZXIuY2FsbChzY29wZSwgc2NvcGUpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgY29uZmlnLndhcm5FeHByZXNzaW9uRXJyb3JzKSB7XG4gICAgICB3YXJuKCdFcnJvciB3aGVuIGV2YWx1YXRpbmcgZXhwcmVzc2lvbiBcIicgKyB0aGlzLmV4cHJlc3Npb24gKyAnXCIuICcgKyAoY29uZmlnLmRlYnVnID8gJycgOiAnVHVybiBvbiBkZWJ1ZyBtb2RlIHRvIHNlZSBzdGFjayB0cmFjZS4nKSwgZSk7XG4gICAgfVxuICB9XG4gIC8vIFwidG91Y2hcIiBldmVyeSBwcm9wZXJ0eSBzbyB0aGV5IGFyZSBhbGwgdHJhY2tlZCBhc1xuICAvLyBkZXBlbmRlbmNpZXMgZm9yIGRlZXAgd2F0Y2hpbmdcbiAgaWYgKHRoaXMuZGVlcCkge1xuICAgIHRyYXZlcnNlKHZhbHVlKTtcbiAgfVxuICBpZiAodGhpcy5wcmVQcm9jZXNzKSB7XG4gICAgdmFsdWUgPSB0aGlzLnByZVByb2Nlc3ModmFsdWUpO1xuICB9XG4gIGlmICh0aGlzLmZpbHRlcnMpIHtcbiAgICB2YWx1ZSA9IHNjb3BlLl9hcHBseUZpbHRlcnModmFsdWUsIG51bGwsIHRoaXMuZmlsdGVycywgZmFsc2UpO1xuICB9XG4gIGlmICh0aGlzLnBvc3RQcm9jZXNzKSB7XG4gICAgdmFsdWUgPSB0aGlzLnBvc3RQcm9jZXNzKHZhbHVlKTtcbiAgfVxuICB0aGlzLmFmdGVyR2V0KCk7XG4gIHJldHVybiB2YWx1ZTtcbn07XG5cbi8qKlxuICogU2V0IHRoZSBjb3JyZXNwb25kaW5nIHZhbHVlIHdpdGggdGhlIHNldHRlci5cbiAqXG4gKiBAcGFyYW0geyp9IHZhbHVlXG4gKi9cblxuV2F0Y2hlci5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gIHZhciBzY29wZSA9IHRoaXMuc2NvcGUgfHwgdGhpcy52bTtcbiAgaWYgKHRoaXMuZmlsdGVycykge1xuICAgIHZhbHVlID0gc2NvcGUuX2FwcGx5RmlsdGVycyh2YWx1ZSwgdGhpcy52YWx1ZSwgdGhpcy5maWx0ZXJzLCB0cnVlKTtcbiAgfVxuICB0cnkge1xuICAgIHRoaXMuc2V0dGVyLmNhbGwoc2NvcGUsIHNjb3BlLCB2YWx1ZSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBjb25maWcud2FybkV4cHJlc3Npb25FcnJvcnMpIHtcbiAgICAgIHdhcm4oJ0Vycm9yIHdoZW4gZXZhbHVhdGluZyBzZXR0ZXIgXCInICsgdGhpcy5leHByZXNzaW9uICsgJ1wiJywgZSk7XG4gICAgfVxuICB9XG4gIC8vIHR3by13YXkgc3luYyBmb3Igdi1mb3IgYWxpYXNcbiAgdmFyIGZvckNvbnRleHQgPSBzY29wZS4kZm9yQ29udGV4dDtcbiAgaWYgKGZvckNvbnRleHQgJiYgZm9yQ29udGV4dC5hbGlhcyA9PT0gdGhpcy5leHByZXNzaW9uKSB7XG4gICAgaWYgKGZvckNvbnRleHQuZmlsdGVycykge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKCdJdCBzZWVtcyB5b3UgYXJlIHVzaW5nIHR3by13YXkgYmluZGluZyBvbiAnICsgJ2Egdi1mb3IgYWxpYXMgKCcgKyB0aGlzLmV4cHJlc3Npb24gKyAnKSwgYW5kIHRoZSAnICsgJ3YtZm9yIGhhcyBmaWx0ZXJzLiBUaGlzIHdpbGwgbm90IHdvcmsgcHJvcGVybHkuICcgKyAnRWl0aGVyIHJlbW92ZSB0aGUgZmlsdGVycyBvciB1c2UgYW4gYXJyYXkgb2YgJyArICdvYmplY3RzIGFuZCBiaW5kIHRvIG9iamVjdCBwcm9wZXJ0aWVzIGluc3RlYWQuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvckNvbnRleHQuX3dpdGhMb2NrKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzY29wZS4ka2V5KSB7XG4gICAgICAgIC8vIG9yaWdpbmFsIGlzIGFuIG9iamVjdFxuICAgICAgICBmb3JDb250ZXh0LnJhd1ZhbHVlW3Njb3BlLiRrZXldID0gdmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3JDb250ZXh0LnJhd1ZhbHVlLiRzZXQoc2NvcGUuJGluZGV4LCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cbi8qKlxuICogUHJlcGFyZSBmb3IgZGVwZW5kZW5jeSBjb2xsZWN0aW9uLlxuICovXG5cbldhdGNoZXIucHJvdG90eXBlLmJlZm9yZUdldCA9IGZ1bmN0aW9uICgpIHtcbiAgRGVwLnRhcmdldCA9IHRoaXM7XG4gIHRoaXMubmV3RGVwcyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG59O1xuXG4vKipcbiAqIENsZWFuIHVwIGZvciBkZXBlbmRlbmN5IGNvbGxlY3Rpb24uXG4gKi9cblxuV2F0Y2hlci5wcm90b3R5cGUuYWZ0ZXJHZXQgPSBmdW5jdGlvbiAoKSB7XG4gIERlcC50YXJnZXQgPSBudWxsO1xuICB2YXIgaWRzID0gT2JqZWN0LmtleXModGhpcy5kZXBzKTtcbiAgdmFyIGkgPSBpZHMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgdmFyIGlkID0gaWRzW2ldO1xuICAgIGlmICghdGhpcy5uZXdEZXBzW2lkXSkge1xuICAgICAgdGhpcy5kZXBzW2lkXS5yZW1vdmVTdWIodGhpcyk7XG4gICAgfVxuICB9XG4gIHRoaXMuZGVwcyA9IHRoaXMubmV3RGVwcztcbn07XG5cbi8qKlxuICogU3Vic2NyaWJlciBpbnRlcmZhY2UuXG4gKiBXaWxsIGJlIGNhbGxlZCB3aGVuIGEgZGVwZW5kZW5jeSBjaGFuZ2VzLlxuICpcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gc2hhbGxvd1xuICovXG5cbldhdGNoZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uIChzaGFsbG93KSB7XG4gIGlmICh0aGlzLmxhenkpIHtcbiAgICB0aGlzLmRpcnR5ID0gdHJ1ZTtcbiAgfSBlbHNlIGlmICh0aGlzLnN5bmMgfHwgIWNvbmZpZy5hc3luYykge1xuICAgIHRoaXMucnVuKCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gaWYgcXVldWVkLCBvbmx5IG92ZXJ3cml0ZSBzaGFsbG93IHdpdGggbm9uLXNoYWxsb3csXG4gICAgLy8gYnV0IG5vdCB0aGUgb3RoZXIgd2F5IGFyb3VuZC5cbiAgICB0aGlzLnNoYWxsb3cgPSB0aGlzLnF1ZXVlZCA/IHNoYWxsb3cgPyB0aGlzLnNoYWxsb3cgOiBmYWxzZSA6ICEhc2hhbGxvdztcbiAgICB0aGlzLnF1ZXVlZCA9IHRydWU7XG4gICAgLy8gcmVjb3JkIGJlZm9yZS1wdXNoIGVycm9yIHN0YWNrIGluIGRlYnVnIG1vZGVcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBjb25maWcuZGVidWcpIHtcbiAgICAgIHRoaXMucHJldkVycm9yID0gbmV3IEVycm9yKCdbdnVlXSBhc3luYyBzdGFjayB0cmFjZScpO1xuICAgIH1cbiAgICBwdXNoV2F0Y2hlcih0aGlzKTtcbiAgfVxufTtcblxuLyoqXG4gKiBCYXRjaGVyIGpvYiBpbnRlcmZhY2UuXG4gKiBXaWxsIGJlIGNhbGxlZCBieSB0aGUgYmF0Y2hlci5cbiAqL1xuXG5XYXRjaGVyLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KCk7XG4gICAgaWYgKHZhbHVlICE9PSB0aGlzLnZhbHVlIHx8XG4gICAgLy8gRGVlcCB3YXRjaGVycyBhbmQgd2F0Y2hlcnMgb24gT2JqZWN0L0FycmF5cyBzaG91bGQgZmlyZSBldmVuXG4gICAgLy8gd2hlbiB0aGUgdmFsdWUgaXMgdGhlIHNhbWUsIGJlY2F1c2UgdGhlIHZhbHVlIG1heVxuICAgIC8vIGhhdmUgbXV0YXRlZDsgYnV0IG9ubHkgZG8gc28gaWYgdGhpcyBpcyBhXG4gICAgLy8gbm9uLXNoYWxsb3cgdXBkYXRlIChjYXVzZWQgYnkgYSB2bSBkaWdlc3QpLlxuICAgIChpc09iamVjdCh2YWx1ZSkgfHwgdGhpcy5kZWVwKSAmJiAhdGhpcy5zaGFsbG93KSB7XG4gICAgICAvLyBzZXQgbmV3IHZhbHVlXG4gICAgICB2YXIgb2xkVmFsdWUgPSB0aGlzLnZhbHVlO1xuICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgICAgLy8gaW4gZGVidWcgKyBhc3luYyBtb2RlLCB3aGVuIGEgd2F0Y2hlciBjYWxsYmFja3NcbiAgICAgIC8vIHRocm93cywgd2UgYWxzbyB0aHJvdyB0aGUgc2F2ZWQgYmVmb3JlLXB1c2ggZXJyb3JcbiAgICAgIC8vIHNvIHRoZSBmdWxsIGNyb3NzLXRpY2sgc3RhY2sgdHJhY2UgaXMgYXZhaWxhYmxlLlxuICAgICAgdmFyIHByZXZFcnJvciA9IHRoaXMucHJldkVycm9yO1xuICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBjb25maWcuZGVidWcgJiYgcHJldkVycm9yKSB7XG4gICAgICAgIHRoaXMucHJldkVycm9yID0gbnVsbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmNiLmNhbGwodGhpcy52bSwgdmFsdWUsIG9sZFZhbHVlKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRocm93IHByZXZFcnJvcjtcbiAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNiLmNhbGwodGhpcy52bSwgdmFsdWUsIG9sZFZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5xdWV1ZWQgPSB0aGlzLnNoYWxsb3cgPSBmYWxzZTtcbiAgfVxufTtcblxuLyoqXG4gKiBFdmFsdWF0ZSB0aGUgdmFsdWUgb2YgdGhlIHdhdGNoZXIuXG4gKiBUaGlzIG9ubHkgZ2V0cyBjYWxsZWQgZm9yIGxhenkgd2F0Y2hlcnMuXG4gKi9cblxuV2F0Y2hlci5wcm90b3R5cGUuZXZhbHVhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIGF2b2lkIG92ZXJ3cml0aW5nIGFub3RoZXIgd2F0Y2hlciB0aGF0IGlzIGJlaW5nXG4gIC8vIGNvbGxlY3RlZC5cbiAgdmFyIGN1cnJlbnQgPSBEZXAudGFyZ2V0O1xuICB0aGlzLnZhbHVlID0gdGhpcy5nZXQoKTtcbiAgdGhpcy5kaXJ0eSA9IGZhbHNlO1xuICBEZXAudGFyZ2V0ID0gY3VycmVudDtcbn07XG5cbi8qKlxuICogRGVwZW5kIG9uIGFsbCBkZXBzIGNvbGxlY3RlZCBieSB0aGlzIHdhdGNoZXIuXG4gKi9cblxuV2F0Y2hlci5wcm90b3R5cGUuZGVwZW5kID0gZnVuY3Rpb24gKCkge1xuICB2YXIgZGVwSWRzID0gT2JqZWN0LmtleXModGhpcy5kZXBzKTtcbiAgdmFyIGkgPSBkZXBJZHMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgdGhpcy5kZXBzW2RlcElkc1tpXV0uZGVwZW5kKCk7XG4gIH1cbn07XG5cbi8qKlxuICogUmVtb3ZlIHNlbGYgZnJvbSBhbGwgZGVwZW5kZW5jaWVzJyBzdWJjcmliZXIgbGlzdC5cbiAqL1xuXG5XYXRjaGVyLnByb3RvdHlwZS50ZWFyZG93biA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuYWN0aXZlKSB7XG4gICAgLy8gcmVtb3ZlIHNlbGYgZnJvbSB2bSdzIHdhdGNoZXIgbGlzdFxuICAgIC8vIHRoaXMgaXMgYSBzb21ld2hhdCBleHBlbnNpdmUgb3BlcmF0aW9uIHNvIHdlIHNraXAgaXRcbiAgICAvLyBpZiB0aGUgdm0gaXMgYmVpbmcgZGVzdHJveWVkIG9yIGlzIHBlcmZvcm1pbmcgYSB2LWZvclxuICAgIC8vIHJlLXJlbmRlciAodGhlIHdhdGNoZXIgbGlzdCBpcyB0aGVuIGZpbHRlcmVkIGJ5IHYtZm9yKS5cbiAgICBpZiAoIXRoaXMudm0uX2lzQmVpbmdEZXN0cm95ZWQgJiYgIXRoaXMudm0uX3ZGb3JSZW1vdmluZykge1xuICAgICAgdGhpcy52bS5fd2F0Y2hlcnMuJHJlbW92ZSh0aGlzKTtcbiAgICB9XG4gICAgdmFyIGRlcElkcyA9IE9iamVjdC5rZXlzKHRoaXMuZGVwcyk7XG4gICAgdmFyIGkgPSBkZXBJZHMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIHRoaXMuZGVwc1tkZXBJZHNbaV1dLnJlbW92ZVN1Yih0aGlzKTtcbiAgICB9XG4gICAgdGhpcy5hY3RpdmUgPSBmYWxzZTtcbiAgICB0aGlzLnZtID0gdGhpcy5jYiA9IHRoaXMudmFsdWUgPSBudWxsO1xuICB9XG59O1xuXG4vKipcbiAqIFJlY3J1c2l2ZWx5IHRyYXZlcnNlIGFuIG9iamVjdCB0byBldm9rZSBhbGwgY29udmVydGVkXG4gKiBnZXR0ZXJzLCBzbyB0aGF0IGV2ZXJ5IG5lc3RlZCBwcm9wZXJ0eSBpbnNpZGUgdGhlIG9iamVjdFxuICogaXMgY29sbGVjdGVkIGFzIGEgXCJkZWVwXCIgZGVwZW5kZW5jeS5cbiAqXG4gKiBAcGFyYW0geyp9IHZhbFxuICovXG5cbmZ1bmN0aW9uIHRyYXZlcnNlKHZhbCkge1xuICB2YXIgaSwga2V5cztcbiAgaWYgKGlzQXJyYXkodmFsKSkge1xuICAgIGkgPSB2YWwubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHRyYXZlcnNlKHZhbFtpXSk7XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QodmFsKSkge1xuICAgIGtleXMgPSBPYmplY3Qua2V5cyh2YWwpO1xuICAgIGkgPSBrZXlzLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB0cmF2ZXJzZSh2YWxba2V5c1tpXV0pO1xuICB9XG59XG5cbnZhciB0ZXh0JDEgPSB7XG5cbiAgYmluZDogZnVuY3Rpb24gYmluZCgpIHtcbiAgICB0aGlzLmF0dHIgPSB0aGlzLmVsLm5vZGVUeXBlID09PSAzID8gJ2RhdGEnIDogJ3RleHRDb250ZW50JztcbiAgfSxcblxuICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZSh2YWx1ZSkge1xuICAgIHRoaXMuZWxbdGhpcy5hdHRyXSA9IF90b1N0cmluZyh2YWx1ZSk7XG4gIH1cbn07XG5cbnZhciB0ZW1wbGF0ZUNhY2hlID0gbmV3IENhY2hlKDEwMDApO1xudmFyIGlkU2VsZWN0b3JDYWNoZSA9IG5ldyBDYWNoZSgxMDAwKTtcblxudmFyIG1hcCA9IHtcbiAgZWZhdWx0OiBbMCwgJycsICcnXSxcbiAgbGVnZW5kOiBbMSwgJzxmaWVsZHNldD4nLCAnPC9maWVsZHNldD4nXSxcbiAgdHI6IFsyLCAnPHRhYmxlPjx0Ym9keT4nLCAnPC90Ym9keT48L3RhYmxlPiddLFxuICBjb2w6IFsyLCAnPHRhYmxlPjx0Ym9keT48L3Rib2R5Pjxjb2xncm91cD4nLCAnPC9jb2xncm91cD48L3RhYmxlPiddXG59O1xuXG5tYXAudGQgPSBtYXAudGggPSBbMywgJzx0YWJsZT48dGJvZHk+PHRyPicsICc8L3RyPjwvdGJvZHk+PC90YWJsZT4nXTtcblxubWFwLm9wdGlvbiA9IG1hcC5vcHRncm91cCA9IFsxLCAnPHNlbGVjdCBtdWx0aXBsZT1cIm11bHRpcGxlXCI+JywgJzwvc2VsZWN0PiddO1xuXG5tYXAudGhlYWQgPSBtYXAudGJvZHkgPSBtYXAuY29sZ3JvdXAgPSBtYXAuY2FwdGlvbiA9IG1hcC50Zm9vdCA9IFsxLCAnPHRhYmxlPicsICc8L3RhYmxlPiddO1xuXG5tYXAuZyA9IG1hcC5kZWZzID0gbWFwLnN5bWJvbCA9IG1hcC51c2UgPSBtYXAuaW1hZ2UgPSBtYXAudGV4dCA9IG1hcC5jaXJjbGUgPSBtYXAuZWxsaXBzZSA9IG1hcC5saW5lID0gbWFwLnBhdGggPSBtYXAucG9seWdvbiA9IG1hcC5wb2x5bGluZSA9IG1hcC5yZWN0ID0gWzEsICc8c3ZnICcgKyAneG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiICcgKyAneG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgJyArICd4bWxuczpldj1cImh0dHA6Ly93d3cudzMub3JnLzIwMDEveG1sLWV2ZW50c1wiJyArICd2ZXJzaW9uPVwiMS4xXCI+JywgJzwvc3ZnPiddO1xuXG4vKipcbiAqIENoZWNrIGlmIGEgbm9kZSBpcyBhIHN1cHBvcnRlZCB0ZW1wbGF0ZSBub2RlIHdpdGggYVxuICogRG9jdW1lbnRGcmFnbWVudCBjb250ZW50LlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuXG5mdW5jdGlvbiBpc1JlYWxUZW1wbGF0ZShub2RlKSB7XG4gIHJldHVybiBpc1RlbXBsYXRlKG5vZGUpICYmIGlzRnJhZ21lbnQobm9kZS5jb250ZW50KTtcbn1cblxudmFyIHRhZ1JFJDEgPSAvPChbXFx3Ol0rKS87XG52YXIgZW50aXR5UkUgPSAvJiM/XFx3Kz87LztcblxuLyoqXG4gKiBDb252ZXJ0IGEgc3RyaW5nIHRlbXBsYXRlIHRvIGEgRG9jdW1lbnRGcmFnbWVudC5cbiAqIERldGVybWluZXMgY29ycmVjdCB3cmFwcGluZyBieSB0YWcgdHlwZXMuIFdyYXBwaW5nXG4gKiBzdHJhdGVneSBmb3VuZCBpbiBqUXVlcnkgJiBjb21wb25lbnQvZG9taWZ5LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0ZW1wbGF0ZVN0cmluZ1xuICogQHBhcmFtIHtCb29sZWFufSByYXdcbiAqIEByZXR1cm4ge0RvY3VtZW50RnJhZ21lbnR9XG4gKi9cblxuZnVuY3Rpb24gc3RyaW5nVG9GcmFnbWVudCh0ZW1wbGF0ZVN0cmluZywgcmF3KSB7XG4gIC8vIHRyeSBhIGNhY2hlIGhpdCBmaXJzdFxuICB2YXIgY2FjaGVLZXkgPSByYXcgPyB0ZW1wbGF0ZVN0cmluZyA6IHRlbXBsYXRlU3RyaW5nLnRyaW0oKTtcbiAgdmFyIGhpdCA9IHRlbXBsYXRlQ2FjaGUuZ2V0KGNhY2hlS2V5KTtcbiAgaWYgKGhpdCkge1xuICAgIHJldHVybiBoaXQ7XG4gIH1cblxuICB2YXIgZnJhZyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgdmFyIHRhZ01hdGNoID0gdGVtcGxhdGVTdHJpbmcubWF0Y2godGFnUkUkMSk7XG4gIHZhciBlbnRpdHlNYXRjaCA9IGVudGl0eVJFLnRlc3QodGVtcGxhdGVTdHJpbmcpO1xuXG4gIGlmICghdGFnTWF0Y2ggJiYgIWVudGl0eU1hdGNoKSB7XG4gICAgLy8gdGV4dCBvbmx5LCByZXR1cm4gYSBzaW5nbGUgdGV4dCBub2RlLlxuICAgIGZyYWcuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGVtcGxhdGVTdHJpbmcpKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgdGFnID0gdGFnTWF0Y2ggJiYgdGFnTWF0Y2hbMV07XG4gICAgdmFyIHdyYXAgPSBtYXBbdGFnXSB8fCBtYXAuZWZhdWx0O1xuICAgIHZhciBkZXB0aCA9IHdyYXBbMF07XG4gICAgdmFyIHByZWZpeCA9IHdyYXBbMV07XG4gICAgdmFyIHN1ZmZpeCA9IHdyYXBbMl07XG4gICAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcblxuICAgIG5vZGUuaW5uZXJIVE1MID0gcHJlZml4ICsgdGVtcGxhdGVTdHJpbmcgKyBzdWZmaXg7XG4gICAgd2hpbGUgKGRlcHRoLS0pIHtcbiAgICAgIG5vZGUgPSBub2RlLmxhc3RDaGlsZDtcbiAgICB9XG5cbiAgICB2YXIgY2hpbGQ7XG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uZC1hc3NpZ24gKi9cbiAgICB3aGlsZSAoY2hpbGQgPSBub2RlLmZpcnN0Q2hpbGQpIHtcbiAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tY29uZC1hc3NpZ24gKi9cbiAgICAgIGZyYWcuYXBwZW5kQ2hpbGQoY2hpbGQpO1xuICAgIH1cbiAgfVxuICBpZiAoIXJhdykge1xuICAgIHRyaW1Ob2RlKGZyYWcpO1xuICB9XG4gIHRlbXBsYXRlQ2FjaGUucHV0KGNhY2hlS2V5LCBmcmFnKTtcbiAgcmV0dXJuIGZyYWc7XG59XG5cbi8qKlxuICogQ29udmVydCBhIHRlbXBsYXRlIG5vZGUgdG8gYSBEb2N1bWVudEZyYWdtZW50LlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICogQHJldHVybiB7RG9jdW1lbnRGcmFnbWVudH1cbiAqL1xuXG5mdW5jdGlvbiBub2RlVG9GcmFnbWVudChub2RlKSB7XG4gIC8vIGlmIGl0cyBhIHRlbXBsYXRlIHRhZyBhbmQgdGhlIGJyb3dzZXIgc3VwcG9ydHMgaXQsXG4gIC8vIGl0cyBjb250ZW50IGlzIGFscmVhZHkgYSBkb2N1bWVudCBmcmFnbWVudC5cbiAgaWYgKGlzUmVhbFRlbXBsYXRlKG5vZGUpKSB7XG4gICAgdHJpbU5vZGUobm9kZS5jb250ZW50KTtcbiAgICByZXR1cm4gbm9kZS5jb250ZW50O1xuICB9XG4gIC8vIHNjcmlwdCB0ZW1wbGF0ZVxuICBpZiAobm9kZS50YWdOYW1lID09PSAnU0NSSVBUJykge1xuICAgIHJldHVybiBzdHJpbmdUb0ZyYWdtZW50KG5vZGUudGV4dENvbnRlbnQpO1xuICB9XG4gIC8vIG5vcm1hbCBub2RlLCBjbG9uZSBpdCB0byBhdm9pZCBtdXRhdGluZyB0aGUgb3JpZ2luYWxcbiAgdmFyIGNsb25lZE5vZGUgPSBjbG9uZU5vZGUobm9kZSk7XG4gIHZhciBmcmFnID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICB2YXIgY2hpbGQ7XG4gIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbmQtYXNzaWduICovXG4gIHdoaWxlIChjaGlsZCA9IGNsb25lZE5vZGUuZmlyc3RDaGlsZCkge1xuICAgIC8qIGVzbGludC1lbmFibGUgbm8tY29uZC1hc3NpZ24gKi9cbiAgICBmcmFnLmFwcGVuZENoaWxkKGNoaWxkKTtcbiAgfVxuICB0cmltTm9kZShmcmFnKTtcbiAgcmV0dXJuIGZyYWc7XG59XG5cbi8vIFRlc3QgZm9yIHRoZSBwcmVzZW5jZSBvZiB0aGUgU2FmYXJpIHRlbXBsYXRlIGNsb25pbmcgYnVnXG4vLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93dWcuY2dpP2lkPTEzNzc1NVxudmFyIGhhc0Jyb2tlblRlbXBsYXRlID0gKGZ1bmN0aW9uICgpIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cbiAgaWYgKGluQnJvd3Nlcikge1xuICAgIHZhciBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgYS5pbm5lckhUTUwgPSAnPHRlbXBsYXRlPjE8L3RlbXBsYXRlPic7XG4gICAgcmV0dXJuICFhLmNsb25lTm9kZSh0cnVlKS5maXJzdENoaWxkLmlubmVySFRNTDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pKCk7XG5cbi8vIFRlc3QgZm9yIElFMTAvMTEgdGV4dGFyZWEgcGxhY2Vob2xkZXIgY2xvbmUgYnVnXG52YXIgaGFzVGV4dGFyZWFDbG9uZUJ1ZyA9IChmdW5jdGlvbiAoKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gIGlmIChpbkJyb3dzZXIpIHtcbiAgICB2YXIgdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgdC5wbGFjZWhvbGRlciA9ICd0JztcbiAgICByZXR1cm4gdC5jbG9uZU5vZGUodHJ1ZSkudmFsdWUgPT09ICd0JztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0pKCk7XG5cbi8qKlxuICogMS4gRGVhbCB3aXRoIFNhZmFyaSBjbG9uaW5nIG5lc3RlZCA8dGVtcGxhdGU+IGJ1ZyBieVxuICogICAgbWFudWFsbHkgY2xvbmluZyBhbGwgdGVtcGxhdGUgaW5zdGFuY2VzLlxuICogMi4gRGVhbCB3aXRoIElFMTAvMTEgdGV4dGFyZWEgcGxhY2Vob2xkZXIgYnVnIGJ5IHNldHRpbmdcbiAqICAgIHRoZSBjb3JyZWN0IHZhbHVlIGFmdGVyIGNsb25pbmcuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fERvY3VtZW50RnJhZ21lbnR9IG5vZGVcbiAqIEByZXR1cm4ge0VsZW1lbnR8RG9jdW1lbnRGcmFnbWVudH1cbiAqL1xuXG5mdW5jdGlvbiBjbG9uZU5vZGUobm9kZSkge1xuICBpZiAoIW5vZGUucXVlcnlTZWxlY3RvckFsbCkge1xuICAgIHJldHVybiBub2RlLmNsb25lTm9kZSgpO1xuICB9XG4gIHZhciByZXMgPSBub2RlLmNsb25lTm9kZSh0cnVlKTtcbiAgdmFyIGksIG9yaWdpbmFsLCBjbG9uZWQ7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAoaGFzQnJva2VuVGVtcGxhdGUpIHtcbiAgICB2YXIgdGVtcENsb25lID0gcmVzO1xuICAgIGlmIChpc1JlYWxUZW1wbGF0ZShub2RlKSkge1xuICAgICAgbm9kZSA9IG5vZGUuY29udGVudDtcbiAgICAgIHRlbXBDbG9uZSA9IHJlcy5jb250ZW50O1xuICAgIH1cbiAgICBvcmlnaW5hbCA9IG5vZGUucXVlcnlTZWxlY3RvckFsbCgndGVtcGxhdGUnKTtcbiAgICBpZiAob3JpZ2luYWwubGVuZ3RoKSB7XG4gICAgICBjbG9uZWQgPSB0ZW1wQ2xvbmUucXVlcnlTZWxlY3RvckFsbCgndGVtcGxhdGUnKTtcbiAgICAgIGkgPSBjbG9uZWQubGVuZ3RoO1xuICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICBjbG9uZWRbaV0ucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoY2xvbmVOb2RlKG9yaWdpbmFsW2ldKSwgY2xvbmVkW2ldKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChoYXNUZXh0YXJlYUNsb25lQnVnKSB7XG4gICAgaWYgKG5vZGUudGFnTmFtZSA9PT0gJ1RFWFRBUkVBJykge1xuICAgICAgcmVzLnZhbHVlID0gbm9kZS52YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3JpZ2luYWwgPSBub2RlLnF1ZXJ5U2VsZWN0b3JBbGwoJ3RleHRhcmVhJyk7XG4gICAgICBpZiAob3JpZ2luYWwubGVuZ3RoKSB7XG4gICAgICAgIGNsb25lZCA9IHJlcy5xdWVyeVNlbGVjdG9yQWxsKCd0ZXh0YXJlYScpO1xuICAgICAgICBpID0gY2xvbmVkLmxlbmd0aDtcbiAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgIGNsb25lZFtpXS52YWx1ZSA9IG9yaWdpbmFsW2ldLnZhbHVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXM7XG59XG5cbi8qKlxuICogUHJvY2VzcyB0aGUgdGVtcGxhdGUgb3B0aW9uIGFuZCBub3JtYWxpemVzIGl0IGludG8gYVxuICogYSBEb2N1bWVudEZyYWdtZW50IHRoYXQgY2FuIGJlIHVzZWQgYXMgYSBwYXJ0aWFsIG9yIGFcbiAqIGluc3RhbmNlIHRlbXBsYXRlLlxuICpcbiAqIEBwYXJhbSB7Kn0gdGVtcGxhdGVcbiAqICAgICAgICBQb3NzaWJsZSB2YWx1ZXMgaW5jbHVkZTpcbiAqICAgICAgICAtIERvY3VtZW50RnJhZ21lbnQgb2JqZWN0XG4gKiAgICAgICAgLSBOb2RlIG9iamVjdCBvZiB0eXBlIFRlbXBsYXRlXG4gKiAgICAgICAgLSBpZCBzZWxlY3RvcjogJyNzb21lLXRlbXBsYXRlLWlkJ1xuICogICAgICAgIC0gdGVtcGxhdGUgc3RyaW5nOiAnPGRpdj48c3Bhbj57e21zZ319PC9zcGFuPjwvZGl2PidcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gc2hvdWxkQ2xvbmVcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gcmF3XG4gKiAgICAgICAgaW5saW5lIEhUTUwgaW50ZXJwb2xhdGlvbi4gRG8gbm90IGNoZWNrIGZvciBpZFxuICogICAgICAgIHNlbGVjdG9yIGFuZCBrZWVwIHdoaXRlc3BhY2UgaW4gdGhlIHN0cmluZy5cbiAqIEByZXR1cm4ge0RvY3VtZW50RnJhZ21lbnR8dW5kZWZpbmVkfVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlVGVtcGxhdGUodGVtcGxhdGUsIHNob3VsZENsb25lLCByYXcpIHtcbiAgdmFyIG5vZGUsIGZyYWc7XG5cbiAgLy8gaWYgdGhlIHRlbXBsYXRlIGlzIGFscmVhZHkgYSBkb2N1bWVudCBmcmFnbWVudCxcbiAgLy8gZG8gbm90aGluZ1xuICBpZiAoaXNGcmFnbWVudCh0ZW1wbGF0ZSkpIHtcbiAgICB0cmltTm9kZSh0ZW1wbGF0ZSk7XG4gICAgcmV0dXJuIHNob3VsZENsb25lID8gY2xvbmVOb2RlKHRlbXBsYXRlKSA6IHRlbXBsYXRlO1xuICB9XG5cbiAgaWYgKHR5cGVvZiB0ZW1wbGF0ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBpZCBzZWxlY3RvclxuICAgIGlmICghcmF3ICYmIHRlbXBsYXRlLmNoYXJBdCgwKSA9PT0gJyMnKSB7XG4gICAgICAvLyBpZCBzZWxlY3RvciBjYW4gYmUgY2FjaGVkIHRvb1xuICAgICAgZnJhZyA9IGlkU2VsZWN0b3JDYWNoZS5nZXQodGVtcGxhdGUpO1xuICAgICAgaWYgKCFmcmFnKSB7XG4gICAgICAgIG5vZGUgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0ZW1wbGF0ZS5zbGljZSgxKSk7XG4gICAgICAgIGlmIChub2RlKSB7XG4gICAgICAgICAgZnJhZyA9IG5vZGVUb0ZyYWdtZW50KG5vZGUpO1xuICAgICAgICAgIC8vIHNhdmUgc2VsZWN0b3IgdG8gY2FjaGVcbiAgICAgICAgICBpZFNlbGVjdG9yQ2FjaGUucHV0KHRlbXBsYXRlLCBmcmFnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBub3JtYWwgc3RyaW5nIHRlbXBsYXRlXG4gICAgICBmcmFnID0gc3RyaW5nVG9GcmFnbWVudCh0ZW1wbGF0ZSwgcmF3KTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodGVtcGxhdGUubm9kZVR5cGUpIHtcbiAgICAvLyBhIGRpcmVjdCBub2RlXG4gICAgZnJhZyA9IG5vZGVUb0ZyYWdtZW50KHRlbXBsYXRlKTtcbiAgfVxuXG4gIHJldHVybiBmcmFnICYmIHNob3VsZENsb25lID8gY2xvbmVOb2RlKGZyYWcpIDogZnJhZztcbn1cblxudmFyIHRlbXBsYXRlID0gT2JqZWN0LmZyZWV6ZSh7XG4gIGNsb25lTm9kZTogY2xvbmVOb2RlLFxuICBwYXJzZVRlbXBsYXRlOiBwYXJzZVRlbXBsYXRlXG59KTtcblxudmFyIGh0bWwgPSB7XG5cbiAgYmluZDogZnVuY3Rpb24gYmluZCgpIHtcbiAgICAvLyBhIGNvbW1lbnQgbm9kZSBtZWFucyB0aGlzIGlzIGEgYmluZGluZyBmb3JcbiAgICAvLyB7e3sgaW5saW5lIHVuZXNjYXBlZCBodG1sIH19fVxuICAgIGlmICh0aGlzLmVsLm5vZGVUeXBlID09PSA4KSB7XG4gICAgICAvLyBob2xkIG5vZGVzXG4gICAgICB0aGlzLm5vZGVzID0gW107XG4gICAgICAvLyByZXBsYWNlIHRoZSBwbGFjZWhvbGRlciB3aXRoIHByb3BlciBhbmNob3JcbiAgICAgIHRoaXMuYW5jaG9yID0gY3JlYXRlQW5jaG9yKCd2LWh0bWwnKTtcbiAgICAgIHJlcGxhY2UodGhpcy5lbCwgdGhpcy5hbmNob3IpO1xuICAgIH1cbiAgfSxcblxuICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZSh2YWx1ZSkge1xuICAgIHZhbHVlID0gX3RvU3RyaW5nKHZhbHVlKTtcbiAgICBpZiAodGhpcy5ub2Rlcykge1xuICAgICAgdGhpcy5zd2FwKHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbC5pbm5lckhUTUwgPSB2YWx1ZTtcbiAgICB9XG4gIH0sXG5cbiAgc3dhcDogZnVuY3Rpb24gc3dhcCh2YWx1ZSkge1xuICAgIC8vIHJlbW92ZSBvbGQgbm9kZXNcbiAgICB2YXIgaSA9IHRoaXMubm9kZXMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIHJlbW92ZSh0aGlzLm5vZGVzW2ldKTtcbiAgICB9XG4gICAgLy8gY29udmVydCBuZXcgdmFsdWUgdG8gYSBmcmFnbWVudFxuICAgIC8vIGRvIG5vdCBhdHRlbXB0IHRvIHJldHJpZXZlIGZyb20gaWQgc2VsZWN0b3JcbiAgICB2YXIgZnJhZyA9IHBhcnNlVGVtcGxhdGUodmFsdWUsIHRydWUsIHRydWUpO1xuICAgIC8vIHNhdmUgYSByZWZlcmVuY2UgdG8gdGhlc2Ugbm9kZXMgc28gd2UgY2FuIHJlbW92ZSBsYXRlclxuICAgIHRoaXMubm9kZXMgPSB0b0FycmF5KGZyYWcuY2hpbGROb2Rlcyk7XG4gICAgYmVmb3JlKGZyYWcsIHRoaXMuYW5jaG9yKTtcbiAgfVxufTtcblxuLyoqXG4gKiBBYnN0cmFjdGlvbiBmb3IgYSBwYXJ0aWFsbHktY29tcGlsZWQgZnJhZ21lbnQuXG4gKiBDYW4gb3B0aW9uYWxseSBjb21waWxlIGNvbnRlbnQgd2l0aCBhIGNoaWxkIHNjb3BlLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGxpbmtlclxuICogQHBhcmFtIHtWdWV9IHZtXG4gKiBAcGFyYW0ge0RvY3VtZW50RnJhZ21lbnR9IGZyYWdcbiAqIEBwYXJhbSB7VnVlfSBbaG9zdF1cbiAqIEBwYXJhbSB7T2JqZWN0fSBbc2NvcGVdXG4gKi9cbmZ1bmN0aW9uIEZyYWdtZW50KGxpbmtlciwgdm0sIGZyYWcsIGhvc3QsIHNjb3BlLCBwYXJlbnRGcmFnKSB7XG4gIHRoaXMuY2hpbGRyZW4gPSBbXTtcbiAgdGhpcy5jaGlsZEZyYWdzID0gW107XG4gIHRoaXMudm0gPSB2bTtcbiAgdGhpcy5zY29wZSA9IHNjb3BlO1xuICB0aGlzLmluc2VydGVkID0gZmFsc2U7XG4gIHRoaXMucGFyZW50RnJhZyA9IHBhcmVudEZyYWc7XG4gIGlmIChwYXJlbnRGcmFnKSB7XG4gICAgcGFyZW50RnJhZy5jaGlsZEZyYWdzLnB1c2godGhpcyk7XG4gIH1cbiAgdGhpcy51bmxpbmsgPSBsaW5rZXIodm0sIGZyYWcsIGhvc3QsIHNjb3BlLCB0aGlzKTtcbiAgdmFyIHNpbmdsZSA9IHRoaXMuc2luZ2xlID0gZnJhZy5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMSAmJlxuICAvLyBkbyBub3QgZ28gc2luZ2xlIG1vZGUgaWYgdGhlIG9ubHkgbm9kZSBpcyBhbiBhbmNob3JcbiAgIWZyYWcuY2hpbGROb2Rlc1swXS5fX3ZfYW5jaG9yO1xuICBpZiAoc2luZ2xlKSB7XG4gICAgdGhpcy5ub2RlID0gZnJhZy5jaGlsZE5vZGVzWzBdO1xuICAgIHRoaXMuYmVmb3JlID0gc2luZ2xlQmVmb3JlO1xuICAgIHRoaXMucmVtb3ZlID0gc2luZ2xlUmVtb3ZlO1xuICB9IGVsc2Uge1xuICAgIHRoaXMubm9kZSA9IGNyZWF0ZUFuY2hvcignZnJhZ21lbnQtc3RhcnQnKTtcbiAgICB0aGlzLmVuZCA9IGNyZWF0ZUFuY2hvcignZnJhZ21lbnQtZW5kJyk7XG4gICAgdGhpcy5mcmFnID0gZnJhZztcbiAgICBwcmVwZW5kKHRoaXMubm9kZSwgZnJhZyk7XG4gICAgZnJhZy5hcHBlbmRDaGlsZCh0aGlzLmVuZCk7XG4gICAgdGhpcy5iZWZvcmUgPSBtdWx0aUJlZm9yZTtcbiAgICB0aGlzLnJlbW92ZSA9IG11bHRpUmVtb3ZlO1xuICB9XG4gIHRoaXMubm9kZS5fX3ZfZnJhZyA9IHRoaXM7XG59XG5cbi8qKlxuICogQ2FsbCBhdHRhY2gvZGV0YWNoIGZvciBhbGwgY29tcG9uZW50cyBjb250YWluZWQgd2l0aGluXG4gKiB0aGlzIGZyYWdtZW50LiBBbHNvIGRvIHNvIHJlY3Vyc2l2ZWx5IGZvciBhbGwgY2hpbGRcbiAqIGZyYWdtZW50cy5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBob29rXG4gKi9cblxuRnJhZ21lbnQucHJvdG90eXBlLmNhbGxIb29rID0gZnVuY3Rpb24gKGhvb2spIHtcbiAgdmFyIGksIGw7XG4gIGZvciAoaSA9IDAsIGwgPSB0aGlzLmNoaWxkRnJhZ3MubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgdGhpcy5jaGlsZEZyYWdzW2ldLmNhbGxIb29rKGhvb2spO1xuICB9XG4gIGZvciAoaSA9IDAsIGwgPSB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGhvb2sodGhpcy5jaGlsZHJlbltpXSk7XG4gIH1cbn07XG5cbi8qKlxuICogSW5zZXJ0IGZyYWdtZW50IGJlZm9yZSB0YXJnZXQsIHNpbmdsZSBub2RlIHZlcnNpb25cbiAqXG4gKiBAcGFyYW0ge05vZGV9IHRhcmdldFxuICogQHBhcmFtIHtCb29sZWFufSB3aXRoVHJhbnNpdGlvblxuICovXG5cbmZ1bmN0aW9uIHNpbmdsZUJlZm9yZSh0YXJnZXQsIHdpdGhUcmFuc2l0aW9uKSB7XG4gIHRoaXMuaW5zZXJ0ZWQgPSB0cnVlO1xuICB2YXIgbWV0aG9kID0gd2l0aFRyYW5zaXRpb24gIT09IGZhbHNlID8gYmVmb3JlV2l0aFRyYW5zaXRpb24gOiBiZWZvcmU7XG4gIG1ldGhvZCh0aGlzLm5vZGUsIHRhcmdldCwgdGhpcy52bSk7XG4gIGlmIChpbkRvYyh0aGlzLm5vZGUpKSB7XG4gICAgdGhpcy5jYWxsSG9vayhhdHRhY2gpO1xuICB9XG59XG5cbi8qKlxuICogUmVtb3ZlIGZyYWdtZW50LCBzaW5nbGUgbm9kZSB2ZXJzaW9uXG4gKi9cblxuZnVuY3Rpb24gc2luZ2xlUmVtb3ZlKCkge1xuICB0aGlzLmluc2VydGVkID0gZmFsc2U7XG4gIHZhciBzaG91bGRDYWxsUmVtb3ZlID0gaW5Eb2ModGhpcy5ub2RlKTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLmJlZm9yZVJlbW92ZSgpO1xuICByZW1vdmVXaXRoVHJhbnNpdGlvbih0aGlzLm5vZGUsIHRoaXMudm0sIGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoc2hvdWxkQ2FsbFJlbW92ZSkge1xuICAgICAgc2VsZi5jYWxsSG9vayhkZXRhY2gpO1xuICAgIH1cbiAgICBzZWxmLmRlc3Ryb3koKTtcbiAgfSk7XG59XG5cbi8qKlxuICogSW5zZXJ0IGZyYWdtZW50IGJlZm9yZSB0YXJnZXQsIG11bHRpLW5vZGVzIHZlcnNpb25cbiAqXG4gKiBAcGFyYW0ge05vZGV9IHRhcmdldFxuICogQHBhcmFtIHtCb29sZWFufSB3aXRoVHJhbnNpdGlvblxuICovXG5cbmZ1bmN0aW9uIG11bHRpQmVmb3JlKHRhcmdldCwgd2l0aFRyYW5zaXRpb24pIHtcbiAgdGhpcy5pbnNlcnRlZCA9IHRydWU7XG4gIHZhciB2bSA9IHRoaXMudm07XG4gIHZhciBtZXRob2QgPSB3aXRoVHJhbnNpdGlvbiAhPT0gZmFsc2UgPyBiZWZvcmVXaXRoVHJhbnNpdGlvbiA6IGJlZm9yZTtcbiAgbWFwTm9kZVJhbmdlKHRoaXMubm9kZSwgdGhpcy5lbmQsIGZ1bmN0aW9uIChub2RlKSB7XG4gICAgbWV0aG9kKG5vZGUsIHRhcmdldCwgdm0pO1xuICB9KTtcbiAgaWYgKGluRG9jKHRoaXMubm9kZSkpIHtcbiAgICB0aGlzLmNhbGxIb29rKGF0dGFjaCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZW1vdmUgZnJhZ21lbnQsIG11bHRpLW5vZGVzIHZlcnNpb25cbiAqL1xuXG5mdW5jdGlvbiBtdWx0aVJlbW92ZSgpIHtcbiAgdGhpcy5pbnNlcnRlZCA9IGZhbHNlO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHZhciBzaG91bGRDYWxsUmVtb3ZlID0gaW5Eb2ModGhpcy5ub2RlKTtcbiAgdGhpcy5iZWZvcmVSZW1vdmUoKTtcbiAgcmVtb3ZlTm9kZVJhbmdlKHRoaXMubm9kZSwgdGhpcy5lbmQsIHRoaXMudm0sIHRoaXMuZnJhZywgZnVuY3Rpb24gKCkge1xuICAgIGlmIChzaG91bGRDYWxsUmVtb3ZlKSB7XG4gICAgICBzZWxmLmNhbGxIb29rKGRldGFjaCk7XG4gICAgfVxuICAgIHNlbGYuZGVzdHJveSgpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBQcmVwYXJlIHRoZSBmcmFnbWVudCBmb3IgcmVtb3ZhbC5cbiAqL1xuXG5GcmFnbWVudC5wcm90b3R5cGUuYmVmb3JlUmVtb3ZlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaSwgbDtcbiAgZm9yIChpID0gMCwgbCA9IHRoaXMuY2hpbGRGcmFncy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAvLyBjYWxsIHRoZSBzYW1lIG1ldGhvZCByZWN1cnNpdmVseSBvbiBjaGlsZFxuICAgIC8vIGZyYWdtZW50cywgZGVwdGgtZmlyc3RcbiAgICB0aGlzLmNoaWxkRnJhZ3NbaV0uYmVmb3JlUmVtb3ZlKGZhbHNlKTtcbiAgfVxuICBmb3IgKGkgPSAwLCBsID0gdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAvLyBDYWxsIGRlc3Ryb3kgZm9yIGFsbCBjb250YWluZWQgaW5zdGFuY2VzLFxuICAgIC8vIHdpdGggcmVtb3ZlOmZhbHNlIGFuZCBkZWZlcjp0cnVlLlxuICAgIC8vIERlZmVyIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHdlIG5lZWQgdG9cbiAgICAvLyBrZWVwIHRoZSBjaGlsZHJlbiB0byBjYWxsIGRldGFjaCBob29rc1xuICAgIC8vIG9uIHRoZW0uXG4gICAgdGhpcy5jaGlsZHJlbltpXS4kZGVzdHJveShmYWxzZSwgdHJ1ZSk7XG4gIH1cbiAgdmFyIGRpcnMgPSB0aGlzLnVubGluay5kaXJzO1xuICBmb3IgKGkgPSAwLCBsID0gZGlycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAvLyBkaXNhYmxlIHRoZSB3YXRjaGVycyBvbiBhbGwgdGhlIGRpcmVjdGl2ZXNcbiAgICAvLyBzbyB0aGF0IHRoZSByZW5kZXJlZCBjb250ZW50IHN0YXlzIHRoZSBzYW1lXG4gICAgLy8gZHVyaW5nIHJlbW92YWwuXG4gICAgZGlyc1tpXS5fd2F0Y2hlciAmJiBkaXJzW2ldLl93YXRjaGVyLnRlYXJkb3duKCk7XG4gIH1cbn07XG5cbi8qKlxuICogRGVzdHJveSB0aGUgZnJhZ21lbnQuXG4gKi9cblxuRnJhZ21lbnQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnBhcmVudEZyYWcpIHtcbiAgICB0aGlzLnBhcmVudEZyYWcuY2hpbGRGcmFncy4kcmVtb3ZlKHRoaXMpO1xuICB9XG4gIHRoaXMubm9kZS5fX3ZfZnJhZyA9IG51bGw7XG4gIHRoaXMudW5saW5rKCk7XG59O1xuXG4vKipcbiAqIENhbGwgYXR0YWNoIGhvb2sgZm9yIGEgVnVlIGluc3RhbmNlLlxuICpcbiAqIEBwYXJhbSB7VnVlfSBjaGlsZFxuICovXG5cbmZ1bmN0aW9uIGF0dGFjaChjaGlsZCkge1xuICBpZiAoIWNoaWxkLl9pc0F0dGFjaGVkKSB7XG4gICAgY2hpbGQuX2NhbGxIb29rKCdhdHRhY2hlZCcpO1xuICB9XG59XG5cbi8qKlxuICogQ2FsbCBkZXRhY2ggaG9vayBmb3IgYSBWdWUgaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtIHtWdWV9IGNoaWxkXG4gKi9cblxuZnVuY3Rpb24gZGV0YWNoKGNoaWxkKSB7XG4gIGlmIChjaGlsZC5faXNBdHRhY2hlZCkge1xuICAgIGNoaWxkLl9jYWxsSG9vaygnZGV0YWNoZWQnKTtcbiAgfVxufVxuXG52YXIgbGlua2VyQ2FjaGUgPSBuZXcgQ2FjaGUoNTAwMCk7XG5cbi8qKlxuICogQSBmYWN0b3J5IHRoYXQgY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGluc3RhbmNlcyBvZiBhXG4gKiBmcmFnbWVudC4gQ2FjaGVzIHRoZSBjb21waWxlZCBsaW5rZXIgaWYgcG9zc2libGUuXG4gKlxuICogQHBhcmFtIHtWdWV9IHZtXG4gKiBAcGFyYW0ge0VsZW1lbnR8U3RyaW5nfSBlbFxuICovXG5mdW5jdGlvbiBGcmFnbWVudEZhY3Rvcnkodm0sIGVsKSB7XG4gIHRoaXMudm0gPSB2bTtcbiAgdmFyIHRlbXBsYXRlO1xuICB2YXIgaXNTdHJpbmcgPSB0eXBlb2YgZWwgPT09ICdzdHJpbmcnO1xuICBpZiAoaXNTdHJpbmcgfHwgaXNUZW1wbGF0ZShlbCkpIHtcbiAgICB0ZW1wbGF0ZSA9IHBhcnNlVGVtcGxhdGUoZWwsIHRydWUpO1xuICB9IGVsc2Uge1xuICAgIHRlbXBsYXRlID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgIHRlbXBsYXRlLmFwcGVuZENoaWxkKGVsKTtcbiAgfVxuICB0aGlzLnRlbXBsYXRlID0gdGVtcGxhdGU7XG4gIC8vIGxpbmtlciBjYW4gYmUgY2FjaGVkLCBidXQgb25seSBmb3IgY29tcG9uZW50c1xuICB2YXIgbGlua2VyO1xuICB2YXIgY2lkID0gdm0uY29uc3RydWN0b3IuY2lkO1xuICBpZiAoY2lkID4gMCkge1xuICAgIHZhciBjYWNoZUlkID0gY2lkICsgKGlzU3RyaW5nID8gZWwgOiBnZXRPdXRlckhUTUwoZWwpKTtcbiAgICBsaW5rZXIgPSBsaW5rZXJDYWNoZS5nZXQoY2FjaGVJZCk7XG4gICAgaWYgKCFsaW5rZXIpIHtcbiAgICAgIGxpbmtlciA9IGNvbXBpbGUodGVtcGxhdGUsIHZtLiRvcHRpb25zLCB0cnVlKTtcbiAgICAgIGxpbmtlckNhY2hlLnB1dChjYWNoZUlkLCBsaW5rZXIpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBsaW5rZXIgPSBjb21waWxlKHRlbXBsYXRlLCB2bS4kb3B0aW9ucywgdHJ1ZSk7XG4gIH1cbiAgdGhpcy5saW5rZXIgPSBsaW5rZXI7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgZnJhZ21lbnQgaW5zdGFuY2Ugd2l0aCBnaXZlbiBob3N0IGFuZCBzY29wZS5cbiAqXG4gKiBAcGFyYW0ge1Z1ZX0gaG9zdFxuICogQHBhcmFtIHtPYmplY3R9IHNjb3BlXG4gKiBAcGFyYW0ge0ZyYWdtZW50fSBwYXJlbnRGcmFnXG4gKi9cblxuRnJhZ21lbnRGYWN0b3J5LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAoaG9zdCwgc2NvcGUsIHBhcmVudEZyYWcpIHtcbiAgdmFyIGZyYWcgPSBjbG9uZU5vZGUodGhpcy50ZW1wbGF0ZSk7XG4gIHJldHVybiBuZXcgRnJhZ21lbnQodGhpcy5saW5rZXIsIHRoaXMudm0sIGZyYWcsIGhvc3QsIHNjb3BlLCBwYXJlbnRGcmFnKTtcbn07XG5cbnZhciBPTiA9IDcwMDtcbnZhciBNT0RFTCA9IDgwMDtcbnZhciBCSU5EID0gODUwO1xudmFyIFRSQU5TSVRJT04gPSAxMTAwO1xudmFyIEVMID0gMTUwMDtcbnZhciBDT01QT05FTlQgPSAxNTAwO1xudmFyIFBBUlRJQUwgPSAxNzUwO1xudmFyIEZPUiA9IDIwMDA7XG52YXIgSUYgPSAyMDAwO1xudmFyIFNMT1QgPSAyMTAwO1xuXG52YXIgdWlkJDMgPSAwO1xuXG52YXIgdkZvciA9IHtcblxuICBwcmlvcml0eTogRk9SLFxuXG4gIHBhcmFtczogWyd0cmFjay1ieScsICdzdGFnZ2VyJywgJ2VudGVyLXN0YWdnZXInLCAnbGVhdmUtc3RhZ2dlciddLFxuXG4gIGJpbmQ6IGZ1bmN0aW9uIGJpbmQoKSB7XG4gICAgLy8gc3VwcG9ydCBcIml0ZW0gaW4vb2YgaXRlbXNcIiBzeW50YXhcbiAgICB2YXIgaW5NYXRjaCA9IHRoaXMuZXhwcmVzc2lvbi5tYXRjaCgvKC4qKSAoPzppbnxvZikgKC4qKS8pO1xuICAgIGlmIChpbk1hdGNoKSB7XG4gICAgICB2YXIgaXRNYXRjaCA9IGluTWF0Y2hbMV0ubWF0Y2goL1xcKCguKiksKC4qKVxcKS8pO1xuICAgICAgaWYgKGl0TWF0Y2gpIHtcbiAgICAgICAgdGhpcy5pdGVyYXRvciA9IGl0TWF0Y2hbMV0udHJpbSgpO1xuICAgICAgICB0aGlzLmFsaWFzID0gaXRNYXRjaFsyXS50cmltKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFsaWFzID0gaW5NYXRjaFsxXS50cmltKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmV4cHJlc3Npb24gPSBpbk1hdGNoWzJdO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5hbGlhcykge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKCdBbGlhcyBpcyByZXF1aXJlZCBpbiB2LWZvci4nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB1aWQgYXMgYSBjYWNoZSBpZGVudGlmaWVyXG4gICAgdGhpcy5pZCA9ICdfX3YtZm9yX18nICsgKyt1aWQkMztcblxuICAgIC8vIGNoZWNrIGlmIHRoaXMgaXMgYW4gb3B0aW9uIGxpc3QsXG4gICAgLy8gc28gdGhhdCB3ZSBrbm93IGlmIHdlIG5lZWQgdG8gdXBkYXRlIHRoZSA8c2VsZWN0PidzXG4gICAgLy8gdi1tb2RlbCB3aGVuIHRoZSBvcHRpb24gbGlzdCBoYXMgY2hhbmdlZC5cbiAgICAvLyBiZWNhdXNlIHYtbW9kZWwgaGFzIGEgbG93ZXIgcHJpb3JpdHkgdGhhbiB2LWZvcixcbiAgICAvLyB0aGUgdi1tb2RlbCBpcyBub3QgYm91bmQgaGVyZSB5ZXQsIHNvIHdlIGhhdmUgdG9cbiAgICAvLyByZXRyaXZlIGl0IGluIHRoZSBhY3R1YWwgdXBkYXRlTW9kZWwoKSBmdW5jdGlvbi5cbiAgICB2YXIgdGFnID0gdGhpcy5lbC50YWdOYW1lO1xuICAgIHRoaXMuaXNPcHRpb24gPSAodGFnID09PSAnT1BUSU9OJyB8fCB0YWcgPT09ICdPUFRHUk9VUCcpICYmIHRoaXMuZWwucGFyZW50Tm9kZS50YWdOYW1lID09PSAnU0VMRUNUJztcblxuICAgIC8vIHNldHVwIGFuY2hvciBub2Rlc1xuICAgIHRoaXMuc3RhcnQgPSBjcmVhdGVBbmNob3IoJ3YtZm9yLXN0YXJ0Jyk7XG4gICAgdGhpcy5lbmQgPSBjcmVhdGVBbmNob3IoJ3YtZm9yLWVuZCcpO1xuICAgIHJlcGxhY2UodGhpcy5lbCwgdGhpcy5lbmQpO1xuICAgIGJlZm9yZSh0aGlzLnN0YXJ0LCB0aGlzLmVuZCk7XG5cbiAgICAvLyBjYWNoZVxuICAgIHRoaXMuY2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICAgLy8gZnJhZ21lbnQgZmFjdG9yeVxuICAgIHRoaXMuZmFjdG9yeSA9IG5ldyBGcmFnbWVudEZhY3RvcnkodGhpcy52bSwgdGhpcy5lbCk7XG4gIH0sXG5cbiAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUoZGF0YSkge1xuICAgIHRoaXMuZGlmZihkYXRhKTtcbiAgICB0aGlzLnVwZGF0ZVJlZigpO1xuICAgIHRoaXMudXBkYXRlTW9kZWwoKTtcbiAgfSxcblxuICAvKipcbiAgICogRGlmZiwgYmFzZWQgb24gbmV3IGRhdGEgYW5kIG9sZCBkYXRhLCBkZXRlcm1pbmUgdGhlXG4gICAqIG1pbmltdW0gYW1vdW50IG9mIERPTSBtYW5pcHVsYXRpb25zIG5lZWRlZCB0byBtYWtlIHRoZVxuICAgKiBET00gcmVmbGVjdCB0aGUgbmV3IGRhdGEgQXJyYXkuXG4gICAqXG4gICAqIFRoZSBhbGdvcml0aG0gZGlmZnMgdGhlIG5ldyBkYXRhIEFycmF5IGJ5IHN0b3JpbmcgYVxuICAgKiBoaWRkZW4gcmVmZXJlbmNlIHRvIGFuIG93bmVyIHZtIGluc3RhbmNlIG9uIHByZXZpb3VzbHlcbiAgICogc2VlbiBkYXRhLiBUaGlzIGFsbG93cyB1cyB0byBhY2hpZXZlIE8obikgd2hpY2ggaXNcbiAgICogYmV0dGVyIHRoYW4gYSBsZXZlbnNodGVpbiBkaXN0YW5jZSBiYXNlZCBhbGdvcml0aG0sXG4gICAqIHdoaWNoIGlzIE8obSAqIG4pLlxuICAgKlxuICAgKiBAcGFyYW0ge0FycmF5fSBkYXRhXG4gICAqL1xuXG4gIGRpZmY6IGZ1bmN0aW9uIGRpZmYoZGF0YSkge1xuICAgIC8vIGNoZWNrIGlmIHRoZSBBcnJheSB3YXMgY29udmVydGVkIGZyb20gYW4gT2JqZWN0XG4gICAgdmFyIGl0ZW0gPSBkYXRhWzBdO1xuICAgIHZhciBjb252ZXJ0ZWRGcm9tT2JqZWN0ID0gdGhpcy5mcm9tT2JqZWN0ID0gaXNPYmplY3QoaXRlbSkgJiYgaGFzT3duKGl0ZW0sICcka2V5JykgJiYgaGFzT3duKGl0ZW0sICckdmFsdWUnKTtcblxuICAgIHZhciB0cmFja0J5S2V5ID0gdGhpcy5wYXJhbXMudHJhY2tCeTtcbiAgICB2YXIgb2xkRnJhZ3MgPSB0aGlzLmZyYWdzO1xuICAgIHZhciBmcmFncyA9IHRoaXMuZnJhZ3MgPSBuZXcgQXJyYXkoZGF0YS5sZW5ndGgpO1xuICAgIHZhciBhbGlhcyA9IHRoaXMuYWxpYXM7XG4gICAgdmFyIGl0ZXJhdG9yID0gdGhpcy5pdGVyYXRvcjtcbiAgICB2YXIgc3RhcnQgPSB0aGlzLnN0YXJ0O1xuICAgIHZhciBlbmQgPSB0aGlzLmVuZDtcbiAgICB2YXIgaW5Eb2N1bWVudCA9IGluRG9jKHN0YXJ0KTtcbiAgICB2YXIgaW5pdCA9ICFvbGRGcmFncztcbiAgICB2YXIgaSwgbCwgZnJhZywga2V5LCB2YWx1ZSwgcHJpbWl0aXZlO1xuXG4gICAgLy8gRmlyc3QgcGFzcywgZ28gdGhyb3VnaCB0aGUgbmV3IEFycmF5IGFuZCBmaWxsIHVwXG4gICAgLy8gdGhlIG5ldyBmcmFncyBhcnJheS4gSWYgYSBwaWVjZSBvZiBkYXRhIGhhcyBhIGNhY2hlZFxuICAgIC8vIGluc3RhbmNlIGZvciBpdCwgd2UgcmV1c2UgaXQuIE90aGVyd2lzZSBidWlsZCBhIG5ld1xuICAgIC8vIGluc3RhbmNlLlxuICAgIGZvciAoaSA9IDAsIGwgPSBkYXRhLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgaXRlbSA9IGRhdGFbaV07XG4gICAgICBrZXkgPSBjb252ZXJ0ZWRGcm9tT2JqZWN0ID8gaXRlbS4ka2V5IDogbnVsbDtcbiAgICAgIHZhbHVlID0gY29udmVydGVkRnJvbU9iamVjdCA/IGl0ZW0uJHZhbHVlIDogaXRlbTtcbiAgICAgIHByaW1pdGl2ZSA9ICFpc09iamVjdCh2YWx1ZSk7XG4gICAgICBmcmFnID0gIWluaXQgJiYgdGhpcy5nZXRDYWNoZWRGcmFnKHZhbHVlLCBpLCBrZXkpO1xuICAgICAgaWYgKGZyYWcpIHtcbiAgICAgICAgLy8gcmV1c2FibGUgZnJhZ21lbnRcbiAgICAgICAgZnJhZy5yZXVzZWQgPSB0cnVlO1xuICAgICAgICAvLyB1cGRhdGUgJGluZGV4XG4gICAgICAgIGZyYWcuc2NvcGUuJGluZGV4ID0gaTtcbiAgICAgICAgLy8gdXBkYXRlICRrZXlcbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgIGZyYWcuc2NvcGUuJGtleSA9IGtleTtcbiAgICAgICAgfVxuICAgICAgICAvLyB1cGRhdGUgaXRlcmF0b3JcbiAgICAgICAgaWYgKGl0ZXJhdG9yKSB7XG4gICAgICAgICAgZnJhZy5zY29wZVtpdGVyYXRvcl0gPSBrZXkgIT09IG51bGwgPyBrZXkgOiBpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHVwZGF0ZSBkYXRhIGZvciB0cmFjay1ieSwgb2JqZWN0IHJlcGVhdCAmXG4gICAgICAgIC8vIHByaW1pdGl2ZSB2YWx1ZXMuXG4gICAgICAgIGlmICh0cmFja0J5S2V5IHx8IGNvbnZlcnRlZEZyb21PYmplY3QgfHwgcHJpbWl0aXZlKSB7XG4gICAgICAgICAgZnJhZy5zY29wZVthbGlhc10gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gbmV3IGlzbnRhbmNlXG4gICAgICAgIGZyYWcgPSB0aGlzLmNyZWF0ZSh2YWx1ZSwgYWxpYXMsIGksIGtleSk7XG4gICAgICAgIGZyYWcuZnJlc2ggPSAhaW5pdDtcbiAgICAgIH1cbiAgICAgIGZyYWdzW2ldID0gZnJhZztcbiAgICAgIGlmIChpbml0KSB7XG4gICAgICAgIGZyYWcuYmVmb3JlKGVuZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gd2UncmUgZG9uZSBmb3IgdGhlIGluaXRpYWwgcmVuZGVyLlxuICAgIGlmIChpbml0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU2Vjb25kIHBhc3MsIGdvIHRocm91Z2ggdGhlIG9sZCBmcmFnbWVudHMgYW5kXG4gICAgLy8gZGVzdHJveSB0aG9zZSB3aG8gYXJlIG5vdCByZXVzZWQgKGFuZCByZW1vdmUgdGhlbVxuICAgIC8vIGZyb20gY2FjaGUpXG4gICAgdmFyIHJlbW92YWxJbmRleCA9IDA7XG4gICAgdmFyIHRvdGFsUmVtb3ZlZCA9IG9sZEZyYWdzLmxlbmd0aCAtIGZyYWdzLmxlbmd0aDtcbiAgICAvLyB3aGVuIHJlbW92aW5nIGEgbGFyZ2UgbnVtYmVyIG9mIGZyYWdtZW50cywgd2F0Y2hlciByZW1vdmFsXG4gICAgLy8gdHVybnMgb3V0IHRvIGJlIGEgcGVyZiBib3R0bGVuZWNrLCBzbyB3ZSBiYXRjaCB0aGUgd2F0Y2hlclxuICAgIC8vIHJlbW92YWxzIGludG8gYSBzaW5nbGUgZmlsdGVyIGNhbGwhXG4gICAgdGhpcy52bS5fdkZvclJlbW92aW5nID0gdHJ1ZTtcbiAgICBmb3IgKGkgPSAwLCBsID0gb2xkRnJhZ3MubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBmcmFnID0gb2xkRnJhZ3NbaV07XG4gICAgICBpZiAoIWZyYWcucmV1c2VkKSB7XG4gICAgICAgIHRoaXMuZGVsZXRlQ2FjaGVkRnJhZyhmcmFnKTtcbiAgICAgICAgdGhpcy5yZW1vdmUoZnJhZywgcmVtb3ZhbEluZGV4KyssIHRvdGFsUmVtb3ZlZCwgaW5Eb2N1bWVudCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudm0uX3ZGb3JSZW1vdmluZyA9IGZhbHNlO1xuICAgIGlmIChyZW1vdmFsSW5kZXgpIHtcbiAgICAgIHRoaXMudm0uX3dhdGNoZXJzID0gdGhpcy52bS5fd2F0Y2hlcnMuZmlsdGVyKGZ1bmN0aW9uICh3KSB7XG4gICAgICAgIHJldHVybiB3LmFjdGl2ZTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEZpbmFsIHBhc3MsIG1vdmUvaW5zZXJ0IG5ldyBmcmFnbWVudHMgaW50byB0aGVcbiAgICAvLyByaWdodCBwbGFjZS5cbiAgICB2YXIgdGFyZ2V0UHJldiwgcHJldkVsLCBjdXJyZW50UHJldjtcbiAgICB2YXIgaW5zZXJ0aW9uSW5kZXggPSAwO1xuICAgIGZvciAoaSA9IDAsIGwgPSBmcmFncy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIGZyYWcgPSBmcmFnc1tpXTtcbiAgICAgIC8vIHRoaXMgaXMgdGhlIGZyYWcgdGhhdCB3ZSBzaG91bGQgYmUgYWZ0ZXJcbiAgICAgIHRhcmdldFByZXYgPSBmcmFnc1tpIC0gMV07XG4gICAgICBwcmV2RWwgPSB0YXJnZXRQcmV2ID8gdGFyZ2V0UHJldi5zdGFnZ2VyQ2IgPyB0YXJnZXRQcmV2LnN0YWdnZXJBbmNob3IgOiB0YXJnZXRQcmV2LmVuZCB8fCB0YXJnZXRQcmV2Lm5vZGUgOiBzdGFydDtcbiAgICAgIGlmIChmcmFnLnJldXNlZCAmJiAhZnJhZy5zdGFnZ2VyQ2IpIHtcbiAgICAgICAgY3VycmVudFByZXYgPSBmaW5kUHJldkZyYWcoZnJhZywgc3RhcnQsIHRoaXMuaWQpO1xuICAgICAgICBpZiAoY3VycmVudFByZXYgIT09IHRhcmdldFByZXYgJiYgKCFjdXJyZW50UHJldiB8fFxuICAgICAgICAvLyBvcHRpbWl6YXRpb24gZm9yIG1vdmluZyBhIHNpbmdsZSBpdGVtLlxuICAgICAgICAvLyB0aGFua3MgdG8gc3VnZ2VzdGlvbnMgYnkgQGxpdm9yYXMgaW4gIzE4MDdcbiAgICAgICAgZmluZFByZXZGcmFnKGN1cnJlbnRQcmV2LCBzdGFydCwgdGhpcy5pZCkgIT09IHRhcmdldFByZXYpKSB7XG4gICAgICAgICAgdGhpcy5tb3ZlKGZyYWcsIHByZXZFbCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG5ldyBpbnN0YW5jZSwgb3Igc3RpbGwgaW4gc3RhZ2dlci5cbiAgICAgICAgLy8gaW5zZXJ0IHdpdGggdXBkYXRlZCBzdGFnZ2VyIGluZGV4LlxuICAgICAgICB0aGlzLmluc2VydChmcmFnLCBpbnNlcnRpb25JbmRleCsrLCBwcmV2RWwsIGluRG9jdW1lbnQpO1xuICAgICAgfVxuICAgICAgZnJhZy5yZXVzZWQgPSBmcmFnLmZyZXNoID0gZmFsc2U7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgZnJhZ21lbnQgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICogQHBhcmFtIHtTdHJpbmd9IGFsaWFzXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRleFxuICAgKiBAcGFyYW0ge1N0cmluZ30gW2tleV1cbiAgICogQHJldHVybiB7RnJhZ21lbnR9XG4gICAqL1xuXG4gIGNyZWF0ZTogZnVuY3Rpb24gY3JlYXRlKHZhbHVlLCBhbGlhcywgaW5kZXgsIGtleSkge1xuICAgIHZhciBob3N0ID0gdGhpcy5faG9zdDtcbiAgICAvLyBjcmVhdGUgaXRlcmF0aW9uIHNjb3BlXG4gICAgdmFyIHBhcmVudFNjb3BlID0gdGhpcy5fc2NvcGUgfHwgdGhpcy52bTtcbiAgICB2YXIgc2NvcGUgPSBPYmplY3QuY3JlYXRlKHBhcmVudFNjb3BlKTtcbiAgICAvLyByZWYgaG9sZGVyIGZvciB0aGUgc2NvcGVcbiAgICBzY29wZS4kcmVmcyA9IE9iamVjdC5jcmVhdGUocGFyZW50U2NvcGUuJHJlZnMpO1xuICAgIHNjb3BlLiRlbHMgPSBPYmplY3QuY3JlYXRlKHBhcmVudFNjb3BlLiRlbHMpO1xuICAgIC8vIG1ha2Ugc3VyZSBwb2ludCAkcGFyZW50IHRvIHBhcmVudCBzY29wZVxuICAgIHNjb3BlLiRwYXJlbnQgPSBwYXJlbnRTY29wZTtcbiAgICAvLyBmb3IgdHdvLXdheSBiaW5kaW5nIG9uIGFsaWFzXG4gICAgc2NvcGUuJGZvckNvbnRleHQgPSB0aGlzO1xuICAgIC8vIGRlZmluZSBzY29wZSBwcm9wZXJ0aWVzXG4gICAgZGVmaW5lUmVhY3RpdmUoc2NvcGUsIGFsaWFzLCB2YWx1ZSk7XG4gICAgZGVmaW5lUmVhY3RpdmUoc2NvcGUsICckaW5kZXgnLCBpbmRleCk7XG4gICAgaWYgKGtleSkge1xuICAgICAgZGVmaW5lUmVhY3RpdmUoc2NvcGUsICcka2V5Jywga2V5KTtcbiAgICB9IGVsc2UgaWYgKHNjb3BlLiRrZXkpIHtcbiAgICAgIC8vIGF2b2lkIGFjY2lkZW50YWwgZmFsbGJhY2tcbiAgICAgIGRlZihzY29wZSwgJyRrZXknLCBudWxsKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuaXRlcmF0b3IpIHtcbiAgICAgIGRlZmluZVJlYWN0aXZlKHNjb3BlLCB0aGlzLml0ZXJhdG9yLCBrZXkgIT09IG51bGwgPyBrZXkgOiBpbmRleCk7XG4gICAgfVxuICAgIHZhciBmcmFnID0gdGhpcy5mYWN0b3J5LmNyZWF0ZShob3N0LCBzY29wZSwgdGhpcy5fZnJhZyk7XG4gICAgZnJhZy5mb3JJZCA9IHRoaXMuaWQ7XG4gICAgdGhpcy5jYWNoZUZyYWcodmFsdWUsIGZyYWcsIGluZGV4LCBrZXkpO1xuICAgIHJldHVybiBmcmFnO1xuICB9LFxuXG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIHYtcmVmIG9uIG93bmVyIHZtLlxuICAgKi9cblxuICB1cGRhdGVSZWY6IGZ1bmN0aW9uIHVwZGF0ZVJlZigpIHtcbiAgICB2YXIgcmVmID0gdGhpcy5kZXNjcmlwdG9yLnJlZjtcbiAgICBpZiAoIXJlZikgcmV0dXJuO1xuICAgIHZhciBoYXNoID0gKHRoaXMuX3Njb3BlIHx8IHRoaXMudm0pLiRyZWZzO1xuICAgIHZhciByZWZzO1xuICAgIGlmICghdGhpcy5mcm9tT2JqZWN0KSB7XG4gICAgICByZWZzID0gdGhpcy5mcmFncy5tYXAoZmluZFZtRnJvbUZyYWcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZWZzID0ge307XG4gICAgICB0aGlzLmZyYWdzLmZvckVhY2goZnVuY3Rpb24gKGZyYWcpIHtcbiAgICAgICAgcmVmc1tmcmFnLnNjb3BlLiRrZXldID0gZmluZFZtRnJvbUZyYWcoZnJhZyk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgaGFzaFtyZWZdID0gcmVmcztcbiAgfSxcblxuICAvKipcbiAgICogRm9yIG9wdGlvbiBsaXN0cywgdXBkYXRlIHRoZSBjb250YWluaW5nIHYtbW9kZWwgb25cbiAgICogcGFyZW50IDxzZWxlY3Q+LlxuICAgKi9cblxuICB1cGRhdGVNb2RlbDogZnVuY3Rpb24gdXBkYXRlTW9kZWwoKSB7XG4gICAgaWYgKHRoaXMuaXNPcHRpb24pIHtcbiAgICAgIHZhciBwYXJlbnQgPSB0aGlzLnN0YXJ0LnBhcmVudE5vZGU7XG4gICAgICB2YXIgbW9kZWwgPSBwYXJlbnQgJiYgcGFyZW50Ll9fdl9tb2RlbDtcbiAgICAgIGlmIChtb2RlbCkge1xuICAgICAgICBtb2RlbC5mb3JjZVVwZGF0ZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogSW5zZXJ0IGEgZnJhZ21lbnQuIEhhbmRsZXMgc3RhZ2dlcmluZy5cbiAgICpcbiAgICogQHBhcmFtIHtGcmFnbWVudH0gZnJhZ1xuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogQHBhcmFtIHtOb2RlfSBwcmV2RWxcbiAgICogQHBhcmFtIHtCb29sZWFufSBpbkRvY3VtZW50XG4gICAqL1xuXG4gIGluc2VydDogZnVuY3Rpb24gaW5zZXJ0KGZyYWcsIGluZGV4LCBwcmV2RWwsIGluRG9jdW1lbnQpIHtcbiAgICBpZiAoZnJhZy5zdGFnZ2VyQ2IpIHtcbiAgICAgIGZyYWcuc3RhZ2dlckNiLmNhbmNlbCgpO1xuICAgICAgZnJhZy5zdGFnZ2VyQ2IgPSBudWxsO1xuICAgIH1cbiAgICB2YXIgc3RhZ2dlckFtb3VudCA9IHRoaXMuZ2V0U3RhZ2dlcihmcmFnLCBpbmRleCwgbnVsbCwgJ2VudGVyJyk7XG4gICAgaWYgKGluRG9jdW1lbnQgJiYgc3RhZ2dlckFtb3VudCkge1xuICAgICAgLy8gY3JlYXRlIGFuIGFuY2hvciBhbmQgaW5zZXJ0IGl0IHN5bmNocm9ub3VzbHksXG4gICAgICAvLyBzbyB0aGF0IHdlIGNhbiByZXNvbHZlIHRoZSBjb3JyZWN0IG9yZGVyIHdpdGhvdXRcbiAgICAgIC8vIHdvcnJ5aW5nIGFib3V0IHNvbWUgZWxlbWVudHMgbm90IGluc2VydGVkIHlldFxuICAgICAgdmFyIGFuY2hvciA9IGZyYWcuc3RhZ2dlckFuY2hvcjtcbiAgICAgIGlmICghYW5jaG9yKSB7XG4gICAgICAgIGFuY2hvciA9IGZyYWcuc3RhZ2dlckFuY2hvciA9IGNyZWF0ZUFuY2hvcignc3RhZ2dlci1hbmNob3InKTtcbiAgICAgICAgYW5jaG9yLl9fdl9mcmFnID0gZnJhZztcbiAgICAgIH1cbiAgICAgIGFmdGVyKGFuY2hvciwgcHJldkVsKTtcbiAgICAgIHZhciBvcCA9IGZyYWcuc3RhZ2dlckNiID0gY2FuY2VsbGFibGUoZnVuY3Rpb24gKCkge1xuICAgICAgICBmcmFnLnN0YWdnZXJDYiA9IG51bGw7XG4gICAgICAgIGZyYWcuYmVmb3JlKGFuY2hvcik7XG4gICAgICAgIHJlbW92ZShhbmNob3IpO1xuICAgICAgfSk7XG4gICAgICBzZXRUaW1lb3V0KG9wLCBzdGFnZ2VyQW1vdW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZnJhZy5iZWZvcmUocHJldkVsLm5leHRTaWJsaW5nKTtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhIGZyYWdtZW50LiBIYW5kbGVzIHN0YWdnZXJpbmcuXG4gICAqXG4gICAqIEBwYXJhbSB7RnJhZ21lbnR9IGZyYWdcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4XG4gICAqIEBwYXJhbSB7TnVtYmVyfSB0b3RhbFxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGluRG9jdW1lbnRcbiAgICovXG5cbiAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUoZnJhZywgaW5kZXgsIHRvdGFsLCBpbkRvY3VtZW50KSB7XG4gICAgaWYgKGZyYWcuc3RhZ2dlckNiKSB7XG4gICAgICBmcmFnLnN0YWdnZXJDYi5jYW5jZWwoKTtcbiAgICAgIGZyYWcuc3RhZ2dlckNiID0gbnVsbDtcbiAgICAgIC8vIGl0J3Mgbm90IHBvc3NpYmxlIGZvciB0aGUgc2FtZSBmcmFnIHRvIGJlIHJlbW92ZWRcbiAgICAgIC8vIHR3aWNlLCBzbyBpZiB3ZSBoYXZlIGEgcGVuZGluZyBzdGFnZ2VyIGNhbGxiYWNrLFxuICAgICAgLy8gaXQgbWVhbnMgdGhpcyBmcmFnIGlzIHF1ZXVlZCBmb3IgZW50ZXIgYnV0IHJlbW92ZWRcbiAgICAgIC8vIGJlZm9yZSBpdHMgdHJhbnNpdGlvbiBzdGFydGVkLiBTaW5jZSBpdCBpcyBhbHJlYWR5XG4gICAgICAvLyBkZXN0cm95ZWQsIHdlIGNhbiBqdXN0IGxlYXZlIGl0IGluIGRldGFjaGVkIHN0YXRlLlxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgc3RhZ2dlckFtb3VudCA9IHRoaXMuZ2V0U3RhZ2dlcihmcmFnLCBpbmRleCwgdG90YWwsICdsZWF2ZScpO1xuICAgIGlmIChpbkRvY3VtZW50ICYmIHN0YWdnZXJBbW91bnQpIHtcbiAgICAgIHZhciBvcCA9IGZyYWcuc3RhZ2dlckNiID0gY2FuY2VsbGFibGUoZnVuY3Rpb24gKCkge1xuICAgICAgICBmcmFnLnN0YWdnZXJDYiA9IG51bGw7XG4gICAgICAgIGZyYWcucmVtb3ZlKCk7XG4gICAgICB9KTtcbiAgICAgIHNldFRpbWVvdXQob3AsIHN0YWdnZXJBbW91bnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmcmFnLnJlbW92ZSgpO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogTW92ZSBhIGZyYWdtZW50IHRvIGEgbmV3IHBvc2l0aW9uLlxuICAgKiBGb3JjZSBubyB0cmFuc2l0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge0ZyYWdtZW50fSBmcmFnXG4gICAqIEBwYXJhbSB7Tm9kZX0gcHJldkVsXG4gICAqL1xuXG4gIG1vdmU6IGZ1bmN0aW9uIG1vdmUoZnJhZywgcHJldkVsKSB7XG4gICAgLy8gZml4IGEgY29tbW9uIGlzc3VlIHdpdGggU29ydGFibGU6XG4gICAgLy8gaWYgcHJldkVsIGRvZXNuJ3QgaGF2ZSBuZXh0U2libGluZywgdGhpcyBtZWFucyBpdCdzXG4gICAgLy8gYmVlbiBkcmFnZ2VkIGFmdGVyIHRoZSBlbmQgYW5jaG9yLiBKdXN0IHJlLXBvc2l0aW9uXG4gICAgLy8gdGhlIGVuZCBhbmNob3IgdG8gdGhlIGVuZCBvZiB0aGUgY29udGFpbmVyLlxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICghcHJldkVsLm5leHRTaWJsaW5nKSB7XG4gICAgICB0aGlzLmVuZC5wYXJlbnROb2RlLmFwcGVuZENoaWxkKHRoaXMuZW5kKTtcbiAgICB9XG4gICAgZnJhZy5iZWZvcmUocHJldkVsLm5leHRTaWJsaW5nLCBmYWxzZSk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENhY2hlIGEgZnJhZ21lbnQgdXNpbmcgdHJhY2stYnkgb3IgdGhlIG9iamVjdCBrZXkuXG4gICAqXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAgICogQHBhcmFtIHtGcmFnbWVudH0gZnJhZ1xuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogQHBhcmFtIHtTdHJpbmd9IFtrZXldXG4gICAqL1xuXG4gIGNhY2hlRnJhZzogZnVuY3Rpb24gY2FjaGVGcmFnKHZhbHVlLCBmcmFnLCBpbmRleCwga2V5KSB7XG4gICAgdmFyIHRyYWNrQnlLZXkgPSB0aGlzLnBhcmFtcy50cmFja0J5O1xuICAgIHZhciBjYWNoZSA9IHRoaXMuY2FjaGU7XG4gICAgdmFyIHByaW1pdGl2ZSA9ICFpc09iamVjdCh2YWx1ZSk7XG4gICAgdmFyIGlkO1xuICAgIGlmIChrZXkgfHwgdHJhY2tCeUtleSB8fCBwcmltaXRpdmUpIHtcbiAgICAgIGlkID0gdHJhY2tCeUtleSA/IHRyYWNrQnlLZXkgPT09ICckaW5kZXgnID8gaW5kZXggOiB2YWx1ZVt0cmFja0J5S2V5XSA6IGtleSB8fCB2YWx1ZTtcbiAgICAgIGlmICghY2FjaGVbaWRdKSB7XG4gICAgICAgIGNhY2hlW2lkXSA9IGZyYWc7XG4gICAgICB9IGVsc2UgaWYgKHRyYWNrQnlLZXkgIT09ICckaW5kZXgnKSB7XG4gICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgdGhpcy53YXJuRHVwbGljYXRlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWQgPSB0aGlzLmlkO1xuICAgICAgaWYgKGhhc093bih2YWx1ZSwgaWQpKSB7XG4gICAgICAgIGlmICh2YWx1ZVtpZF0gPT09IG51bGwpIHtcbiAgICAgICAgICB2YWx1ZVtpZF0gPSBmcmFnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgdGhpcy53YXJuRHVwbGljYXRlKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVmKHZhbHVlLCBpZCwgZnJhZyk7XG4gICAgICB9XG4gICAgfVxuICAgIGZyYWcucmF3ID0gdmFsdWU7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEdldCBhIGNhY2hlZCBmcmFnbWVudCBmcm9tIHRoZSB2YWx1ZS9pbmRleC9rZXlcbiAgICpcbiAgICogQHBhcmFtIHsqfSB2YWx1ZVxuICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXhcbiAgICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICAgKiBAcmV0dXJuIHtGcmFnbWVudH1cbiAgICovXG5cbiAgZ2V0Q2FjaGVkRnJhZzogZnVuY3Rpb24gZ2V0Q2FjaGVkRnJhZyh2YWx1ZSwgaW5kZXgsIGtleSkge1xuICAgIHZhciB0cmFja0J5S2V5ID0gdGhpcy5wYXJhbXMudHJhY2tCeTtcbiAgICB2YXIgcHJpbWl0aXZlID0gIWlzT2JqZWN0KHZhbHVlKTtcbiAgICB2YXIgZnJhZztcbiAgICBpZiAoa2V5IHx8IHRyYWNrQnlLZXkgfHwgcHJpbWl0aXZlKSB7XG4gICAgICB2YXIgaWQgPSB0cmFja0J5S2V5ID8gdHJhY2tCeUtleSA9PT0gJyRpbmRleCcgPyBpbmRleCA6IHZhbHVlW3RyYWNrQnlLZXldIDoga2V5IHx8IHZhbHVlO1xuICAgICAgZnJhZyA9IHRoaXMuY2FjaGVbaWRdO1xuICAgIH0gZWxzZSB7XG4gICAgICBmcmFnID0gdmFsdWVbdGhpcy5pZF07XG4gICAgfVxuICAgIGlmIChmcmFnICYmIChmcmFnLnJldXNlZCB8fCBmcmFnLmZyZXNoKSkge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB0aGlzLndhcm5EdXBsaWNhdGUodmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gZnJhZztcbiAgfSxcblxuICAvKipcbiAgICogRGVsZXRlIGEgZnJhZ21lbnQgZnJvbSBjYWNoZS5cbiAgICpcbiAgICogQHBhcmFtIHtGcmFnbWVudH0gZnJhZ1xuICAgKi9cblxuICBkZWxldGVDYWNoZWRGcmFnOiBmdW5jdGlvbiBkZWxldGVDYWNoZWRGcmFnKGZyYWcpIHtcbiAgICB2YXIgdmFsdWUgPSBmcmFnLnJhdztcbiAgICB2YXIgdHJhY2tCeUtleSA9IHRoaXMucGFyYW1zLnRyYWNrQnk7XG4gICAgdmFyIHNjb3BlID0gZnJhZy5zY29wZTtcbiAgICB2YXIgaW5kZXggPSBzY29wZS4kaW5kZXg7XG4gICAgLy8gZml4ICM5NDg6IGF2b2lkIGFjY2lkZW50YWxseSBmYWxsIHRocm91Z2ggdG9cbiAgICAvLyBhIHBhcmVudCByZXBlYXRlciB3aGljaCBoYXBwZW5zIHRvIGhhdmUgJGtleS5cbiAgICB2YXIga2V5ID0gaGFzT3duKHNjb3BlLCAnJGtleScpICYmIHNjb3BlLiRrZXk7XG4gICAgdmFyIHByaW1pdGl2ZSA9ICFpc09iamVjdCh2YWx1ZSk7XG4gICAgaWYgKHRyYWNrQnlLZXkgfHwga2V5IHx8IHByaW1pdGl2ZSkge1xuICAgICAgdmFyIGlkID0gdHJhY2tCeUtleSA/IHRyYWNrQnlLZXkgPT09ICckaW5kZXgnID8gaW5kZXggOiB2YWx1ZVt0cmFja0J5S2V5XSA6IGtleSB8fCB2YWx1ZTtcbiAgICAgIHRoaXMuY2FjaGVbaWRdID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWVbdGhpcy5pZF0gPSBudWxsO1xuICAgICAgZnJhZy5yYXcgPSBudWxsO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogR2V0IHRoZSBzdGFnZ2VyIGFtb3VudCBmb3IgYW4gaW5zZXJ0aW9uL3JlbW92YWwuXG4gICAqXG4gICAqIEBwYXJhbSB7RnJhZ21lbnR9IGZyYWdcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGluZGV4XG4gICAqIEBwYXJhbSB7TnVtYmVyfSB0b3RhbFxuICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICAgKi9cblxuICBnZXRTdGFnZ2VyOiBmdW5jdGlvbiBnZXRTdGFnZ2VyKGZyYWcsIGluZGV4LCB0b3RhbCwgdHlwZSkge1xuICAgIHR5cGUgPSB0eXBlICsgJ1N0YWdnZXInO1xuICAgIHZhciB0cmFucyA9IGZyYWcubm9kZS5fX3ZfdHJhbnM7XG4gICAgdmFyIGhvb2tzID0gdHJhbnMgJiYgdHJhbnMuaG9va3M7XG4gICAgdmFyIGhvb2sgPSBob29rcyAmJiAoaG9va3NbdHlwZV0gfHwgaG9va3Muc3RhZ2dlcik7XG4gICAgcmV0dXJuIGhvb2sgPyBob29rLmNhbGwoZnJhZywgaW5kZXgsIHRvdGFsKSA6IGluZGV4ICogcGFyc2VJbnQodGhpcy5wYXJhbXNbdHlwZV0gfHwgdGhpcy5wYXJhbXMuc3RhZ2dlciwgMTApO1xuICB9LFxuXG4gIC8qKlxuICAgKiBQcmUtcHJvY2VzcyB0aGUgdmFsdWUgYmVmb3JlIHBpcGluZyBpdCB0aHJvdWdoIHRoZVxuICAgKiBmaWx0ZXJzLiBUaGlzIGlzIHBhc3NlZCB0byBhbmQgY2FsbGVkIGJ5IHRoZSB3YXRjaGVyLlxuICAgKi9cblxuICBfcHJlUHJvY2VzczogZnVuY3Rpb24gX3ByZVByb2Nlc3ModmFsdWUpIHtcbiAgICAvLyByZWdhcmRsZXNzIG9mIHR5cGUsIHN0b3JlIHRoZSB1bi1maWx0ZXJlZCByYXcgdmFsdWUuXG4gICAgdGhpcy5yYXdWYWx1ZSA9IHZhbHVlO1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfSxcblxuICAvKipcbiAgICogUG9zdC1wcm9jZXNzIHRoZSB2YWx1ZSBhZnRlciBpdCBoYXMgYmVlbiBwaXBlZCB0aHJvdWdoXG4gICAqIHRoZSBmaWx0ZXJzLiBUaGlzIGlzIHBhc3NlZCB0byBhbmQgY2FsbGVkIGJ5IHRoZSB3YXRjaGVyLlxuICAgKlxuICAgKiBJdCBpcyBuZWNlc3NhcnkgZm9yIHRoaXMgdG8gYmUgY2FsbGVkIGR1cmluZyB0aGVcbiAgICogd2F0aGNlcidzIGRlcGVuZGVuY3kgY29sbGVjdGlvbiBwaGFzZSBiZWNhdXNlIHdlIHdhbnRcbiAgICogdGhlIHYtZm9yIHRvIHVwZGF0ZSB3aGVuIHRoZSBzb3VyY2UgT2JqZWN0IGlzIG11dGF0ZWQuXG4gICAqL1xuXG4gIF9wb3N0UHJvY2VzczogZnVuY3Rpb24gX3Bvc3RQcm9jZXNzKHZhbHVlKSB7XG4gICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHZhbHVlKSkge1xuICAgICAgLy8gY29udmVydCBwbGFpbiBvYmplY3QgdG8gYXJyYXkuXG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKTtcbiAgICAgIHZhciBpID0ga2V5cy5sZW5ndGg7XG4gICAgICB2YXIgcmVzID0gbmV3IEFycmF5KGkpO1xuICAgICAgdmFyIGtleTtcbiAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgcmVzW2ldID0ge1xuICAgICAgICAgICRrZXk6IGtleSxcbiAgICAgICAgICAkdmFsdWU6IHZhbHVlW2tleV1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInICYmICFpc05hTih2YWx1ZSkpIHtcbiAgICAgICAgdmFsdWUgPSByYW5nZSh2YWx1ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsdWUgfHwgW107XG4gICAgfVxuICB9LFxuXG4gIHVuYmluZDogZnVuY3Rpb24gdW5iaW5kKCkge1xuICAgIGlmICh0aGlzLmRlc2NyaXB0b3IucmVmKSB7XG4gICAgICAodGhpcy5fc2NvcGUgfHwgdGhpcy52bSkuJHJlZnNbdGhpcy5kZXNjcmlwdG9yLnJlZl0gPSBudWxsO1xuICAgIH1cbiAgICBpZiAodGhpcy5mcmFncykge1xuICAgICAgdmFyIGkgPSB0aGlzLmZyYWdzLmxlbmd0aDtcbiAgICAgIHZhciBmcmFnO1xuICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICBmcmFnID0gdGhpcy5mcmFnc1tpXTtcbiAgICAgICAgdGhpcy5kZWxldGVDYWNoZWRGcmFnKGZyYWcpO1xuICAgICAgICBmcmFnLmRlc3Ryb3koKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogSGVscGVyIHRvIGZpbmQgdGhlIHByZXZpb3VzIGVsZW1lbnQgdGhhdCBpcyBhIGZyYWdtZW50XG4gKiBhbmNob3IuIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgYSBkZXN0cm95ZWQgZnJhZydzXG4gKiBlbGVtZW50IGNvdWxkIHN0aWxsIGJlIGxpbmdlcmluZyBpbiB0aGUgRE9NIGJlZm9yZSBpdHNcbiAqIGxlYXZpbmcgdHJhbnNpdGlvbiBmaW5pc2hlcywgYnV0IGl0cyBpbnNlcnRlZCBmbGFnXG4gKiBzaG91bGQgaGF2ZSBiZWVuIHNldCB0byBmYWxzZSBzbyB3ZSBjYW4gc2tpcCB0aGVtLlxuICpcbiAqIElmIHRoaXMgaXMgYSBibG9jayByZXBlYXQsIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHdlIG9ubHlcbiAqIHJldHVybiBmcmFnIHRoYXQgaXMgYm91bmQgdG8gdGhpcyB2LWZvci4gKHNlZSAjOTI5KVxuICpcbiAqIEBwYXJhbSB7RnJhZ21lbnR9IGZyYWdcbiAqIEBwYXJhbSB7Q29tbWVudHxUZXh0fSBhbmNob3JcbiAqIEBwYXJhbSB7U3RyaW5nfSBpZFxuICogQHJldHVybiB7RnJhZ21lbnR9XG4gKi9cblxuZnVuY3Rpb24gZmluZFByZXZGcmFnKGZyYWcsIGFuY2hvciwgaWQpIHtcbiAgdmFyIGVsID0gZnJhZy5ub2RlLnByZXZpb3VzU2libGluZztcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmICghZWwpIHJldHVybjtcbiAgZnJhZyA9IGVsLl9fdl9mcmFnO1xuICB3aGlsZSAoKCFmcmFnIHx8IGZyYWcuZm9ySWQgIT09IGlkIHx8ICFmcmFnLmluc2VydGVkKSAmJiBlbCAhPT0gYW5jaG9yKSB7XG4gICAgZWwgPSBlbC5wcmV2aW91c1NpYmxpbmc7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKCFlbCkgcmV0dXJuO1xuICAgIGZyYWcgPSBlbC5fX3ZfZnJhZztcbiAgfVxuICByZXR1cm4gZnJhZztcbn1cblxuLyoqXG4gKiBGaW5kIGEgdm0gZnJvbSBhIGZyYWdtZW50LlxuICpcbiAqIEBwYXJhbSB7RnJhZ21lbnR9IGZyYWdcbiAqIEByZXR1cm4ge1Z1ZXx1bmRlZmluZWR9XG4gKi9cblxuZnVuY3Rpb24gZmluZFZtRnJvbUZyYWcoZnJhZykge1xuICB2YXIgbm9kZSA9IGZyYWcubm9kZTtcbiAgLy8gaGFuZGxlIG11bHRpLW5vZGUgZnJhZ1xuICBpZiAoZnJhZy5lbmQpIHtcbiAgICB3aGlsZSAoIW5vZGUuX192dWVfXyAmJiBub2RlICE9PSBmcmFnLmVuZCAmJiBub2RlLm5leHRTaWJsaW5nKSB7XG4gICAgICBub2RlID0gbm9kZS5uZXh0U2libGluZztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5vZGUuX192dWVfXztcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSByYW5nZSBhcnJheSBmcm9tIGdpdmVuIG51bWJlci5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gblxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cblxuZnVuY3Rpb24gcmFuZ2Uobikge1xuICB2YXIgaSA9IC0xO1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KE1hdGguZmxvb3IobikpO1xuICB3aGlsZSAoKytpIDwgbikge1xuICAgIHJldFtpXSA9IGk7XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgdkZvci53YXJuRHVwbGljYXRlID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgd2FybignRHVwbGljYXRlIHZhbHVlIGZvdW5kIGluIHYtZm9yPVwiJyArIHRoaXMuZGVzY3JpcHRvci5yYXcgKyAnXCI6ICcgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkgKyAnLiBVc2UgdHJhY2stYnk9XCIkaW5kZXhcIiBpZiAnICsgJ3lvdSBhcmUgZXhwZWN0aW5nIGR1cGxpY2F0ZSB2YWx1ZXMuJyk7XG4gIH07XG59XG5cbnZhciB2SWYgPSB7XG5cbiAgcHJpb3JpdHk6IElGLFxuXG4gIGJpbmQ6IGZ1bmN0aW9uIGJpbmQoKSB7XG4gICAgdmFyIGVsID0gdGhpcy5lbDtcbiAgICBpZiAoIWVsLl9fdnVlX18pIHtcbiAgICAgIC8vIGNoZWNrIGVsc2UgYmxvY2tcbiAgICAgIHZhciBuZXh0ID0gZWwubmV4dEVsZW1lbnRTaWJsaW5nO1xuICAgICAgaWYgKG5leHQgJiYgZ2V0QXR0cihuZXh0LCAndi1lbHNlJykgIT09IG51bGwpIHtcbiAgICAgICAgcmVtb3ZlKG5leHQpO1xuICAgICAgICB0aGlzLmVsc2VGYWN0b3J5ID0gbmV3IEZyYWdtZW50RmFjdG9yeShuZXh0Ll9jb250ZXh0IHx8IHRoaXMudm0sIG5leHQpO1xuICAgICAgfVxuICAgICAgLy8gY2hlY2sgbWFpbiBibG9ja1xuICAgICAgdGhpcy5hbmNob3IgPSBjcmVhdGVBbmNob3IoJ3YtaWYnKTtcbiAgICAgIHJlcGxhY2UoZWwsIHRoaXMuYW5jaG9yKTtcbiAgICAgIHRoaXMuZmFjdG9yeSA9IG5ldyBGcmFnbWVudEZhY3RvcnkodGhpcy52bSwgZWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oJ3YtaWY9XCInICsgdGhpcy5leHByZXNzaW9uICsgJ1wiIGNhbm5vdCBiZSAnICsgJ3VzZWQgb24gYW4gaW5zdGFuY2Ugcm9vdCBlbGVtZW50LicpO1xuICAgICAgdGhpcy5pbnZhbGlkID0gdHJ1ZTtcbiAgICB9XG4gIH0sXG5cbiAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUodmFsdWUpIHtcbiAgICBpZiAodGhpcy5pbnZhbGlkKSByZXR1cm47XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICBpZiAoIXRoaXMuZnJhZykge1xuICAgICAgICB0aGlzLmluc2VydCgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlbW92ZSgpO1xuICAgIH1cbiAgfSxcblxuICBpbnNlcnQ6IGZ1bmN0aW9uIGluc2VydCgpIHtcbiAgICBpZiAodGhpcy5lbHNlRnJhZykge1xuICAgICAgdGhpcy5lbHNlRnJhZy5yZW1vdmUoKTtcbiAgICAgIHRoaXMuZWxzZUZyYWcgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLmZyYWcgPSB0aGlzLmZhY3RvcnkuY3JlYXRlKHRoaXMuX2hvc3QsIHRoaXMuX3Njb3BlLCB0aGlzLl9mcmFnKTtcbiAgICB0aGlzLmZyYWcuYmVmb3JlKHRoaXMuYW5jaG9yKTtcbiAgfSxcblxuICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZSgpIHtcbiAgICBpZiAodGhpcy5mcmFnKSB7XG4gICAgICB0aGlzLmZyYWcucmVtb3ZlKCk7XG4gICAgICB0aGlzLmZyYWcgPSBudWxsO1xuICAgIH1cbiAgICBpZiAodGhpcy5lbHNlRmFjdG9yeSAmJiAhdGhpcy5lbHNlRnJhZykge1xuICAgICAgdGhpcy5lbHNlRnJhZyA9IHRoaXMuZWxzZUZhY3RvcnkuY3JlYXRlKHRoaXMuX2hvc3QsIHRoaXMuX3Njb3BlLCB0aGlzLl9mcmFnKTtcbiAgICAgIHRoaXMuZWxzZUZyYWcuYmVmb3JlKHRoaXMuYW5jaG9yKTtcbiAgICB9XG4gIH0sXG5cbiAgdW5iaW5kOiBmdW5jdGlvbiB1bmJpbmQoKSB7XG4gICAgaWYgKHRoaXMuZnJhZykge1xuICAgICAgdGhpcy5mcmFnLmRlc3Ryb3koKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZWxzZUZyYWcpIHtcbiAgICAgIHRoaXMuZWxzZUZyYWcuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxufTtcblxudmFyIHNob3cgPSB7XG5cbiAgYmluZDogZnVuY3Rpb24gYmluZCgpIHtcbiAgICAvLyBjaGVjayBlbHNlIGJsb2NrXG4gICAgdmFyIG5leHQgPSB0aGlzLmVsLm5leHRFbGVtZW50U2libGluZztcbiAgICBpZiAobmV4dCAmJiBnZXRBdHRyKG5leHQsICd2LWVsc2UnKSAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5lbHNlRWwgPSBuZXh0O1xuICAgIH1cbiAgfSxcblxuICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZSh2YWx1ZSkge1xuICAgIHRoaXMuYXBwbHkodGhpcy5lbCwgdmFsdWUpO1xuICAgIGlmICh0aGlzLmVsc2VFbCkge1xuICAgICAgdGhpcy5hcHBseSh0aGlzLmVsc2VFbCwgIXZhbHVlKTtcbiAgICB9XG4gIH0sXG5cbiAgYXBwbHk6IGZ1bmN0aW9uIGFwcGx5KGVsLCB2YWx1ZSkge1xuICAgIGlmIChpbkRvYyhlbCkpIHtcbiAgICAgIGFwcGx5VHJhbnNpdGlvbihlbCwgdmFsdWUgPyAxIDogLTEsIHRvZ2dsZSwgdGhpcy52bSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRvZ2dsZSgpO1xuICAgIH1cbiAgICBmdW5jdGlvbiB0b2dnbGUoKSB7XG4gICAgICBlbC5zdHlsZS5kaXNwbGF5ID0gdmFsdWUgPyAnJyA6ICdub25lJztcbiAgICB9XG4gIH1cbn07XG5cbnZhciB0ZXh0JDIgPSB7XG5cbiAgYmluZDogZnVuY3Rpb24gYmluZCgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGVsID0gdGhpcy5lbDtcbiAgICB2YXIgaXNSYW5nZSA9IGVsLnR5cGUgPT09ICdyYW5nZSc7XG4gICAgdmFyIGxhenkgPSB0aGlzLnBhcmFtcy5sYXp5O1xuICAgIHZhciBudW1iZXIgPSB0aGlzLnBhcmFtcy5udW1iZXI7XG4gICAgdmFyIGRlYm91bmNlID0gdGhpcy5wYXJhbXMuZGVib3VuY2U7XG5cbiAgICAvLyBoYW5kbGUgY29tcG9zaXRpb24gZXZlbnRzLlxuICAgIC8vICAgaHR0cDovL2Jsb2cuZXZhbnlvdS5tZS8yMDE0LzAxLzAzL2NvbXBvc2l0aW9uLWV2ZW50L1xuICAgIC8vIHNraXAgdGhpcyBmb3IgQW5kcm9pZCBiZWNhdXNlIGl0IGhhbmRsZXMgY29tcG9zaXRpb25cbiAgICAvLyBldmVudHMgcXVpdGUgZGlmZmVyZW50bHkuIEFuZHJvaWQgZG9lc24ndCB0cmlnZ2VyXG4gICAgLy8gY29tcG9zaXRpb24gZXZlbnRzIGZvciBsYW5ndWFnZSBpbnB1dCBtZXRob2RzIGUuZy5cbiAgICAvLyBDaGluZXNlLCBidXQgaW5zdGVhZCB0cmlnZ2VycyB0aGVtIGZvciBzcGVsbGluZ1xuICAgIC8vIHN1Z2dlc3Rpb25zLi4uIChzZWUgRGlzY3Vzc2lvbi8jMTYyKVxuICAgIHZhciBjb21wb3NpbmcgPSBmYWxzZTtcbiAgICBpZiAoIWlzQW5kcm9pZCAmJiAhaXNSYW5nZSkge1xuICAgICAgdGhpcy5vbignY29tcG9zaXRpb25zdGFydCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29tcG9zaW5nID0gdHJ1ZTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5vbignY29tcG9zaXRpb25lbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNvbXBvc2luZyA9IGZhbHNlO1xuICAgICAgICAvLyBpbiBJRTExIHRoZSBcImNvbXBvc2l0aW9uZW5kXCIgZXZlbnQgZmlyZXMgQUZURVJcbiAgICAgICAgLy8gdGhlIFwiaW5wdXRcIiBldmVudCwgc28gdGhlIGlucHV0IGhhbmRsZXIgaXMgYmxvY2tlZFxuICAgICAgICAvLyBhdCB0aGUgZW5kLi4uIGhhdmUgdG8gY2FsbCBpdCBoZXJlLlxuICAgICAgICAvL1xuICAgICAgICAvLyAjMTMyNzogaW4gbGF6eSBtb2RlIHRoaXMgaXMgdW5lY2Vzc2FyeS5cbiAgICAgICAgaWYgKCFsYXp5KSB7XG4gICAgICAgICAgc2VsZi5saXN0ZW5lcigpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBwcmV2ZW50IG1lc3Npbmcgd2l0aCB0aGUgaW5wdXQgd2hlbiB1c2VyIGlzIHR5cGluZyxcbiAgICAvLyBhbmQgZm9yY2UgdXBkYXRlIG9uIGJsdXIuXG4gICAgdGhpcy5mb2N1c2VkID0gZmFsc2U7XG4gICAgaWYgKCFpc1JhbmdlICYmICFsYXp5KSB7XG4gICAgICB0aGlzLm9uKCdmb2N1cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5mb2N1c2VkID0gdHJ1ZTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5vbignYmx1cicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5mb2N1c2VkID0gZmFsc2U7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBOb3cgYXR0YWNoIHRoZSBtYWluIGxpc3RlbmVyXG4gICAgdGhpcy5saXN0ZW5lciA9IHRoaXMucmF3TGlzdGVuZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoY29tcG9zaW5nIHx8ICFzZWxmLl9ib3VuZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgdmFsID0gbnVtYmVyIHx8IGlzUmFuZ2UgPyB0b051bWJlcihlbC52YWx1ZSkgOiBlbC52YWx1ZTtcbiAgICAgIHNlbGYuc2V0KHZhbCk7XG4gICAgICAvLyBmb3JjZSB1cGRhdGUgb24gbmV4dCB0aWNrIHRvIGF2b2lkIGxvY2sgJiBzYW1lIHZhbHVlXG4gICAgICAvLyBhbHNvIG9ubHkgdXBkYXRlIHdoZW4gdXNlciBpcyBub3QgdHlwaW5nXG4gICAgICBuZXh0VGljayhmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChzZWxmLl9ib3VuZCAmJiAhc2VsZi5mb2N1c2VkKSB7XG4gICAgICAgICAgc2VsZi51cGRhdGUoc2VsZi5fd2F0Y2hlci52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvLyBhcHBseSBkZWJvdW5jZVxuICAgIGlmIChkZWJvdW5jZSkge1xuICAgICAgdGhpcy5saXN0ZW5lciA9IF9kZWJvdW5jZSh0aGlzLmxpc3RlbmVyLCBkZWJvdW5jZSk7XG4gICAgfVxuXG4gICAgLy8gU3VwcG9ydCBqUXVlcnkgZXZlbnRzLCBzaW5jZSBqUXVlcnkudHJpZ2dlcigpIGRvZXNuJ3RcbiAgICAvLyB0cmlnZ2VyIG5hdGl2ZSBldmVudHMgaW4gc29tZSBjYXNlcyBhbmQgc29tZSBwbHVnaW5zXG4gICAgLy8gcmVseSBvbiAkLnRyaWdnZXIoKVxuICAgIC8vXG4gICAgLy8gV2Ugd2FudCB0byBtYWtlIHN1cmUgaWYgYSBsaXN0ZW5lciBpcyBhdHRhY2hlZCB1c2luZ1xuICAgIC8vIGpRdWVyeSwgaXQgaXMgYWxzbyByZW1vdmVkIHdpdGggalF1ZXJ5LCB0aGF0J3Mgd2h5XG4gICAgLy8gd2UgZG8gdGhlIGNoZWNrIGZvciBlYWNoIGRpcmVjdGl2ZSBpbnN0YW5jZSBhbmRcbiAgICAvLyBzdG9yZSB0aGF0IGNoZWNrIHJlc3VsdCBvbiBpdHNlbGYuIFRoaXMgYWxzbyBhbGxvd3NcbiAgICAvLyBlYXNpZXIgdGVzdCBjb3ZlcmFnZSBjb250cm9sIGJ5IHVuc2V0dGluZyB0aGUgZ2xvYmFsXG4gICAgLy8galF1ZXJ5IHZhcmlhYmxlIGluIHRlc3RzLlxuICAgIHRoaXMuaGFzalF1ZXJ5ID0gdHlwZW9mIGpRdWVyeSA9PT0gJ2Z1bmN0aW9uJztcbiAgICBpZiAodGhpcy5oYXNqUXVlcnkpIHtcbiAgICAgIHZhciBtZXRob2QgPSBqUXVlcnkuZm4ub24gPyAnb24nIDogJ2JpbmQnO1xuICAgICAgalF1ZXJ5KGVsKVttZXRob2RdKCdjaGFuZ2UnLCB0aGlzLnJhd0xpc3RlbmVyKTtcbiAgICAgIGlmICghbGF6eSkge1xuICAgICAgICBqUXVlcnkoZWwpW21ldGhvZF0oJ2lucHV0JywgdGhpcy5saXN0ZW5lcik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub24oJ2NoYW5nZScsIHRoaXMucmF3TGlzdGVuZXIpO1xuICAgICAgaWYgKCFsYXp5KSB7XG4gICAgICAgIHRoaXMub24oJ2lucHV0JywgdGhpcy5saXN0ZW5lcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSUU5IGRvZXNuJ3QgZmlyZSBpbnB1dCBldmVudCBvbiBiYWNrc3BhY2UvZGVsL2N1dFxuICAgIGlmICghbGF6eSAmJiBpc0lFOSkge1xuICAgICAgdGhpcy5vbignY3V0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBuZXh0VGljayhzZWxmLmxpc3RlbmVyKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5vbigna2V5dXAnLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICBpZiAoZS5rZXlDb2RlID09PSA0NiB8fCBlLmtleUNvZGUgPT09IDgpIHtcbiAgICAgICAgICBzZWxmLmxpc3RlbmVyKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIHNldCBpbml0aWFsIHZhbHVlIGlmIHByZXNlbnRcbiAgICBpZiAoZWwuaGFzQXR0cmlidXRlKCd2YWx1ZScpIHx8IGVsLnRhZ05hbWUgPT09ICdURVhUQVJFQScgJiYgZWwudmFsdWUudHJpbSgpKSB7XG4gICAgICB0aGlzLmFmdGVyQmluZCA9IHRoaXMubGlzdGVuZXI7XG4gICAgfVxuICB9LFxuXG4gIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKHZhbHVlKSB7XG4gICAgdGhpcy5lbC52YWx1ZSA9IF90b1N0cmluZyh2YWx1ZSk7XG4gIH0sXG5cbiAgdW5iaW5kOiBmdW5jdGlvbiB1bmJpbmQoKSB7XG4gICAgdmFyIGVsID0gdGhpcy5lbDtcbiAgICBpZiAodGhpcy5oYXNqUXVlcnkpIHtcbiAgICAgIHZhciBtZXRob2QgPSBqUXVlcnkuZm4ub2ZmID8gJ29mZicgOiAndW5iaW5kJztcbiAgICAgIGpRdWVyeShlbClbbWV0aG9kXSgnY2hhbmdlJywgdGhpcy5saXN0ZW5lcik7XG4gICAgICBqUXVlcnkoZWwpW21ldGhvZF0oJ2lucHV0JywgdGhpcy5saXN0ZW5lcik7XG4gICAgfVxuICB9XG59O1xuXG52YXIgcmFkaW8gPSB7XG5cbiAgYmluZDogZnVuY3Rpb24gYmluZCgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGVsID0gdGhpcy5lbDtcblxuICAgIHRoaXMuZ2V0VmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAvLyB2YWx1ZSBvdmVyd3JpdGUgdmlhIHYtYmluZDp2YWx1ZVxuICAgICAgaWYgKGVsLmhhc093blByb3BlcnR5KCdfdmFsdWUnKSkge1xuICAgICAgICByZXR1cm4gZWwuX3ZhbHVlO1xuICAgICAgfVxuICAgICAgdmFyIHZhbCA9IGVsLnZhbHVlO1xuICAgICAgaWYgKHNlbGYucGFyYW1zLm51bWJlcikge1xuICAgICAgICB2YWwgPSB0b051bWJlcih2YWwpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbDtcbiAgICB9O1xuXG4gICAgdGhpcy5saXN0ZW5lciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHNlbGYuc2V0KHNlbGYuZ2V0VmFsdWUoKSk7XG4gICAgfTtcbiAgICB0aGlzLm9uKCdjaGFuZ2UnLCB0aGlzLmxpc3RlbmVyKTtcblxuICAgIGlmIChlbC5oYXNBdHRyaWJ1dGUoJ2NoZWNrZWQnKSkge1xuICAgICAgdGhpcy5hZnRlckJpbmQgPSB0aGlzLmxpc3RlbmVyO1xuICAgIH1cbiAgfSxcblxuICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZSh2YWx1ZSkge1xuICAgIHRoaXMuZWwuY2hlY2tlZCA9IGxvb3NlRXF1YWwodmFsdWUsIHRoaXMuZ2V0VmFsdWUoKSk7XG4gIH1cbn07XG5cbnZhciBzZWxlY3QgPSB7XG5cbiAgYmluZDogZnVuY3Rpb24gYmluZCgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGVsID0gdGhpcy5lbDtcblxuICAgIC8vIG1ldGhvZCB0byBmb3JjZSB1cGRhdGUgRE9NIHVzaW5nIGxhdGVzdCB2YWx1ZS5cbiAgICB0aGlzLmZvcmNlVXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHNlbGYuX3dhdGNoZXIpIHtcbiAgICAgICAgc2VsZi51cGRhdGUoc2VsZi5fd2F0Y2hlci5nZXQoKSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIGNoZWNrIGlmIHRoaXMgaXMgYSBtdWx0aXBsZSBzZWxlY3RcbiAgICB2YXIgbXVsdGlwbGUgPSB0aGlzLm11bHRpcGxlID0gZWwuaGFzQXR0cmlidXRlKCdtdWx0aXBsZScpO1xuXG4gICAgLy8gYXR0YWNoIGxpc3RlbmVyXG4gICAgdGhpcy5saXN0ZW5lciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGdldFZhbHVlKGVsLCBtdWx0aXBsZSk7XG4gICAgICB2YWx1ZSA9IHNlbGYucGFyYW1zLm51bWJlciA/IGlzQXJyYXkodmFsdWUpID8gdmFsdWUubWFwKHRvTnVtYmVyKSA6IHRvTnVtYmVyKHZhbHVlKSA6IHZhbHVlO1xuICAgICAgc2VsZi5zZXQodmFsdWUpO1xuICAgIH07XG4gICAgdGhpcy5vbignY2hhbmdlJywgdGhpcy5saXN0ZW5lcik7XG5cbiAgICAvLyBpZiBoYXMgaW5pdGlhbCB2YWx1ZSwgc2V0IGFmdGVyQmluZFxuICAgIHZhciBpbml0VmFsdWUgPSBnZXRWYWx1ZShlbCwgbXVsdGlwbGUsIHRydWUpO1xuICAgIGlmIChtdWx0aXBsZSAmJiBpbml0VmFsdWUubGVuZ3RoIHx8ICFtdWx0aXBsZSAmJiBpbml0VmFsdWUgIT09IG51bGwpIHtcbiAgICAgIHRoaXMuYWZ0ZXJCaW5kID0gdGhpcy5saXN0ZW5lcjtcbiAgICB9XG5cbiAgICAvLyBBbGwgbWFqb3IgYnJvd3NlcnMgZXhjZXB0IEZpcmVmb3ggcmVzZXRzXG4gICAgLy8gc2VsZWN0ZWRJbmRleCB3aXRoIHZhbHVlIC0xIHRvIDAgd2hlbiB0aGUgZWxlbWVudFxuICAgIC8vIGlzIGFwcGVuZGVkIHRvIGEgbmV3IHBhcmVudCwgdGhlcmVmb3JlIHdlIGhhdmUgdG9cbiAgICAvLyBmb3JjZSBhIERPTSB1cGRhdGUgd2hlbmV2ZXIgdGhhdCBoYXBwZW5zLi4uXG4gICAgdGhpcy52bS4kb24oJ2hvb2s6YXR0YWNoZWQnLCB0aGlzLmZvcmNlVXBkYXRlKTtcbiAgfSxcblxuICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZSh2YWx1ZSkge1xuICAgIHZhciBlbCA9IHRoaXMuZWw7XG4gICAgZWwuc2VsZWN0ZWRJbmRleCA9IC0xO1xuICAgIHZhciBtdWx0aSA9IHRoaXMubXVsdGlwbGUgJiYgaXNBcnJheSh2YWx1ZSk7XG4gICAgdmFyIG9wdGlvbnMgPSBlbC5vcHRpb25zO1xuICAgIHZhciBpID0gb3B0aW9ucy5sZW5ndGg7XG4gICAgdmFyIG9wLCB2YWw7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgb3AgPSBvcHRpb25zW2ldO1xuICAgICAgdmFsID0gb3AuaGFzT3duUHJvcGVydHkoJ192YWx1ZScpID8gb3AuX3ZhbHVlIDogb3AudmFsdWU7XG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSBlcWVxZXEgKi9cbiAgICAgIG9wLnNlbGVjdGVkID0gbXVsdGkgPyBpbmRleE9mJDEodmFsdWUsIHZhbCkgPiAtMSA6IGxvb3NlRXF1YWwodmFsdWUsIHZhbCk7XG4gICAgICAvKiBlc2xpbnQtZW5hYmxlIGVxZXFlcSAqL1xuICAgIH1cbiAgfSxcblxuICB1bmJpbmQ6IGZ1bmN0aW9uIHVuYmluZCgpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIHRoaXMudm0uJG9mZignaG9vazphdHRhY2hlZCcsIHRoaXMuZm9yY2VVcGRhdGUpO1xuICB9XG59O1xuXG4vKipcbiAqIEdldCBzZWxlY3QgdmFsdWVcbiAqXG4gKiBAcGFyYW0ge1NlbGVjdEVsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG11bHRpXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGluaXRcbiAqIEByZXR1cm4ge0FycmF5fCp9XG4gKi9cblxuZnVuY3Rpb24gZ2V0VmFsdWUoZWwsIG11bHRpLCBpbml0KSB7XG4gIHZhciByZXMgPSBtdWx0aSA/IFtdIDogbnVsbDtcbiAgdmFyIG9wLCB2YWwsIHNlbGVjdGVkO1xuICBmb3IgKHZhciBpID0gMCwgbCA9IGVsLm9wdGlvbnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgb3AgPSBlbC5vcHRpb25zW2ldO1xuICAgIHNlbGVjdGVkID0gaW5pdCA/IG9wLmhhc0F0dHJpYnV0ZSgnc2VsZWN0ZWQnKSA6IG9wLnNlbGVjdGVkO1xuICAgIGlmIChzZWxlY3RlZCkge1xuICAgICAgdmFsID0gb3AuaGFzT3duUHJvcGVydHkoJ192YWx1ZScpID8gb3AuX3ZhbHVlIDogb3AudmFsdWU7XG4gICAgICBpZiAobXVsdGkpIHtcbiAgICAgICAgcmVzLnB1c2godmFsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXM7XG59XG5cbi8qKlxuICogTmF0aXZlIEFycmF5LmluZGV4T2YgdXNlcyBzdHJpY3QgZXF1YWwsIGJ1dCBpbiB0aGlzXG4gKiBjYXNlIHdlIG5lZWQgdG8gbWF0Y2ggc3RyaW5nL251bWJlcnMgd2l0aCBjdXN0b20gZXF1YWwuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gYXJyXG4gKiBAcGFyYW0geyp9IHZhbFxuICovXG5cbmZ1bmN0aW9uIGluZGV4T2YkMShhcnIsIHZhbCkge1xuICB2YXIgaSA9IGFyci5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBpZiAobG9vc2VFcXVhbChhcnJbaV0sIHZhbCkpIHtcbiAgICAgIHJldHVybiBpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbnZhciBjaGVja2JveCA9IHtcblxuICBiaW5kOiBmdW5jdGlvbiBiaW5kKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgZWwgPSB0aGlzLmVsO1xuXG4gICAgdGhpcy5nZXRWYWx1ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBlbC5oYXNPd25Qcm9wZXJ0eSgnX3ZhbHVlJykgPyBlbC5fdmFsdWUgOiBzZWxmLnBhcmFtcy5udW1iZXIgPyB0b051bWJlcihlbC52YWx1ZSkgOiBlbC52YWx1ZTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gZ2V0Qm9vbGVhblZhbHVlKCkge1xuICAgICAgdmFyIHZhbCA9IGVsLmNoZWNrZWQ7XG4gICAgICBpZiAodmFsICYmIGVsLmhhc093blByb3BlcnR5KCdfdHJ1ZVZhbHVlJykpIHtcbiAgICAgICAgcmV0dXJuIGVsLl90cnVlVmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAoIXZhbCAmJiBlbC5oYXNPd25Qcm9wZXJ0eSgnX2ZhbHNlVmFsdWUnKSkge1xuICAgICAgICByZXR1cm4gZWwuX2ZhbHNlVmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gdmFsO1xuICAgIH1cblxuICAgIHRoaXMubGlzdGVuZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgbW9kZWwgPSBzZWxmLl93YXRjaGVyLnZhbHVlO1xuICAgICAgaWYgKGlzQXJyYXkobW9kZWwpKSB7XG4gICAgICAgIHZhciB2YWwgPSBzZWxmLmdldFZhbHVlKCk7XG4gICAgICAgIGlmIChlbC5jaGVja2VkKSB7XG4gICAgICAgICAgaWYgKGluZGV4T2YobW9kZWwsIHZhbCkgPCAwKSB7XG4gICAgICAgICAgICBtb2RlbC5wdXNoKHZhbCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1vZGVsLiRyZW1vdmUodmFsKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VsZi5zZXQoZ2V0Qm9vbGVhblZhbHVlKCkpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB0aGlzLm9uKCdjaGFuZ2UnLCB0aGlzLmxpc3RlbmVyKTtcbiAgICBpZiAoZWwuaGFzQXR0cmlidXRlKCdjaGVja2VkJykpIHtcbiAgICAgIHRoaXMuYWZ0ZXJCaW5kID0gdGhpcy5saXN0ZW5lcjtcbiAgICB9XG4gIH0sXG5cbiAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUodmFsdWUpIHtcbiAgICB2YXIgZWwgPSB0aGlzLmVsO1xuICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgZWwuY2hlY2tlZCA9IGluZGV4T2YodmFsdWUsIHRoaXMuZ2V0VmFsdWUoKSkgPiAtMTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGVsLmhhc093blByb3BlcnR5KCdfdHJ1ZVZhbHVlJykpIHtcbiAgICAgICAgZWwuY2hlY2tlZCA9IGxvb3NlRXF1YWwodmFsdWUsIGVsLl90cnVlVmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWwuY2hlY2tlZCA9ICEhdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG52YXIgaGFuZGxlcnMgPSB7XG4gIHRleHQ6IHRleHQkMixcbiAgcmFkaW86IHJhZGlvLFxuICBzZWxlY3Q6IHNlbGVjdCxcbiAgY2hlY2tib3g6IGNoZWNrYm94XG59O1xuXG52YXIgbW9kZWwgPSB7XG5cbiAgcHJpb3JpdHk6IE1PREVMLFxuICB0d29XYXk6IHRydWUsXG4gIGhhbmRsZXJzOiBoYW5kbGVycyxcbiAgcGFyYW1zOiBbJ2xhenknLCAnbnVtYmVyJywgJ2RlYm91bmNlJ10sXG5cbiAgLyoqXG4gICAqIFBvc3NpYmxlIGVsZW1lbnRzOlxuICAgKiAgIDxzZWxlY3Q+XG4gICAqICAgPHRleHRhcmVhPlxuICAgKiAgIDxpbnB1dCB0eXBlPVwiKlwiPlxuICAgKiAgICAgLSB0ZXh0XG4gICAqICAgICAtIGNoZWNrYm94XG4gICAqICAgICAtIHJhZGlvXG4gICAqICAgICAtIG51bWJlclxuICAgKi9cblxuICBiaW5kOiBmdW5jdGlvbiBiaW5kKCkge1xuICAgIC8vIGZyaWVuZGx5IHdhcm5pbmcuLi5cbiAgICB0aGlzLmNoZWNrRmlsdGVycygpO1xuICAgIGlmICh0aGlzLmhhc1JlYWQgJiYgIXRoaXMuaGFzV3JpdGUpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybignSXQgc2VlbXMgeW91IGFyZSB1c2luZyBhIHJlYWQtb25seSBmaWx0ZXIgd2l0aCAnICsgJ3YtbW9kZWwuIFlvdSBtaWdodCB3YW50IHRvIHVzZSBhIHR3by13YXkgZmlsdGVyICcgKyAndG8gZW5zdXJlIGNvcnJlY3QgYmVoYXZpb3IuJyk7XG4gICAgfVxuICAgIHZhciBlbCA9IHRoaXMuZWw7XG4gICAgdmFyIHRhZyA9IGVsLnRhZ05hbWU7XG4gICAgdmFyIGhhbmRsZXI7XG4gICAgaWYgKHRhZyA9PT0gJ0lOUFVUJykge1xuICAgICAgaGFuZGxlciA9IGhhbmRsZXJzW2VsLnR5cGVdIHx8IGhhbmRsZXJzLnRleHQ7XG4gICAgfSBlbHNlIGlmICh0YWcgPT09ICdTRUxFQ1QnKSB7XG4gICAgICBoYW5kbGVyID0gaGFuZGxlcnMuc2VsZWN0O1xuICAgIH0gZWxzZSBpZiAodGFnID09PSAnVEVYVEFSRUEnKSB7XG4gICAgICBoYW5kbGVyID0gaGFuZGxlcnMudGV4dDtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKCd2LW1vZGVsIGRvZXMgbm90IHN1cHBvcnQgZWxlbWVudCB0eXBlOiAnICsgdGFnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZWwuX192X21vZGVsID0gdGhpcztcbiAgICBoYW5kbGVyLmJpbmQuY2FsbCh0aGlzKTtcbiAgICB0aGlzLnVwZGF0ZSA9IGhhbmRsZXIudXBkYXRlO1xuICAgIHRoaXMuX3VuYmluZCA9IGhhbmRsZXIudW5iaW5kO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDaGVjayByZWFkL3dyaXRlIGZpbHRlciBzdGF0cy5cbiAgICovXG5cbiAgY2hlY2tGaWx0ZXJzOiBmdW5jdGlvbiBjaGVja0ZpbHRlcnMoKSB7XG4gICAgdmFyIGZpbHRlcnMgPSB0aGlzLmZpbHRlcnM7XG4gICAgaWYgKCFmaWx0ZXJzKSByZXR1cm47XG4gICAgdmFyIGkgPSBmaWx0ZXJzLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICB2YXIgZmlsdGVyID0gcmVzb2x2ZUFzc2V0KHRoaXMudm0uJG9wdGlvbnMsICdmaWx0ZXJzJywgZmlsdGVyc1tpXS5uYW1lKTtcbiAgICAgIGlmICh0eXBlb2YgZmlsdGVyID09PSAnZnVuY3Rpb24nIHx8IGZpbHRlci5yZWFkKSB7XG4gICAgICAgIHRoaXMuaGFzUmVhZCA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAoZmlsdGVyLndyaXRlKSB7XG4gICAgICAgIHRoaXMuaGFzV3JpdGUgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICB1bmJpbmQ6IGZ1bmN0aW9uIHVuYmluZCgpIHtcbiAgICB0aGlzLmVsLl9fdl9tb2RlbCA9IG51bGw7XG4gICAgdGhpcy5fdW5iaW5kICYmIHRoaXMuX3VuYmluZCgpO1xuICB9XG59O1xuXG4vLyBrZXlDb2RlIGFsaWFzZXNcbnZhciBrZXlDb2RlcyA9IHtcbiAgZXNjOiAyNyxcbiAgdGFiOiA5LFxuICBlbnRlcjogMTMsXG4gIHNwYWNlOiAzMixcbiAgJ2RlbGV0ZSc6IFs4LCA0Nl0sXG4gIHVwOiAzOCxcbiAgbGVmdDogMzcsXG4gIHJpZ2h0OiAzOSxcbiAgZG93bjogNDBcbn07XG5cbmZ1bmN0aW9uIGtleUZpbHRlcihoYW5kbGVyLCBrZXlzKSB7XG4gIHZhciBjb2RlcyA9IGtleXMubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICB2YXIgY2hhckNvZGUgPSBrZXkuY2hhckNvZGVBdCgwKTtcbiAgICBpZiAoY2hhckNvZGUgPiA0NyAmJiBjaGFyQ29kZSA8IDU4KSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQoa2V5LCAxMCk7XG4gICAgfVxuICAgIGlmIChrZXkubGVuZ3RoID09PSAxKSB7XG4gICAgICBjaGFyQ29kZSA9IGtleS50b1VwcGVyQ2FzZSgpLmNoYXJDb2RlQXQoMCk7XG4gICAgICBpZiAoY2hhckNvZGUgPiA2NCAmJiBjaGFyQ29kZSA8IDkxKSB7XG4gICAgICAgIHJldHVybiBjaGFyQ29kZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleUNvZGVzW2tleV07XG4gIH0pO1xuICBjb2RlcyA9IFtdLmNvbmNhdC5hcHBseShbXSwgY29kZXMpO1xuICByZXR1cm4gZnVuY3Rpb24ga2V5SGFuZGxlcihlKSB7XG4gICAgaWYgKGNvZGVzLmluZGV4T2YoZS5rZXlDb2RlKSA+IC0xKSB7XG4gICAgICByZXR1cm4gaGFuZGxlci5jYWxsKHRoaXMsIGUpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gc3RvcEZpbHRlcihoYW5kbGVyKSB7XG4gIHJldHVybiBmdW5jdGlvbiBzdG9wSGFuZGxlcihlKSB7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICByZXR1cm4gaGFuZGxlci5jYWxsKHRoaXMsIGUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBwcmV2ZW50RmlsdGVyKGhhbmRsZXIpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHByZXZlbnRIYW5kbGVyKGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgcmV0dXJuIGhhbmRsZXIuY2FsbCh0aGlzLCBlKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc2VsZkZpbHRlcihoYW5kbGVyKSB7XG4gIHJldHVybiBmdW5jdGlvbiBzZWxmSGFuZGxlcihlKSB7XG4gICAgaWYgKGUudGFyZ2V0ID09PSBlLmN1cnJlbnRUYXJnZXQpIHtcbiAgICAgIHJldHVybiBoYW5kbGVyLmNhbGwodGhpcywgZSk7XG4gICAgfVxuICB9O1xufVxuXG52YXIgb24kMSA9IHtcblxuICBwcmlvcml0eTogT04sXG4gIGFjY2VwdFN0YXRlbWVudDogdHJ1ZSxcbiAga2V5Q29kZXM6IGtleUNvZGVzLFxuXG4gIGJpbmQ6IGZ1bmN0aW9uIGJpbmQoKSB7XG4gICAgLy8gZGVhbCB3aXRoIGlmcmFtZXNcbiAgICBpZiAodGhpcy5lbC50YWdOYW1lID09PSAnSUZSQU1FJyAmJiB0aGlzLmFyZyAhPT0gJ2xvYWQnKSB7XG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICB0aGlzLmlmcmFtZUJpbmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG9uKHNlbGYuZWwuY29udGVudFdpbmRvdywgc2VsZi5hcmcsIHNlbGYuaGFuZGxlciwgc2VsZi5tb2RpZmllcnMuY2FwdHVyZSk7XG4gICAgICB9O1xuICAgICAgdGhpcy5vbignbG9hZCcsIHRoaXMuaWZyYW1lQmluZCk7XG4gICAgfVxuICB9LFxuXG4gIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKGhhbmRsZXIpIHtcbiAgICAvLyBzdHViIGEgbm9vcCBmb3Igdi1vbiB3aXRoIG5vIHZhbHVlLFxuICAgIC8vIGUuZy4gQG1vdXNlZG93bi5wcmV2ZW50XG4gICAgaWYgKCF0aGlzLmRlc2NyaXB0b3IucmF3KSB7XG4gICAgICBoYW5kbGVyID0gZnVuY3Rpb24gKCkge307XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBoYW5kbGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oJ3Ytb246JyArIHRoaXMuYXJnICsgJz1cIicgKyB0aGlzLmV4cHJlc3Npb24gKyAnXCIgZXhwZWN0cyBhIGZ1bmN0aW9uIHZhbHVlLCAnICsgJ2dvdCAnICsgaGFuZGxlcik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gYXBwbHkgbW9kaWZpZXJzXG4gICAgaWYgKHRoaXMubW9kaWZpZXJzLnN0b3ApIHtcbiAgICAgIGhhbmRsZXIgPSBzdG9wRmlsdGVyKGhhbmRsZXIpO1xuICAgIH1cbiAgICBpZiAodGhpcy5tb2RpZmllcnMucHJldmVudCkge1xuICAgICAgaGFuZGxlciA9IHByZXZlbnRGaWx0ZXIoaGFuZGxlcik7XG4gICAgfVxuICAgIGlmICh0aGlzLm1vZGlmaWVycy5zZWxmKSB7XG4gICAgICBoYW5kbGVyID0gc2VsZkZpbHRlcihoYW5kbGVyKTtcbiAgICB9XG4gICAgLy8ga2V5IGZpbHRlclxuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXModGhpcy5tb2RpZmllcnMpLmZpbHRlcihmdW5jdGlvbiAoa2V5KSB7XG4gICAgICByZXR1cm4ga2V5ICE9PSAnc3RvcCcgJiYga2V5ICE9PSAncHJldmVudCc7XG4gICAgfSk7XG4gICAgaWYgKGtleXMubGVuZ3RoKSB7XG4gICAgICBoYW5kbGVyID0ga2V5RmlsdGVyKGhhbmRsZXIsIGtleXMpO1xuICAgIH1cblxuICAgIHRoaXMucmVzZXQoKTtcbiAgICB0aGlzLmhhbmRsZXIgPSBoYW5kbGVyO1xuXG4gICAgaWYgKHRoaXMuaWZyYW1lQmluZCkge1xuICAgICAgdGhpcy5pZnJhbWVCaW5kKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9uKHRoaXMuZWwsIHRoaXMuYXJnLCB0aGlzLmhhbmRsZXIsIHRoaXMubW9kaWZpZXJzLmNhcHR1cmUpO1xuICAgIH1cbiAgfSxcblxuICByZXNldDogZnVuY3Rpb24gcmVzZXQoKSB7XG4gICAgdmFyIGVsID0gdGhpcy5pZnJhbWVCaW5kID8gdGhpcy5lbC5jb250ZW50V2luZG93IDogdGhpcy5lbDtcbiAgICBpZiAodGhpcy5oYW5kbGVyKSB7XG4gICAgICBvZmYoZWwsIHRoaXMuYXJnLCB0aGlzLmhhbmRsZXIpO1xuICAgIH1cbiAgfSxcblxuICB1bmJpbmQ6IGZ1bmN0aW9uIHVuYmluZCgpIHtcbiAgICB0aGlzLnJlc2V0KCk7XG4gIH1cbn07XG5cbnZhciBwcmVmaXhlcyA9IFsnLXdlYmtpdC0nLCAnLW1vei0nLCAnLW1zLSddO1xudmFyIGNhbWVsUHJlZml4ZXMgPSBbJ1dlYmtpdCcsICdNb3onLCAnbXMnXTtcbnZhciBpbXBvcnRhbnRSRSA9IC8haW1wb3J0YW50Oz8kLztcbnZhciBwcm9wQ2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG52YXIgdGVzdEVsID0gbnVsbDtcblxudmFyIHN0eWxlID0ge1xuXG4gIGRlZXA6IHRydWUsXG5cbiAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5lbC5zdHlsZS5jc3NUZXh0ID0gdmFsdWU7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgdGhpcy5oYW5kbGVPYmplY3QodmFsdWUucmVkdWNlKGV4dGVuZCwge30pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5oYW5kbGVPYmplY3QodmFsdWUgfHwge30pO1xuICAgIH1cbiAgfSxcblxuICBoYW5kbGVPYmplY3Q6IGZ1bmN0aW9uIGhhbmRsZU9iamVjdCh2YWx1ZSkge1xuICAgIC8vIGNhY2hlIG9iamVjdCBzdHlsZXMgc28gdGhhdCBvbmx5IGNoYW5nZWQgcHJvcHNcbiAgICAvLyBhcmUgYWN0dWFsbHkgdXBkYXRlZC5cbiAgICB2YXIgY2FjaGUgPSB0aGlzLmNhY2hlIHx8ICh0aGlzLmNhY2hlID0ge30pO1xuICAgIHZhciBuYW1lLCB2YWw7XG4gICAgZm9yIChuYW1lIGluIGNhY2hlKSB7XG4gICAgICBpZiAoIShuYW1lIGluIHZhbHVlKSkge1xuICAgICAgICB0aGlzLmhhbmRsZVNpbmdsZShuYW1lLCBudWxsKTtcbiAgICAgICAgZGVsZXRlIGNhY2hlW25hbWVdO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKG5hbWUgaW4gdmFsdWUpIHtcbiAgICAgIHZhbCA9IHZhbHVlW25hbWVdO1xuICAgICAgaWYgKHZhbCAhPT0gY2FjaGVbbmFtZV0pIHtcbiAgICAgICAgY2FjaGVbbmFtZV0gPSB2YWw7XG4gICAgICAgIHRoaXMuaGFuZGxlU2luZ2xlKG5hbWUsIHZhbCk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIGhhbmRsZVNpbmdsZTogZnVuY3Rpb24gaGFuZGxlU2luZ2xlKHByb3AsIHZhbHVlKSB7XG4gICAgcHJvcCA9IG5vcm1hbGl6ZShwcm9wKTtcbiAgICBpZiAoIXByb3ApIHJldHVybjsgLy8gdW5zdXBwb3J0ZWQgcHJvcFxuICAgIC8vIGNhc3QgcG9zc2libGUgbnVtYmVycy9ib29sZWFucyBpbnRvIHN0cmluZ3NcbiAgICBpZiAodmFsdWUgIT0gbnVsbCkgdmFsdWUgKz0gJyc7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB2YXIgaXNJbXBvcnRhbnQgPSBpbXBvcnRhbnRSRS50ZXN0KHZhbHVlKSA/ICdpbXBvcnRhbnQnIDogJyc7XG4gICAgICBpZiAoaXNJbXBvcnRhbnQpIHtcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKGltcG9ydGFudFJFLCAnJykudHJpbSgpO1xuICAgICAgfVxuICAgICAgdGhpcy5lbC5zdHlsZS5zZXRQcm9wZXJ0eShwcm9wLCB2YWx1ZSwgaXNJbXBvcnRhbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVsLnN0eWxlLnJlbW92ZVByb3BlcnR5KHByb3ApO1xuICAgIH1cbiAgfVxuXG59O1xuXG4vKipcbiAqIE5vcm1hbGl6ZSBhIENTUyBwcm9wZXJ0eSBuYW1lLlxuICogLSBjYWNoZSByZXN1bHRcbiAqIC0gYXV0byBwcmVmaXhcbiAqIC0gY2FtZWxDYXNlIC0+IGRhc2gtY2FzZVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cblxuZnVuY3Rpb24gbm9ybWFsaXplKHByb3ApIHtcbiAgaWYgKHByb3BDYWNoZVtwcm9wXSkge1xuICAgIHJldHVybiBwcm9wQ2FjaGVbcHJvcF07XG4gIH1cbiAgdmFyIHJlcyA9IHByZWZpeChwcm9wKTtcbiAgcHJvcENhY2hlW3Byb3BdID0gcHJvcENhY2hlW3Jlc10gPSByZXM7XG4gIHJldHVybiByZXM7XG59XG5cbi8qKlxuICogQXV0byBkZXRlY3QgdGhlIGFwcHJvcHJpYXRlIHByZWZpeCBmb3IgYSBDU1MgcHJvcGVydHkuXG4gKiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9wYXVsaXJpc2gvNTIzNjkyXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHByb3BcbiAqIEByZXR1cm4ge1N0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBwcmVmaXgocHJvcCkge1xuICBwcm9wID0gaHlwaGVuYXRlKHByb3ApO1xuICB2YXIgY2FtZWwgPSBjYW1lbGl6ZShwcm9wKTtcbiAgdmFyIHVwcGVyID0gY2FtZWwuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBjYW1lbC5zbGljZSgxKTtcbiAgaWYgKCF0ZXN0RWwpIHtcbiAgICB0ZXN0RWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgfVxuICB2YXIgaSA9IHByZWZpeGVzLmxlbmd0aDtcbiAgdmFyIHByZWZpeGVkO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgcHJlZml4ZWQgPSBjYW1lbFByZWZpeGVzW2ldICsgdXBwZXI7XG4gICAgaWYgKHByZWZpeGVkIGluIHRlc3RFbC5zdHlsZSkge1xuICAgICAgcmV0dXJuIHByZWZpeGVzW2ldICsgcHJvcDtcbiAgICB9XG4gIH1cbiAgaWYgKGNhbWVsIGluIHRlc3RFbC5zdHlsZSkge1xuICAgIHJldHVybiBwcm9wO1xuICB9XG59XG5cbi8vIHhsaW5rXG52YXIgeGxpbmtOUyA9ICdodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rJztcbnZhciB4bGlua1JFID0gL154bGluazovO1xuXG4vLyBjaGVjayBmb3IgYXR0cmlidXRlcyB0aGF0IHByb2hpYml0IGludGVycG9sYXRpb25zXG52YXIgZGlzYWxsb3dlZEludGVycEF0dHJSRSA9IC9edi18Xjp8XkB8Xig/OmlzfHRyYW5zaXRpb258dHJhbnNpdGlvbi1tb2RlfGRlYm91bmNlfHRyYWNrLWJ5fHN0YWdnZXJ8ZW50ZXItc3RhZ2dlcnxsZWF2ZS1zdGFnZ2VyKSQvO1xuLy8gdGhlc2UgYXR0cmlidXRlcyBzaG91bGQgYWxzbyBzZXQgdGhlaXIgY29ycmVzcG9uZGluZyBwcm9wZXJ0aWVzXG4vLyBiZWNhdXNlIHRoZXkgb25seSBhZmZlY3QgdGhlIGluaXRpYWwgc3RhdGUgb2YgdGhlIGVsZW1lbnRcbnZhciBhdHRyV2l0aFByb3BzUkUgPSAvXig/OnZhbHVlfGNoZWNrZWR8c2VsZWN0ZWR8bXV0ZWQpJC87XG4vLyB0aGVzZSBhdHRyaWJ1dGVzIGV4cGVjdCBlbnVtcmF0ZWQgdmFsdWVzIG9mIFwidHJ1ZVwiIG9yIFwiZmFsc2VcIlxuLy8gYnV0IGFyZSBub3QgYm9vbGVhbiBhdHRyaWJ1dGVzXG52YXIgZW51bWVyYXRlZEF0dHJSRSA9IC9eKD86ZHJhZ2dhYmxlfGNvbnRlbnRlZGl0YWJsZXxzcGVsbGNoZWNrKSQvO1xuXG4vLyB0aGVzZSBhdHRyaWJ1dGVzIHNob3VsZCBzZXQgYSBoaWRkZW4gcHJvcGVydHkgZm9yXG4vLyBiaW5kaW5nIHYtbW9kZWwgdG8gb2JqZWN0IHZhbHVlc1xudmFyIG1vZGVsUHJvcHMgPSB7XG4gIHZhbHVlOiAnX3ZhbHVlJyxcbiAgJ3RydWUtdmFsdWUnOiAnX3RydWVWYWx1ZScsXG4gICdmYWxzZS12YWx1ZSc6ICdfZmFsc2VWYWx1ZSdcbn07XG5cbnZhciBiaW5kJDEgPSB7XG5cbiAgcHJpb3JpdHk6IEJJTkQsXG5cbiAgYmluZDogZnVuY3Rpb24gYmluZCgpIHtcbiAgICB2YXIgYXR0ciA9IHRoaXMuYXJnO1xuICAgIHZhciB0YWcgPSB0aGlzLmVsLnRhZ05hbWU7XG4gICAgLy8gc2hvdWxkIGJlIGRlZXAgd2F0Y2ggb24gb2JqZWN0IG1vZGVcbiAgICBpZiAoIWF0dHIpIHtcbiAgICAgIHRoaXMuZGVlcCA9IHRydWU7XG4gICAgfVxuICAgIC8vIGhhbmRsZSBpbnRlcnBvbGF0aW9uIGJpbmRpbmdzXG4gICAgdmFyIGRlc2NyaXB0b3IgPSB0aGlzLmRlc2NyaXB0b3I7XG4gICAgdmFyIHRva2VucyA9IGRlc2NyaXB0b3IuaW50ZXJwO1xuICAgIGlmICh0b2tlbnMpIHtcbiAgICAgIC8vIGhhbmRsZSBpbnRlcnBvbGF0aW9ucyB3aXRoIG9uZS10aW1lIHRva2Vuc1xuICAgICAgaWYgKGRlc2NyaXB0b3IuaGFzT25lVGltZSkge1xuICAgICAgICB0aGlzLmV4cHJlc3Npb24gPSB0b2tlbnNUb0V4cCh0b2tlbnMsIHRoaXMuX3Njb3BlIHx8IHRoaXMudm0pO1xuICAgICAgfVxuXG4gICAgICAvLyBvbmx5IGFsbG93IGJpbmRpbmcgb24gbmF0aXZlIGF0dHJpYnV0ZXNcbiAgICAgIGlmIChkaXNhbGxvd2VkSW50ZXJwQXR0clJFLnRlc3QoYXR0cikgfHwgYXR0ciA9PT0gJ25hbWUnICYmICh0YWcgPT09ICdQQVJUSUFMJyB8fCB0YWcgPT09ICdTTE9UJykpIHtcbiAgICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKGF0dHIgKyAnPVwiJyArIGRlc2NyaXB0b3IucmF3ICsgJ1wiOiAnICsgJ2F0dHJpYnV0ZSBpbnRlcnBvbGF0aW9uIGlzIG5vdCBhbGxvd2VkIGluIFZ1ZS5qcyAnICsgJ2RpcmVjdGl2ZXMgYW5kIHNwZWNpYWwgYXR0cmlidXRlcy4nKTtcbiAgICAgICAgdGhpcy5lbC5yZW1vdmVBdHRyaWJ1dGUoYXR0cik7XG4gICAgICAgIHRoaXMuaW52YWxpZCA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgdmFyIHJhdyA9IGF0dHIgKyAnPVwiJyArIGRlc2NyaXB0b3IucmF3ICsgJ1wiOiAnO1xuICAgICAgICAvLyB3YXJuIHNyY1xuICAgICAgICBpZiAoYXR0ciA9PT0gJ3NyYycpIHtcbiAgICAgICAgICB3YXJuKHJhdyArICdpbnRlcnBvbGF0aW9uIGluIFwic3JjXCIgYXR0cmlidXRlIHdpbGwgY2F1c2UgJyArICdhIDQwNCByZXF1ZXN0LiBVc2Ugdi1iaW5kOnNyYyBpbnN0ZWFkLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gd2FybiBzdHlsZVxuICAgICAgICBpZiAoYXR0ciA9PT0gJ3N0eWxlJykge1xuICAgICAgICAgIHdhcm4ocmF3ICsgJ2ludGVycG9sYXRpb24gaW4gXCJzdHlsZVwiIGF0dHJpYnV0ZSB3aWxsIGNhdXNlICcgKyAndGhlIGF0dHJpYnV0ZSB0byBiZSBkaXNjYXJkZWQgaW4gSW50ZXJuZXQgRXhwbG9yZXIuICcgKyAnVXNlIHYtYmluZDpzdHlsZSBpbnN0ZWFkLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKHZhbHVlKSB7XG4gICAgaWYgKHRoaXMuaW52YWxpZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgYXR0ciA9IHRoaXMuYXJnO1xuICAgIGlmICh0aGlzLmFyZykge1xuICAgICAgdGhpcy5oYW5kbGVTaW5nbGUoYXR0ciwgdmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhhbmRsZU9iamVjdCh2YWx1ZSB8fCB7fSk7XG4gICAgfVxuICB9LFxuXG4gIC8vIHNoYXJlIG9iamVjdCBoYW5kbGVyIHdpdGggdi1iaW5kOmNsYXNzXG4gIGhhbmRsZU9iamVjdDogc3R5bGUuaGFuZGxlT2JqZWN0LFxuXG4gIGhhbmRsZVNpbmdsZTogZnVuY3Rpb24gaGFuZGxlU2luZ2xlKGF0dHIsIHZhbHVlKSB7XG4gICAgdmFyIGVsID0gdGhpcy5lbDtcbiAgICB2YXIgaW50ZXJwID0gdGhpcy5kZXNjcmlwdG9yLmludGVycDtcbiAgICBpZiAodGhpcy5tb2RpZmllcnMuY2FtZWwpIHtcbiAgICAgIGF0dHIgPSBjYW1lbGl6ZShhdHRyKTtcbiAgICB9XG4gICAgaWYgKCFpbnRlcnAgJiYgYXR0cldpdGhQcm9wc1JFLnRlc3QoYXR0cikgJiYgYXR0ciBpbiBlbCkge1xuICAgICAgZWxbYXR0cl0gPSBhdHRyID09PSAndmFsdWUnID8gdmFsdWUgPT0gbnVsbCAvLyBJRTkgd2lsbCBzZXQgaW5wdXQudmFsdWUgdG8gXCJudWxsXCIgZm9yIG51bGwuLi5cbiAgICAgID8gJycgOiB2YWx1ZSA6IHZhbHVlO1xuICAgIH1cbiAgICAvLyBzZXQgbW9kZWwgcHJvcHNcbiAgICB2YXIgbW9kZWxQcm9wID0gbW9kZWxQcm9wc1thdHRyXTtcbiAgICBpZiAoIWludGVycCAmJiBtb2RlbFByb3ApIHtcbiAgICAgIGVsW21vZGVsUHJvcF0gPSB2YWx1ZTtcbiAgICAgIC8vIHVwZGF0ZSB2LW1vZGVsIGlmIHByZXNlbnRcbiAgICAgIHZhciBtb2RlbCA9IGVsLl9fdl9tb2RlbDtcbiAgICAgIGlmIChtb2RlbCkge1xuICAgICAgICBtb2RlbC5saXN0ZW5lcigpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBkbyBub3Qgc2V0IHZhbHVlIGF0dHJpYnV0ZSBmb3IgdGV4dGFyZWFcbiAgICBpZiAoYXR0ciA9PT0gJ3ZhbHVlJyAmJiBlbC50YWdOYW1lID09PSAnVEVYVEFSRUEnKSB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoYXR0cik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIHVwZGF0ZSBhdHRyaWJ1dGVcbiAgICBpZiAoZW51bWVyYXRlZEF0dHJSRS50ZXN0KGF0dHIpKSB7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoYXR0ciwgdmFsdWUgPyAndHJ1ZScgOiAnZmFsc2UnKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlICE9IG51bGwgJiYgdmFsdWUgIT09IGZhbHNlKSB7XG4gICAgICBpZiAoYXR0ciA9PT0gJ2NsYXNzJykge1xuICAgICAgICAvLyBoYW5kbGUgZWRnZSBjYXNlICMxOTYwOlxuICAgICAgICAvLyBjbGFzcyBpbnRlcnBvbGF0aW9uIHNob3VsZCBub3Qgb3ZlcndyaXRlIFZ1ZSB0cmFuc2l0aW9uIGNsYXNzXG4gICAgICAgIGlmIChlbC5fX3ZfdHJhbnMpIHtcbiAgICAgICAgICB2YWx1ZSArPSAnICcgKyBlbC5fX3ZfdHJhbnMuaWQgKyAnLXRyYW5zaXRpb24nO1xuICAgICAgICB9XG4gICAgICAgIHNldENsYXNzKGVsLCB2YWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKHhsaW5rUkUudGVzdChhdHRyKSkge1xuICAgICAgICBlbC5zZXRBdHRyaWJ1dGVOUyh4bGlua05TLCBhdHRyLCB2YWx1ZSA9PT0gdHJ1ZSA/ICcnIDogdmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWwuc2V0QXR0cmlidXRlKGF0dHIsIHZhbHVlID09PSB0cnVlID8gJycgOiB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShhdHRyKTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciBlbCA9IHtcblxuICBwcmlvcml0eTogRUwsXG5cbiAgYmluZDogZnVuY3Rpb24gYmluZCgpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICBpZiAoIXRoaXMuYXJnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBpZCA9IHRoaXMuaWQgPSBjYW1lbGl6ZSh0aGlzLmFyZyk7XG4gICAgdmFyIHJlZnMgPSAodGhpcy5fc2NvcGUgfHwgdGhpcy52bSkuJGVscztcbiAgICBpZiAoaGFzT3duKHJlZnMsIGlkKSkge1xuICAgICAgcmVmc1tpZF0gPSB0aGlzLmVsO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWZpbmVSZWFjdGl2ZShyZWZzLCBpZCwgdGhpcy5lbCk7XG4gICAgfVxuICB9LFxuXG4gIHVuYmluZDogZnVuY3Rpb24gdW5iaW5kKCkge1xuICAgIHZhciByZWZzID0gKHRoaXMuX3Njb3BlIHx8IHRoaXMudm0pLiRlbHM7XG4gICAgaWYgKHJlZnNbdGhpcy5pZF0gPT09IHRoaXMuZWwpIHtcbiAgICAgIHJlZnNbdGhpcy5pZF0gPSBudWxsO1xuICAgIH1cbiAgfVxufTtcblxudmFyIHJlZiA9IHtcbiAgYmluZDogZnVuY3Rpb24gYmluZCgpIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oJ3YtcmVmOicgKyB0aGlzLmFyZyArICcgbXVzdCBiZSB1c2VkIG9uIGEgY2hpbGQgJyArICdjb21wb25lbnQuIEZvdW5kIG9uIDwnICsgdGhpcy5lbC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgKyAnPi4nKTtcbiAgfVxufTtcblxudmFyIGNsb2FrID0ge1xuICBiaW5kOiBmdW5jdGlvbiBiaW5kKCkge1xuICAgIHZhciBlbCA9IHRoaXMuZWw7XG4gICAgdGhpcy52bS4kb25jZSgncHJlLWhvb2s6Y29tcGlsZWQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoJ3YtY2xvYWsnKTtcbiAgICB9KTtcbiAgfVxufTtcblxuLy8gbXVzdCBleHBvcnQgcGxhaW4gb2JqZWN0XG52YXIgZGlyZWN0aXZlcyA9IHtcbiAgdGV4dDogdGV4dCQxLFxuICBodG1sOiBodG1sLFxuICAnZm9yJzogdkZvcixcbiAgJ2lmJzogdklmLFxuICBzaG93OiBzaG93LFxuICBtb2RlbDogbW9kZWwsXG4gIG9uOiBvbiQxLFxuICBiaW5kOiBiaW5kJDEsXG4gIGVsOiBlbCxcbiAgcmVmOiByZWYsXG4gIGNsb2FrOiBjbG9ha1xufTtcblxudmFyIHZDbGFzcyA9IHtcblxuICBkZWVwOiB0cnVlLFxuXG4gIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRoaXMuaGFuZGxlT2JqZWN0KHN0cmluZ1RvT2JqZWN0KHZhbHVlKSk7XG4gICAgfSBlbHNlIGlmIChpc1BsYWluT2JqZWN0KHZhbHVlKSkge1xuICAgICAgdGhpcy5oYW5kbGVPYmplY3QodmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHRoaXMuaGFuZGxlQXJyYXkodmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNsZWFudXAoKTtcbiAgICB9XG4gIH0sXG5cbiAgaGFuZGxlT2JqZWN0OiBmdW5jdGlvbiBoYW5kbGVPYmplY3QodmFsdWUpIHtcbiAgICB0aGlzLmNsZWFudXAodmFsdWUpO1xuICAgIHZhciBrZXlzID0gdGhpcy5wcmV2S2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGtleXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICAgIGlmICh2YWx1ZVtrZXldKSB7XG4gICAgICAgIGFkZENsYXNzKHRoaXMuZWwsIGtleSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZW1vdmVDbGFzcyh0aGlzLmVsLCBrZXkpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBoYW5kbGVBcnJheTogZnVuY3Rpb24gaGFuZGxlQXJyYXkodmFsdWUpIHtcbiAgICB0aGlzLmNsZWFudXAodmFsdWUpO1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBpZiAodmFsdWVbaV0pIHtcbiAgICAgICAgYWRkQ2xhc3ModGhpcy5lbCwgdmFsdWVbaV0pO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnByZXZLZXlzID0gdmFsdWUuc2xpY2UoKTtcbiAgfSxcblxuICBjbGVhbnVwOiBmdW5jdGlvbiBjbGVhbnVwKHZhbHVlKSB7XG4gICAgaWYgKHRoaXMucHJldktleXMpIHtcbiAgICAgIHZhciBpID0gdGhpcy5wcmV2S2V5cy5sZW5ndGg7XG4gICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgIHZhciBrZXkgPSB0aGlzLnByZXZLZXlzW2ldO1xuICAgICAgICBpZiAoa2V5ICYmICghdmFsdWUgfHwgIWNvbnRhaW5zKHZhbHVlLCBrZXkpKSkge1xuICAgICAgICAgIHJlbW92ZUNsYXNzKHRoaXMuZWwsIGtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHN0cmluZ1RvT2JqZWN0KHZhbHVlKSB7XG4gIHZhciByZXMgPSB7fTtcbiAgdmFyIGtleXMgPSB2YWx1ZS50cmltKCkuc3BsaXQoL1xccysvKTtcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIHJlc1trZXlzW2ldXSA9IHRydWU7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn1cblxuZnVuY3Rpb24gY29udGFpbnModmFsdWUsIGtleSkge1xuICByZXR1cm4gaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZS5pbmRleE9mKGtleSkgPiAtMSA6IGhhc093bih2YWx1ZSwga2V5KTtcbn1cblxudmFyIGNvbXBvbmVudCA9IHtcblxuICBwcmlvcml0eTogQ09NUE9ORU5ULFxuXG4gIHBhcmFtczogWydrZWVwLWFsaXZlJywgJ3RyYW5zaXRpb24tbW9kZScsICdpbmxpbmUtdGVtcGxhdGUnXSxcblxuICAvKipcbiAgICogU2V0dXAuIFR3byBwb3NzaWJsZSB1c2FnZXM6XG4gICAqXG4gICAqIC0gc3RhdGljOlxuICAgKiAgIDxjb21wPiBvciA8ZGl2IHYtY29tcG9uZW50PVwiY29tcFwiPlxuICAgKlxuICAgKiAtIGR5bmFtaWM6XG4gICAqICAgPGNvbXBvbmVudCA6aXM9XCJ2aWV3XCI+XG4gICAqL1xuXG4gIGJpbmQ6IGZ1bmN0aW9uIGJpbmQoKSB7XG4gICAgaWYgKCF0aGlzLmVsLl9fdnVlX18pIHtcbiAgICAgIC8vIGtlZXAtYWxpdmUgY2FjaGVcbiAgICAgIHRoaXMua2VlcEFsaXZlID0gdGhpcy5wYXJhbXMua2VlcEFsaXZlO1xuICAgICAgaWYgKHRoaXMua2VlcEFsaXZlKSB7XG4gICAgICAgIHRoaXMuY2FjaGUgPSB7fTtcbiAgICAgIH1cbiAgICAgIC8vIGNoZWNrIGlubGluZS10ZW1wbGF0ZVxuICAgICAgaWYgKHRoaXMucGFyYW1zLmlubGluZVRlbXBsYXRlKSB7XG4gICAgICAgIC8vIGV4dHJhY3QgaW5saW5lIHRlbXBsYXRlIGFzIGEgRG9jdW1lbnRGcmFnbWVudFxuICAgICAgICB0aGlzLmlubGluZVRlbXBsYXRlID0gZXh0cmFjdENvbnRlbnQodGhpcy5lbCwgdHJ1ZSk7XG4gICAgICB9XG4gICAgICAvLyBjb21wb25lbnQgcmVzb2x1dGlvbiByZWxhdGVkIHN0YXRlXG4gICAgICB0aGlzLnBlbmRpbmdDb21wb25lbnRDYiA9IHRoaXMuQ29tcG9uZW50ID0gbnVsbDtcbiAgICAgIC8vIHRyYW5zaXRpb24gcmVsYXRlZCBzdGF0ZVxuICAgICAgdGhpcy5wZW5kaW5nUmVtb3ZhbHMgPSAwO1xuICAgICAgdGhpcy5wZW5kaW5nUmVtb3ZhbENiID0gbnVsbDtcbiAgICAgIC8vIGNyZWF0ZSBhIHJlZiBhbmNob3JcbiAgICAgIHRoaXMuYW5jaG9yID0gY3JlYXRlQW5jaG9yKCd2LWNvbXBvbmVudCcpO1xuICAgICAgcmVwbGFjZSh0aGlzLmVsLCB0aGlzLmFuY2hvcik7XG4gICAgICAvLyByZW1vdmUgaXMgYXR0cmlidXRlLlxuICAgICAgLy8gdGhpcyBpcyByZW1vdmVkIGR1cmluZyBjb21waWxhdGlvbiwgYnV0IGJlY2F1c2UgY29tcGlsYXRpb24gaXNcbiAgICAgIC8vIGNhY2hlZCwgd2hlbiB0aGUgY29tcG9uZW50IGlzIHVzZWQgZWxzZXdoZXJlIHRoaXMgYXR0cmlidXRlXG4gICAgICAvLyB3aWxsIHJlbWFpbiBhdCBsaW5rIHRpbWUuXG4gICAgICB0aGlzLmVsLnJlbW92ZUF0dHJpYnV0ZSgnaXMnKTtcbiAgICAgIC8vIHJlbW92ZSByZWYsIHNhbWUgYXMgYWJvdmVcbiAgICAgIGlmICh0aGlzLmRlc2NyaXB0b3IucmVmKSB7XG4gICAgICAgIHRoaXMuZWwucmVtb3ZlQXR0cmlidXRlKCd2LXJlZjonICsgaHlwaGVuYXRlKHRoaXMuZGVzY3JpcHRvci5yZWYpKTtcbiAgICAgIH1cbiAgICAgIC8vIGlmIHN0YXRpYywgYnVpbGQgcmlnaHQgbm93LlxuICAgICAgaWYgKHRoaXMubGl0ZXJhbCkge1xuICAgICAgICB0aGlzLnNldENvbXBvbmVudCh0aGlzLmV4cHJlc3Npb24pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oJ2Nhbm5vdCBtb3VudCBjb21wb25lbnQgXCInICsgdGhpcy5leHByZXNzaW9uICsgJ1wiICcgKyAnb24gYWxyZWFkeSBtb3VudGVkIGVsZW1lbnQ6ICcgKyB0aGlzLmVsKTtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIFB1YmxpYyB1cGRhdGUsIGNhbGxlZCBieSB0aGUgd2F0Y2hlciBpbiB0aGUgZHluYW1pY1xuICAgKiBsaXRlcmFsIHNjZW5hcmlvLCBlLmcuIDxjb21wb25lbnQgOmlzPVwidmlld1wiPlxuICAgKi9cblxuICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZSh2YWx1ZSkge1xuICAgIGlmICghdGhpcy5saXRlcmFsKSB7XG4gICAgICB0aGlzLnNldENvbXBvbmVudCh2YWx1ZSk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBTd2l0Y2ggZHluYW1pYyBjb21wb25lbnRzLiBNYXkgcmVzb2x2ZSB0aGUgY29tcG9uZW50XG4gICAqIGFzeW5jaHJvbm91c2x5LCBhbmQgcGVyZm9ybSB0cmFuc2l0aW9uIGJhc2VkIG9uXG4gICAqIHNwZWNpZmllZCB0cmFuc2l0aW9uIG1vZGUuIEFjY2VwdHMgYSBmZXcgYWRkaXRpb25hbFxuICAgKiBhcmd1bWVudHMgc3BlY2lmaWNhbGx5IGZvciB2dWUtcm91dGVyLlxuICAgKlxuICAgKiBUaGUgY2FsbGJhY2sgaXMgY2FsbGVkIHdoZW4gdGhlIGZ1bGwgdHJhbnNpdGlvbiBpc1xuICAgKiBmaW5pc2hlZC5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYl1cbiAgICovXG5cbiAgc2V0Q29tcG9uZW50OiBmdW5jdGlvbiBzZXRDb21wb25lbnQodmFsdWUsIGNiKSB7XG4gICAgdGhpcy5pbnZhbGlkYXRlUGVuZGluZygpO1xuICAgIGlmICghdmFsdWUpIHtcbiAgICAgIC8vIGp1c3QgcmVtb3ZlIGN1cnJlbnRcbiAgICAgIHRoaXMudW5idWlsZCh0cnVlKTtcbiAgICAgIHRoaXMucmVtb3ZlKHRoaXMuY2hpbGRWTSwgY2IpO1xuICAgICAgdGhpcy5jaGlsZFZNID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgdGhpcy5yZXNvbHZlQ29tcG9uZW50KHZhbHVlLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYubW91bnRDb21wb25lbnQoY2IpO1xuICAgICAgfSk7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIHRoZSBjb21wb25lbnQgY29uc3RydWN0b3IgdG8gdXNlIHdoZW4gY3JlYXRpbmdcbiAgICogdGhlIGNoaWxkIHZtLlxuICAgKi9cblxuICByZXNvbHZlQ29tcG9uZW50OiBmdW5jdGlvbiByZXNvbHZlQ29tcG9uZW50KGlkLCBjYikge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB0aGlzLnBlbmRpbmdDb21wb25lbnRDYiA9IGNhbmNlbGxhYmxlKGZ1bmN0aW9uIChDb21wb25lbnQpIHtcbiAgICAgIHNlbGYuQ29tcG9uZW50TmFtZSA9IENvbXBvbmVudC5vcHRpb25zLm5hbWUgfHwgaWQ7XG4gICAgICBzZWxmLkNvbXBvbmVudCA9IENvbXBvbmVudDtcbiAgICAgIGNiKCk7XG4gICAgfSk7XG4gICAgdGhpcy52bS5fcmVzb2x2ZUNvbXBvbmVudChpZCwgdGhpcy5wZW5kaW5nQ29tcG9uZW50Q2IpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2UgdXNpbmcgdGhlIGN1cnJlbnQgY29uc3RydWN0b3IgYW5kXG4gICAqIHJlcGxhY2UgdGhlIGV4aXN0aW5nIGluc3RhbmNlLiBUaGlzIG1ldGhvZCBkb2Vzbid0IGNhcmVcbiAgICogd2hldGhlciB0aGUgbmV3IGNvbXBvbmVudCBhbmQgdGhlIG9sZCBvbmUgYXJlIGFjdHVhbGx5XG4gICAqIHRoZSBzYW1lLlxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2JdXG4gICAqL1xuXG4gIG1vdW50Q29tcG9uZW50OiBmdW5jdGlvbiBtb3VudENvbXBvbmVudChjYikge1xuICAgIC8vIGFjdHVhbCBtb3VudFxuICAgIHRoaXMudW5idWlsZCh0cnVlKTtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGFjdGl2YXRlSG9va3MgPSB0aGlzLkNvbXBvbmVudC5vcHRpb25zLmFjdGl2YXRlO1xuICAgIHZhciBjYWNoZWQgPSB0aGlzLmdldENhY2hlZCgpO1xuICAgIHZhciBuZXdDb21wb25lbnQgPSB0aGlzLmJ1aWxkKCk7XG4gICAgaWYgKGFjdGl2YXRlSG9va3MgJiYgIWNhY2hlZCkge1xuICAgICAgdGhpcy53YWl0aW5nRm9yID0gbmV3Q29tcG9uZW50O1xuICAgICAgY2FsbEFjdGl2YXRlSG9va3MoYWN0aXZhdGVIb29rcywgbmV3Q29tcG9uZW50LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChzZWxmLndhaXRpbmdGb3IgIT09IG5ld0NvbXBvbmVudCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzZWxmLndhaXRpbmdGb3IgPSBudWxsO1xuICAgICAgICBzZWxmLnRyYW5zaXRpb24obmV3Q29tcG9uZW50LCBjYik7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gdXBkYXRlIHJlZiBmb3Iga2VwdC1hbGl2ZSBjb21wb25lbnRcbiAgICAgIGlmIChjYWNoZWQpIHtcbiAgICAgICAgbmV3Q29tcG9uZW50Ll91cGRhdGVSZWYoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudHJhbnNpdGlvbihuZXdDb21wb25lbnQsIGNiKTtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIFdoZW4gdGhlIGNvbXBvbmVudCBjaGFuZ2VzIG9yIHVuYmluZHMgYmVmb3JlIGFuIGFzeW5jXG4gICAqIGNvbnN0cnVjdG9yIGlzIHJlc29sdmVkLCB3ZSBuZWVkIHRvIGludmFsaWRhdGUgaXRzXG4gICAqIHBlbmRpbmcgY2FsbGJhY2suXG4gICAqL1xuXG4gIGludmFsaWRhdGVQZW5kaW5nOiBmdW5jdGlvbiBpbnZhbGlkYXRlUGVuZGluZygpIHtcbiAgICBpZiAodGhpcy5wZW5kaW5nQ29tcG9uZW50Q2IpIHtcbiAgICAgIHRoaXMucGVuZGluZ0NvbXBvbmVudENiLmNhbmNlbCgpO1xuICAgICAgdGhpcy5wZW5kaW5nQ29tcG9uZW50Q2IgPSBudWxsO1xuICAgIH1cbiAgfSxcblxuICAvKipcbiAgICogSW5zdGFudGlhdGUvaW5zZXJ0IGEgbmV3IGNoaWxkIHZtLlxuICAgKiBJZiBrZWVwIGFsaXZlIGFuZCBoYXMgY2FjaGVkIGluc3RhbmNlLCBpbnNlcnQgdGhhdFxuICAgKiBpbnN0YW5jZTsgb3RoZXJ3aXNlIGJ1aWxkIGEgbmV3IG9uZSBhbmQgY2FjaGUgaXQuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbZXh0cmFPcHRpb25zXVxuICAgKiBAcmV0dXJuIHtWdWV9IC0gdGhlIGNyZWF0ZWQgaW5zdGFuY2VcbiAgICovXG5cbiAgYnVpbGQ6IGZ1bmN0aW9uIGJ1aWxkKGV4dHJhT3B0aW9ucykge1xuICAgIHZhciBjYWNoZWQgPSB0aGlzLmdldENhY2hlZCgpO1xuICAgIGlmIChjYWNoZWQpIHtcbiAgICAgIHJldHVybiBjYWNoZWQ7XG4gICAgfVxuICAgIGlmICh0aGlzLkNvbXBvbmVudCkge1xuICAgICAgLy8gZGVmYXVsdCBvcHRpb25zXG4gICAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgICAgbmFtZTogdGhpcy5Db21wb25lbnROYW1lLFxuICAgICAgICBlbDogY2xvbmVOb2RlKHRoaXMuZWwpLFxuICAgICAgICB0ZW1wbGF0ZTogdGhpcy5pbmxpbmVUZW1wbGF0ZSxcbiAgICAgICAgLy8gbWFrZSBzdXJlIHRvIGFkZCB0aGUgY2hpbGQgd2l0aCBjb3JyZWN0IHBhcmVudFxuICAgICAgICAvLyBpZiB0aGlzIGlzIGEgdHJhbnNjbHVkZWQgY29tcG9uZW50LCBpdHMgcGFyZW50XG4gICAgICAgIC8vIHNob3VsZCBiZSB0aGUgdHJhbnNjbHVzaW9uIGhvc3QuXG4gICAgICAgIHBhcmVudDogdGhpcy5faG9zdCB8fCB0aGlzLnZtLFxuICAgICAgICAvLyBpZiBubyBpbmxpbmUtdGVtcGxhdGUsIHRoZW4gdGhlIGNvbXBpbGVkXG4gICAgICAgIC8vIGxpbmtlciBjYW4gYmUgY2FjaGVkIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UuXG4gICAgICAgIF9saW5rZXJDYWNoYWJsZTogIXRoaXMuaW5saW5lVGVtcGxhdGUsXG4gICAgICAgIF9yZWY6IHRoaXMuZGVzY3JpcHRvci5yZWYsXG4gICAgICAgIF9hc0NvbXBvbmVudDogdHJ1ZSxcbiAgICAgICAgX2lzUm91dGVyVmlldzogdGhpcy5faXNSb3V0ZXJWaWV3LFxuICAgICAgICAvLyBpZiB0aGlzIGlzIGEgdHJhbnNjbHVkZWQgY29tcG9uZW50LCBjb250ZXh0XG4gICAgICAgIC8vIHdpbGwgYmUgdGhlIGNvbW1vbiBwYXJlbnQgdm0gb2YgdGhpcyBpbnN0YW5jZVxuICAgICAgICAvLyBhbmQgaXRzIGhvc3QuXG4gICAgICAgIF9jb250ZXh0OiB0aGlzLnZtLFxuICAgICAgICAvLyBpZiB0aGlzIGlzIGluc2lkZSBhbiBpbmxpbmUgdi1mb3IsIHRoZSBzY29wZVxuICAgICAgICAvLyB3aWxsIGJlIHRoZSBpbnRlcm1lZGlhdGUgc2NvcGUgY3JlYXRlZCBmb3IgdGhpc1xuICAgICAgICAvLyByZXBlYXQgZnJhZ21lbnQuIHRoaXMgaXMgdXNlZCBmb3IgbGlua2luZyBwcm9wc1xuICAgICAgICAvLyBhbmQgY29udGFpbmVyIGRpcmVjdGl2ZXMuXG4gICAgICAgIF9zY29wZTogdGhpcy5fc2NvcGUsXG4gICAgICAgIC8vIHBhc3MgaW4gdGhlIG93bmVyIGZyYWdtZW50IG9mIHRoaXMgY29tcG9uZW50LlxuICAgICAgICAvLyB0aGlzIGlzIG5lY2Vzc2FyeSBzbyB0aGF0IHRoZSBmcmFnbWVudCBjYW4ga2VlcFxuICAgICAgICAvLyB0cmFjayBvZiBpdHMgY29udGFpbmVkIGNvbXBvbmVudHMgaW4gb3JkZXIgdG9cbiAgICAgICAgLy8gY2FsbCBhdHRhY2gvZGV0YWNoIGhvb2tzIGZvciB0aGVtLlxuICAgICAgICBfZnJhZzogdGhpcy5fZnJhZ1xuICAgICAgfTtcbiAgICAgIC8vIGV4dHJhIG9wdGlvbnNcbiAgICAgIC8vIGluIDEuMC4wIHRoaXMgaXMgdXNlZCBieSB2dWUtcm91dGVyIG9ubHlcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgaWYgKGV4dHJhT3B0aW9ucykge1xuICAgICAgICBleHRlbmQob3B0aW9ucywgZXh0cmFPcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHZhciBjaGlsZCA9IG5ldyB0aGlzLkNvbXBvbmVudChvcHRpb25zKTtcbiAgICAgIGlmICh0aGlzLmtlZXBBbGl2ZSkge1xuICAgICAgICB0aGlzLmNhY2hlW3RoaXMuQ29tcG9uZW50LmNpZF0gPSBjaGlsZDtcbiAgICAgIH1cbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgdGhpcy5lbC5oYXNBdHRyaWJ1dGUoJ3RyYW5zaXRpb24nKSAmJiBjaGlsZC5faXNGcmFnbWVudCkge1xuICAgICAgICB3YXJuKCdUcmFuc2l0aW9ucyB3aWxsIG5vdCB3b3JrIG9uIGEgZnJhZ21lbnQgaW5zdGFuY2UuICcgKyAnVGVtcGxhdGU6ICcgKyBjaGlsZC4kb3B0aW9ucy50ZW1wbGF0ZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY2hpbGQ7XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiBUcnkgdG8gZ2V0IGEgY2FjaGVkIGluc3RhbmNlIG9mIHRoZSBjdXJyZW50IGNvbXBvbmVudC5cbiAgICpcbiAgICogQHJldHVybiB7VnVlfHVuZGVmaW5lZH1cbiAgICovXG5cbiAgZ2V0Q2FjaGVkOiBmdW5jdGlvbiBnZXRDYWNoZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMua2VlcEFsaXZlICYmIHRoaXMuY2FjaGVbdGhpcy5Db21wb25lbnQuY2lkXTtcbiAgfSxcblxuICAvKipcbiAgICogVGVhcmRvd24gdGhlIGN1cnJlbnQgY2hpbGQsIGJ1dCBkZWZlcnMgY2xlYW51cCBzb1xuICAgKiB0aGF0IHdlIGNhbiBzZXBhcmF0ZSB0aGUgZGVzdHJveSBhbmQgcmVtb3ZhbCBzdGVwcy5cbiAgICpcbiAgICogQHBhcmFtIHtCb29sZWFufSBkZWZlclxuICAgKi9cblxuICB1bmJ1aWxkOiBmdW5jdGlvbiB1bmJ1aWxkKGRlZmVyKSB7XG4gICAgaWYgKHRoaXMud2FpdGluZ0Zvcikge1xuICAgICAgdGhpcy53YWl0aW5nRm9yLiRkZXN0cm95KCk7XG4gICAgICB0aGlzLndhaXRpbmdGb3IgPSBudWxsO1xuICAgIH1cbiAgICB2YXIgY2hpbGQgPSB0aGlzLmNoaWxkVk07XG4gICAgaWYgKCFjaGlsZCB8fCB0aGlzLmtlZXBBbGl2ZSkge1xuICAgICAgaWYgKGNoaWxkKSB7XG4gICAgICAgIC8vIHJlbW92ZSByZWZcbiAgICAgICAgY2hpbGQuX3VwZGF0ZVJlZih0cnVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gdGhlIHNvbGUgcHVycG9zZSBvZiBgZGVmZXJDbGVhbnVwYCBpcyBzbyB0aGF0IHdlIGNhblxuICAgIC8vIFwiZGVhY3RpdmF0ZVwiIHRoZSB2bSByaWdodCBub3cgYW5kIHBlcmZvcm0gRE9NIHJlbW92YWxcbiAgICAvLyBsYXRlci5cbiAgICBjaGlsZC4kZGVzdHJveShmYWxzZSwgZGVmZXIpO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZW1vdmUgY3VycmVudCBkZXN0cm95ZWQgY2hpbGQgYW5kIG1hbnVhbGx5IGRvXG4gICAqIHRoZSBjbGVhbnVwIGFmdGVyIHJlbW92YWwuXG4gICAqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNiXG4gICAqL1xuXG4gIHJlbW92ZTogZnVuY3Rpb24gcmVtb3ZlKGNoaWxkLCBjYikge1xuICAgIHZhciBrZWVwQWxpdmUgPSB0aGlzLmtlZXBBbGl2ZTtcbiAgICBpZiAoY2hpbGQpIHtcbiAgICAgIC8vIHdlIG1heSBoYXZlIGEgY29tcG9uZW50IHN3aXRjaCB3aGVuIGEgcHJldmlvdXNcbiAgICAgIC8vIGNvbXBvbmVudCBpcyBzdGlsbCBiZWluZyB0cmFuc2l0aW9uZWQgb3V0LlxuICAgICAgLy8gd2Ugd2FudCB0byB0cmlnZ2VyIG9ubHkgb25lIGxhc3Rlc3QgaW5zZXJ0aW9uIGNiXG4gICAgICAvLyB3aGVuIHRoZSBleGlzdGluZyB0cmFuc2l0aW9uIGZpbmlzaGVzLiAoIzExMTkpXG4gICAgICB0aGlzLnBlbmRpbmdSZW1vdmFscysrO1xuICAgICAgdGhpcy5wZW5kaW5nUmVtb3ZhbENiID0gY2I7XG4gICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICBjaGlsZC4kcmVtb3ZlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5wZW5kaW5nUmVtb3ZhbHMtLTtcbiAgICAgICAgaWYgKCFrZWVwQWxpdmUpIGNoaWxkLl9jbGVhbnVwKCk7XG4gICAgICAgIGlmICghc2VsZi5wZW5kaW5nUmVtb3ZhbHMgJiYgc2VsZi5wZW5kaW5nUmVtb3ZhbENiKSB7XG4gICAgICAgICAgc2VsZi5wZW5kaW5nUmVtb3ZhbENiKCk7XG4gICAgICAgICAgc2VsZi5wZW5kaW5nUmVtb3ZhbENiID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChjYikge1xuICAgICAgY2IoKTtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIEFjdHVhbGx5IHN3YXAgdGhlIGNvbXBvbmVudHMsIGRlcGVuZGluZyBvbiB0aGVcbiAgICogdHJhbnNpdGlvbiBtb2RlLiBEZWZhdWx0cyB0byBzaW11bHRhbmVvdXMuXG4gICAqXG4gICAqIEBwYXJhbSB7VnVlfSB0YXJnZXRcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NiXVxuICAgKi9cblxuICB0cmFuc2l0aW9uOiBmdW5jdGlvbiB0cmFuc2l0aW9uKHRhcmdldCwgY2IpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIGN1cnJlbnQgPSB0aGlzLmNoaWxkVk07XG4gICAgLy8gZm9yIGRldnRvb2wgaW5zcGVjdGlvblxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICBpZiAoY3VycmVudCkgY3VycmVudC5faW5hY3RpdmUgPSB0cnVlO1xuICAgICAgdGFyZ2V0Ll9pbmFjdGl2ZSA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLmNoaWxkVk0gPSB0YXJnZXQ7XG4gICAgc3dpdGNoIChzZWxmLnBhcmFtcy50cmFuc2l0aW9uTW9kZSkge1xuICAgICAgY2FzZSAnaW4tb3V0JzpcbiAgICAgICAgdGFyZ2V0LiRiZWZvcmUoc2VsZi5hbmNob3IsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBzZWxmLnJlbW92ZShjdXJyZW50LCBjYik7XG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ291dC1pbic6XG4gICAgICAgIHNlbGYucmVtb3ZlKGN1cnJlbnQsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB0YXJnZXQuJGJlZm9yZShzZWxmLmFuY2hvciwgY2IpO1xuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBzZWxmLnJlbW92ZShjdXJyZW50KTtcbiAgICAgICAgdGFyZ2V0LiRiZWZvcmUoc2VsZi5hbmNob3IsIGNiKTtcbiAgICB9XG4gIH0sXG5cbiAgLyoqXG4gICAqIFVuYmluZC5cbiAgICovXG5cbiAgdW5iaW5kOiBmdW5jdGlvbiB1bmJpbmQoKSB7XG4gICAgdGhpcy5pbnZhbGlkYXRlUGVuZGluZygpO1xuICAgIC8vIERvIG5vdCBkZWZlciBjbGVhbnVwIHdoZW4gdW5iaW5kaW5nXG4gICAgdGhpcy51bmJ1aWxkKCk7XG4gICAgLy8gZGVzdHJveSBhbGwga2VlcC1hbGl2ZSBjYWNoZWQgaW5zdGFuY2VzXG4gICAgaWYgKHRoaXMuY2FjaGUpIHtcbiAgICAgIGZvciAodmFyIGtleSBpbiB0aGlzLmNhY2hlKSB7XG4gICAgICAgIHRoaXMuY2FjaGVba2V5XS4kZGVzdHJveSgpO1xuICAgICAgfVxuICAgICAgdGhpcy5jYWNoZSA9IG51bGw7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIENhbGwgYWN0aXZhdGUgaG9va3MgaW4gb3JkZXIgKGFzeW5jaHJvbm91cylcbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBob29rc1xuICogQHBhcmFtIHtWdWV9IHZtXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYlxuICovXG5cbmZ1bmN0aW9uIGNhbGxBY3RpdmF0ZUhvb2tzKGhvb2tzLCB2bSwgY2IpIHtcbiAgdmFyIHRvdGFsID0gaG9va3MubGVuZ3RoO1xuICB2YXIgY2FsbGVkID0gMDtcbiAgaG9va3NbMF0uY2FsbCh2bSwgbmV4dCk7XG4gIGZ1bmN0aW9uIG5leHQoKSB7XG4gICAgaWYgKCsrY2FsbGVkID49IHRvdGFsKSB7XG4gICAgICBjYigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBob29rc1tjYWxsZWRdLmNhbGwodm0sIG5leHQpO1xuICAgIH1cbiAgfVxufVxuXG52YXIgYmluZGluZ01vZGVzID0gY29uZmlnLl9wcm9wQmluZGluZ01vZGVzO1xuXG52YXIgcHJvcERlZiA9IHtcblxuICBiaW5kOiBmdW5jdGlvbiBiaW5kKCkge1xuICAgIHZhciBjaGlsZCA9IHRoaXMudm07XG4gICAgdmFyIHBhcmVudCA9IGNoaWxkLl9jb250ZXh0O1xuICAgIC8vIHBhc3NlZCBpbiBmcm9tIGNvbXBpbGVyIGRpcmVjdGx5XG4gICAgdmFyIHByb3AgPSB0aGlzLmRlc2NyaXB0b3IucHJvcDtcbiAgICB2YXIgY2hpbGRLZXkgPSBwcm9wLnBhdGg7XG4gICAgdmFyIHBhcmVudEtleSA9IHByb3AucGFyZW50UGF0aDtcbiAgICB2YXIgdHdvV2F5ID0gcHJvcC5tb2RlID09PSBiaW5kaW5nTW9kZXMuVFdPX1dBWTtcblxuICAgIHZhciBwYXJlbnRXYXRjaGVyID0gdGhpcy5wYXJlbnRXYXRjaGVyID0gbmV3IFdhdGNoZXIocGFyZW50LCBwYXJlbnRLZXksIGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgIHZhbCA9IGNvZXJjZVByb3AocHJvcCwgdmFsKTtcbiAgICAgIGlmIChhc3NlcnRQcm9wKHByb3AsIHZhbCkpIHtcbiAgICAgICAgY2hpbGRbY2hpbGRLZXldID0gdmFsO1xuICAgICAgfVxuICAgIH0sIHtcbiAgICAgIHR3b1dheTogdHdvV2F5LFxuICAgICAgZmlsdGVyczogcHJvcC5maWx0ZXJzLFxuICAgICAgLy8gaW1wb3J0YW50OiBwcm9wcyBuZWVkIHRvIGJlIG9ic2VydmVkIG9uIHRoZVxuICAgICAgLy8gdi1mb3Igc2NvcGUgaWYgcHJlc2VudFxuICAgICAgc2NvcGU6IHRoaXMuX3Njb3BlXG4gICAgfSk7XG5cbiAgICAvLyBzZXQgdGhlIGNoaWxkIGluaXRpYWwgdmFsdWUuXG4gICAgaW5pdFByb3AoY2hpbGQsIHByb3AsIHBhcmVudFdhdGNoZXIudmFsdWUpO1xuXG4gICAgLy8gc2V0dXAgdHdvLXdheSBiaW5kaW5nXG4gICAgaWYgKHR3b1dheSkge1xuICAgICAgLy8gaW1wb3J0YW50OiBkZWZlciB0aGUgY2hpbGQgd2F0Y2hlciBjcmVhdGlvbiB1bnRpbFxuICAgICAgLy8gdGhlIGNyZWF0ZWQgaG9vayAoYWZ0ZXIgZGF0YSBvYnNlcnZhdGlvbilcbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIGNoaWxkLiRvbmNlKCdwcmUtaG9vazpjcmVhdGVkJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLmNoaWxkV2F0Y2hlciA9IG5ldyBXYXRjaGVyKGNoaWxkLCBjaGlsZEtleSwgZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICAgIHBhcmVudFdhdGNoZXIuc2V0KHZhbCk7XG4gICAgICAgIH0sIHtcbiAgICAgICAgICAvLyBlbnN1cmUgc3luYyB1cHdhcmQgYmVmb3JlIHBhcmVudCBzeW5jIGRvd24uXG4gICAgICAgICAgLy8gdGhpcyBpcyBuZWNlc3NhcnkgaW4gY2FzZXMgZS5nLiB0aGUgY2hpbGRcbiAgICAgICAgICAvLyBtdXRhdGVzIGEgcHJvcCBhcnJheSwgdGhlbiByZXBsYWNlcyBpdC4gKCMxNjgzKVxuICAgICAgICAgIHN5bmM6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG5cbiAgdW5iaW5kOiBmdW5jdGlvbiB1bmJpbmQoKSB7XG4gICAgdGhpcy5wYXJlbnRXYXRjaGVyLnRlYXJkb3duKCk7XG4gICAgaWYgKHRoaXMuY2hpbGRXYXRjaGVyKSB7XG4gICAgICB0aGlzLmNoaWxkV2F0Y2hlci50ZWFyZG93bigpO1xuICAgIH1cbiAgfVxufTtcblxudmFyIHF1ZXVlJDEgPSBbXTtcbnZhciBxdWV1ZWQgPSBmYWxzZTtcblxuLyoqXG4gKiBQdXNoIGEgam9iIGludG8gdGhlIHF1ZXVlLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGpvYlxuICovXG5cbmZ1bmN0aW9uIHB1c2hKb2Ioam9iKSB7XG4gIHF1ZXVlJDEucHVzaChqb2IpO1xuICBpZiAoIXF1ZXVlZCkge1xuICAgIHF1ZXVlZCA9IHRydWU7XG4gICAgbmV4dFRpY2soZmx1c2gpO1xuICB9XG59XG5cbi8qKlxuICogRmx1c2ggdGhlIHF1ZXVlLCBhbmQgZG8gb25lIGZvcmNlZCByZWZsb3cgYmVmb3JlXG4gKiB0cmlnZ2VyaW5nIHRyYW5zaXRpb25zLlxuICovXG5cbmZ1bmN0aW9uIGZsdXNoKCkge1xuICAvLyBGb3JjZSBsYXlvdXRcbiAgdmFyIGYgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHF1ZXVlJDEubGVuZ3RoOyBpKyspIHtcbiAgICBxdWV1ZSQxW2ldKCk7XG4gIH1cbiAgcXVldWUkMSA9IFtdO1xuICBxdWV1ZWQgPSBmYWxzZTtcbiAgLy8gZHVtbXkgcmV0dXJuLCBzbyBqcyBsaW50ZXJzIGRvbid0IGNvbXBsYWluIGFib3V0XG4gIC8vIHVudXNlZCB2YXJpYWJsZSBmXG4gIHJldHVybiBmO1xufVxuXG52YXIgVFlQRV9UUkFOU0lUSU9OID0gJ3RyYW5zaXRpb24nO1xudmFyIFRZUEVfQU5JTUFUSU9OID0gJ2FuaW1hdGlvbic7XG52YXIgdHJhbnNEdXJhdGlvblByb3AgPSB0cmFuc2l0aW9uUHJvcCArICdEdXJhdGlvbic7XG52YXIgYW5pbUR1cmF0aW9uUHJvcCA9IGFuaW1hdGlvblByb3AgKyAnRHVyYXRpb24nO1xuXG4vKipcbiAqIEEgVHJhbnNpdGlvbiBvYmplY3QgdGhhdCBlbmNhcHN1bGF0ZXMgdGhlIHN0YXRlIGFuZCBsb2dpY1xuICogb2YgdGhlIHRyYW5zaXRpb24uXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtTdHJpbmd9IGlkXG4gKiBAcGFyYW0ge09iamVjdH0gaG9va3NcbiAqIEBwYXJhbSB7VnVlfSB2bVxuICovXG5mdW5jdGlvbiBUcmFuc2l0aW9uKGVsLCBpZCwgaG9va3MsIHZtKSB7XG4gIHRoaXMuaWQgPSBpZDtcbiAgdGhpcy5lbCA9IGVsO1xuICB0aGlzLmVudGVyQ2xhc3MgPSBob29rcyAmJiBob29rcy5lbnRlckNsYXNzIHx8IGlkICsgJy1lbnRlcic7XG4gIHRoaXMubGVhdmVDbGFzcyA9IGhvb2tzICYmIGhvb2tzLmxlYXZlQ2xhc3MgfHwgaWQgKyAnLWxlYXZlJztcbiAgdGhpcy5ob29rcyA9IGhvb2tzO1xuICB0aGlzLnZtID0gdm07XG4gIC8vIGFzeW5jIHN0YXRlXG4gIHRoaXMucGVuZGluZ0Nzc0V2ZW50ID0gdGhpcy5wZW5kaW5nQ3NzQ2IgPSB0aGlzLmNhbmNlbCA9IHRoaXMucGVuZGluZ0pzQ2IgPSB0aGlzLm9wID0gdGhpcy5jYiA9IG51bGw7XG4gIHRoaXMuanVzdEVudGVyZWQgPSBmYWxzZTtcbiAgdGhpcy5lbnRlcmVkID0gdGhpcy5sZWZ0ID0gZmFsc2U7XG4gIHRoaXMudHlwZUNhY2hlID0ge307XG4gIC8vIGNoZWNrIGNzcyB0cmFuc2l0aW9uIHR5cGVcbiAgdGhpcy50eXBlID0gaG9va3MgJiYgaG9va3MudHlwZTtcbiAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgaWYgKHRoaXMudHlwZSAmJiB0aGlzLnR5cGUgIT09IFRZUEVfVFJBTlNJVElPTiAmJiB0aGlzLnR5cGUgIT09IFRZUEVfQU5JTUFUSU9OKSB7XG4gICAgICB3YXJuKCdpbnZhbGlkIENTUyB0cmFuc2l0aW9uIHR5cGUgZm9yIHRyYW5zaXRpb249XCInICsgdGhpcy5pZCArICdcIjogJyArIHRoaXMudHlwZSk7XG4gICAgfVxuICB9XG4gIC8vIGJpbmRcbiAgdmFyIHNlbGYgPSB0aGlzO1snZW50ZXJOZXh0VGljaycsICdlbnRlckRvbmUnLCAnbGVhdmVOZXh0VGljaycsICdsZWF2ZURvbmUnXS5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgc2VsZlttXSA9IGJpbmQoc2VsZlttXSwgc2VsZik7XG4gIH0pO1xufVxuXG52YXIgcCQxID0gVHJhbnNpdGlvbi5wcm90b3R5cGU7XG5cbi8qKlxuICogU3RhcnQgYW4gZW50ZXJpbmcgdHJhbnNpdGlvbi5cbiAqXG4gKiAxLiBlbnRlciB0cmFuc2l0aW9uIHRyaWdnZXJlZFxuICogMi4gY2FsbCBiZWZvcmVFbnRlciBob29rXG4gKiAzLiBhZGQgZW50ZXIgY2xhc3NcbiAqIDQuIGluc2VydC9zaG93IGVsZW1lbnRcbiAqIDUuIGNhbGwgZW50ZXIgaG9vayAod2l0aCBwb3NzaWJsZSBleHBsaWNpdCBqcyBjYWxsYmFjaylcbiAqIDYuIHJlZmxvd1xuICogNy4gYmFzZWQgb24gdHJhbnNpdGlvbiB0eXBlOlxuICogICAgLSB0cmFuc2l0aW9uOlxuICogICAgICAgIHJlbW92ZSBjbGFzcyBub3csIHdhaXQgZm9yIHRyYW5zaXRpb25lbmQsXG4gKiAgICAgICAgdGhlbiBkb25lIGlmIHRoZXJlJ3Mgbm8gZXhwbGljaXQganMgY2FsbGJhY2suXG4gKiAgICAtIGFuaW1hdGlvbjpcbiAqICAgICAgICB3YWl0IGZvciBhbmltYXRpb25lbmQsIHJlbW92ZSBjbGFzcyxcbiAqICAgICAgICB0aGVuIGRvbmUgaWYgdGhlcmUncyBubyBleHBsaWNpdCBqcyBjYWxsYmFjay5cbiAqICAgIC0gbm8gY3NzIHRyYW5zaXRpb246XG4gKiAgICAgICAgZG9uZSBub3cgaWYgdGhlcmUncyBubyBleHBsaWNpdCBqcyBjYWxsYmFjay5cbiAqIDguIHdhaXQgZm9yIGVpdGhlciBkb25lIG9yIGpzIGNhbGxiYWNrLCB0aGVuIGNhbGxcbiAqICAgIGFmdGVyRW50ZXIgaG9vay5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBvcCAtIGluc2VydC9zaG93IHRoZSBlbGVtZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2JdXG4gKi9cblxucCQxLmVudGVyID0gZnVuY3Rpb24gKG9wLCBjYikge1xuICB0aGlzLmNhbmNlbFBlbmRpbmcoKTtcbiAgdGhpcy5jYWxsSG9vaygnYmVmb3JlRW50ZXInKTtcbiAgdGhpcy5jYiA9IGNiO1xuICBhZGRDbGFzcyh0aGlzLmVsLCB0aGlzLmVudGVyQ2xhc3MpO1xuICBvcCgpO1xuICB0aGlzLmVudGVyZWQgPSBmYWxzZTtcbiAgdGhpcy5jYWxsSG9va1dpdGhDYignZW50ZXInKTtcbiAgaWYgKHRoaXMuZW50ZXJlZCkge1xuICAgIHJldHVybjsgLy8gdXNlciBjYWxsZWQgZG9uZSBzeW5jaHJvbm91c2x5LlxuICB9XG4gIHRoaXMuY2FuY2VsID0gdGhpcy5ob29rcyAmJiB0aGlzLmhvb2tzLmVudGVyQ2FuY2VsbGVkO1xuICBwdXNoSm9iKHRoaXMuZW50ZXJOZXh0VGljayk7XG59O1xuXG4vKipcbiAqIFRoZSBcIm5leHRUaWNrXCIgcGhhc2Ugb2YgYW4gZW50ZXJpbmcgdHJhbnNpdGlvbiwgd2hpY2ggaXNcbiAqIHRvIGJlIHB1c2hlZCBpbnRvIGEgcXVldWUgYW5kIGV4ZWN1dGVkIGFmdGVyIGEgcmVmbG93IHNvXG4gKiB0aGF0IHJlbW92aW5nIHRoZSBjbGFzcyBjYW4gdHJpZ2dlciBhIENTUyB0cmFuc2l0aW9uLlxuICovXG5cbnAkMS5lbnRlck5leHRUaWNrID0gZnVuY3Rpb24gKCkge1xuICAvLyBJbXBvcnRhbnQgaGFjazpcbiAgLy8gaW4gQ2hyb21lLCBpZiBhIGp1c3QtZW50ZXJlZCBlbGVtZW50IGlzIGFwcGxpZWQgdGhlXG4gIC8vIGxlYXZlIGNsYXNzIHdoaWxlIGl0cyBpbnRlcnBvbGF0ZWQgcHJvcGVydHkgc3RpbGwgaGFzXG4gIC8vIGEgdmVyeSBzbWFsbCB2YWx1ZSAod2l0aGluIG9uZSBmcmFtZSksIENocm9tZSB3aWxsXG4gIC8vIHNraXAgdGhlIGxlYXZlIHRyYW5zaXRpb24gZW50aXJlbHkgYW5kIG5vdCBmaXJpbmcgdGhlXG4gIC8vIHRyYW5zdGlvbmVuZCBldmVudC4gVGhlcmVmb3JlIHdlIG5lZWQgdG8gcHJvdGVjdGVkXG4gIC8vIGFnYWluc3Qgc3VjaCBjYXNlcyB1c2luZyBhIG9uZS1mcmFtZSB0aW1lb3V0LlxuICB0aGlzLmp1c3RFbnRlcmVkID0gdHJ1ZTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICBzZWxmLmp1c3RFbnRlcmVkID0gZmFsc2U7XG4gIH0sIDE3KTtcblxuICB2YXIgZW50ZXJEb25lID0gdGhpcy5lbnRlckRvbmU7XG4gIHZhciB0eXBlID0gdGhpcy5nZXRDc3NUcmFuc2l0aW9uVHlwZSh0aGlzLmVudGVyQ2xhc3MpO1xuICBpZiAoIXRoaXMucGVuZGluZ0pzQ2IpIHtcbiAgICBpZiAodHlwZSA9PT0gVFlQRV9UUkFOU0lUSU9OKSB7XG4gICAgICAvLyB0cmlnZ2VyIHRyYW5zaXRpb24gYnkgcmVtb3ZpbmcgZW50ZXIgY2xhc3Mgbm93XG4gICAgICByZW1vdmVDbGFzcyh0aGlzLmVsLCB0aGlzLmVudGVyQ2xhc3MpO1xuICAgICAgdGhpcy5zZXR1cENzc0NiKHRyYW5zaXRpb25FbmRFdmVudCwgZW50ZXJEb25lKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFRZUEVfQU5JTUFUSU9OKSB7XG4gICAgICB0aGlzLnNldHVwQ3NzQ2IoYW5pbWF0aW9uRW5kRXZlbnQsIGVudGVyRG9uZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVudGVyRG9uZSgpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlID09PSBUWVBFX1RSQU5TSVRJT04pIHtcbiAgICByZW1vdmVDbGFzcyh0aGlzLmVsLCB0aGlzLmVudGVyQ2xhc3MpO1xuICB9XG59O1xuXG4vKipcbiAqIFRoZSBcImNsZWFudXBcIiBwaGFzZSBvZiBhbiBlbnRlcmluZyB0cmFuc2l0aW9uLlxuICovXG5cbnAkMS5lbnRlckRvbmUgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMuZW50ZXJlZCA9IHRydWU7XG4gIHRoaXMuY2FuY2VsID0gdGhpcy5wZW5kaW5nSnNDYiA9IG51bGw7XG4gIHJlbW92ZUNsYXNzKHRoaXMuZWwsIHRoaXMuZW50ZXJDbGFzcyk7XG4gIHRoaXMuY2FsbEhvb2soJ2FmdGVyRW50ZXInKTtcbiAgaWYgKHRoaXMuY2IpIHRoaXMuY2IoKTtcbn07XG5cbi8qKlxuICogU3RhcnQgYSBsZWF2aW5nIHRyYW5zaXRpb24uXG4gKlxuICogMS4gbGVhdmUgdHJhbnNpdGlvbiB0cmlnZ2VyZWQuXG4gKiAyLiBjYWxsIGJlZm9yZUxlYXZlIGhvb2tcbiAqIDMuIGFkZCBsZWF2ZSBjbGFzcyAodHJpZ2dlciBjc3MgdHJhbnNpdGlvbilcbiAqIDQuIGNhbGwgbGVhdmUgaG9vayAod2l0aCBwb3NzaWJsZSBleHBsaWNpdCBqcyBjYWxsYmFjaylcbiAqIDUuIHJlZmxvdyBpZiBubyBleHBsaWNpdCBqcyBjYWxsYmFjayBpcyBwcm92aWRlZFxuICogNi4gYmFzZWQgb24gdHJhbnNpdGlvbiB0eXBlOlxuICogICAgLSB0cmFuc2l0aW9uIG9yIGFuaW1hdGlvbjpcbiAqICAgICAgICB3YWl0IGZvciBlbmQgZXZlbnQsIHJlbW92ZSBjbGFzcywgdGhlbiBkb25lIGlmXG4gKiAgICAgICAgdGhlcmUncyBubyBleHBsaWNpdCBqcyBjYWxsYmFjay5cbiAqICAgIC0gbm8gY3NzIHRyYW5zaXRpb246XG4gKiAgICAgICAgZG9uZSBpZiB0aGVyZSdzIG5vIGV4cGxpY2l0IGpzIGNhbGxiYWNrLlxuICogNy4gd2FpdCBmb3IgZWl0aGVyIGRvbmUgb3IganMgY2FsbGJhY2ssIHRoZW4gY2FsbFxuICogICAgYWZ0ZXJMZWF2ZSBob29rLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG9wIC0gcmVtb3ZlL2hpZGUgdGhlIGVsZW1lbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYl1cbiAqL1xuXG5wJDEubGVhdmUgPSBmdW5jdGlvbiAob3AsIGNiKSB7XG4gIHRoaXMuY2FuY2VsUGVuZGluZygpO1xuICB0aGlzLmNhbGxIb29rKCdiZWZvcmVMZWF2ZScpO1xuICB0aGlzLm9wID0gb3A7XG4gIHRoaXMuY2IgPSBjYjtcbiAgYWRkQ2xhc3ModGhpcy5lbCwgdGhpcy5sZWF2ZUNsYXNzKTtcbiAgdGhpcy5sZWZ0ID0gZmFsc2U7XG4gIHRoaXMuY2FsbEhvb2tXaXRoQ2IoJ2xlYXZlJyk7XG4gIGlmICh0aGlzLmxlZnQpIHtcbiAgICByZXR1cm47IC8vIHVzZXIgY2FsbGVkIGRvbmUgc3luY2hyb25vdXNseS5cbiAgfVxuICB0aGlzLmNhbmNlbCA9IHRoaXMuaG9va3MgJiYgdGhpcy5ob29rcy5sZWF2ZUNhbmNlbGxlZDtcbiAgLy8gb25seSBuZWVkIHRvIGhhbmRsZSBsZWF2ZURvbmUgaWZcbiAgLy8gMS4gdGhlIHRyYW5zaXRpb24gaXMgYWxyZWFkeSBkb25lIChzeW5jaHJvbm91c2x5IGNhbGxlZFxuICAvLyAgICBieSB0aGUgdXNlciwgd2hpY2ggY2F1c2VzIHRoaXMub3Agc2V0IHRvIG51bGwpXG4gIC8vIDIuIHRoZXJlJ3Mgbm8gZXhwbGljaXQganMgY2FsbGJhY2tcbiAgaWYgKHRoaXMub3AgJiYgIXRoaXMucGVuZGluZ0pzQ2IpIHtcbiAgICAvLyBpZiBhIENTUyB0cmFuc2l0aW9uIGxlYXZlcyBpbW1lZGlhdGVseSBhZnRlciBlbnRlcixcbiAgICAvLyB0aGUgdHJhbnNpdGlvbmVuZCBldmVudCBuZXZlciBmaXJlcy4gdGhlcmVmb3JlIHdlXG4gICAgLy8gZGV0ZWN0IHN1Y2ggY2FzZXMgYW5kIGVuZCB0aGUgbGVhdmUgaW1tZWRpYXRlbHkuXG4gICAgaWYgKHRoaXMuanVzdEVudGVyZWQpIHtcbiAgICAgIHRoaXMubGVhdmVEb25lKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHB1c2hKb2IodGhpcy5sZWF2ZU5leHRUaWNrKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogVGhlIFwibmV4dFRpY2tcIiBwaGFzZSBvZiBhIGxlYXZpbmcgdHJhbnNpdGlvbi5cbiAqL1xuXG5wJDEubGVhdmVOZXh0VGljayA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHR5cGUgPSB0aGlzLmdldENzc1RyYW5zaXRpb25UeXBlKHRoaXMubGVhdmVDbGFzcyk7XG4gIGlmICh0eXBlKSB7XG4gICAgdmFyIGV2ZW50ID0gdHlwZSA9PT0gVFlQRV9UUkFOU0lUSU9OID8gdHJhbnNpdGlvbkVuZEV2ZW50IDogYW5pbWF0aW9uRW5kRXZlbnQ7XG4gICAgdGhpcy5zZXR1cENzc0NiKGV2ZW50LCB0aGlzLmxlYXZlRG9uZSk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5sZWF2ZURvbmUoKTtcbiAgfVxufTtcblxuLyoqXG4gKiBUaGUgXCJjbGVhbnVwXCIgcGhhc2Ugb2YgYSBsZWF2aW5nIHRyYW5zaXRpb24uXG4gKi9cblxucCQxLmxlYXZlRG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5sZWZ0ID0gdHJ1ZTtcbiAgdGhpcy5jYW5jZWwgPSB0aGlzLnBlbmRpbmdKc0NiID0gbnVsbDtcbiAgdGhpcy5vcCgpO1xuICByZW1vdmVDbGFzcyh0aGlzLmVsLCB0aGlzLmxlYXZlQ2xhc3MpO1xuICB0aGlzLmNhbGxIb29rKCdhZnRlckxlYXZlJyk7XG4gIGlmICh0aGlzLmNiKSB0aGlzLmNiKCk7XG4gIHRoaXMub3AgPSBudWxsO1xufTtcblxuLyoqXG4gKiBDYW5jZWwgYW55IHBlbmRpbmcgY2FsbGJhY2tzIGZyb20gYSBwcmV2aW91c2x5IHJ1bm5pbmdcbiAqIGJ1dCBub3QgZmluaXNoZWQgdHJhbnNpdGlvbi5cbiAqL1xuXG5wJDEuY2FuY2VsUGVuZGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5vcCA9IHRoaXMuY2IgPSBudWxsO1xuICB2YXIgaGFzUGVuZGluZyA9IGZhbHNlO1xuICBpZiAodGhpcy5wZW5kaW5nQ3NzQ2IpIHtcbiAgICBoYXNQZW5kaW5nID0gdHJ1ZTtcbiAgICBvZmYodGhpcy5lbCwgdGhpcy5wZW5kaW5nQ3NzRXZlbnQsIHRoaXMucGVuZGluZ0Nzc0NiKTtcbiAgICB0aGlzLnBlbmRpbmdDc3NFdmVudCA9IHRoaXMucGVuZGluZ0Nzc0NiID0gbnVsbDtcbiAgfVxuICBpZiAodGhpcy5wZW5kaW5nSnNDYikge1xuICAgIGhhc1BlbmRpbmcgPSB0cnVlO1xuICAgIHRoaXMucGVuZGluZ0pzQ2IuY2FuY2VsKCk7XG4gICAgdGhpcy5wZW5kaW5nSnNDYiA9IG51bGw7XG4gIH1cbiAgaWYgKGhhc1BlbmRpbmcpIHtcbiAgICByZW1vdmVDbGFzcyh0aGlzLmVsLCB0aGlzLmVudGVyQ2xhc3MpO1xuICAgIHJlbW92ZUNsYXNzKHRoaXMuZWwsIHRoaXMubGVhdmVDbGFzcyk7XG4gIH1cbiAgaWYgKHRoaXMuY2FuY2VsKSB7XG4gICAgdGhpcy5jYW5jZWwuY2FsbCh0aGlzLnZtLCB0aGlzLmVsKTtcbiAgICB0aGlzLmNhbmNlbCA9IG51bGw7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbCBhIHVzZXItcHJvdmlkZWQgc3luY2hyb25vdXMgaG9vayBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICovXG5cbnAkMS5jYWxsSG9vayA9IGZ1bmN0aW9uICh0eXBlKSB7XG4gIGlmICh0aGlzLmhvb2tzICYmIHRoaXMuaG9va3NbdHlwZV0pIHtcbiAgICB0aGlzLmhvb2tzW3R5cGVdLmNhbGwodGhpcy52bSwgdGhpcy5lbCk7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbCBhIHVzZXItcHJvdmlkZWQsIHBvdGVudGlhbGx5LWFzeW5jIGhvb2sgZnVuY3Rpb24uXG4gKiBXZSBjaGVjayBmb3IgdGhlIGxlbmd0aCBvZiBhcmd1bWVudHMgdG8gc2VlIGlmIHRoZSBob29rXG4gKiBleHBlY3RzIGEgYGRvbmVgIGNhbGxiYWNrLiBJZiB0cnVlLCB0aGUgdHJhbnNpdGlvbidzIGVuZFxuICogd2lsbCBiZSBkZXRlcm1pbmVkIGJ5IHdoZW4gdGhlIHVzZXIgY2FsbHMgdGhhdCBjYWxsYmFjaztcbiAqIG90aGVyd2lzZSwgdGhlIGVuZCBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBDU1MgdHJhbnNpdGlvbiBvclxuICogYW5pbWF0aW9uLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKi9cblxucCQxLmNhbGxIb29rV2l0aENiID0gZnVuY3Rpb24gKHR5cGUpIHtcbiAgdmFyIGhvb2sgPSB0aGlzLmhvb2tzICYmIHRoaXMuaG9va3NbdHlwZV07XG4gIGlmIChob29rKSB7XG4gICAgaWYgKGhvb2subGVuZ3RoID4gMSkge1xuICAgICAgdGhpcy5wZW5kaW5nSnNDYiA9IGNhbmNlbGxhYmxlKHRoaXNbdHlwZSArICdEb25lJ10pO1xuICAgIH1cbiAgICBob29rLmNhbGwodGhpcy52bSwgdGhpcy5lbCwgdGhpcy5wZW5kaW5nSnNDYik7XG4gIH1cbn07XG5cbi8qKlxuICogR2V0IGFuIGVsZW1lbnQncyB0cmFuc2l0aW9uIHR5cGUgYmFzZWQgb24gdGhlXG4gKiBjYWxjdWxhdGVkIHN0eWxlcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gY2xhc3NOYW1lXG4gKiBAcmV0dXJuIHtOdW1iZXJ9XG4gKi9cblxucCQxLmdldENzc1RyYW5zaXRpb25UeXBlID0gZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgaWYgKCF0cmFuc2l0aW9uRW5kRXZlbnQgfHxcbiAgLy8gc2tpcCBDU1MgdHJhbnNpdGlvbnMgaWYgcGFnZSBpcyBub3QgdmlzaWJsZSAtXG4gIC8vIHRoaXMgc29sdmVzIHRoZSBpc3N1ZSBvZiB0cmFuc2l0aW9uZW5kIGV2ZW50cyBub3RcbiAgLy8gZmlyaW5nIHVudGlsIHRoZSBwYWdlIGlzIHZpc2libGUgYWdhaW4uXG4gIC8vIHBhZ2VWaXNpYmlsaXR5IEFQSSBpcyBzdXBwb3J0ZWQgaW4gSUUxMCssIHNhbWUgYXNcbiAgLy8gQ1NTIHRyYW5zaXRpb25zLlxuICBkb2N1bWVudC5oaWRkZW4gfHxcbiAgLy8gZXhwbGljaXQganMtb25seSB0cmFuc2l0aW9uXG4gIHRoaXMuaG9va3MgJiYgdGhpcy5ob29rcy5jc3MgPT09IGZhbHNlIHx8XG4gIC8vIGVsZW1lbnQgaXMgaGlkZGVuXG4gIGlzSGlkZGVuKHRoaXMuZWwpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciB0eXBlID0gdGhpcy50eXBlIHx8IHRoaXMudHlwZUNhY2hlW2NsYXNzTmFtZV07XG4gIGlmICh0eXBlKSByZXR1cm4gdHlwZTtcbiAgdmFyIGlubGluZVN0eWxlcyA9IHRoaXMuZWwuc3R5bGU7XG4gIHZhciBjb21wdXRlZFN0eWxlcyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHRoaXMuZWwpO1xuICB2YXIgdHJhbnNEdXJhdGlvbiA9IGlubGluZVN0eWxlc1t0cmFuc0R1cmF0aW9uUHJvcF0gfHwgY29tcHV0ZWRTdHlsZXNbdHJhbnNEdXJhdGlvblByb3BdO1xuICBpZiAodHJhbnNEdXJhdGlvbiAmJiB0cmFuc0R1cmF0aW9uICE9PSAnMHMnKSB7XG4gICAgdHlwZSA9IFRZUEVfVFJBTlNJVElPTjtcbiAgfSBlbHNlIHtcbiAgICB2YXIgYW5pbUR1cmF0aW9uID0gaW5saW5lU3R5bGVzW2FuaW1EdXJhdGlvblByb3BdIHx8IGNvbXB1dGVkU3R5bGVzW2FuaW1EdXJhdGlvblByb3BdO1xuICAgIGlmIChhbmltRHVyYXRpb24gJiYgYW5pbUR1cmF0aW9uICE9PSAnMHMnKSB7XG4gICAgICB0eXBlID0gVFlQRV9BTklNQVRJT047XG4gICAgfVxuICB9XG4gIGlmICh0eXBlKSB7XG4gICAgdGhpcy50eXBlQ2FjaGVbY2xhc3NOYW1lXSA9IHR5cGU7XG4gIH1cbiAgcmV0dXJuIHR5cGU7XG59O1xuXG4vKipcbiAqIFNldHVwIGEgQ1NTIHRyYW5zaXRpb25lbmQvYW5pbWF0aW9uZW5kIGNhbGxiYWNrLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2JcbiAqL1xuXG5wJDEuc2V0dXBDc3NDYiA9IGZ1bmN0aW9uIChldmVudCwgY2IpIHtcbiAgdGhpcy5wZW5kaW5nQ3NzRXZlbnQgPSBldmVudDtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgZWwgPSB0aGlzLmVsO1xuICB2YXIgb25FbmQgPSB0aGlzLnBlbmRpbmdDc3NDYiA9IGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKGUudGFyZ2V0ID09PSBlbCkge1xuICAgICAgb2ZmKGVsLCBldmVudCwgb25FbmQpO1xuICAgICAgc2VsZi5wZW5kaW5nQ3NzRXZlbnQgPSBzZWxmLnBlbmRpbmdDc3NDYiA9IG51bGw7XG4gICAgICBpZiAoIXNlbGYucGVuZGluZ0pzQ2IgJiYgY2IpIHtcbiAgICAgICAgY2IoKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIG9uKGVsLCBldmVudCwgb25FbmQpO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBhbiBlbGVtZW50IGlzIGhpZGRlbiAtIGluIHRoYXQgY2FzZSB3ZSBjYW4ganVzdFxuICogc2tpcCB0aGUgdHJhbnNpdGlvbiBhbGx0b2dldGhlci5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbmZ1bmN0aW9uIGlzSGlkZGVuKGVsKSB7XG4gIGlmICgvc3ZnJC8udGVzdChlbC5uYW1lc3BhY2VVUkkpKSB7XG4gICAgLy8gU1ZHIGVsZW1lbnRzIGRvIG5vdCBoYXZlIG9mZnNldChXaWR0aHxIZWlnaHQpXG4gICAgLy8gc28gd2UgbmVlZCB0byBjaGVjayB0aGUgY2xpZW50IHJlY3RcbiAgICB2YXIgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiAhKHJlY3Qud2lkdGggfHwgcmVjdC5oZWlnaHQpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAhKGVsLm9mZnNldFdpZHRoIHx8IGVsLm9mZnNldEhlaWdodCB8fCBlbC5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCk7XG4gIH1cbn1cblxudmFyIHRyYW5zaXRpb24kMSA9IHtcblxuICBwcmlvcml0eTogVFJBTlNJVElPTixcblxuICB1cGRhdGU6IGZ1bmN0aW9uIHVwZGF0ZShpZCwgb2xkSWQpIHtcbiAgICB2YXIgZWwgPSB0aGlzLmVsO1xuICAgIC8vIHJlc29sdmUgb24gb3duZXIgdm1cbiAgICB2YXIgaG9va3MgPSByZXNvbHZlQXNzZXQodGhpcy52bS4kb3B0aW9ucywgJ3RyYW5zaXRpb25zJywgaWQpO1xuICAgIGlkID0gaWQgfHwgJ3YnO1xuICAgIGVsLl9fdl90cmFucyA9IG5ldyBUcmFuc2l0aW9uKGVsLCBpZCwgaG9va3MsIHRoaXMudm0pO1xuICAgIGlmIChvbGRJZCkge1xuICAgICAgcmVtb3ZlQ2xhc3MoZWwsIG9sZElkICsgJy10cmFuc2l0aW9uJyk7XG4gICAgfVxuICAgIGFkZENsYXNzKGVsLCBpZCArICctdHJhbnNpdGlvbicpO1xuICB9XG59O1xuXG52YXIgaW50ZXJuYWxEaXJlY3RpdmVzID0ge1xuICBzdHlsZTogc3R5bGUsXG4gICdjbGFzcyc6IHZDbGFzcyxcbiAgY29tcG9uZW50OiBjb21wb25lbnQsXG4gIHByb3A6IHByb3BEZWYsXG4gIHRyYW5zaXRpb246IHRyYW5zaXRpb24kMVxufTtcblxudmFyIHByb3BCaW5kaW5nTW9kZXMgPSBjb25maWcuX3Byb3BCaW5kaW5nTW9kZXM7XG52YXIgZW1wdHkgPSB7fTtcblxuLy8gcmVnZXhlc1xudmFyIGlkZW50UkUkMSA9IC9eWyRfYS16QS1aXStbXFx3JF0qJC87XG52YXIgc2V0dGFibGVQYXRoUkUgPSAvXltBLVphLXpfJF1bXFx3JF0qKFxcLltBLVphLXpfJF1bXFx3JF0qfFxcW1teXFxbXFxdXStcXF0pKiQvO1xuXG4vKipcbiAqIENvbXBpbGUgcHJvcHMgb24gYSByb290IGVsZW1lbnQgYW5kIHJldHVyblxuICogYSBwcm9wcyBsaW5rIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudHxEb2N1bWVudEZyYWdtZW50fSBlbFxuICogQHBhcmFtIHtBcnJheX0gcHJvcE9wdGlvbnNcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBwcm9wc0xpbmtGblxuICovXG5cbmZ1bmN0aW9uIGNvbXBpbGVQcm9wcyhlbCwgcHJvcE9wdGlvbnMpIHtcbiAgdmFyIHByb3BzID0gW107XG4gIHZhciBuYW1lcyA9IE9iamVjdC5rZXlzKHByb3BPcHRpb25zKTtcbiAgdmFyIGkgPSBuYW1lcy5sZW5ndGg7XG4gIHZhciBvcHRpb25zLCBuYW1lLCBhdHRyLCB2YWx1ZSwgcGF0aCwgcGFyc2VkLCBwcm9wO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgbmFtZSA9IG5hbWVzW2ldO1xuICAgIG9wdGlvbnMgPSBwcm9wT3B0aW9uc1tuYW1lXSB8fCBlbXB0eTtcblxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIG5hbWUgPT09ICckZGF0YScpIHtcbiAgICAgIHdhcm4oJ0RvIG5vdCB1c2UgJGRhdGEgYXMgcHJvcC4nKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHByb3BzIGNvdWxkIGNvbnRhaW4gZGFzaGVzLCB3aGljaCB3aWxsIGJlXG4gICAgLy8gaW50ZXJwcmV0ZWQgYXMgbWludXMgY2FsY3VsYXRpb25zIGJ5IHRoZSBwYXJzZXJcbiAgICAvLyBzbyB3ZSBuZWVkIHRvIGNhbWVsaXplIHRoZSBwYXRoIGhlcmVcbiAgICBwYXRoID0gY2FtZWxpemUobmFtZSk7XG4gICAgaWYgKCFpZGVudFJFJDEudGVzdChwYXRoKSkge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKCdJbnZhbGlkIHByb3Aga2V5OiBcIicgKyBuYW1lICsgJ1wiLiBQcm9wIGtleXMgJyArICdtdXN0IGJlIHZhbGlkIGlkZW50aWZpZXJzLicpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgcHJvcCA9IHtcbiAgICAgIG5hbWU6IG5hbWUsXG4gICAgICBwYXRoOiBwYXRoLFxuICAgICAgb3B0aW9uczogb3B0aW9ucyxcbiAgICAgIG1vZGU6IHByb3BCaW5kaW5nTW9kZXMuT05FX1dBWSxcbiAgICAgIHJhdzogbnVsbFxuICAgIH07XG5cbiAgICBhdHRyID0gaHlwaGVuYXRlKG5hbWUpO1xuICAgIC8vIGZpcnN0IGNoZWNrIGR5bmFtaWMgdmVyc2lvblxuICAgIGlmICgodmFsdWUgPSBnZXRCaW5kQXR0cihlbCwgYXR0cikpID09PSBudWxsKSB7XG4gICAgICBpZiAoKHZhbHVlID0gZ2V0QmluZEF0dHIoZWwsIGF0dHIgKyAnLnN5bmMnKSkgIT09IG51bGwpIHtcbiAgICAgICAgcHJvcC5tb2RlID0gcHJvcEJpbmRpbmdNb2Rlcy5UV09fV0FZO1xuICAgICAgfSBlbHNlIGlmICgodmFsdWUgPSBnZXRCaW5kQXR0cihlbCwgYXR0ciArICcub25jZScpKSAhPT0gbnVsbCkge1xuICAgICAgICBwcm9wLm1vZGUgPSBwcm9wQmluZGluZ01vZGVzLk9ORV9USU1FO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcbiAgICAgIC8vIGhhcyBkeW5hbWljIGJpbmRpbmchXG4gICAgICBwcm9wLnJhdyA9IHZhbHVlO1xuICAgICAgcGFyc2VkID0gcGFyc2VEaXJlY3RpdmUodmFsdWUpO1xuICAgICAgdmFsdWUgPSBwYXJzZWQuZXhwcmVzc2lvbjtcbiAgICAgIHByb3AuZmlsdGVycyA9IHBhcnNlZC5maWx0ZXJzO1xuICAgICAgLy8gY2hlY2sgYmluZGluZyB0eXBlXG4gICAgICBpZiAoaXNMaXRlcmFsKHZhbHVlKSAmJiAhcGFyc2VkLmZpbHRlcnMpIHtcbiAgICAgICAgLy8gZm9yIGV4cHJlc3Npb25zIGNvbnRhaW5pbmcgbGl0ZXJhbCBudW1iZXJzIGFuZFxuICAgICAgICAvLyBib29sZWFucywgdGhlcmUncyBubyBuZWVkIHRvIHNldHVwIGEgcHJvcCBiaW5kaW5nLFxuICAgICAgICAvLyBzbyB3ZSBjYW4gb3B0aW1pemUgdGhlbSBhcyBhIG9uZS10aW1lIHNldC5cbiAgICAgICAgcHJvcC5vcHRpbWl6ZWRMaXRlcmFsID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByb3AuZHluYW1pYyA9IHRydWU7XG4gICAgICAgIC8vIGNoZWNrIG5vbi1zZXR0YWJsZSBwYXRoIGZvciB0d28td2F5IGJpbmRpbmdzXG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHByb3AubW9kZSA9PT0gcHJvcEJpbmRpbmdNb2Rlcy5UV09fV0FZICYmICFzZXR0YWJsZVBhdGhSRS50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgIHByb3AubW9kZSA9IHByb3BCaW5kaW5nTW9kZXMuT05FX1dBWTtcbiAgICAgICAgICB3YXJuKCdDYW5ub3QgYmluZCB0d28td2F5IHByb3Agd2l0aCBub24tc2V0dGFibGUgJyArICdwYXJlbnQgcGF0aDogJyArIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcHJvcC5wYXJlbnRQYXRoID0gdmFsdWU7XG5cbiAgICAgIC8vIHdhcm4gcmVxdWlyZWQgdHdvLXdheVxuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgb3B0aW9ucy50d29XYXkgJiYgcHJvcC5tb2RlICE9PSBwcm9wQmluZGluZ01vZGVzLlRXT19XQVkpIHtcbiAgICAgICAgd2FybignUHJvcCBcIicgKyBuYW1lICsgJ1wiIGV4cGVjdHMgYSB0d28td2F5IGJpbmRpbmcgdHlwZS4nKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCh2YWx1ZSA9IGdldEF0dHIoZWwsIGF0dHIpKSAhPT0gbnVsbCkge1xuICAgICAgLy8gaGFzIGxpdGVyYWwgYmluZGluZyFcbiAgICAgIHByb3AucmF3ID0gdmFsdWU7XG4gICAgfSBlbHNlIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAvLyBjaGVjayBwb3NzaWJsZSBjYW1lbENhc2UgcHJvcCB1c2FnZVxuICAgICAgdmFyIGxvd2VyQ2FzZU5hbWUgPSBwYXRoLnRvTG93ZXJDYXNlKCk7XG4gICAgICB2YWx1ZSA9IC9bQS1aXFwtXS8udGVzdChuYW1lKSAmJiAoZWwuZ2V0QXR0cmlidXRlKGxvd2VyQ2FzZU5hbWUpIHx8IGVsLmdldEF0dHJpYnV0ZSgnOicgKyBsb3dlckNhc2VOYW1lKSB8fCBlbC5nZXRBdHRyaWJ1dGUoJ3YtYmluZDonICsgbG93ZXJDYXNlTmFtZSkgfHwgZWwuZ2V0QXR0cmlidXRlKCc6JyArIGxvd2VyQ2FzZU5hbWUgKyAnLm9uY2UnKSB8fCBlbC5nZXRBdHRyaWJ1dGUoJ3YtYmluZDonICsgbG93ZXJDYXNlTmFtZSArICcub25jZScpIHx8IGVsLmdldEF0dHJpYnV0ZSgnOicgKyBsb3dlckNhc2VOYW1lICsgJy5zeW5jJykgfHwgZWwuZ2V0QXR0cmlidXRlKCd2LWJpbmQ6JyArIGxvd2VyQ2FzZU5hbWUgKyAnLnN5bmMnKSk7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgd2FybignUG9zc2libGUgdXNhZ2UgZXJyb3IgZm9yIHByb3AgYCcgKyBsb3dlckNhc2VOYW1lICsgJ2AgLSAnICsgJ2RpZCB5b3UgbWVhbiBgJyArIGF0dHIgKyAnYD8gSFRNTCBpcyBjYXNlLWluc2Vuc2l0aXZlLCByZW1lbWJlciB0byB1c2UgJyArICdrZWJhYi1jYXNlIGZvciBwcm9wcyBpbiB0ZW1wbGF0ZXMuJyk7XG4gICAgICB9IGVsc2UgaWYgKG9wdGlvbnMucmVxdWlyZWQpIHtcbiAgICAgICAgLy8gd2FybiBtaXNzaW5nIHJlcXVpcmVkXG4gICAgICAgIHdhcm4oJ01pc3NpbmcgcmVxdWlyZWQgcHJvcDogJyArIG5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBwdXNoIHByb3BcbiAgICBwcm9wcy5wdXNoKHByb3ApO1xuICB9XG4gIHJldHVybiBtYWtlUHJvcHNMaW5rRm4ocHJvcHMpO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEgZnVuY3Rpb24gdGhhdCBhcHBsaWVzIHByb3BzIHRvIGEgdm0uXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcHJvcHNcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBwcm9wc0xpbmtGblxuICovXG5cbmZ1bmN0aW9uIG1ha2VQcm9wc0xpbmtGbihwcm9wcykge1xuICByZXR1cm4gZnVuY3Rpb24gcHJvcHNMaW5rRm4odm0sIHNjb3BlKSB7XG4gICAgLy8gc3RvcmUgcmVzb2x2ZWQgcHJvcHMgaW5mb1xuICAgIHZtLl9wcm9wcyA9IHt9O1xuICAgIHZhciBpID0gcHJvcHMubGVuZ3RoO1xuICAgIHZhciBwcm9wLCBwYXRoLCBvcHRpb25zLCB2YWx1ZSwgcmF3O1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIHByb3AgPSBwcm9wc1tpXTtcbiAgICAgIHJhdyA9IHByb3AucmF3O1xuICAgICAgcGF0aCA9IHByb3AucGF0aDtcbiAgICAgIG9wdGlvbnMgPSBwcm9wLm9wdGlvbnM7XG4gICAgICB2bS5fcHJvcHNbcGF0aF0gPSBwcm9wO1xuICAgICAgaWYgKHJhdyA9PT0gbnVsbCkge1xuICAgICAgICAvLyBpbml0aWFsaXplIGFic2VudCBwcm9wXG4gICAgICAgIGluaXRQcm9wKHZtLCBwcm9wLCBnZXREZWZhdWx0KHZtLCBvcHRpb25zKSk7XG4gICAgICB9IGVsc2UgaWYgKHByb3AuZHluYW1pYykge1xuICAgICAgICAvLyBkeW5hbWljIHByb3BcbiAgICAgICAgaWYgKHByb3AubW9kZSA9PT0gcHJvcEJpbmRpbmdNb2Rlcy5PTkVfVElNRSkge1xuICAgICAgICAgIC8vIG9uZSB0aW1lIGJpbmRpbmdcbiAgICAgICAgICB2YWx1ZSA9IChzY29wZSB8fCB2bS5fY29udGV4dCB8fCB2bSkuJGdldChwcm9wLnBhcmVudFBhdGgpO1xuICAgICAgICAgIGluaXRQcm9wKHZtLCBwcm9wLCB2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHZtLl9jb250ZXh0KSB7XG4gICAgICAgICAgICAvLyBkeW5hbWljIGJpbmRpbmdcbiAgICAgICAgICAgIHZtLl9iaW5kRGlyKHtcbiAgICAgICAgICAgICAgbmFtZTogJ3Byb3AnLFxuICAgICAgICAgICAgICBkZWY6IHByb3BEZWYsXG4gICAgICAgICAgICAgIHByb3A6IHByb3BcbiAgICAgICAgICAgIH0sIG51bGwsIG51bGwsIHNjb3BlKTsgLy8gZWwsIGhvc3QsIHNjb3BlXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gcm9vdCBpbnN0YW5jZVxuICAgICAgICAgICAgICBpbml0UHJvcCh2bSwgcHJvcCwgdm0uJGdldChwcm9wLnBhcmVudFBhdGgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwcm9wLm9wdGltaXplZExpdGVyYWwpIHtcbiAgICAgICAgLy8gb3B0aW1pemVkIGxpdGVyYWwsIGNhc3QgaXQgYW5kIGp1c3Qgc2V0IG9uY2VcbiAgICAgICAgdmFyIHN0cmlwcGVkID0gc3RyaXBRdW90ZXMocmF3KTtcbiAgICAgICAgdmFsdWUgPSBzdHJpcHBlZCA9PT0gcmF3ID8gdG9Cb29sZWFuKHRvTnVtYmVyKHJhdykpIDogc3RyaXBwZWQ7XG4gICAgICAgIGluaXRQcm9wKHZtLCBwcm9wLCB2YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBzdHJpbmcgbGl0ZXJhbCwgYnV0IHdlIG5lZWQgdG8gY2F0ZXIgZm9yXG4gICAgICAgIC8vIEJvb2xlYW4gcHJvcHMgd2l0aCBubyB2YWx1ZVxuICAgICAgICB2YWx1ZSA9IG9wdGlvbnMudHlwZSA9PT0gQm9vbGVhbiAmJiByYXcgPT09ICcnID8gdHJ1ZSA6IHJhdztcbiAgICAgICAgaW5pdFByb3Aodm0sIHByb3AsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogR2V0IHRoZSBkZWZhdWx0IHZhbHVlIG9mIGEgcHJvcC5cbiAqXG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcmV0dXJuIHsqfVxuICovXG5cbmZ1bmN0aW9uIGdldERlZmF1bHQodm0sIG9wdGlvbnMpIHtcbiAgLy8gbm8gZGVmYXVsdCwgcmV0dXJuIHVuZGVmaW5lZFxuICBpZiAoIWhhc093bihvcHRpb25zLCAnZGVmYXVsdCcpKSB7XG4gICAgLy8gYWJzZW50IGJvb2xlYW4gdmFsdWUgZGVmYXVsdHMgdG8gZmFsc2VcbiAgICByZXR1cm4gb3B0aW9ucy50eXBlID09PSBCb29sZWFuID8gZmFsc2UgOiB1bmRlZmluZWQ7XG4gIH1cbiAgdmFyIGRlZiA9IG9wdGlvbnNbJ2RlZmF1bHQnXTtcbiAgLy8gd2FybiBhZ2FpbnN0IG5vbi1mYWN0b3J5IGRlZmF1bHRzIGZvciBPYmplY3QgJiBBcnJheVxuICBpZiAoaXNPYmplY3QoZGVmKSkge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybignT2JqZWN0L0FycmF5IGFzIGRlZmF1bHQgcHJvcCB2YWx1ZXMgd2lsbCBiZSBzaGFyZWQgJyArICdhY3Jvc3MgbXVsdGlwbGUgaW5zdGFuY2VzLiBVc2UgYSBmYWN0b3J5IGZ1bmN0aW9uICcgKyAndG8gcmV0dXJuIHRoZSBkZWZhdWx0IHZhbHVlIGluc3RlYWQuJyk7XG4gIH1cbiAgLy8gY2FsbCBmYWN0b3J5IGZ1bmN0aW9uIGZvciBub24tRnVuY3Rpb24gdHlwZXNcbiAgcmV0dXJuIHR5cGVvZiBkZWYgPT09ICdmdW5jdGlvbicgJiYgb3B0aW9ucy50eXBlICE9PSBGdW5jdGlvbiA/IGRlZi5jYWxsKHZtKSA6IGRlZjtcbn1cblxuLy8gc3BlY2lhbCBiaW5kaW5nIHByZWZpeGVzXG52YXIgYmluZFJFID0gL152LWJpbmQ6fF46LztcbnZhciBvblJFID0gL152LW9uOnxeQC87XG52YXIgZGlyQXR0clJFID0gL152LShbXjpdKykoPzokfDooLiopJCkvO1xudmFyIG1vZGlmaWVyUkUgPSAvXFwuW15cXC5dKy9nO1xudmFyIHRyYW5zaXRpb25SRSA9IC9eKHYtYmluZDp8Oik/dHJhbnNpdGlvbiQvO1xuXG4vLyB0ZXJtaW5hbCBkaXJlY3RpdmVzXG52YXIgdGVybWluYWxEaXJlY3RpdmVzID0gWydmb3InLCAnaWYnXTtcblxuLy8gZGVmYXVsdCBkaXJlY3RpdmUgcHJpb3JpdHlcbnZhciBERUZBVUxUX1BSSU9SSVRZID0gMTAwMDtcblxuLyoqXG4gKiBDb21waWxlIGEgdGVtcGxhdGUgYW5kIHJldHVybiBhIHJldXNhYmxlIGNvbXBvc2l0ZSBsaW5rXG4gKiBmdW5jdGlvbiwgd2hpY2ggcmVjdXJzaXZlbHkgY29udGFpbnMgbW9yZSBsaW5rIGZ1bmN0aW9uc1xuICogaW5zaWRlLiBUaGlzIHRvcCBsZXZlbCBjb21waWxlIGZ1bmN0aW9uIHdvdWxkIG5vcm1hbGx5XG4gKiBiZSBjYWxsZWQgb24gaW5zdGFuY2Ugcm9vdCBub2RlcywgYnV0IGNhbiBhbHNvIGJlIHVzZWRcbiAqIGZvciBwYXJ0aWFsIGNvbXBpbGF0aW9uIGlmIHRoZSBwYXJ0aWFsIGFyZ3VtZW50IGlzIHRydWUuXG4gKlxuICogVGhlIHJldHVybmVkIGNvbXBvc2l0ZSBsaW5rIGZ1bmN0aW9uLCB3aGVuIGNhbGxlZCwgd2lsbFxuICogcmV0dXJuIGFuIHVubGluayBmdW5jdGlvbiB0aGF0IHRlYXJzZG93biBhbGwgZGlyZWN0aXZlc1xuICogY3JlYXRlZCBkdXJpbmcgdGhlIGxpbmtpbmcgcGhhc2UuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fERvY3VtZW50RnJhZ21lbnR9IGVsXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtIHtCb29sZWFufSBwYXJ0aWFsXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5mdW5jdGlvbiBjb21waWxlKGVsLCBvcHRpb25zLCBwYXJ0aWFsKSB7XG4gIC8vIGxpbmsgZnVuY3Rpb24gZm9yIHRoZSBub2RlIGl0c2VsZi5cbiAgdmFyIG5vZGVMaW5rRm4gPSBwYXJ0aWFsIHx8ICFvcHRpb25zLl9hc0NvbXBvbmVudCA/IGNvbXBpbGVOb2RlKGVsLCBvcHRpb25zKSA6IG51bGw7XG4gIC8vIGxpbmsgZnVuY3Rpb24gZm9yIHRoZSBjaGlsZE5vZGVzXG4gIHZhciBjaGlsZExpbmtGbiA9ICEobm9kZUxpbmtGbiAmJiBub2RlTGlua0ZuLnRlcm1pbmFsKSAmJiBlbC50YWdOYW1lICE9PSAnU0NSSVBUJyAmJiBlbC5oYXNDaGlsZE5vZGVzKCkgPyBjb21waWxlTm9kZUxpc3QoZWwuY2hpbGROb2Rlcywgb3B0aW9ucykgOiBudWxsO1xuXG4gIC8qKlxuICAgKiBBIGNvbXBvc2l0ZSBsaW5rZXIgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIG9uIGEgYWxyZWFkeVxuICAgKiBjb21waWxlZCBwaWVjZSBvZiBET00sIHdoaWNoIGluc3RhbnRpYXRlcyBhbGwgZGlyZWN0aXZlXG4gICAqIGluc3RhbmNlcy5cbiAgICpcbiAgICogQHBhcmFtIHtWdWV9IHZtXG4gICAqIEBwYXJhbSB7RWxlbWVudHxEb2N1bWVudEZyYWdtZW50fSBlbFxuICAgKiBAcGFyYW0ge1Z1ZX0gW2hvc3RdIC0gaG9zdCB2bSBvZiB0cmFuc2NsdWRlZCBjb250ZW50XG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbc2NvcGVdIC0gdi1mb3Igc2NvcGVcbiAgICogQHBhcmFtIHtGcmFnbWVudH0gW2ZyYWddIC0gbGluayBjb250ZXh0IGZyYWdtZW50XG4gICAqIEByZXR1cm4ge0Z1bmN0aW9ufHVuZGVmaW5lZH1cbiAgICovXG5cbiAgcmV0dXJuIGZ1bmN0aW9uIGNvbXBvc2l0ZUxpbmtGbih2bSwgZWwsIGhvc3QsIHNjb3BlLCBmcmFnKSB7XG4gICAgLy8gY2FjaGUgY2hpbGROb2RlcyBiZWZvcmUgbGlua2luZyBwYXJlbnQsIGZpeCAjNjU3XG4gICAgdmFyIGNoaWxkTm9kZXMgPSB0b0FycmF5KGVsLmNoaWxkTm9kZXMpO1xuICAgIC8vIGxpbmtcbiAgICB2YXIgZGlycyA9IGxpbmtBbmRDYXB0dXJlKGZ1bmN0aW9uIGNvbXBvc2l0ZUxpbmtDYXB0dXJlcigpIHtcbiAgICAgIGlmIChub2RlTGlua0ZuKSBub2RlTGlua0ZuKHZtLCBlbCwgaG9zdCwgc2NvcGUsIGZyYWcpO1xuICAgICAgaWYgKGNoaWxkTGlua0ZuKSBjaGlsZExpbmtGbih2bSwgY2hpbGROb2RlcywgaG9zdCwgc2NvcGUsIGZyYWcpO1xuICAgIH0sIHZtKTtcbiAgICByZXR1cm4gbWFrZVVubGlua0ZuKHZtLCBkaXJzKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBBcHBseSBhIGxpbmtlciB0byBhIHZtL2VsZW1lbnQgcGFpciBhbmQgY2FwdHVyZSB0aGVcbiAqIGRpcmVjdGl2ZXMgY3JlYXRlZCBkdXJpbmcgdGhlIHByb2Nlc3MuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gbGlua2VyXG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqL1xuXG5mdW5jdGlvbiBsaW5rQW5kQ2FwdHVyZShsaW5rZXIsIHZtKSB7XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICAgIC8vIHJlc2V0IGRpcmVjdGl2ZXMgYmVmb3JlIGV2ZXJ5IGNhcHR1cmUgaW4gcHJvZHVjdGlvblxuICAgIC8vIG1vZGUsIHNvIHRoYXQgd2hlbiB1bmxpbmtpbmcgd2UgZG9uJ3QgbmVlZCB0byBzcGxpY2VcbiAgICAvLyB0aGVtIG91dCAod2hpY2ggdHVybnMgb3V0IHRvIGJlIGEgcGVyZiBoaXQpLlxuICAgIC8vIHRoZXkgYXJlIGtlcHQgaW4gZGV2ZWxvcG1lbnQgbW9kZSBiZWNhdXNlIHRoZXkgYXJlXG4gICAgLy8gdXNlZnVsIGZvciBWdWUncyBvd24gdGVzdHMuXG4gICAgdm0uX2RpcmVjdGl2ZXMgPSBbXTtcbiAgfVxuICB2YXIgb3JpZ2luYWxEaXJDb3VudCA9IHZtLl9kaXJlY3RpdmVzLmxlbmd0aDtcbiAgbGlua2VyKCk7XG4gIHZhciBkaXJzID0gdm0uX2RpcmVjdGl2ZXMuc2xpY2Uob3JpZ2luYWxEaXJDb3VudCk7XG4gIGRpcnMuc29ydChkaXJlY3RpdmVDb21wYXJhdG9yKTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBkaXJzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGRpcnNbaV0uX2JpbmQoKTtcbiAgfVxuICByZXR1cm4gZGlycztcbn1cblxuLyoqXG4gKiBEaXJlY3RpdmUgcHJpb3JpdHkgc29ydCBjb21wYXJhdG9yXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGFcbiAqIEBwYXJhbSB7T2JqZWN0fSBiXG4gKi9cblxuZnVuY3Rpb24gZGlyZWN0aXZlQ29tcGFyYXRvcihhLCBiKSB7XG4gIGEgPSBhLmRlc2NyaXB0b3IuZGVmLnByaW9yaXR5IHx8IERFRkFVTFRfUFJJT1JJVFk7XG4gIGIgPSBiLmRlc2NyaXB0b3IuZGVmLnByaW9yaXR5IHx8IERFRkFVTFRfUFJJT1JJVFk7XG4gIHJldHVybiBhID4gYiA/IC0xIDogYSA9PT0gYiA/IDAgOiAxO1xufVxuXG4vKipcbiAqIExpbmtlciBmdW5jdGlvbnMgcmV0dXJuIGFuIHVubGluayBmdW5jdGlvbiB0aGF0XG4gKiB0ZWFyc2Rvd24gYWxsIGRpcmVjdGl2ZXMgaW5zdGFuY2VzIGdlbmVyYXRlZCBkdXJpbmdcbiAqIHRoZSBwcm9jZXNzLlxuICpcbiAqIFdlIGNyZWF0ZSB1bmxpbmsgZnVuY3Rpb25zIHdpdGggb25seSB0aGUgbmVjZXNzYXJ5XG4gKiBpbmZvcm1hdGlvbiB0byBhdm9pZCByZXRhaW5pbmcgYWRkaXRpb25hbCBjbG9zdXJlcy5cbiAqXG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqIEBwYXJhbSB7QXJyYXl9IGRpcnNcbiAqIEBwYXJhbSB7VnVlfSBbY29udGV4dF1cbiAqIEBwYXJhbSB7QXJyYXl9IFtjb250ZXh0RGlyc11cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5cbmZ1bmN0aW9uIG1ha2VVbmxpbmtGbih2bSwgZGlycywgY29udGV4dCwgY29udGV4dERpcnMpIHtcbiAgZnVuY3Rpb24gdW5saW5rKGRlc3Ryb3lpbmcpIHtcbiAgICB0ZWFyZG93bkRpcnModm0sIGRpcnMsIGRlc3Ryb3lpbmcpO1xuICAgIGlmIChjb250ZXh0ICYmIGNvbnRleHREaXJzKSB7XG4gICAgICB0ZWFyZG93bkRpcnMoY29udGV4dCwgY29udGV4dERpcnMpO1xuICAgIH1cbiAgfVxuICAvLyBleHBvc2UgbGlua2VkIGRpcmVjdGl2ZXNcbiAgdW5saW5rLmRpcnMgPSBkaXJzO1xuICByZXR1cm4gdW5saW5rO1xufVxuXG4vKipcbiAqIFRlYXJkb3duIHBhcnRpYWwgbGlua2VkIGRpcmVjdGl2ZXMuXG4gKlxuICogQHBhcmFtIHtWdWV9IHZtXG4gKiBAcGFyYW0ge0FycmF5fSBkaXJzXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGRlc3Ryb3lpbmdcbiAqL1xuXG5mdW5jdGlvbiB0ZWFyZG93bkRpcnModm0sIGRpcnMsIGRlc3Ryb3lpbmcpIHtcbiAgdmFyIGkgPSBkaXJzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIGRpcnNbaV0uX3RlYXJkb3duKCk7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgIWRlc3Ryb3lpbmcpIHtcbiAgICAgIHZtLl9kaXJlY3RpdmVzLiRyZW1vdmUoZGlyc1tpXSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQ29tcGlsZSBsaW5rIHByb3BzIG9uIGFuIGluc3RhbmNlLlxuICpcbiAqIEBwYXJhbSB7VnVlfSB2bVxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtPYmplY3R9IHByb3BzXG4gKiBAcGFyYW0ge09iamVjdH0gW3Njb3BlXVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cblxuZnVuY3Rpb24gY29tcGlsZUFuZExpbmtQcm9wcyh2bSwgZWwsIHByb3BzLCBzY29wZSkge1xuICB2YXIgcHJvcHNMaW5rRm4gPSBjb21waWxlUHJvcHMoZWwsIHByb3BzKTtcbiAgdmFyIHByb3BEaXJzID0gbGlua0FuZENhcHR1cmUoZnVuY3Rpb24gKCkge1xuICAgIHByb3BzTGlua0ZuKHZtLCBzY29wZSk7XG4gIH0sIHZtKTtcbiAgcmV0dXJuIG1ha2VVbmxpbmtGbih2bSwgcHJvcERpcnMpO1xufVxuXG4vKipcbiAqIENvbXBpbGUgdGhlIHJvb3QgZWxlbWVudCBvZiBhbiBpbnN0YW5jZS5cbiAqXG4gKiAxLiBhdHRycyBvbiBjb250ZXh0IGNvbnRhaW5lciAoY29udGV4dCBzY29wZSlcbiAqIDIuIGF0dHJzIG9uIHRoZSBjb21wb25lbnQgdGVtcGxhdGUgcm9vdCBub2RlLCBpZlxuICogICAgcmVwbGFjZTp0cnVlIChjaGlsZCBzY29wZSlcbiAqXG4gKiBJZiB0aGlzIGlzIGEgZnJhZ21lbnQgaW5zdGFuY2UsIHdlIG9ubHkgbmVlZCB0byBjb21waWxlIDEuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0T3B0aW9uc1xuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cblxuZnVuY3Rpb24gY29tcGlsZVJvb3QoZWwsIG9wdGlvbnMsIGNvbnRleHRPcHRpb25zKSB7XG4gIHZhciBjb250YWluZXJBdHRycyA9IG9wdGlvbnMuX2NvbnRhaW5lckF0dHJzO1xuICB2YXIgcmVwbGFjZXJBdHRycyA9IG9wdGlvbnMuX3JlcGxhY2VyQXR0cnM7XG4gIHZhciBjb250ZXh0TGlua0ZuLCByZXBsYWNlckxpbmtGbjtcblxuICAvLyBvbmx5IG5lZWQgdG8gY29tcGlsZSBvdGhlciBhdHRyaWJ1dGVzIGZvclxuICAvLyBub24tZnJhZ21lbnQgaW5zdGFuY2VzXG4gIGlmIChlbC5ub2RlVHlwZSAhPT0gMTEpIHtcbiAgICAvLyBmb3IgY29tcG9uZW50cywgY29udGFpbmVyIGFuZCByZXBsYWNlciBuZWVkIHRvIGJlXG4gICAgLy8gY29tcGlsZWQgc2VwYXJhdGVseSBhbmQgbGlua2VkIGluIGRpZmZlcmVudCBzY29wZXMuXG4gICAgaWYgKG9wdGlvbnMuX2FzQ29tcG9uZW50KSB7XG4gICAgICAvLyAyLiBjb250YWluZXIgYXR0cmlidXRlc1xuICAgICAgaWYgKGNvbnRhaW5lckF0dHJzICYmIGNvbnRleHRPcHRpb25zKSB7XG4gICAgICAgIGNvbnRleHRMaW5rRm4gPSBjb21waWxlRGlyZWN0aXZlcyhjb250YWluZXJBdHRycywgY29udGV4dE9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgaWYgKHJlcGxhY2VyQXR0cnMpIHtcbiAgICAgICAgLy8gMy4gcmVwbGFjZXIgYXR0cmlidXRlc1xuICAgICAgICByZXBsYWNlckxpbmtGbiA9IGNvbXBpbGVEaXJlY3RpdmVzKHJlcGxhY2VyQXR0cnMsIG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBub24tY29tcG9uZW50LCBqdXN0IGNvbXBpbGUgYXMgYSBub3JtYWwgZWxlbWVudC5cbiAgICAgIHJlcGxhY2VyTGlua0ZuID0gY29tcGlsZURpcmVjdGl2ZXMoZWwuYXR0cmlidXRlcywgb3B0aW9ucyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgY29udGFpbmVyQXR0cnMpIHtcbiAgICAvLyB3YXJuIGNvbnRhaW5lciBkaXJlY3RpdmVzIGZvciBmcmFnbWVudCBpbnN0YW5jZXNcbiAgICB2YXIgbmFtZXMgPSBjb250YWluZXJBdHRycy5maWx0ZXIoZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgIC8vIGFsbG93IHZ1ZS1sb2FkZXIvdnVlaWZ5IHNjb3BlZCBjc3MgYXR0cmlidXRlc1xuICAgICAgcmV0dXJuIGF0dHIubmFtZS5pbmRleE9mKCdfdi0nKSA8IDAgJiZcbiAgICAgIC8vIGFsbG93IGV2ZW50IGxpc3RlbmVyc1xuICAgICAgIW9uUkUudGVzdChhdHRyLm5hbWUpICYmXG4gICAgICAvLyBhbGxvdyBzbG90c1xuICAgICAgYXR0ci5uYW1lICE9PSAnc2xvdCc7XG4gICAgfSkubWFwKGZ1bmN0aW9uIChhdHRyKSB7XG4gICAgICByZXR1cm4gJ1wiJyArIGF0dHIubmFtZSArICdcIic7XG4gICAgfSk7XG4gICAgaWYgKG5hbWVzLmxlbmd0aCkge1xuICAgICAgdmFyIHBsdXJhbCA9IG5hbWVzLmxlbmd0aCA+IDE7XG4gICAgICB3YXJuKCdBdHRyaWJ1dGUnICsgKHBsdXJhbCA/ICdzICcgOiAnICcpICsgbmFtZXMuam9pbignLCAnKSArIChwbHVyYWwgPyAnIGFyZScgOiAnIGlzJykgKyAnIGlnbm9yZWQgb24gY29tcG9uZW50ICcgKyAnPCcgKyBvcHRpb25zLmVsLnRhZ05hbWUudG9Mb3dlckNhc2UoKSArICc+IGJlY2F1c2UgJyArICd0aGUgY29tcG9uZW50IGlzIGEgZnJhZ21lbnQgaW5zdGFuY2U6ICcgKyAnaHR0cDovL3Z1ZWpzLm9yZy9ndWlkZS9jb21wb25lbnRzLmh0bWwjRnJhZ21lbnRfSW5zdGFuY2UnKTtcbiAgICB9XG4gIH1cblxuICBvcHRpb25zLl9jb250YWluZXJBdHRycyA9IG9wdGlvbnMuX3JlcGxhY2VyQXR0cnMgPSBudWxsO1xuICByZXR1cm4gZnVuY3Rpb24gcm9vdExpbmtGbih2bSwgZWwsIHNjb3BlKSB7XG4gICAgLy8gbGluayBjb250ZXh0IHNjb3BlIGRpcnNcbiAgICB2YXIgY29udGV4dCA9IHZtLl9jb250ZXh0O1xuICAgIHZhciBjb250ZXh0RGlycztcbiAgICBpZiAoY29udGV4dCAmJiBjb250ZXh0TGlua0ZuKSB7XG4gICAgICBjb250ZXh0RGlycyA9IGxpbmtBbmRDYXB0dXJlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29udGV4dExpbmtGbihjb250ZXh0LCBlbCwgbnVsbCwgc2NvcGUpO1xuICAgICAgfSwgY29udGV4dCk7XG4gICAgfVxuXG4gICAgLy8gbGluayBzZWxmXG4gICAgdmFyIHNlbGZEaXJzID0gbGlua0FuZENhcHR1cmUoZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHJlcGxhY2VyTGlua0ZuKSByZXBsYWNlckxpbmtGbih2bSwgZWwpO1xuICAgIH0sIHZtKTtcblxuICAgIC8vIHJldHVybiB0aGUgdW5saW5rIGZ1bmN0aW9uIHRoYXQgdGVhcnNkb3duIGNvbnRleHRcbiAgICAvLyBjb250YWluZXIgZGlyZWN0aXZlcy5cbiAgICByZXR1cm4gbWFrZVVubGlua0ZuKHZtLCBzZWxmRGlycywgY29udGV4dCwgY29udGV4dERpcnMpO1xuICB9O1xufVxuXG4vKipcbiAqIENvbXBpbGUgYSBub2RlIGFuZCByZXR1cm4gYSBub2RlTGlua0ZuIGJhc2VkIG9uIHRoZVxuICogbm9kZSB0eXBlLlxuICpcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufG51bGx9XG4gKi9cblxuZnVuY3Rpb24gY29tcGlsZU5vZGUobm9kZSwgb3B0aW9ucykge1xuICB2YXIgdHlwZSA9IG5vZGUubm9kZVR5cGU7XG4gIGlmICh0eXBlID09PSAxICYmIG5vZGUudGFnTmFtZSAhPT0gJ1NDUklQVCcpIHtcbiAgICByZXR1cm4gY29tcGlsZUVsZW1lbnQobm9kZSwgb3B0aW9ucyk7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gMyAmJiBub2RlLmRhdGEudHJpbSgpKSB7XG4gICAgcmV0dXJuIGNvbXBpbGVUZXh0Tm9kZShub2RlLCBvcHRpb25zKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG4vKipcbiAqIENvbXBpbGUgYW4gZWxlbWVudCBhbmQgcmV0dXJuIGEgbm9kZUxpbmtGbi5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHJldHVybiB7RnVuY3Rpb258bnVsbH1cbiAqL1xuXG5mdW5jdGlvbiBjb21waWxlRWxlbWVudChlbCwgb3B0aW9ucykge1xuICAvLyBwcmVwcm9jZXNzIHRleHRhcmVhcy5cbiAgLy8gdGV4dGFyZWEgdHJlYXRzIGl0cyB0ZXh0IGNvbnRlbnQgYXMgdGhlIGluaXRpYWwgdmFsdWUuXG4gIC8vIGp1c3QgYmluZCBpdCBhcyBhbiBhdHRyIGRpcmVjdGl2ZSBmb3IgdmFsdWUuXG4gIGlmIChlbC50YWdOYW1lID09PSAnVEVYVEFSRUEnKSB7XG4gICAgdmFyIHRva2VucyA9IHBhcnNlVGV4dChlbC52YWx1ZSk7XG4gICAgaWYgKHRva2Vucykge1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCc6dmFsdWUnLCB0b2tlbnNUb0V4cCh0b2tlbnMpKTtcbiAgICAgIGVsLnZhbHVlID0gJyc7XG4gICAgfVxuICB9XG4gIHZhciBsaW5rRm47XG4gIHZhciBoYXNBdHRycyA9IGVsLmhhc0F0dHJpYnV0ZXMoKTtcbiAgLy8gY2hlY2sgdGVybWluYWwgZGlyZWN0aXZlcyAoZm9yICYgaWYpXG4gIGlmIChoYXNBdHRycykge1xuICAgIGxpbmtGbiA9IGNoZWNrVGVybWluYWxEaXJlY3RpdmVzKGVsLCBvcHRpb25zKTtcbiAgfVxuICAvLyBjaGVjayBlbGVtZW50IGRpcmVjdGl2ZXNcbiAgaWYgKCFsaW5rRm4pIHtcbiAgICBsaW5rRm4gPSBjaGVja0VsZW1lbnREaXJlY3RpdmVzKGVsLCBvcHRpb25zKTtcbiAgfVxuICAvLyBjaGVjayBjb21wb25lbnRcbiAgaWYgKCFsaW5rRm4pIHtcbiAgICBsaW5rRm4gPSBjaGVja0NvbXBvbmVudChlbCwgb3B0aW9ucyk7XG4gIH1cbiAgLy8gbm9ybWFsIGRpcmVjdGl2ZXNcbiAgaWYgKCFsaW5rRm4gJiYgaGFzQXR0cnMpIHtcbiAgICBsaW5rRm4gPSBjb21waWxlRGlyZWN0aXZlcyhlbC5hdHRyaWJ1dGVzLCBvcHRpb25zKTtcbiAgfVxuICByZXR1cm4gbGlua0ZuO1xufVxuXG4vKipcbiAqIENvbXBpbGUgYSB0ZXh0Tm9kZSBhbmQgcmV0dXJuIGEgbm9kZUxpbmtGbi5cbiAqXG4gKiBAcGFyYW0ge1RleHROb2RlfSBub2RlXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHJldHVybiB7RnVuY3Rpb258bnVsbH0gdGV4dE5vZGVMaW5rRm5cbiAqL1xuXG5mdW5jdGlvbiBjb21waWxlVGV4dE5vZGUobm9kZSwgb3B0aW9ucykge1xuICAvLyBza2lwIG1hcmtlZCB0ZXh0IG5vZGVzXG4gIGlmIChub2RlLl9za2lwKSB7XG4gICAgcmV0dXJuIHJlbW92ZVRleHQ7XG4gIH1cblxuICB2YXIgdG9rZW5zID0gcGFyc2VUZXh0KG5vZGUud2hvbGVUZXh0KTtcbiAgaWYgKCF0b2tlbnMpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIG1hcmsgYWRqYWNlbnQgdGV4dCBub2RlcyBhcyBza2lwcGVkLFxuICAvLyBiZWNhdXNlIHdlIGFyZSB1c2luZyBub2RlLndob2xlVGV4dCB0byBjb21waWxlXG4gIC8vIGFsbCBhZGphY2VudCB0ZXh0IG5vZGVzIHRvZ2V0aGVyLiBUaGlzIGZpeGVzXG4gIC8vIGlzc3VlcyBpbiBJRSB3aGVyZSBzb21ldGltZXMgaXQgc3BsaXRzIHVwIGEgc2luZ2xlXG4gIC8vIHRleHQgbm9kZSBpbnRvIG11bHRpcGxlIG9uZXMuXG4gIHZhciBuZXh0ID0gbm9kZS5uZXh0U2libGluZztcbiAgd2hpbGUgKG5leHQgJiYgbmV4dC5ub2RlVHlwZSA9PT0gMykge1xuICAgIG5leHQuX3NraXAgPSB0cnVlO1xuICAgIG5leHQgPSBuZXh0Lm5leHRTaWJsaW5nO1xuICB9XG5cbiAgdmFyIGZyYWcgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gIHZhciBlbCwgdG9rZW47XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdG9rZW5zLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIHRva2VuID0gdG9rZW5zW2ldO1xuICAgIGVsID0gdG9rZW4udGFnID8gcHJvY2Vzc1RleHRUb2tlbih0b2tlbiwgb3B0aW9ucykgOiBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0b2tlbi52YWx1ZSk7XG4gICAgZnJhZy5hcHBlbmRDaGlsZChlbCk7XG4gIH1cbiAgcmV0dXJuIG1ha2VUZXh0Tm9kZUxpbmtGbih0b2tlbnMsIGZyYWcsIG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIExpbmtlciBmb3IgYW4gc2tpcHBlZCB0ZXh0IG5vZGUuXG4gKlxuICogQHBhcmFtIHtWdWV9IHZtXG4gKiBAcGFyYW0ge1RleHR9IG5vZGVcbiAqL1xuXG5mdW5jdGlvbiByZW1vdmVUZXh0KHZtLCBub2RlKSB7XG4gIHJlbW92ZShub2RlKTtcbn1cblxuLyoqXG4gKiBQcm9jZXNzIGEgc2luZ2xlIHRleHQgdG9rZW4uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHRva2VuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHJldHVybiB7Tm9kZX1cbiAqL1xuXG5mdW5jdGlvbiBwcm9jZXNzVGV4dFRva2VuKHRva2VuLCBvcHRpb25zKSB7XG4gIHZhciBlbDtcbiAgaWYgKHRva2VuLm9uZVRpbWUpIHtcbiAgICBlbCA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRva2VuLnZhbHVlKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAodG9rZW4uaHRtbCkge1xuICAgICAgZWwgPSBkb2N1bWVudC5jcmVhdGVDb21tZW50KCd2LWh0bWwnKTtcbiAgICAgIHNldFRva2VuVHlwZSgnaHRtbCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJRSB3aWxsIGNsZWFuIHVwIGVtcHR5IHRleHROb2RlcyBkdXJpbmdcbiAgICAgIC8vIGZyYWcuY2xvbmVOb2RlKHRydWUpLCBzbyB3ZSBoYXZlIHRvIGdpdmUgaXRcbiAgICAgIC8vIHNvbWV0aGluZyBoZXJlLi4uXG4gICAgICBlbCA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcgJyk7XG4gICAgICBzZXRUb2tlblR5cGUoJ3RleHQnKTtcbiAgICB9XG4gIH1cbiAgZnVuY3Rpb24gc2V0VG9rZW5UeXBlKHR5cGUpIHtcbiAgICBpZiAodG9rZW4uZGVzY3JpcHRvcikgcmV0dXJuO1xuICAgIHZhciBwYXJzZWQgPSBwYXJzZURpcmVjdGl2ZSh0b2tlbi52YWx1ZSk7XG4gICAgdG9rZW4uZGVzY3JpcHRvciA9IHtcbiAgICAgIG5hbWU6IHR5cGUsXG4gICAgICBkZWY6IGRpcmVjdGl2ZXNbdHlwZV0sXG4gICAgICBleHByZXNzaW9uOiBwYXJzZWQuZXhwcmVzc2lvbixcbiAgICAgIGZpbHRlcnM6IHBhcnNlZC5maWx0ZXJzXG4gICAgfTtcbiAgfVxuICByZXR1cm4gZWw7XG59XG5cbi8qKlxuICogQnVpbGQgYSBmdW5jdGlvbiB0aGF0IHByb2Nlc3NlcyBhIHRleHROb2RlLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gdG9rZW5zXG4gKiBAcGFyYW0ge0RvY3VtZW50RnJhZ21lbnR9IGZyYWdcbiAqL1xuXG5mdW5jdGlvbiBtYWtlVGV4dE5vZGVMaW5rRm4odG9rZW5zLCBmcmFnKSB7XG4gIHJldHVybiBmdW5jdGlvbiB0ZXh0Tm9kZUxpbmtGbih2bSwgZWwsIGhvc3QsIHNjb3BlKSB7XG4gICAgdmFyIGZyYWdDbG9uZSA9IGZyYWcuY2xvbmVOb2RlKHRydWUpO1xuICAgIHZhciBjaGlsZE5vZGVzID0gdG9BcnJheShmcmFnQ2xvbmUuY2hpbGROb2Rlcyk7XG4gICAgdmFyIHRva2VuLCB2YWx1ZSwgbm9kZTtcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRva2Vucy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHRva2VuID0gdG9rZW5zW2ldO1xuICAgICAgdmFsdWUgPSB0b2tlbi52YWx1ZTtcbiAgICAgIGlmICh0b2tlbi50YWcpIHtcbiAgICAgICAgbm9kZSA9IGNoaWxkTm9kZXNbaV07XG4gICAgICAgIGlmICh0b2tlbi5vbmVUaW1lKSB7XG4gICAgICAgICAgdmFsdWUgPSAoc2NvcGUgfHwgdm0pLiRldmFsKHZhbHVlKTtcbiAgICAgICAgICBpZiAodG9rZW4uaHRtbCkge1xuICAgICAgICAgICAgcmVwbGFjZShub2RlLCBwYXJzZVRlbXBsYXRlKHZhbHVlLCB0cnVlKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG5vZGUuZGF0YSA9IHZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2bS5fYmluZERpcih0b2tlbi5kZXNjcmlwdG9yLCBub2RlLCBob3N0LCBzY29wZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmVwbGFjZShlbCwgZnJhZ0Nsb25lKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBDb21waWxlIGEgbm9kZSBsaXN0IGFuZCByZXR1cm4gYSBjaGlsZExpbmtGbi5cbiAqXG4gKiBAcGFyYW0ge05vZGVMaXN0fSBub2RlTGlzdFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufHVuZGVmaW5lZH1cbiAqL1xuXG5mdW5jdGlvbiBjb21waWxlTm9kZUxpc3Qobm9kZUxpc3QsIG9wdGlvbnMpIHtcbiAgdmFyIGxpbmtGbnMgPSBbXTtcbiAgdmFyIG5vZGVMaW5rRm4sIGNoaWxkTGlua0ZuLCBub2RlO1xuICBmb3IgKHZhciBpID0gMCwgbCA9IG5vZGVMaXN0Lmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIG5vZGUgPSBub2RlTGlzdFtpXTtcbiAgICBub2RlTGlua0ZuID0gY29tcGlsZU5vZGUobm9kZSwgb3B0aW9ucyk7XG4gICAgY2hpbGRMaW5rRm4gPSAhKG5vZGVMaW5rRm4gJiYgbm9kZUxpbmtGbi50ZXJtaW5hbCkgJiYgbm9kZS50YWdOYW1lICE9PSAnU0NSSVBUJyAmJiBub2RlLmhhc0NoaWxkTm9kZXMoKSA/IGNvbXBpbGVOb2RlTGlzdChub2RlLmNoaWxkTm9kZXMsIG9wdGlvbnMpIDogbnVsbDtcbiAgICBsaW5rRm5zLnB1c2gobm9kZUxpbmtGbiwgY2hpbGRMaW5rRm4pO1xuICB9XG4gIHJldHVybiBsaW5rRm5zLmxlbmd0aCA/IG1ha2VDaGlsZExpbmtGbihsaW5rRm5zKSA6IG51bGw7XG59XG5cbi8qKlxuICogTWFrZSBhIGNoaWxkIGxpbmsgZnVuY3Rpb24gZm9yIGEgbm9kZSdzIGNoaWxkTm9kZXMuXG4gKlxuICogQHBhcmFtIHtBcnJheTxGdW5jdGlvbj59IGxpbmtGbnNcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBjaGlsZExpbmtGblxuICovXG5cbmZ1bmN0aW9uIG1ha2VDaGlsZExpbmtGbihsaW5rRm5zKSB7XG4gIHJldHVybiBmdW5jdGlvbiBjaGlsZExpbmtGbih2bSwgbm9kZXMsIGhvc3QsIHNjb3BlLCBmcmFnKSB7XG4gICAgdmFyIG5vZGUsIG5vZGVMaW5rRm4sIGNoaWxkcmVuTGlua0ZuO1xuICAgIGZvciAodmFyIGkgPSAwLCBuID0gMCwgbCA9IGxpbmtGbnMubGVuZ3RoOyBpIDwgbDsgbisrKSB7XG4gICAgICBub2RlID0gbm9kZXNbbl07XG4gICAgICBub2RlTGlua0ZuID0gbGlua0Zuc1tpKytdO1xuICAgICAgY2hpbGRyZW5MaW5rRm4gPSBsaW5rRm5zW2krK107XG4gICAgICAvLyBjYWNoZSBjaGlsZE5vZGVzIGJlZm9yZSBsaW5raW5nIHBhcmVudCwgZml4ICM2NTdcbiAgICAgIHZhciBjaGlsZE5vZGVzID0gdG9BcnJheShub2RlLmNoaWxkTm9kZXMpO1xuICAgICAgaWYgKG5vZGVMaW5rRm4pIHtcbiAgICAgICAgbm9kZUxpbmtGbih2bSwgbm9kZSwgaG9zdCwgc2NvcGUsIGZyYWcpO1xuICAgICAgfVxuICAgICAgaWYgKGNoaWxkcmVuTGlua0ZuKSB7XG4gICAgICAgIGNoaWxkcmVuTGlua0ZuKHZtLCBjaGlsZE5vZGVzLCBob3N0LCBzY29wZSwgZnJhZyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIENoZWNrIGZvciBlbGVtZW50IGRpcmVjdGl2ZXMgKGN1c3RvbSBlbGVtZW50cyB0aGF0IHNob3VsZFxuICogYmUgcmVzb3ZsZWQgYXMgdGVybWluYWwgZGlyZWN0aXZlcykuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqL1xuXG5mdW5jdGlvbiBjaGVja0VsZW1lbnREaXJlY3RpdmVzKGVsLCBvcHRpb25zKSB7XG4gIHZhciB0YWcgPSBlbC50YWdOYW1lLnRvTG93ZXJDYXNlKCk7XG4gIGlmIChjb21tb25UYWdSRS50ZXN0KHRhZykpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGRlZiA9IHJlc29sdmVBc3NldChvcHRpb25zLCAnZWxlbWVudERpcmVjdGl2ZXMnLCB0YWcpO1xuICBpZiAoZGVmKSB7XG4gICAgcmV0dXJuIG1ha2VUZXJtaW5hbE5vZGVMaW5rRm4oZWwsIHRhZywgJycsIG9wdGlvbnMsIGRlZik7XG4gIH1cbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhbiBlbGVtZW50IGlzIGEgY29tcG9uZW50LiBJZiB5ZXMsIHJldHVyblxuICogYSBjb21wb25lbnQgbGluayBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHJldHVybiB7RnVuY3Rpb258dW5kZWZpbmVkfVxuICovXG5cbmZ1bmN0aW9uIGNoZWNrQ29tcG9uZW50KGVsLCBvcHRpb25zKSB7XG4gIHZhciBjb21wb25lbnQgPSBjaGVja0NvbXBvbmVudEF0dHIoZWwsIG9wdGlvbnMpO1xuICBpZiAoY29tcG9uZW50KSB7XG4gICAgdmFyIHJlZiA9IGZpbmRSZWYoZWwpO1xuICAgIHZhciBkZXNjcmlwdG9yID0ge1xuICAgICAgbmFtZTogJ2NvbXBvbmVudCcsXG4gICAgICByZWY6IHJlZixcbiAgICAgIGV4cHJlc3Npb246IGNvbXBvbmVudC5pZCxcbiAgICAgIGRlZjogaW50ZXJuYWxEaXJlY3RpdmVzLmNvbXBvbmVudCxcbiAgICAgIG1vZGlmaWVyczoge1xuICAgICAgICBsaXRlcmFsOiAhY29tcG9uZW50LmR5bmFtaWNcbiAgICAgIH1cbiAgICB9O1xuICAgIHZhciBjb21wb25lbnRMaW5rRm4gPSBmdW5jdGlvbiBjb21wb25lbnRMaW5rRm4odm0sIGVsLCBob3N0LCBzY29wZSwgZnJhZykge1xuICAgICAgaWYgKHJlZikge1xuICAgICAgICBkZWZpbmVSZWFjdGl2ZSgoc2NvcGUgfHwgdm0pLiRyZWZzLCByZWYsIG51bGwpO1xuICAgICAgfVxuICAgICAgdm0uX2JpbmREaXIoZGVzY3JpcHRvciwgZWwsIGhvc3QsIHNjb3BlLCBmcmFnKTtcbiAgICB9O1xuICAgIGNvbXBvbmVudExpbmtGbi50ZXJtaW5hbCA9IHRydWU7XG4gICAgcmV0dXJuIGNvbXBvbmVudExpbmtGbjtcbiAgfVxufVxuXG4vKipcbiAqIENoZWNrIGFuIGVsZW1lbnQgZm9yIHRlcm1pbmFsIGRpcmVjdGl2ZXMgaW4gZml4ZWQgb3JkZXIuXG4gKiBJZiBpdCBmaW5kcyBvbmUsIHJldHVybiBhIHRlcm1pbmFsIGxpbmsgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSB0ZXJtaW5hbExpbmtGblxuICovXG5cbmZ1bmN0aW9uIGNoZWNrVGVybWluYWxEaXJlY3RpdmVzKGVsLCBvcHRpb25zKSB7XG4gIC8vIHNraXAgdi1wcmVcbiAgaWYgKGdldEF0dHIoZWwsICd2LXByZScpICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIHNraXA7XG4gIH1cbiAgLy8gc2tpcCB2LWVsc2UgYmxvY2ssIGJ1dCBvbmx5IGlmIGZvbGxvd2luZyB2LWlmXG4gIGlmIChlbC5oYXNBdHRyaWJ1dGUoJ3YtZWxzZScpKSB7XG4gICAgdmFyIHByZXYgPSBlbC5wcmV2aW91c0VsZW1lbnRTaWJsaW5nO1xuICAgIGlmIChwcmV2ICYmIHByZXYuaGFzQXR0cmlidXRlKCd2LWlmJykpIHtcbiAgICAgIHJldHVybiBza2lwO1xuICAgIH1cbiAgfVxuICB2YXIgdmFsdWUsIGRpck5hbWU7XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdGVybWluYWxEaXJlY3RpdmVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGRpck5hbWUgPSB0ZXJtaW5hbERpcmVjdGl2ZXNbaV07XG4gICAgdmFsdWUgPSBlbC5nZXRBdHRyaWJ1dGUoJ3YtJyArIGRpck5hbWUpO1xuICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gbWFrZVRlcm1pbmFsTm9kZUxpbmtGbihlbCwgZGlyTmFtZSwgdmFsdWUsIG9wdGlvbnMpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBza2lwKCkge31cbnNraXAudGVybWluYWwgPSB0cnVlO1xuXG4vKipcbiAqIEJ1aWxkIGEgbm9kZSBsaW5rIGZ1bmN0aW9uIGZvciBhIHRlcm1pbmFsIGRpcmVjdGl2ZS5cbiAqIEEgdGVybWluYWwgbGluayBmdW5jdGlvbiB0ZXJtaW5hdGVzIHRoZSBjdXJyZW50XG4gKiBjb21waWxhdGlvbiByZWN1cnNpb24gYW5kIGhhbmRsZXMgY29tcGlsYXRpb24gb2YgdGhlXG4gKiBzdWJ0cmVlIGluIHRoZSBkaXJlY3RpdmUuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtTdHJpbmd9IGRpck5hbWVcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBbZGVmXVxuICogQHJldHVybiB7RnVuY3Rpb259IHRlcm1pbmFsTGlua0ZuXG4gKi9cblxuZnVuY3Rpb24gbWFrZVRlcm1pbmFsTm9kZUxpbmtGbihlbCwgZGlyTmFtZSwgdmFsdWUsIG9wdGlvbnMsIGRlZikge1xuICB2YXIgcGFyc2VkID0gcGFyc2VEaXJlY3RpdmUodmFsdWUpO1xuICB2YXIgZGVzY3JpcHRvciA9IHtcbiAgICBuYW1lOiBkaXJOYW1lLFxuICAgIGV4cHJlc3Npb246IHBhcnNlZC5leHByZXNzaW9uLFxuICAgIGZpbHRlcnM6IHBhcnNlZC5maWx0ZXJzLFxuICAgIHJhdzogdmFsdWUsXG4gICAgLy8gZWl0aGVyIGFuIGVsZW1lbnQgZGlyZWN0aXZlLCBvciBpZi9mb3JcbiAgICAvLyAjMjM2NiBvciBjdXN0b20gdGVybWluYWwgZGlyZWN0aXZlXG4gICAgZGVmOiBkZWYgfHwgcmVzb2x2ZUFzc2V0KG9wdGlvbnMsICdkaXJlY3RpdmVzJywgZGlyTmFtZSlcbiAgfTtcbiAgLy8gY2hlY2sgcmVmIGZvciB2LWZvciBhbmQgcm91dGVyLXZpZXdcbiAgaWYgKGRpck5hbWUgPT09ICdmb3InIHx8IGRpck5hbWUgPT09ICdyb3V0ZXItdmlldycpIHtcbiAgICBkZXNjcmlwdG9yLnJlZiA9IGZpbmRSZWYoZWwpO1xuICB9XG4gIHZhciBmbiA9IGZ1bmN0aW9uIHRlcm1pbmFsTm9kZUxpbmtGbih2bSwgZWwsIGhvc3QsIHNjb3BlLCBmcmFnKSB7XG4gICAgaWYgKGRlc2NyaXB0b3IucmVmKSB7XG4gICAgICBkZWZpbmVSZWFjdGl2ZSgoc2NvcGUgfHwgdm0pLiRyZWZzLCBkZXNjcmlwdG9yLnJlZiwgbnVsbCk7XG4gICAgfVxuICAgIHZtLl9iaW5kRGlyKGRlc2NyaXB0b3IsIGVsLCBob3N0LCBzY29wZSwgZnJhZyk7XG4gIH07XG4gIGZuLnRlcm1pbmFsID0gdHJ1ZTtcbiAgcmV0dXJuIGZuO1xufVxuXG4vKipcbiAqIENvbXBpbGUgdGhlIGRpcmVjdGl2ZXMgb24gYW4gZWxlbWVudCBhbmQgcmV0dXJuIGEgbGlua2VyLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl8TmFtZWROb2RlTWFwfSBhdHRyc1xuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5cbmZ1bmN0aW9uIGNvbXBpbGVEaXJlY3RpdmVzKGF0dHJzLCBvcHRpb25zKSB7XG4gIHZhciBpID0gYXR0cnMubGVuZ3RoO1xuICB2YXIgZGlycyA9IFtdO1xuICB2YXIgYXR0ciwgbmFtZSwgdmFsdWUsIHJhd05hbWUsIHJhd1ZhbHVlLCBkaXJOYW1lLCBhcmcsIG1vZGlmaWVycywgZGlyRGVmLCB0b2tlbnMsIG1hdGNoZWQ7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBhdHRyID0gYXR0cnNbaV07XG4gICAgbmFtZSA9IHJhd05hbWUgPSBhdHRyLm5hbWU7XG4gICAgdmFsdWUgPSByYXdWYWx1ZSA9IGF0dHIudmFsdWU7XG4gICAgdG9rZW5zID0gcGFyc2VUZXh0KHZhbHVlKTtcbiAgICAvLyByZXNldCBhcmdcbiAgICBhcmcgPSBudWxsO1xuICAgIC8vIGNoZWNrIG1vZGlmaWVyc1xuICAgIG1vZGlmaWVycyA9IHBhcnNlTW9kaWZpZXJzKG5hbWUpO1xuICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UobW9kaWZpZXJSRSwgJycpO1xuXG4gICAgLy8gYXR0cmlidXRlIGludGVycG9sYXRpb25zXG4gICAgaWYgKHRva2Vucykge1xuICAgICAgdmFsdWUgPSB0b2tlbnNUb0V4cCh0b2tlbnMpO1xuICAgICAgYXJnID0gbmFtZTtcbiAgICAgIHB1c2hEaXIoJ2JpbmQnLCBkaXJlY3RpdmVzLmJpbmQsIHRva2Vucyk7XG4gICAgICAvLyB3YXJuIGFnYWluc3QgbWl4aW5nIG11c3RhY2hlcyB3aXRoIHYtYmluZFxuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgaWYgKG5hbWUgPT09ICdjbGFzcycgJiYgQXJyYXkucHJvdG90eXBlLnNvbWUuY2FsbChhdHRycywgZnVuY3Rpb24gKGF0dHIpIHtcbiAgICAgICAgICByZXR1cm4gYXR0ci5uYW1lID09PSAnOmNsYXNzJyB8fCBhdHRyLm5hbWUgPT09ICd2LWJpbmQ6Y2xhc3MnO1xuICAgICAgICB9KSkge1xuICAgICAgICAgIHdhcm4oJ2NsYXNzPVwiJyArIHJhd1ZhbHVlICsgJ1wiOiBEbyBub3QgbWl4IG11c3RhY2hlIGludGVycG9sYXRpb24gJyArICdhbmQgdi1iaW5kIGZvciBcImNsYXNzXCIgb24gdGhlIHNhbWUgZWxlbWVudC4gVXNlIG9uZSBvciB0aGUgb3RoZXIuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2VcblxuICAgICAgLy8gc3BlY2lhbCBhdHRyaWJ1dGU6IHRyYW5zaXRpb25cbiAgICAgIGlmICh0cmFuc2l0aW9uUkUudGVzdChuYW1lKSkge1xuICAgICAgICBtb2RpZmllcnMubGl0ZXJhbCA9ICFiaW5kUkUudGVzdChuYW1lKTtcbiAgICAgICAgcHVzaERpcigndHJhbnNpdGlvbicsIGludGVybmFsRGlyZWN0aXZlcy50cmFuc2l0aW9uKTtcbiAgICAgIH0gZWxzZVxuXG4gICAgICAgIC8vIGV2ZW50IGhhbmRsZXJzXG4gICAgICAgIGlmIChvblJFLnRlc3QobmFtZSkpIHtcbiAgICAgICAgICBhcmcgPSBuYW1lLnJlcGxhY2Uob25SRSwgJycpO1xuICAgICAgICAgIHB1c2hEaXIoJ29uJywgZGlyZWN0aXZlcy5vbik7XG4gICAgICAgIH0gZWxzZVxuXG4gICAgICAgICAgLy8gYXR0cmlidXRlIGJpbmRpbmdzXG4gICAgICAgICAgaWYgKGJpbmRSRS50ZXN0KG5hbWUpKSB7XG4gICAgICAgICAgICBkaXJOYW1lID0gbmFtZS5yZXBsYWNlKGJpbmRSRSwgJycpO1xuICAgICAgICAgICAgaWYgKGRpck5hbWUgPT09ICdzdHlsZScgfHwgZGlyTmFtZSA9PT0gJ2NsYXNzJykge1xuICAgICAgICAgICAgICBwdXNoRGlyKGRpck5hbWUsIGludGVybmFsRGlyZWN0aXZlc1tkaXJOYW1lXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBhcmcgPSBkaXJOYW1lO1xuICAgICAgICAgICAgICBwdXNoRGlyKCdiaW5kJywgZGlyZWN0aXZlcy5iaW5kKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2VcblxuICAgICAgICAgICAgLy8gbm9ybWFsIGRpcmVjdGl2ZXNcbiAgICAgICAgICAgIGlmIChtYXRjaGVkID0gbmFtZS5tYXRjaChkaXJBdHRyUkUpKSB7XG4gICAgICAgICAgICAgIGRpck5hbWUgPSBtYXRjaGVkWzFdO1xuICAgICAgICAgICAgICBhcmcgPSBtYXRjaGVkWzJdO1xuXG4gICAgICAgICAgICAgIC8vIHNraXAgdi1lbHNlICh3aGVuIHVzZWQgd2l0aCB2LXNob3cpXG4gICAgICAgICAgICAgIGlmIChkaXJOYW1lID09PSAnZWxzZScpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGRpckRlZiA9IHJlc29sdmVBc3NldChvcHRpb25zLCAnZGlyZWN0aXZlcycsIGRpck5hbWUpO1xuXG4gICAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0QXNzZXQoZGlyRGVmLCAnZGlyZWN0aXZlJywgZGlyTmFtZSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoZGlyRGVmKSB7XG4gICAgICAgICAgICAgICAgcHVzaERpcihkaXJOYW1lLCBkaXJEZWYpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHVzaCBhIGRpcmVjdGl2ZS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGRpck5hbWVcbiAgICogQHBhcmFtIHtPYmplY3R8RnVuY3Rpb259IGRlZlxuICAgKiBAcGFyYW0ge0FycmF5fSBbaW50ZXJwVG9rZW5zXVxuICAgKi9cblxuICBmdW5jdGlvbiBwdXNoRGlyKGRpck5hbWUsIGRlZiwgaW50ZXJwVG9rZW5zKSB7XG4gICAgdmFyIGhhc09uZVRpbWVUb2tlbiA9IGludGVycFRva2VucyAmJiBoYXNPbmVUaW1lKGludGVycFRva2Vucyk7XG4gICAgdmFyIHBhcnNlZCA9ICFoYXNPbmVUaW1lVG9rZW4gJiYgcGFyc2VEaXJlY3RpdmUodmFsdWUpO1xuICAgIGRpcnMucHVzaCh7XG4gICAgICBuYW1lOiBkaXJOYW1lLFxuICAgICAgYXR0cjogcmF3TmFtZSxcbiAgICAgIHJhdzogcmF3VmFsdWUsXG4gICAgICBkZWY6IGRlZixcbiAgICAgIGFyZzogYXJnLFxuICAgICAgbW9kaWZpZXJzOiBtb2RpZmllcnMsXG4gICAgICAvLyBjb252ZXJzaW9uIGZyb20gaW50ZXJwb2xhdGlvbiBzdHJpbmdzIHdpdGggb25lLXRpbWUgdG9rZW5cbiAgICAgIC8vIHRvIGV4cHJlc3Npb24gaXMgZGlmZmVyZWQgdW50aWwgZGlyZWN0aXZlIGJpbmQgdGltZSBzbyB0aGF0IHdlXG4gICAgICAvLyBoYXZlIGFjY2VzcyB0byB0aGUgYWN0dWFsIHZtIGNvbnRleHQgZm9yIG9uZS10aW1lIGJpbmRpbmdzLlxuICAgICAgZXhwcmVzc2lvbjogcGFyc2VkICYmIHBhcnNlZC5leHByZXNzaW9uLFxuICAgICAgZmlsdGVyczogcGFyc2VkICYmIHBhcnNlZC5maWx0ZXJzLFxuICAgICAgaW50ZXJwOiBpbnRlcnBUb2tlbnMsXG4gICAgICBoYXNPbmVUaW1lOiBoYXNPbmVUaW1lVG9rZW5cbiAgICB9KTtcbiAgfVxuXG4gIGlmIChkaXJzLmxlbmd0aCkge1xuICAgIHJldHVybiBtYWtlTm9kZUxpbmtGbihkaXJzKTtcbiAgfVxufVxuXG4vKipcbiAqIFBhcnNlIG1vZGlmaWVycyBmcm9tIGRpcmVjdGl2ZSBhdHRyaWJ1dGUgbmFtZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlTW9kaWZpZXJzKG5hbWUpIHtcbiAgdmFyIHJlcyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIHZhciBtYXRjaCA9IG5hbWUubWF0Y2gobW9kaWZpZXJSRSk7XG4gIGlmIChtYXRjaCkge1xuICAgIHZhciBpID0gbWF0Y2gubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIHJlc1ttYXRjaFtpXS5zbGljZSgxKV0gPSB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEgbGluayBmdW5jdGlvbiBmb3IgYWxsIGRpcmVjdGl2ZXMgb24gYSBzaW5nbGUgbm9kZS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBkaXJlY3RpdmVzXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gZGlyZWN0aXZlc0xpbmtGblxuICovXG5cbmZ1bmN0aW9uIG1ha2VOb2RlTGlua0ZuKGRpcmVjdGl2ZXMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIG5vZGVMaW5rRm4odm0sIGVsLCBob3N0LCBzY29wZSwgZnJhZykge1xuICAgIC8vIHJldmVyc2UgYXBwbHkgYmVjYXVzZSBpdCdzIHNvcnRlZCBsb3cgdG8gaGlnaFxuICAgIHZhciBpID0gZGlyZWN0aXZlcy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgdm0uX2JpbmREaXIoZGlyZWN0aXZlc1tpXSwgZWwsIGhvc3QsIHNjb3BlLCBmcmFnKTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYW4gaW50ZXJwb2xhdGlvbiBzdHJpbmcgY29udGFpbnMgb25lLXRpbWUgdG9rZW5zLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHRva2Vuc1xuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuXG5mdW5jdGlvbiBoYXNPbmVUaW1lKHRva2Vucykge1xuICB2YXIgaSA9IHRva2Vucy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBpZiAodG9rZW5zW2ldLm9uZVRpbWUpIHJldHVybiB0cnVlO1xuICB9XG59XG5cbnZhciBzcGVjaWFsQ2hhclJFID0gL1teXFx3XFwtOlxcLl0vO1xuXG4vKipcbiAqIFByb2Nlc3MgYW4gZWxlbWVudCBvciBhIERvY3VtZW50RnJhZ21lbnQgYmFzZWQgb24gYVxuICogaW5zdGFuY2Ugb3B0aW9uIG9iamVjdC4gVGhpcyBhbGxvd3MgdXMgdG8gdHJhbnNjbHVkZVxuICogYSB0ZW1wbGF0ZSBub2RlL2ZyYWdtZW50IGJlZm9yZSB0aGUgaW5zdGFuY2UgaXMgY3JlYXRlZCxcbiAqIHNvIHRoZSBwcm9jZXNzZWQgZnJhZ21lbnQgY2FuIHRoZW4gYmUgY2xvbmVkIGFuZCByZXVzZWRcbiAqIGluIHYtZm9yLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcmV0dXJuIHtFbGVtZW50fERvY3VtZW50RnJhZ21lbnR9XG4gKi9cblxuZnVuY3Rpb24gdHJhbnNjbHVkZShlbCwgb3B0aW9ucykge1xuICAvLyBleHRyYWN0IGNvbnRhaW5lciBhdHRyaWJ1dGVzIHRvIHBhc3MgdGhlbSBkb3duXG4gIC8vIHRvIGNvbXBpbGVyLCBiZWNhdXNlIHRoZXkgbmVlZCB0byBiZSBjb21waWxlZCBpblxuICAvLyBwYXJlbnQgc2NvcGUuIHdlIGFyZSBtdXRhdGluZyB0aGUgb3B0aW9ucyBvYmplY3QgaGVyZVxuICAvLyBhc3N1bWluZyB0aGUgc2FtZSBvYmplY3Qgd2lsbCBiZSB1c2VkIGZvciBjb21waWxlXG4gIC8vIHJpZ2h0IGFmdGVyIHRoaXMuXG4gIGlmIChvcHRpb25zKSB7XG4gICAgb3B0aW9ucy5fY29udGFpbmVyQXR0cnMgPSBleHRyYWN0QXR0cnMoZWwpO1xuICB9XG4gIC8vIGZvciB0ZW1wbGF0ZSB0YWdzLCB3aGF0IHdlIHdhbnQgaXMgaXRzIGNvbnRlbnQgYXNcbiAgLy8gYSBkb2N1bWVudEZyYWdtZW50IChmb3IgZnJhZ21lbnQgaW5zdGFuY2VzKVxuICBpZiAoaXNUZW1wbGF0ZShlbCkpIHtcbiAgICBlbCA9IHBhcnNlVGVtcGxhdGUoZWwpO1xuICB9XG4gIGlmIChvcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbnMuX2FzQ29tcG9uZW50ICYmICFvcHRpb25zLnRlbXBsYXRlKSB7XG4gICAgICBvcHRpb25zLnRlbXBsYXRlID0gJzxzbG90Pjwvc2xvdD4nO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy50ZW1wbGF0ZSkge1xuICAgICAgb3B0aW9ucy5fY29udGVudCA9IGV4dHJhY3RDb250ZW50KGVsKTtcbiAgICAgIGVsID0gdHJhbnNjbHVkZVRlbXBsYXRlKGVsLCBvcHRpb25zKTtcbiAgICB9XG4gIH1cbiAgaWYgKGlzRnJhZ21lbnQoZWwpKSB7XG4gICAgLy8gYW5jaG9ycyBmb3IgZnJhZ21lbnQgaW5zdGFuY2VcbiAgICAvLyBwYXNzaW5nIGluIGBwZXJzaXN0OiB0cnVlYCB0byBhdm9pZCB0aGVtIGJlaW5nXG4gICAgLy8gZGlzY2FyZGVkIGJ5IElFIGR1cmluZyB0ZW1wbGF0ZSBjbG9uaW5nXG4gICAgcHJlcGVuZChjcmVhdGVBbmNob3IoJ3Ytc3RhcnQnLCB0cnVlKSwgZWwpO1xuICAgIGVsLmFwcGVuZENoaWxkKGNyZWF0ZUFuY2hvcigndi1lbmQnLCB0cnVlKSk7XG4gIH1cbiAgcmV0dXJuIGVsO1xufVxuXG4vKipcbiAqIFByb2Nlc3MgdGhlIHRlbXBsYXRlIG9wdGlvbi5cbiAqIElmIHRoZSByZXBsYWNlIG9wdGlvbiBpcyB0cnVlIHRoaXMgd2lsbCBzd2FwIHRoZSAkZWwuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge0VsZW1lbnR8RG9jdW1lbnRGcmFnbWVudH1cbiAqL1xuXG5mdW5jdGlvbiB0cmFuc2NsdWRlVGVtcGxhdGUoZWwsIG9wdGlvbnMpIHtcbiAgdmFyIHRlbXBsYXRlID0gb3B0aW9ucy50ZW1wbGF0ZTtcbiAgdmFyIGZyYWcgPSBwYXJzZVRlbXBsYXRlKHRlbXBsYXRlLCB0cnVlKTtcbiAgaWYgKGZyYWcpIHtcbiAgICB2YXIgcmVwbGFjZXIgPSBmcmFnLmZpcnN0Q2hpbGQ7XG4gICAgdmFyIHRhZyA9IHJlcGxhY2VyLnRhZ05hbWUgJiYgcmVwbGFjZXIudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChvcHRpb25zLnJlcGxhY2UpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgaWYgKGVsID09PSBkb2N1bWVudC5ib2R5KSB7XG4gICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybignWW91IGFyZSBtb3VudGluZyBhbiBpbnN0YW5jZSB3aXRoIGEgdGVtcGxhdGUgdG8gJyArICc8Ym9keT4uIFRoaXMgd2lsbCByZXBsYWNlIDxib2R5PiBlbnRpcmVseS4gWW91ICcgKyAnc2hvdWxkIHByb2JhYmx5IHVzZSBgcmVwbGFjZTogZmFsc2VgIGhlcmUuJyk7XG4gICAgICB9XG4gICAgICAvLyB0aGVyZSBhcmUgbWFueSBjYXNlcyB3aGVyZSB0aGUgaW5zdGFuY2UgbXVzdFxuICAgICAgLy8gYmVjb21lIGEgZnJhZ21lbnQgaW5zdGFuY2U6IGJhc2ljYWxseSBhbnl0aGluZyB0aGF0XG4gICAgICAvLyBjYW4gY3JlYXRlIG1vcmUgdGhhbiAxIHJvb3Qgbm9kZXMuXG4gICAgICBpZiAoXG4gICAgICAvLyBtdWx0aS1jaGlsZHJlbiB0ZW1wbGF0ZVxuICAgICAgZnJhZy5jaGlsZE5vZGVzLmxlbmd0aCA+IDEgfHxcbiAgICAgIC8vIG5vbi1lbGVtZW50IHRlbXBsYXRlXG4gICAgICByZXBsYWNlci5ub2RlVHlwZSAhPT0gMSB8fFxuICAgICAgLy8gc2luZ2xlIG5lc3RlZCBjb21wb25lbnRcbiAgICAgIHRhZyA9PT0gJ2NvbXBvbmVudCcgfHwgcmVzb2x2ZUFzc2V0KG9wdGlvbnMsICdjb21wb25lbnRzJywgdGFnKSB8fCBoYXNCaW5kQXR0cihyZXBsYWNlciwgJ2lzJykgfHxcbiAgICAgIC8vIGVsZW1lbnQgZGlyZWN0aXZlXG4gICAgICByZXNvbHZlQXNzZXQob3B0aW9ucywgJ2VsZW1lbnREaXJlY3RpdmVzJywgdGFnKSB8fFxuICAgICAgLy8gZm9yIGJsb2NrXG4gICAgICByZXBsYWNlci5oYXNBdHRyaWJ1dGUoJ3YtZm9yJykgfHxcbiAgICAgIC8vIGlmIGJsb2NrXG4gICAgICByZXBsYWNlci5oYXNBdHRyaWJ1dGUoJ3YtaWYnKSkge1xuICAgICAgICByZXR1cm4gZnJhZztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9wdGlvbnMuX3JlcGxhY2VyQXR0cnMgPSBleHRyYWN0QXR0cnMocmVwbGFjZXIpO1xuICAgICAgICBtZXJnZUF0dHJzKGVsLCByZXBsYWNlcik7XG4gICAgICAgIHJldHVybiByZXBsYWNlcjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZWwuYXBwZW5kQ2hpbGQoZnJhZyk7XG4gICAgICByZXR1cm4gZWw7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybignSW52YWxpZCB0ZW1wbGF0ZSBvcHRpb246ICcgKyB0ZW1wbGF0ZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBIZWxwZXIgdG8gZXh0cmFjdCBhIGNvbXBvbmVudCBjb250YWluZXIncyBhdHRyaWJ1dGVzXG4gKiBpbnRvIGEgcGxhaW4gb2JqZWN0IGFycmF5LlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5cbmZ1bmN0aW9uIGV4dHJhY3RBdHRycyhlbCkge1xuICBpZiAoZWwubm9kZVR5cGUgPT09IDEgJiYgZWwuaGFzQXR0cmlidXRlcygpKSB7XG4gICAgcmV0dXJuIHRvQXJyYXkoZWwuYXR0cmlidXRlcyk7XG4gIH1cbn1cblxuLyoqXG4gKiBNZXJnZSB0aGUgYXR0cmlidXRlcyBvZiB0d28gZWxlbWVudHMsIGFuZCBtYWtlIHN1cmVcbiAqIHRoZSBjbGFzcyBuYW1lcyBhcmUgbWVyZ2VkIHByb3Blcmx5LlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZnJvbVxuICogQHBhcmFtIHtFbGVtZW50fSB0b1xuICovXG5cbmZ1bmN0aW9uIG1lcmdlQXR0cnMoZnJvbSwgdG8pIHtcbiAgdmFyIGF0dHJzID0gZnJvbS5hdHRyaWJ1dGVzO1xuICB2YXIgaSA9IGF0dHJzLmxlbmd0aDtcbiAgdmFyIG5hbWUsIHZhbHVlO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgbmFtZSA9IGF0dHJzW2ldLm5hbWU7XG4gICAgdmFsdWUgPSBhdHRyc1tpXS52YWx1ZTtcbiAgICBpZiAoIXRvLmhhc0F0dHJpYnV0ZShuYW1lKSAmJiAhc3BlY2lhbENoYXJSRS50ZXN0KG5hbWUpKSB7XG4gICAgICB0by5zZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUpO1xuICAgIH0gZWxzZSBpZiAobmFtZSA9PT0gJ2NsYXNzJyAmJiAhcGFyc2VUZXh0KHZhbHVlKSkge1xuICAgICAgdmFsdWUuc3BsaXQoL1xccysvKS5mb3JFYWNoKGZ1bmN0aW9uIChjbHMpIHtcbiAgICAgICAgYWRkQ2xhc3ModG8sIGNscyk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBTY2FuIGFuZCBkZXRlcm1pbmUgc2xvdCBjb250ZW50IGRpc3RyaWJ1dGlvbi5cbiAqIFdlIGRvIHRoaXMgZHVyaW5nIHRyYW5zY2x1c2lvbiBpbnN0ZWFkIGF0IGNvbXBpbGUgdGltZSBzbyB0aGF0XG4gKiB0aGUgZGlzdHJpYnV0aW9uIGlzIGRlY291cGxlZCBmcm9tIHRoZSBjb21waWxhdGlvbiBvcmRlciBvZlxuICogdGhlIHNsb3RzLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudHxEb2N1bWVudEZyYWdtZW50fSB0ZW1wbGF0ZVxuICogQHBhcmFtIHtFbGVtZW50fSBjb250ZW50XG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqL1xuXG5mdW5jdGlvbiBzY2FuU2xvdHModGVtcGxhdGUsIGNvbnRlbnQsIHZtKSB7XG4gIGlmICghY29udGVudCkge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgY29udGVudHMgPSB2bS5fc2xvdENvbnRlbnRzID0ge307XG4gIHZhciBzbG90cyA9IHRlbXBsYXRlLnF1ZXJ5U2VsZWN0b3JBbGwoJ3Nsb3QnKTtcbiAgaWYgKHNsb3RzLmxlbmd0aCkge1xuICAgIHZhciBoYXNEZWZhdWx0LCBzbG90LCBuYW1lO1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gc2xvdHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBzbG90ID0gc2xvdHNbaV07XG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25kLWFzc2lnbiAqL1xuICAgICAgaWYgKG5hbWUgPSBzbG90LmdldEF0dHJpYnV0ZSgnbmFtZScpKSB7XG4gICAgICAgIHNlbGVjdChzbG90LCBuYW1lKTtcbiAgICAgIH0gZWxzZSBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiAobmFtZSA9IGdldEJpbmRBdHRyKHNsb3QsICduYW1lJykpKSB7XG4gICAgICAgIHdhcm4oJzxzbG90IDpuYW1lPVwiJyArIG5hbWUgKyAnXCI+OiBzbG90IG5hbWVzIGNhbm5vdCBiZSBkeW5hbWljLicpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZGVmYXVsdCBzbG90XG4gICAgICAgIGhhc0RlZmF1bHQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25kLWFzc2lnbiAqL1xuICAgIH1cbiAgICBpZiAoaGFzRGVmYXVsdCkge1xuICAgICAgY29udGVudHNbJ2RlZmF1bHQnXSA9IGV4dHJhY3RGcmFnbWVudChjb250ZW50LmNoaWxkTm9kZXMsIGNvbnRlbnQpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNlbGVjdChzbG90LCBuYW1lKSB7XG4gICAgLy8gbmFtZWQgc2xvdFxuICAgIHZhciBzZWxlY3RvciA9ICdbc2xvdD1cIicgKyBuYW1lICsgJ1wiXSc7XG4gICAgdmFyIG5vZGVzID0gY29udGVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcbiAgICBpZiAobm9kZXMubGVuZ3RoKSB7XG4gICAgICBjb250ZW50c1tuYW1lXSA9IGV4dHJhY3RGcmFnbWVudChub2RlcywgY29udGVudCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRXh0cmFjdCBxdWFsaWZpZWQgY29udGVudCBub2RlcyBmcm9tIGEgbm9kZSBsaXN0LlxuICpcbiAqIEBwYXJhbSB7Tm9kZUxpc3R9IG5vZGVzXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHBhcmVudFxuICogQHJldHVybiB7RG9jdW1lbnRGcmFnbWVudH1cbiAqL1xuXG5mdW5jdGlvbiBleHRyYWN0RnJhZ21lbnQobm9kZXMsIHBhcmVudCkge1xuICB2YXIgZnJhZyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgbm9kZXMgPSB0b0FycmF5KG5vZGVzKTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBub2Rlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICB2YXIgbm9kZSA9IG5vZGVzW2ldO1xuICAgIGlmIChub2RlLnBhcmVudE5vZGUgPT09IHBhcmVudCkge1xuICAgICAgaWYgKGlzVGVtcGxhdGUobm9kZSkgJiYgIW5vZGUuaGFzQXR0cmlidXRlKCd2LWlmJykgJiYgIW5vZGUuaGFzQXR0cmlidXRlKCd2LWZvcicpKSB7XG4gICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChub2RlKTtcbiAgICAgICAgbm9kZSA9IHBhcnNlVGVtcGxhdGUobm9kZSk7XG4gICAgICB9XG4gICAgICBmcmFnLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZnJhZztcbn1cblxuXG5cbnZhciBjb21waWxlciA9IE9iamVjdC5mcmVlemUoe1xuXHRjb21waWxlOiBjb21waWxlLFxuXHRjb21waWxlQW5kTGlua1Byb3BzOiBjb21waWxlQW5kTGlua1Byb3BzLFxuXHRjb21waWxlUm9vdDogY29tcGlsZVJvb3QsXG5cdHRlcm1pbmFsRGlyZWN0aXZlczogdGVybWluYWxEaXJlY3RpdmVzLFxuXHR0cmFuc2NsdWRlOiB0cmFuc2NsdWRlLFxuXHRzY2FuU2xvdHM6IHNjYW5TbG90c1xufSk7XG5cbmZ1bmN0aW9uIHN0YXRlTWl4aW4gKFZ1ZSkge1xuICAvKipcbiAgICogQWNjZXNzb3IgZm9yIGAkZGF0YWAgcHJvcGVydHksIHNpbmNlIHNldHRpbmcgJGRhdGFcbiAgICogcmVxdWlyZXMgb2JzZXJ2aW5nIHRoZSBuZXcgb2JqZWN0IGFuZCB1cGRhdGluZ1xuICAgKiBwcm94aWVkIHByb3BlcnRpZXMuXG4gICAqL1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShWdWUucHJvdG90eXBlLCAnJGRhdGEnLCB7XG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fZGF0YTtcbiAgICB9LFxuICAgIHNldDogZnVuY3Rpb24gc2V0KG5ld0RhdGEpIHtcbiAgICAgIGlmIChuZXdEYXRhICE9PSB0aGlzLl9kYXRhKSB7XG4gICAgICAgIHRoaXMuX3NldERhdGEobmV3RGF0YSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICAvKipcbiAgICogU2V0dXAgdGhlIHNjb3BlIG9mIGFuIGluc3RhbmNlLCB3aGljaCBjb250YWluczpcbiAgICogLSBvYnNlcnZlZCBkYXRhXG4gICAqIC0gY29tcHV0ZWQgcHJvcGVydGllc1xuICAgKiAtIHVzZXIgbWV0aG9kc1xuICAgKiAtIG1ldGEgcHJvcGVydGllc1xuICAgKi9cblxuICBWdWUucHJvdG90eXBlLl9pbml0U3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5faW5pdFByb3BzKCk7XG4gICAgdGhpcy5faW5pdE1ldGEoKTtcbiAgICB0aGlzLl9pbml0TWV0aG9kcygpO1xuICAgIHRoaXMuX2luaXREYXRhKCk7XG4gICAgdGhpcy5faW5pdENvbXB1dGVkKCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgcHJvcHMuXG4gICAqL1xuXG4gIFZ1ZS5wcm90b3R5cGUuX2luaXRQcm9wcyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgb3B0aW9ucyA9IHRoaXMuJG9wdGlvbnM7XG4gICAgdmFyIGVsID0gb3B0aW9ucy5lbDtcbiAgICB2YXIgcHJvcHMgPSBvcHRpb25zLnByb3BzO1xuICAgIGlmIChwcm9wcyAmJiAhZWwpIHtcbiAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybignUHJvcHMgd2lsbCBub3QgYmUgY29tcGlsZWQgaWYgbm8gYGVsYCBvcHRpb24gaXMgJyArICdwcm92aWRlZCBhdCBpbnN0YW50aWF0aW9uLicpO1xuICAgIH1cbiAgICAvLyBtYWtlIHN1cmUgdG8gY29udmVydCBzdHJpbmcgc2VsZWN0b3JzIGludG8gZWxlbWVudCBub3dcbiAgICBlbCA9IG9wdGlvbnMuZWwgPSBxdWVyeShlbCk7XG4gICAgdGhpcy5fcHJvcHNVbmxpbmtGbiA9IGVsICYmIGVsLm5vZGVUeXBlID09PSAxICYmIHByb3BzXG4gICAgLy8gcHJvcHMgbXVzdCBiZSBsaW5rZWQgaW4gcHJvcGVyIHNjb3BlIGlmIGluc2lkZSB2LWZvclxuICAgID8gY29tcGlsZUFuZExpbmtQcm9wcyh0aGlzLCBlbCwgcHJvcHMsIHRoaXMuX3Njb3BlKSA6IG51bGw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgdGhlIGRhdGEuXG4gICAqL1xuXG4gIFZ1ZS5wcm90b3R5cGUuX2luaXREYXRhID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBwcm9wc0RhdGEgPSB0aGlzLl9kYXRhO1xuICAgIHZhciBvcHRpb25zRGF0YUZuID0gdGhpcy4kb3B0aW9ucy5kYXRhO1xuICAgIHZhciBvcHRpb25zRGF0YSA9IG9wdGlvbnNEYXRhRm4gJiYgb3B0aW9uc0RhdGFGbigpO1xuICAgIHZhciBydW50aW1lRGF0YTtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgcnVudGltZURhdGEgPSAodHlwZW9mIHRoaXMuX3J1bnRpbWVEYXRhID09PSAnZnVuY3Rpb24nID8gdGhpcy5fcnVudGltZURhdGEoKSA6IHRoaXMuX3J1bnRpbWVEYXRhKSB8fCB7fTtcbiAgICAgIHRoaXMuX3J1bnRpbWVEYXRhID0gbnVsbDtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnNEYXRhKSB7XG4gICAgICB0aGlzLl9kYXRhID0gb3B0aW9uc0RhdGE7XG4gICAgICBmb3IgKHZhciBwcm9wIGluIHByb3BzRGF0YSkge1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBoYXNPd24ob3B0aW9uc0RhdGEsIHByb3ApICYmICFoYXNPd24ocnVudGltZURhdGEsIHByb3ApKSB7XG4gICAgICAgICAgd2FybignRGF0YSBmaWVsZCBcIicgKyBwcm9wICsgJ1wiIGlzIGFscmVhZHkgZGVmaW5lZCAnICsgJ2FzIGEgcHJvcC4gVXNlIHByb3AgZGVmYXVsdCB2YWx1ZSBpbnN0ZWFkLicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9wcm9wc1twcm9wXS5yYXcgIT09IG51bGwgfHwgIWhhc093bihvcHRpb25zRGF0YSwgcHJvcCkpIHtcbiAgICAgICAgICBzZXQob3B0aW9uc0RhdGEsIHByb3AsIHByb3BzRGF0YVtwcm9wXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhO1xuICAgIC8vIHByb3h5IGRhdGEgb24gaW5zdGFuY2VcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGRhdGEpO1xuICAgIHZhciBpLCBrZXk7XG4gICAgaSA9IGtleXMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICB0aGlzLl9wcm94eShrZXkpO1xuICAgIH1cbiAgICAvLyBvYnNlcnZlIGRhdGFcbiAgICBvYnNlcnZlKGRhdGEsIHRoaXMpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBTd2FwIHRoZSBpbnN0YW5jZSdzICRkYXRhLiBDYWxsZWQgaW4gJGRhdGEncyBzZXR0ZXIuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBuZXdEYXRhXG4gICAqL1xuXG4gIFZ1ZS5wcm90b3R5cGUuX3NldERhdGEgPSBmdW5jdGlvbiAobmV3RGF0YSkge1xuICAgIG5ld0RhdGEgPSBuZXdEYXRhIHx8IHt9O1xuICAgIHZhciBvbGREYXRhID0gdGhpcy5fZGF0YTtcbiAgICB0aGlzLl9kYXRhID0gbmV3RGF0YTtcbiAgICB2YXIga2V5cywga2V5LCBpO1xuICAgIC8vIHVucHJveHkga2V5cyBub3QgcHJlc2VudCBpbiBuZXcgZGF0YVxuICAgIGtleXMgPSBPYmplY3Qua2V5cyhvbGREYXRhKTtcbiAgICBpID0ga2V5cy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgIGlmICghKGtleSBpbiBuZXdEYXRhKSkge1xuICAgICAgICB0aGlzLl91bnByb3h5KGtleSk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIHByb3h5IGtleXMgbm90IGFscmVhZHkgcHJveGllZCxcbiAgICAvLyBhbmQgdHJpZ2dlciBjaGFuZ2UgZm9yIGNoYW5nZWQgdmFsdWVzXG4gICAga2V5cyA9IE9iamVjdC5rZXlzKG5ld0RhdGEpO1xuICAgIGkgPSBrZXlzLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICBrZXkgPSBrZXlzW2ldO1xuICAgICAgaWYgKCFoYXNPd24odGhpcywga2V5KSkge1xuICAgICAgICAvLyBuZXcgcHJvcGVydHlcbiAgICAgICAgdGhpcy5fcHJveHkoa2V5KTtcbiAgICAgIH1cbiAgICB9XG4gICAgb2xkRGF0YS5fX29iX18ucmVtb3ZlVm0odGhpcyk7XG4gICAgb2JzZXJ2ZShuZXdEYXRhLCB0aGlzKTtcbiAgICB0aGlzLl9kaWdlc3QoKTtcbiAgfTtcblxuICAvKipcbiAgICogUHJveHkgYSBwcm9wZXJ0eSwgc28gdGhhdFxuICAgKiB2bS5wcm9wID09PSB2bS5fZGF0YS5wcm9wXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS5fcHJveHkgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgaWYgKCFpc1Jlc2VydmVkKGtleSkpIHtcbiAgICAgIC8vIG5lZWQgdG8gc3RvcmUgcmVmIHRvIHNlbGYgaGVyZVxuICAgICAgLy8gYmVjYXVzZSB0aGVzZSBnZXR0ZXIvc2V0dGVycyBtaWdodFxuICAgICAgLy8gYmUgY2FsbGVkIGJ5IGNoaWxkIHNjb3BlcyB2aWFcbiAgICAgIC8vIHByb3RvdHlwZSBpbmhlcml0YW5jZS5cbiAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzZWxmLCBrZXksIHtcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBnZXQ6IGZ1bmN0aW9uIHByb3h5R2V0dGVyKCkge1xuICAgICAgICAgIHJldHVybiBzZWxmLl9kYXRhW2tleV07XG4gICAgICAgIH0sXG4gICAgICAgIHNldDogZnVuY3Rpb24gcHJveHlTZXR0ZXIodmFsKSB7XG4gICAgICAgICAgc2VsZi5fZGF0YVtrZXldID0gdmFsO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIFVucHJveHkgYSBwcm9wZXJ0eS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLl91bnByb3h5ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIGlmICghaXNSZXNlcnZlZChrZXkpKSB7XG4gICAgICBkZWxldGUgdGhpc1trZXldO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogRm9yY2UgdXBkYXRlIG9uIGV2ZXJ5IHdhdGNoZXIgaW4gc2NvcGUuXG4gICAqL1xuXG4gIFZ1ZS5wcm90b3R5cGUuX2RpZ2VzdCA9IGZ1bmN0aW9uICgpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IHRoaXMuX3dhdGNoZXJzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgdGhpcy5fd2F0Y2hlcnNbaV0udXBkYXRlKHRydWUpOyAvLyBzaGFsbG93IHVwZGF0ZXNcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIFNldHVwIGNvbXB1dGVkIHByb3BlcnRpZXMuIFRoZXkgYXJlIGVzc2VudGlhbGx5XG4gICAqIHNwZWNpYWwgZ2V0dGVyL3NldHRlcnNcbiAgICovXG5cbiAgZnVuY3Rpb24gbm9vcCgpIHt9XG4gIFZ1ZS5wcm90b3R5cGUuX2luaXRDb21wdXRlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY29tcHV0ZWQgPSB0aGlzLiRvcHRpb25zLmNvbXB1dGVkO1xuICAgIGlmIChjb21wdXRlZCkge1xuICAgICAgZm9yICh2YXIga2V5IGluIGNvbXB1dGVkKSB7XG4gICAgICAgIHZhciB1c2VyRGVmID0gY29tcHV0ZWRba2V5XTtcbiAgICAgICAgdmFyIGRlZiA9IHtcbiAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJEZWYgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBkZWYuZ2V0ID0gbWFrZUNvbXB1dGVkR2V0dGVyKHVzZXJEZWYsIHRoaXMpO1xuICAgICAgICAgIGRlZi5zZXQgPSBub29wO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlZi5nZXQgPSB1c2VyRGVmLmdldCA/IHVzZXJEZWYuY2FjaGUgIT09IGZhbHNlID8gbWFrZUNvbXB1dGVkR2V0dGVyKHVzZXJEZWYuZ2V0LCB0aGlzKSA6IGJpbmQodXNlckRlZi5nZXQsIHRoaXMpIDogbm9vcDtcbiAgICAgICAgICBkZWYuc2V0ID0gdXNlckRlZi5zZXQgPyBiaW5kKHVzZXJEZWYuc2V0LCB0aGlzKSA6IG5vb3A7XG4gICAgICAgIH1cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIGtleSwgZGVmKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgZnVuY3Rpb24gbWFrZUNvbXB1dGVkR2V0dGVyKGdldHRlciwgb3duZXIpIHtcbiAgICB2YXIgd2F0Y2hlciA9IG5ldyBXYXRjaGVyKG93bmVyLCBnZXR0ZXIsIG51bGwsIHtcbiAgICAgIGxhenk6IHRydWVcbiAgICB9KTtcbiAgICByZXR1cm4gZnVuY3Rpb24gY29tcHV0ZWRHZXR0ZXIoKSB7XG4gICAgICBpZiAod2F0Y2hlci5kaXJ0eSkge1xuICAgICAgICB3YXRjaGVyLmV2YWx1YXRlKCk7XG4gICAgICB9XG4gICAgICBpZiAoRGVwLnRhcmdldCkge1xuICAgICAgICB3YXRjaGVyLmRlcGVuZCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdhdGNoZXIudmFsdWU7XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXR1cCBpbnN0YW5jZSBtZXRob2RzLiBNZXRob2RzIG11c3QgYmUgYm91bmQgdG8gdGhlXG4gICAqIGluc3RhbmNlIHNpbmNlIHRoZXkgbWlnaHQgYmUgcGFzc2VkIGRvd24gYXMgYSBwcm9wIHRvXG4gICAqIGNoaWxkIGNvbXBvbmVudHMuXG4gICAqL1xuXG4gIFZ1ZS5wcm90b3R5cGUuX2luaXRNZXRob2RzID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBtZXRob2RzID0gdGhpcy4kb3B0aW9ucy5tZXRob2RzO1xuICAgIGlmIChtZXRob2RzKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gbWV0aG9kcykge1xuICAgICAgICB0aGlzW2tleV0gPSBiaW5kKG1ldGhvZHNba2V5XSwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIG1ldGEgaW5mb3JtYXRpb24gbGlrZSAkaW5kZXgsICRrZXkgJiAkdmFsdWUuXG4gICAqL1xuXG4gIFZ1ZS5wcm90b3R5cGUuX2luaXRNZXRhID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBtZXRhcyA9IHRoaXMuJG9wdGlvbnMuX21ldGE7XG4gICAgaWYgKG1ldGFzKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gbWV0YXMpIHtcbiAgICAgICAgZGVmaW5lUmVhY3RpdmUodGhpcywga2V5LCBtZXRhc1trZXldKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG59XG5cbnZhciBldmVudFJFID0gL152LW9uOnxeQC87XG5cbmZ1bmN0aW9uIGV2ZW50c01peGluIChWdWUpIHtcbiAgLyoqXG4gICAqIFNldHVwIHRoZSBpbnN0YW5jZSdzIG9wdGlvbiBldmVudHMgJiB3YXRjaGVycy5cbiAgICogSWYgdGhlIHZhbHVlIGlzIGEgc3RyaW5nLCB3ZSBwdWxsIGl0IGZyb20gdGhlXG4gICAqIGluc3RhbmNlJ3MgbWV0aG9kcyBieSBuYW1lLlxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLl9pbml0RXZlbnRzID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBvcHRpb25zID0gdGhpcy4kb3B0aW9ucztcbiAgICBpZiAob3B0aW9ucy5fYXNDb21wb25lbnQpIHtcbiAgICAgIHJlZ2lzdGVyQ29tcG9uZW50RXZlbnRzKHRoaXMsIG9wdGlvbnMuZWwpO1xuICAgIH1cbiAgICByZWdpc3RlckNhbGxiYWNrcyh0aGlzLCAnJG9uJywgb3B0aW9ucy5ldmVudHMpO1xuICAgIHJlZ2lzdGVyQ2FsbGJhY2tzKHRoaXMsICckd2F0Y2gnLCBvcHRpb25zLndhdGNoKTtcbiAgfTtcblxuICAvKipcbiAgICogUmVnaXN0ZXIgdi1vbiBldmVudHMgb24gYSBjaGlsZCBjb21wb25lbnRcbiAgICpcbiAgICogQHBhcmFtIHtWdWV9IHZtXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAgICovXG5cbiAgZnVuY3Rpb24gcmVnaXN0ZXJDb21wb25lbnRFdmVudHModm0sIGVsKSB7XG4gICAgdmFyIGF0dHJzID0gZWwuYXR0cmlidXRlcztcbiAgICB2YXIgbmFtZSwgaGFuZGxlcjtcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGF0dHJzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgbmFtZSA9IGF0dHJzW2ldLm5hbWU7XG4gICAgICBpZiAoZXZlbnRSRS50ZXN0KG5hbWUpKSB7XG4gICAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoZXZlbnRSRSwgJycpO1xuICAgICAgICBoYW5kbGVyID0gKHZtLl9zY29wZSB8fCB2bS5fY29udGV4dCkuJGV2YWwoYXR0cnNbaV0udmFsdWUsIHRydWUpO1xuICAgICAgICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBoYW5kbGVyLl9mcm9tUGFyZW50ID0gdHJ1ZTtcbiAgICAgICAgICB2bS4kb24obmFtZS5yZXBsYWNlKGV2ZW50UkUpLCBoYW5kbGVyKTtcbiAgICAgICAgfSBlbHNlIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgICAgd2Fybigndi1vbjonICsgbmFtZSArICc9XCInICsgYXR0cnNbaV0udmFsdWUgKyAnXCInICsgKHZtLiRvcHRpb25zLm5hbWUgPyAnIG9uIGNvbXBvbmVudCA8JyArIHZtLiRvcHRpb25zLm5hbWUgKyAnPicgOiAnJykgKyAnIGV4cGVjdHMgYSBmdW5jdGlvbiB2YWx1ZSwgZ290ICcgKyBoYW5kbGVyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBjYWxsYmFja3MgZm9yIG9wdGlvbiBldmVudHMgYW5kIHdhdGNoZXJzLlxuICAgKlxuICAgKiBAcGFyYW0ge1Z1ZX0gdm1cbiAgICogQHBhcmFtIHtTdHJpbmd9IGFjdGlvblxuICAgKiBAcGFyYW0ge09iamVjdH0gaGFzaFxuICAgKi9cblxuICBmdW5jdGlvbiByZWdpc3RlckNhbGxiYWNrcyh2bSwgYWN0aW9uLCBoYXNoKSB7XG4gICAgaWYgKCFoYXNoKSByZXR1cm47XG4gICAgdmFyIGhhbmRsZXJzLCBrZXksIGksIGo7XG4gICAgZm9yIChrZXkgaW4gaGFzaCkge1xuICAgICAgaGFuZGxlcnMgPSBoYXNoW2tleV07XG4gICAgICBpZiAoaXNBcnJheShoYW5kbGVycykpIHtcbiAgICAgICAgZm9yIChpID0gMCwgaiA9IGhhbmRsZXJzLmxlbmd0aDsgaSA8IGo7IGkrKykge1xuICAgICAgICAgIHJlZ2lzdGVyKHZtLCBhY3Rpb24sIGtleSwgaGFuZGxlcnNbaV0pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZWdpc3Rlcih2bSwgYWN0aW9uLCBrZXksIGhhbmRsZXJzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGVscGVyIHRvIHJlZ2lzdGVyIGFuIGV2ZW50L3dhdGNoIGNhbGxiYWNrLlxuICAgKlxuICAgKiBAcGFyYW0ge1Z1ZX0gdm1cbiAgICogQHBhcmFtIHtTdHJpbmd9IGFjdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5XG4gICAqIEBwYXJhbSB7RnVuY3Rpb258U3RyaW5nfE9iamVjdH0gaGFuZGxlclxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqL1xuXG4gIGZ1bmN0aW9uIHJlZ2lzdGVyKHZtLCBhY3Rpb24sIGtleSwgaGFuZGxlciwgb3B0aW9ucykge1xuICAgIHZhciB0eXBlID0gdHlwZW9mIGhhbmRsZXI7XG4gICAgaWYgKHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHZtW2FjdGlvbl0oa2V5LCBoYW5kbGVyLCBvcHRpb25zKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YXIgbWV0aG9kcyA9IHZtLiRvcHRpb25zLm1ldGhvZHM7XG4gICAgICB2YXIgbWV0aG9kID0gbWV0aG9kcyAmJiBtZXRob2RzW2hhbmRsZXJdO1xuICAgICAgaWYgKG1ldGhvZCkge1xuICAgICAgICB2bVthY3Rpb25dKGtleSwgbWV0aG9kLCBvcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgd2FybignVW5rbm93biBtZXRob2Q6IFwiJyArIGhhbmRsZXIgKyAnXCIgd2hlbiAnICsgJ3JlZ2lzdGVyaW5nIGNhbGxiYWNrIGZvciAnICsgYWN0aW9uICsgJzogXCInICsga2V5ICsgJ1wiLicpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaGFuZGxlciAmJiB0eXBlID09PSAnb2JqZWN0Jykge1xuICAgICAgcmVnaXN0ZXIodm0sIGFjdGlvbiwga2V5LCBoYW5kbGVyLmhhbmRsZXIsIGhhbmRsZXIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXR1cCByZWN1cnNpdmUgYXR0YWNoZWQvZGV0YWNoZWQgY2FsbHNcbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS5faW5pdERPTUhvb2tzID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuJG9uKCdob29rOmF0dGFjaGVkJywgb25BdHRhY2hlZCk7XG4gICAgdGhpcy4kb24oJ2hvb2s6ZGV0YWNoZWQnLCBvbkRldGFjaGVkKTtcbiAgfTtcblxuICAvKipcbiAgICogQ2FsbGJhY2sgdG8gcmVjdXJzaXZlbHkgY2FsbCBhdHRhY2hlZCBob29rIG9uIGNoaWxkcmVuXG4gICAqL1xuXG4gIGZ1bmN0aW9uIG9uQXR0YWNoZWQoKSB7XG4gICAgaWYgKCF0aGlzLl9pc0F0dGFjaGVkKSB7XG4gICAgICB0aGlzLl9pc0F0dGFjaGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMuJGNoaWxkcmVuLmZvckVhY2goY2FsbEF0dGFjaCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEl0ZXJhdG9yIHRvIGNhbGwgYXR0YWNoZWQgaG9va1xuICAgKlxuICAgKiBAcGFyYW0ge1Z1ZX0gY2hpbGRcbiAgICovXG5cbiAgZnVuY3Rpb24gY2FsbEF0dGFjaChjaGlsZCkge1xuICAgIGlmICghY2hpbGQuX2lzQXR0YWNoZWQgJiYgaW5Eb2MoY2hpbGQuJGVsKSkge1xuICAgICAgY2hpbGQuX2NhbGxIb29rKCdhdHRhY2hlZCcpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxsYmFjayB0byByZWN1cnNpdmVseSBjYWxsIGRldGFjaGVkIGhvb2sgb24gY2hpbGRyZW5cbiAgICovXG5cbiAgZnVuY3Rpb24gb25EZXRhY2hlZCgpIHtcbiAgICBpZiAodGhpcy5faXNBdHRhY2hlZCkge1xuICAgICAgdGhpcy5faXNBdHRhY2hlZCA9IGZhbHNlO1xuICAgICAgdGhpcy4kY2hpbGRyZW4uZm9yRWFjaChjYWxsRGV0YWNoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0b3IgdG8gY2FsbCBkZXRhY2hlZCBob29rXG4gICAqXG4gICAqIEBwYXJhbSB7VnVlfSBjaGlsZFxuICAgKi9cblxuICBmdW5jdGlvbiBjYWxsRGV0YWNoKGNoaWxkKSB7XG4gICAgaWYgKGNoaWxkLl9pc0F0dGFjaGVkICYmICFpbkRvYyhjaGlsZC4kZWwpKSB7XG4gICAgICBjaGlsZC5fY2FsbEhvb2soJ2RldGFjaGVkJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaWdnZXIgYWxsIGhhbmRsZXJzIGZvciBhIGhvb2tcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGhvb2tcbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS5fY2FsbEhvb2sgPSBmdW5jdGlvbiAoaG9vaykge1xuICAgIHRoaXMuJGVtaXQoJ3ByZS1ob29rOicgKyBob29rKTtcbiAgICB2YXIgaGFuZGxlcnMgPSB0aGlzLiRvcHRpb25zW2hvb2tdO1xuICAgIGlmIChoYW5kbGVycykge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGogPSBoYW5kbGVycy5sZW5ndGg7IGkgPCBqOyBpKyspIHtcbiAgICAgICAgaGFuZGxlcnNbaV0uY2FsbCh0aGlzKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy4kZW1pdCgnaG9vazonICsgaG9vayk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG4vKipcbiAqIEEgZGlyZWN0aXZlIGxpbmtzIGEgRE9NIGVsZW1lbnQgd2l0aCBhIHBpZWNlIG9mIGRhdGEsXG4gKiB3aGljaCBpcyB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpbmcgYW4gZXhwcmVzc2lvbi5cbiAqIEl0IHJlZ2lzdGVycyBhIHdhdGNoZXIgd2l0aCB0aGUgZXhwcmVzc2lvbiBhbmQgY2FsbHNcbiAqIHRoZSBET00gdXBkYXRlIGZ1bmN0aW9uIHdoZW4gYSBjaGFuZ2UgaXMgdHJpZ2dlcmVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcGFyYW0ge05vZGV9IGVsXG4gKiBAcGFyYW0ge1Z1ZX0gdm1cbiAqIEBwYXJhbSB7T2JqZWN0fSBkZXNjcmlwdG9yXG4gKiAgICAgICAgICAgICAgICAgLSB7U3RyaW5nfSBuYW1lXG4gKiAgICAgICAgICAgICAgICAgLSB7T2JqZWN0fSBkZWZcbiAqICAgICAgICAgICAgICAgICAtIHtTdHJpbmd9IGV4cHJlc3Npb25cbiAqICAgICAgICAgICAgICAgICAtIHtBcnJheTxPYmplY3Q+fSBbZmlsdGVyc11cbiAqICAgICAgICAgICAgICAgICAtIHtCb29sZWFufSBsaXRlcmFsXG4gKiAgICAgICAgICAgICAgICAgLSB7U3RyaW5nfSBhdHRyXG4gKiAgICAgICAgICAgICAgICAgLSB7U3RyaW5nfSByYXdcbiAqIEBwYXJhbSB7T2JqZWN0fSBkZWYgLSBkaXJlY3RpdmUgZGVmaW5pdGlvbiBvYmplY3RcbiAqIEBwYXJhbSB7VnVlfSBbaG9zdF0gLSB0cmFuc2NsdXNpb24gaG9zdCBjb21wb25lbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBbc2NvcGVdIC0gdi1mb3Igc2NvcGVcbiAqIEBwYXJhbSB7RnJhZ21lbnR9IFtmcmFnXSAtIG93bmVyIGZyYWdtZW50XG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gRGlyZWN0aXZlKGRlc2NyaXB0b3IsIHZtLCBlbCwgaG9zdCwgc2NvcGUsIGZyYWcpIHtcbiAgdGhpcy52bSA9IHZtO1xuICB0aGlzLmVsID0gZWw7XG4gIC8vIGNvcHkgZGVzY3JpcHRvciBwcm9wZXJ0aWVzXG4gIHRoaXMuZGVzY3JpcHRvciA9IGRlc2NyaXB0b3I7XG4gIHRoaXMubmFtZSA9IGRlc2NyaXB0b3IubmFtZTtcbiAgdGhpcy5leHByZXNzaW9uID0gZGVzY3JpcHRvci5leHByZXNzaW9uO1xuICB0aGlzLmFyZyA9IGRlc2NyaXB0b3IuYXJnO1xuICB0aGlzLm1vZGlmaWVycyA9IGRlc2NyaXB0b3IubW9kaWZpZXJzO1xuICB0aGlzLmZpbHRlcnMgPSBkZXNjcmlwdG9yLmZpbHRlcnM7XG4gIHRoaXMubGl0ZXJhbCA9IHRoaXMubW9kaWZpZXJzICYmIHRoaXMubW9kaWZpZXJzLmxpdGVyYWw7XG4gIC8vIHByaXZhdGVcbiAgdGhpcy5fbG9ja2VkID0gZmFsc2U7XG4gIHRoaXMuX2JvdW5kID0gZmFsc2U7XG4gIHRoaXMuX2xpc3RlbmVycyA9IG51bGw7XG4gIC8vIGxpbmsgY29udGV4dFxuICB0aGlzLl9ob3N0ID0gaG9zdDtcbiAgdGhpcy5fc2NvcGUgPSBzY29wZTtcbiAgdGhpcy5fZnJhZyA9IGZyYWc7XG4gIC8vIHN0b3JlIGRpcmVjdGl2ZXMgb24gbm9kZSBpbiBkZXYgbW9kZVxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB0aGlzLmVsKSB7XG4gICAgdGhpcy5lbC5fdnVlX2RpcmVjdGl2ZXMgPSB0aGlzLmVsLl92dWVfZGlyZWN0aXZlcyB8fCBbXTtcbiAgICB0aGlzLmVsLl92dWVfZGlyZWN0aXZlcy5wdXNoKHRoaXMpO1xuICB9XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZSB0aGUgZGlyZWN0aXZlLCBtaXhpbiBkZWZpbml0aW9uIHByb3BlcnRpZXMsXG4gKiBzZXR1cCB0aGUgd2F0Y2hlciwgY2FsbCBkZWZpbml0aW9uIGJpbmQoKSBhbmQgdXBkYXRlKClcbiAqIGlmIHByZXNlbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGRlZlxuICovXG5cbkRpcmVjdGl2ZS5wcm90b3R5cGUuX2JpbmQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBuYW1lID0gdGhpcy5uYW1lO1xuICB2YXIgZGVzY3JpcHRvciA9IHRoaXMuZGVzY3JpcHRvcjtcblxuICAvLyByZW1vdmUgYXR0cmlidXRlXG4gIGlmICgobmFtZSAhPT0gJ2Nsb2FrJyB8fCB0aGlzLnZtLl9pc0NvbXBpbGVkKSAmJiB0aGlzLmVsICYmIHRoaXMuZWwucmVtb3ZlQXR0cmlidXRlKSB7XG4gICAgdmFyIGF0dHIgPSBkZXNjcmlwdG9yLmF0dHIgfHwgJ3YtJyArIG5hbWU7XG4gICAgdGhpcy5lbC5yZW1vdmVBdHRyaWJ1dGUoYXR0cik7XG4gIH1cblxuICAvLyBjb3B5IGRlZiBwcm9wZXJ0aWVzXG4gIHZhciBkZWYgPSBkZXNjcmlwdG9yLmRlZjtcbiAgaWYgKHR5cGVvZiBkZWYgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0aGlzLnVwZGF0ZSA9IGRlZjtcbiAgfSBlbHNlIHtcbiAgICBleHRlbmQodGhpcywgZGVmKTtcbiAgfVxuXG4gIC8vIHNldHVwIGRpcmVjdGl2ZSBwYXJhbXNcbiAgdGhpcy5fc2V0dXBQYXJhbXMoKTtcblxuICAvLyBpbml0aWFsIGJpbmRcbiAgaWYgKHRoaXMuYmluZCkge1xuICAgIHRoaXMuYmluZCgpO1xuICB9XG4gIHRoaXMuX2JvdW5kID0gdHJ1ZTtcblxuICBpZiAodGhpcy5saXRlcmFsKSB7XG4gICAgdGhpcy51cGRhdGUgJiYgdGhpcy51cGRhdGUoZGVzY3JpcHRvci5yYXcpO1xuICB9IGVsc2UgaWYgKCh0aGlzLmV4cHJlc3Npb24gfHwgdGhpcy5tb2RpZmllcnMpICYmICh0aGlzLnVwZGF0ZSB8fCB0aGlzLnR3b1dheSkgJiYgIXRoaXMuX2NoZWNrU3RhdGVtZW50KCkpIHtcbiAgICAvLyB3cmFwcGVkIHVwZGF0ZXIgZm9yIGNvbnRleHRcbiAgICB2YXIgZGlyID0gdGhpcztcbiAgICBpZiAodGhpcy51cGRhdGUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZSA9IGZ1bmN0aW9uICh2YWwsIG9sZFZhbCkge1xuICAgICAgICBpZiAoIWRpci5fbG9ja2VkKSB7XG4gICAgICAgICAgZGlyLnVwZGF0ZSh2YWwsIG9sZFZhbCk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3VwZGF0ZSA9IG5vb3A7XG4gICAgfVxuICAgIHZhciBwcmVQcm9jZXNzID0gdGhpcy5fcHJlUHJvY2VzcyA/IGJpbmQodGhpcy5fcHJlUHJvY2VzcywgdGhpcykgOiBudWxsO1xuICAgIHZhciBwb3N0UHJvY2VzcyA9IHRoaXMuX3Bvc3RQcm9jZXNzID8gYmluZCh0aGlzLl9wb3N0UHJvY2VzcywgdGhpcykgOiBudWxsO1xuICAgIHZhciB3YXRjaGVyID0gdGhpcy5fd2F0Y2hlciA9IG5ldyBXYXRjaGVyKHRoaXMudm0sIHRoaXMuZXhwcmVzc2lvbiwgdGhpcy5fdXBkYXRlLCAvLyBjYWxsYmFja1xuICAgIHtcbiAgICAgIGZpbHRlcnM6IHRoaXMuZmlsdGVycyxcbiAgICAgIHR3b1dheTogdGhpcy50d29XYXksXG4gICAgICBkZWVwOiB0aGlzLmRlZXAsXG4gICAgICBwcmVQcm9jZXNzOiBwcmVQcm9jZXNzLFxuICAgICAgcG9zdFByb2Nlc3M6IHBvc3RQcm9jZXNzLFxuICAgICAgc2NvcGU6IHRoaXMuX3Njb3BlXG4gICAgfSk7XG4gICAgLy8gdi1tb2RlbCB3aXRoIGluaXRhbCBpbmxpbmUgdmFsdWUgbmVlZCB0byBzeW5jIGJhY2sgdG9cbiAgICAvLyBtb2RlbCBpbnN0ZWFkIG9mIHVwZGF0ZSB0byBET00gb24gaW5pdC4gVGhleSB3b3VsZFxuICAgIC8vIHNldCB0aGUgYWZ0ZXJCaW5kIGhvb2sgdG8gaW5kaWNhdGUgdGhhdC5cbiAgICBpZiAodGhpcy5hZnRlckJpbmQpIHtcbiAgICAgIHRoaXMuYWZ0ZXJCaW5kKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnVwZGF0ZSkge1xuICAgICAgdGhpcy51cGRhdGUod2F0Y2hlci52YWx1ZSk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFNldHVwIGFsbCBwYXJhbSBhdHRyaWJ1dGVzLCBlLmcuIHRyYWNrLWJ5LFxuICogdHJhbnNpdGlvbi1tb2RlLCBldGMuLi5cbiAqL1xuXG5EaXJlY3RpdmUucHJvdG90eXBlLl9zZXR1cFBhcmFtcyA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLnBhcmFtcykge1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgcGFyYW1zID0gdGhpcy5wYXJhbXM7XG4gIC8vIHN3YXAgdGhlIHBhcmFtcyBhcnJheSB3aXRoIGEgZnJlc2ggb2JqZWN0LlxuICB0aGlzLnBhcmFtcyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIHZhciBpID0gcGFyYW1zLmxlbmd0aDtcbiAgdmFyIGtleSwgdmFsLCBtYXBwZWRLZXk7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBrZXkgPSBwYXJhbXNbaV07XG4gICAgbWFwcGVkS2V5ID0gY2FtZWxpemUoa2V5KTtcbiAgICB2YWwgPSBnZXRCaW5kQXR0cih0aGlzLmVsLCBrZXkpO1xuICAgIGlmICh2YWwgIT0gbnVsbCkge1xuICAgICAgLy8gZHluYW1pY1xuICAgICAgdGhpcy5fc2V0dXBQYXJhbVdhdGNoZXIobWFwcGVkS2V5LCB2YWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBzdGF0aWNcbiAgICAgIHZhbCA9IGdldEF0dHIodGhpcy5lbCwga2V5KTtcbiAgICAgIGlmICh2YWwgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLnBhcmFtc1ttYXBwZWRLZXldID0gdmFsID09PSAnJyA/IHRydWUgOiB2YWw7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFNldHVwIGEgd2F0Y2hlciBmb3IgYSBkeW5hbWljIHBhcmFtLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqIEBwYXJhbSB7U3RyaW5nfSBleHByZXNzaW9uXG4gKi9cblxuRGlyZWN0aXZlLnByb3RvdHlwZS5fc2V0dXBQYXJhbVdhdGNoZXIgPSBmdW5jdGlvbiAoa2V5LCBleHByZXNzaW9uKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICB2YXIgdW53YXRjaCA9ICh0aGlzLl9zY29wZSB8fCB0aGlzLnZtKS4kd2F0Y2goZXhwcmVzc2lvbiwgZnVuY3Rpb24gKHZhbCwgb2xkVmFsKSB7XG4gICAgc2VsZi5wYXJhbXNba2V5XSA9IHZhbDtcbiAgICAvLyBzaW5jZSB3ZSBhcmUgaW4gaW1tZWRpYXRlIG1vZGUsXG4gICAgLy8gb25seSBjYWxsIHRoZSBwYXJhbSBjaGFuZ2UgY2FsbGJhY2tzIGlmIHRoaXMgaXMgbm90IHRoZSBmaXJzdCB1cGRhdGUuXG4gICAgaWYgKGNhbGxlZCkge1xuICAgICAgdmFyIGNiID0gc2VsZi5wYXJhbVdhdGNoZXJzICYmIHNlbGYucGFyYW1XYXRjaGVyc1trZXldO1xuICAgICAgaWYgKGNiKSB7XG4gICAgICAgIGNiLmNhbGwoc2VsZiwgdmFsLCBvbGRWYWwpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsZWQgPSB0cnVlO1xuICAgIH1cbiAgfSwge1xuICAgIGltbWVkaWF0ZTogdHJ1ZSxcbiAgICB1c2VyOiBmYWxzZVxuICB9KTsodGhpcy5fcGFyYW1VbndhdGNoRm5zIHx8ICh0aGlzLl9wYXJhbVVud2F0Y2hGbnMgPSBbXSkpLnB1c2godW53YXRjaCk7XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIHRoZSBkaXJlY3RpdmUgaXMgYSBmdW5jdGlvbiBjYWxsZXJcbiAqIGFuZCBpZiB0aGUgZXhwcmVzc2lvbiBpcyBhIGNhbGxhYmxlIG9uZS4gSWYgYm90aCB0cnVlLFxuICogd2Ugd3JhcCB1cCB0aGUgZXhwcmVzc2lvbiBhbmQgdXNlIGl0IGFzIHRoZSBldmVudFxuICogaGFuZGxlci5cbiAqXG4gKiBlLmcuIG9uLWNsaWNrPVwiYSsrXCJcbiAqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbkRpcmVjdGl2ZS5wcm90b3R5cGUuX2NoZWNrU3RhdGVtZW50ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgZXhwcmVzc2lvbiA9IHRoaXMuZXhwcmVzc2lvbjtcbiAgaWYgKGV4cHJlc3Npb24gJiYgdGhpcy5hY2NlcHRTdGF0ZW1lbnQgJiYgIWlzU2ltcGxlUGF0aChleHByZXNzaW9uKSkge1xuICAgIHZhciBmbiA9IHBhcnNlRXhwcmVzc2lvbihleHByZXNzaW9uKS5nZXQ7XG4gICAgdmFyIHNjb3BlID0gdGhpcy5fc2NvcGUgfHwgdGhpcy52bTtcbiAgICB2YXIgaGFuZGxlciA9IGZ1bmN0aW9uIGhhbmRsZXIoZSkge1xuICAgICAgc2NvcGUuJGV2ZW50ID0gZTtcbiAgICAgIGZuLmNhbGwoc2NvcGUsIHNjb3BlKTtcbiAgICAgIHNjb3BlLiRldmVudCA9IG51bGw7XG4gICAgfTtcbiAgICBpZiAodGhpcy5maWx0ZXJzKSB7XG4gICAgICBoYW5kbGVyID0gc2NvcGUuX2FwcGx5RmlsdGVycyhoYW5kbGVyLCBudWxsLCB0aGlzLmZpbHRlcnMpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZShoYW5kbGVyKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZXQgdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUgd2l0aCB0aGUgc2V0dGVyLlxuICogVGhpcyBzaG91bGQgb25seSBiZSB1c2VkIGluIHR3by13YXkgZGlyZWN0aXZlc1xuICogZS5nLiB2LW1vZGVsLlxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsdWVcbiAqIEBwdWJsaWNcbiAqL1xuXG5EaXJlY3RpdmUucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICBpZiAodGhpcy50d29XYXkpIHtcbiAgICB0aGlzLl93aXRoTG9jayhmdW5jdGlvbiAoKSB7XG4gICAgICB0aGlzLl93YXRjaGVyLnNldCh2YWx1ZSk7XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIHdhcm4oJ0RpcmVjdGl2ZS5zZXQoKSBjYW4gb25seSBiZSB1c2VkIGluc2lkZSB0d29XYXknICsgJ2RpcmVjdGl2ZXMuJyk7XG4gIH1cbn07XG5cbi8qKlxuICogRXhlY3V0ZSBhIGZ1bmN0aW9uIHdoaWxlIHByZXZlbnRpbmcgdGhhdCBmdW5jdGlvbiBmcm9tXG4gKiB0cmlnZ2VyaW5nIHVwZGF0ZXMgb24gdGhpcyBkaXJlY3RpdmUgaW5zdGFuY2UuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqL1xuXG5EaXJlY3RpdmUucHJvdG90eXBlLl93aXRoTG9jayA9IGZ1bmN0aW9uIChmbikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHNlbGYuX2xvY2tlZCA9IHRydWU7XG4gIGZuLmNhbGwoc2VsZik7XG4gIG5leHRUaWNrKGZ1bmN0aW9uICgpIHtcbiAgICBzZWxmLl9sb2NrZWQgPSBmYWxzZTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIENvbnZlbmllbmNlIG1ldGhvZCB0aGF0IGF0dGFjaGVzIGEgRE9NIGV2ZW50IGxpc3RlbmVyXG4gKiB0byB0aGUgZGlyZWN0aXZlIGVsZW1lbnQgYW5kIGF1dG9tZXRpY2FsbHkgdGVhcnMgaXQgZG93blxuICogZHVyaW5nIHVuYmluZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW3VzZUNhcHR1cmVdXG4gKi9cblxuRGlyZWN0aXZlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudCwgaGFuZGxlciwgdXNlQ2FwdHVyZSkge1xuICBvbih0aGlzLmVsLCBldmVudCwgaGFuZGxlciwgdXNlQ2FwdHVyZSk7KHRoaXMuX2xpc3RlbmVycyB8fCAodGhpcy5fbGlzdGVuZXJzID0gW10pKS5wdXNoKFtldmVudCwgaGFuZGxlcl0pO1xufTtcblxuLyoqXG4gKiBUZWFyZG93biB0aGUgd2F0Y2hlciBhbmQgY2FsbCB1bmJpbmQuXG4gKi9cblxuRGlyZWN0aXZlLnByb3RvdHlwZS5fdGVhcmRvd24gPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLl9ib3VuZCkge1xuICAgIHRoaXMuX2JvdW5kID0gZmFsc2U7XG4gICAgaWYgKHRoaXMudW5iaW5kKSB7XG4gICAgICB0aGlzLnVuYmluZCgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5fd2F0Y2hlcikge1xuICAgICAgdGhpcy5fd2F0Y2hlci50ZWFyZG93bigpO1xuICAgIH1cbiAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fbGlzdGVuZXJzO1xuICAgIHZhciBpO1xuICAgIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAgIGkgPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICBvZmYodGhpcy5lbCwgbGlzdGVuZXJzW2ldWzBdLCBsaXN0ZW5lcnNbaV1bMV0pO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgdW53YXRjaEZucyA9IHRoaXMuX3BhcmFtVW53YXRjaEZucztcbiAgICBpZiAodW53YXRjaEZucykge1xuICAgICAgaSA9IHVud2F0Y2hGbnMubGVuZ3RoO1xuICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICB1bndhdGNoRm5zW2ldKCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHRoaXMuZWwpIHtcbiAgICAgIHRoaXMuZWwuX3Z1ZV9kaXJlY3RpdmVzLiRyZW1vdmUodGhpcyk7XG4gICAgfVxuICAgIHRoaXMudm0gPSB0aGlzLmVsID0gdGhpcy5fd2F0Y2hlciA9IHRoaXMuX2xpc3RlbmVycyA9IG51bGw7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGxpZmVjeWNsZU1peGluIChWdWUpIHtcbiAgLyoqXG4gICAqIFVwZGF0ZSB2LXJlZiBmb3IgY29tcG9uZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlbW92ZVxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLl91cGRhdGVSZWYgPSBmdW5jdGlvbiAocmVtb3ZlKSB7XG4gICAgdmFyIHJlZiA9IHRoaXMuJG9wdGlvbnMuX3JlZjtcbiAgICBpZiAocmVmKSB7XG4gICAgICB2YXIgcmVmcyA9ICh0aGlzLl9zY29wZSB8fCB0aGlzLl9jb250ZXh0KS4kcmVmcztcbiAgICAgIGlmIChyZW1vdmUpIHtcbiAgICAgICAgaWYgKHJlZnNbcmVmXSA9PT0gdGhpcykge1xuICAgICAgICAgIHJlZnNbcmVmXSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlZnNbcmVmXSA9IHRoaXM7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBUcmFuc2NsdWRlLCBjb21waWxlIGFuZCBsaW5rIGVsZW1lbnQuXG4gICAqXG4gICAqIElmIGEgcHJlLWNvbXBpbGVkIGxpbmtlciBpcyBhdmFpbGFibGUsIHRoYXQgbWVhbnMgdGhlXG4gICAqIHBhc3NlZCBpbiBlbGVtZW50IHdpbGwgYmUgcHJlLXRyYW5zY2x1ZGVkIGFuZCBjb21waWxlZFxuICAgKiBhcyB3ZWxsIC0gYWxsIHdlIG5lZWQgdG8gZG8gaXMgdG8gY2FsbCB0aGUgbGlua2VyLlxuICAgKlxuICAgKiBPdGhlcndpc2Ugd2UgbmVlZCB0byBjYWxsIHRyYW5zY2x1ZGUvY29tcGlsZS9saW5rIGhlcmUuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS5fY29tcGlsZSA9IGZ1bmN0aW9uIChlbCkge1xuICAgIHZhciBvcHRpb25zID0gdGhpcy4kb3B0aW9ucztcblxuICAgIC8vIHRyYW5zY2x1ZGUgYW5kIGluaXQgZWxlbWVudFxuICAgIC8vIHRyYW5zY2x1ZGUgY2FuIHBvdGVudGlhbGx5IHJlcGxhY2Ugb3JpZ2luYWxcbiAgICAvLyBzbyB3ZSBuZWVkIHRvIGtlZXAgcmVmZXJlbmNlOyB0aGlzIHN0ZXAgYWxzbyBpbmplY3RzXG4gICAgLy8gdGhlIHRlbXBsYXRlIGFuZCBjYWNoZXMgdGhlIG9yaWdpbmFsIGF0dHJpYnV0ZXNcbiAgICAvLyBvbiB0aGUgY29udGFpbmVyIG5vZGUgYW5kIHJlcGxhY2VyIG5vZGUuXG4gICAgdmFyIG9yaWdpbmFsID0gZWw7XG4gICAgZWwgPSB0cmFuc2NsdWRlKGVsLCBvcHRpb25zKTtcbiAgICB0aGlzLl9pbml0RWxlbWVudChlbCk7XG5cbiAgICAvLyBoYW5kbGUgdi1wcmUgb24gcm9vdCBub2RlICgjMjAyNilcbiAgICBpZiAoZWwubm9kZVR5cGUgPT09IDEgJiYgZ2V0QXR0cihlbCwgJ3YtcHJlJykgIT09IG51bGwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyByb290IGlzIGFsd2F5cyBjb21waWxlZCBwZXItaW5zdGFuY2UsIGJlY2F1c2VcbiAgICAvLyBjb250YWluZXIgYXR0cnMgYW5kIHByb3BzIGNhbiBiZSBkaWZmZXJlbnQgZXZlcnkgdGltZS5cbiAgICB2YXIgY29udGV4dE9wdGlvbnMgPSB0aGlzLl9jb250ZXh0ICYmIHRoaXMuX2NvbnRleHQuJG9wdGlvbnM7XG4gICAgdmFyIHJvb3RMaW5rZXIgPSBjb21waWxlUm9vdChlbCwgb3B0aW9ucywgY29udGV4dE9wdGlvbnMpO1xuXG4gICAgLy8gc2NhbiBmb3Igc2xvdCBkaXN0cmlidXRpb24gYmVmb3JlIGNvbXBpbGluZyB0aGUgY29udGVudFxuICAgIC8vIHNvIHRoYXQgaXQncyBkZWNvdXBlbGQgZnJvbSBzbG90L2RpcmVjdGl2ZSBjb21waWxhdGlvbiBvcmRlclxuICAgIHNjYW5TbG90cyhlbCwgb3B0aW9ucy5fY29udGVudCwgdGhpcyk7XG5cbiAgICAvLyBjb21waWxlIGFuZCBsaW5rIHRoZSByZXN0XG4gICAgdmFyIGNvbnRlbnRMaW5rRm47XG4gICAgdmFyIGN0b3IgPSB0aGlzLmNvbnN0cnVjdG9yO1xuICAgIC8vIGNvbXBvbmVudCBjb21waWxhdGlvbiBjYW4gYmUgY2FjaGVkXG4gICAgLy8gYXMgbG9uZyBhcyBpdCdzIG5vdCB1c2luZyBpbmxpbmUtdGVtcGxhdGVcbiAgICBpZiAob3B0aW9ucy5fbGlua2VyQ2FjaGFibGUpIHtcbiAgICAgIGNvbnRlbnRMaW5rRm4gPSBjdG9yLmxpbmtlcjtcbiAgICAgIGlmICghY29udGVudExpbmtGbikge1xuICAgICAgICBjb250ZW50TGlua0ZuID0gY3Rvci5saW5rZXIgPSBjb21waWxlKGVsLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBsaW5rIHBoYXNlXG4gICAgLy8gbWFrZSBzdXJlIHRvIGxpbmsgcm9vdCB3aXRoIHByb3Agc2NvcGUhXG4gICAgdmFyIHJvb3RVbmxpbmtGbiA9IHJvb3RMaW5rZXIodGhpcywgZWwsIHRoaXMuX3Njb3BlKTtcbiAgICB2YXIgY29udGVudFVubGlua0ZuID0gY29udGVudExpbmtGbiA/IGNvbnRlbnRMaW5rRm4odGhpcywgZWwpIDogY29tcGlsZShlbCwgb3B0aW9ucykodGhpcywgZWwpO1xuXG4gICAgLy8gcmVnaXN0ZXIgY29tcG9zaXRlIHVubGluayBmdW5jdGlvblxuICAgIC8vIHRvIGJlIGNhbGxlZCBkdXJpbmcgaW5zdGFuY2UgZGVzdHJ1Y3Rpb25cbiAgICB0aGlzLl91bmxpbmtGbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJvb3RVbmxpbmtGbigpO1xuICAgICAgLy8gcGFzc2luZyBkZXN0cm95aW5nOiB0cnVlIHRvIGF2b2lkIHNlYXJjaGluZyBhbmRcbiAgICAgIC8vIHNwbGljaW5nIHRoZSBkaXJlY3RpdmVzXG4gICAgICBjb250ZW50VW5saW5rRm4odHJ1ZSk7XG4gICAgfTtcblxuICAgIC8vIGZpbmFsbHkgcmVwbGFjZSBvcmlnaW5hbFxuICAgIGlmIChvcHRpb25zLnJlcGxhY2UpIHtcbiAgICAgIHJlcGxhY2Uob3JpZ2luYWwsIGVsKTtcbiAgICB9XG5cbiAgICB0aGlzLl9pc0NvbXBpbGVkID0gdHJ1ZTtcbiAgICB0aGlzLl9jYWxsSG9vaygnY29tcGlsZWQnKTtcbiAgfTtcblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBpbnN0YW5jZSBlbGVtZW50LiBDYWxsZWQgaW4gdGhlIHB1YmxpY1xuICAgKiAkbW91bnQoKSBtZXRob2QuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS5faW5pdEVsZW1lbnQgPSBmdW5jdGlvbiAoZWwpIHtcbiAgICBpZiAoaXNGcmFnbWVudChlbCkpIHtcbiAgICAgIHRoaXMuX2lzRnJhZ21lbnQgPSB0cnVlO1xuICAgICAgdGhpcy4kZWwgPSB0aGlzLl9mcmFnbWVudFN0YXJ0ID0gZWwuZmlyc3RDaGlsZDtcbiAgICAgIHRoaXMuX2ZyYWdtZW50RW5kID0gZWwubGFzdENoaWxkO1xuICAgICAgLy8gc2V0IHBlcnNpc3RlZCB0ZXh0IGFuY2hvcnMgdG8gZW1wdHlcbiAgICAgIGlmICh0aGlzLl9mcmFnbWVudFN0YXJ0Lm5vZGVUeXBlID09PSAzKSB7XG4gICAgICAgIHRoaXMuX2ZyYWdtZW50U3RhcnQuZGF0YSA9IHRoaXMuX2ZyYWdtZW50RW5kLmRhdGEgPSAnJztcbiAgICAgIH1cbiAgICAgIHRoaXMuX2ZyYWdtZW50ID0gZWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuJGVsID0gZWw7XG4gICAgfVxuICAgIHRoaXMuJGVsLl9fdnVlX18gPSB0aGlzO1xuICAgIHRoaXMuX2NhbGxIb29rKCdiZWZvcmVDb21waWxlJyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhbmQgYmluZCBhIGRpcmVjdGl2ZSB0byBhbiBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSAtIGRpcmVjdGl2ZSBuYW1lXG4gICAqIEBwYXJhbSB7Tm9kZX0gbm9kZSAgIC0gdGFyZ2V0IG5vZGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGRlc2MgLSBwYXJzZWQgZGlyZWN0aXZlIGRlc2NyaXB0b3JcbiAgICogQHBhcmFtIHtPYmplY3R9IGRlZiAgLSBkaXJlY3RpdmUgZGVmaW5pdGlvbiBvYmplY3RcbiAgICogQHBhcmFtIHtWdWV9IFtob3N0XSAtIHRyYW5zY2x1c2lvbiBob3N0IGNvbXBvbmVudFxuICAgKiBAcGFyYW0ge09iamVjdH0gW3Njb3BlXSAtIHYtZm9yIHNjb3BlXG4gICAqIEBwYXJhbSB7RnJhZ21lbnR9IFtmcmFnXSAtIG93bmVyIGZyYWdtZW50XG4gICAqL1xuXG4gIFZ1ZS5wcm90b3R5cGUuX2JpbmREaXIgPSBmdW5jdGlvbiAoZGVzY3JpcHRvciwgbm9kZSwgaG9zdCwgc2NvcGUsIGZyYWcpIHtcbiAgICB0aGlzLl9kaXJlY3RpdmVzLnB1c2gobmV3IERpcmVjdGl2ZShkZXNjcmlwdG9yLCB0aGlzLCBub2RlLCBob3N0LCBzY29wZSwgZnJhZykpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBUZWFyZG93biBhbiBpbnN0YW5jZSwgdW5vYnNlcnZlcyB0aGUgZGF0YSwgdW5iaW5kIGFsbCB0aGVcbiAgICogZGlyZWN0aXZlcywgdHVybiBvZmYgYWxsIHRoZSBldmVudCBsaXN0ZW5lcnMsIGV0Yy5cbiAgICpcbiAgICogQHBhcmFtIHtCb29sZWFufSByZW1vdmUgLSB3aGV0aGVyIHRvIHJlbW92ZSB0aGUgRE9NIG5vZGUuXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gZGVmZXJDbGVhbnVwIC0gaWYgdHJ1ZSwgZGVmZXIgY2xlYW51cCB0b1xuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJlIGNhbGxlZCBsYXRlclxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24gKHJlbW92ZSwgZGVmZXJDbGVhbnVwKSB7XG4gICAgaWYgKHRoaXMuX2lzQmVpbmdEZXN0cm95ZWQpIHtcbiAgICAgIGlmICghZGVmZXJDbGVhbnVwKSB7XG4gICAgICAgIHRoaXMuX2NsZWFudXAoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZGVzdHJveVJlYWR5O1xuICAgIHZhciBwZW5kaW5nUmVtb3ZhbDtcblxuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAvLyBDbGVhbnVwIHNob3VsZCBiZSBjYWxsZWQgZWl0aGVyIHN5bmNocm9ub3VzbHkgb3IgYXN5bmNocm9ub3lzbHkgYXNcbiAgICAvLyBjYWxsYmFjayBvZiB0aGlzLiRyZW1vdmUoKSwgb3IgaWYgcmVtb3ZlIGFuZCBkZWZlckNsZWFudXAgYXJlIGZhbHNlLlxuICAgIC8vIEluIGFueSBjYXNlIGl0IHNob3VsZCBiZSBjYWxsZWQgYWZ0ZXIgYWxsIG90aGVyIHJlbW92aW5nLCB1bmJpbmRpbmcgYW5kXG4gICAgLy8gdHVybmluZyBvZiBpcyBkb25lXG4gICAgdmFyIGNsZWFudXBJZlBvc3NpYmxlID0gZnVuY3Rpb24gY2xlYW51cElmUG9zc2libGUoKSB7XG4gICAgICBpZiAoZGVzdHJveVJlYWR5ICYmICFwZW5kaW5nUmVtb3ZhbCAmJiAhZGVmZXJDbGVhbnVwKSB7XG4gICAgICAgIHNlbGYuX2NsZWFudXAoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgLy8gcmVtb3ZlIERPTSBlbGVtZW50XG4gICAgaWYgKHJlbW92ZSAmJiB0aGlzLiRlbCkge1xuICAgICAgcGVuZGluZ1JlbW92YWwgPSB0cnVlO1xuICAgICAgdGhpcy4kcmVtb3ZlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcGVuZGluZ1JlbW92YWwgPSBmYWxzZTtcbiAgICAgICAgY2xlYW51cElmUG9zc2libGUoKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuX2NhbGxIb29rKCdiZWZvcmVEZXN0cm95Jyk7XG4gICAgdGhpcy5faXNCZWluZ0Rlc3Ryb3llZCA9IHRydWU7XG4gICAgdmFyIGk7XG4gICAgLy8gcmVtb3ZlIHNlbGYgZnJvbSBwYXJlbnQuIG9ubHkgbmVjZXNzYXJ5XG4gICAgLy8gaWYgcGFyZW50IGlzIG5vdCBiZWluZyBkZXN0cm95ZWQgYXMgd2VsbC5cbiAgICB2YXIgcGFyZW50ID0gdGhpcy4kcGFyZW50O1xuICAgIGlmIChwYXJlbnQgJiYgIXBhcmVudC5faXNCZWluZ0Rlc3Ryb3llZCkge1xuICAgICAgcGFyZW50LiRjaGlsZHJlbi4kcmVtb3ZlKHRoaXMpO1xuICAgICAgLy8gdW5yZWdpc3RlciByZWYgKHJlbW92ZTogdHJ1ZSlcbiAgICAgIHRoaXMuX3VwZGF0ZVJlZih0cnVlKTtcbiAgICB9XG4gICAgLy8gZGVzdHJveSBhbGwgY2hpbGRyZW4uXG4gICAgaSA9IHRoaXMuJGNoaWxkcmVuLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICB0aGlzLiRjaGlsZHJlbltpXS4kZGVzdHJveSgpO1xuICAgIH1cbiAgICAvLyB0ZWFyZG93biBwcm9wc1xuICAgIGlmICh0aGlzLl9wcm9wc1VubGlua0ZuKSB7XG4gICAgICB0aGlzLl9wcm9wc1VubGlua0ZuKCk7XG4gICAgfVxuICAgIC8vIHRlYXJkb3duIGFsbCBkaXJlY3RpdmVzLiB0aGlzIGFsc28gdGVhcnNkb3duIGFsbFxuICAgIC8vIGRpcmVjdGl2ZS1vd25lZCB3YXRjaGVycy5cbiAgICBpZiAodGhpcy5fdW5saW5rRm4pIHtcbiAgICAgIHRoaXMuX3VubGlua0ZuKCk7XG4gICAgfVxuICAgIGkgPSB0aGlzLl93YXRjaGVycy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgdGhpcy5fd2F0Y2hlcnNbaV0udGVhcmRvd24oKTtcbiAgICB9XG4gICAgLy8gcmVtb3ZlIHJlZmVyZW5jZSB0byBzZWxmIG9uICRlbFxuICAgIGlmICh0aGlzLiRlbCkge1xuICAgICAgdGhpcy4kZWwuX192dWVfXyA9IG51bGw7XG4gICAgfVxuXG4gICAgZGVzdHJveVJlYWR5ID0gdHJ1ZTtcbiAgICBjbGVhbnVwSWZQb3NzaWJsZSgpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDbGVhbiB1cCB0byBlbnN1cmUgZ2FyYmFnZSBjb2xsZWN0aW9uLlxuICAgKiBUaGlzIGlzIGNhbGxlZCBhZnRlciB0aGUgbGVhdmUgdHJhbnNpdGlvbiBpZiB0aGVyZVxuICAgKiBpcyBhbnkuXG4gICAqL1xuXG4gIFZ1ZS5wcm90b3R5cGUuX2NsZWFudXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuX2lzRGVzdHJveWVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIHJlbW92ZSBzZWxmIGZyb20gb3duZXIgZnJhZ21lbnRcbiAgICAvLyBkbyBpdCBpbiBjbGVhbnVwIHNvIHRoYXQgd2UgY2FuIGNhbGwgJGRlc3Ryb3kgd2l0aFxuICAgIC8vIGRlZmVyIHJpZ2h0IHdoZW4gYSBmcmFnbWVudCBpcyBhYm91dCB0byBiZSByZW1vdmVkLlxuICAgIGlmICh0aGlzLl9mcmFnKSB7XG4gICAgICB0aGlzLl9mcmFnLmNoaWxkcmVuLiRyZW1vdmUodGhpcyk7XG4gICAgfVxuICAgIC8vIHJlbW92ZSByZWZlcmVuY2UgZnJvbSBkYXRhIG9iXG4gICAgLy8gZnJvemVuIG9iamVjdCBtYXkgbm90IGhhdmUgb2JzZXJ2ZXIuXG4gICAgaWYgKHRoaXMuX2RhdGEuX19vYl9fKSB7XG4gICAgICB0aGlzLl9kYXRhLl9fb2JfXy5yZW1vdmVWbSh0aGlzKTtcbiAgICB9XG4gICAgLy8gQ2xlYW4gdXAgcmVmZXJlbmNlcyB0byBwcml2YXRlIHByb3BlcnRpZXMgYW5kIG90aGVyXG4gICAgLy8gaW5zdGFuY2VzLiBwcmVzZXJ2ZSByZWZlcmVuY2UgdG8gX2RhdGEgc28gdGhhdCBwcm94eVxuICAgIC8vIGFjY2Vzc29ycyBzdGlsbCB3b3JrLiBUaGUgb25seSBwb3RlbnRpYWwgc2lkZSBlZmZlY3RcbiAgICAvLyBoZXJlIGlzIHRoYXQgbXV0YXRpbmcgdGhlIGluc3RhbmNlIGFmdGVyIGl0J3MgZGVzdHJveWVkXG4gICAgLy8gbWF5IGFmZmVjdCB0aGUgc3RhdGUgb2Ygb3RoZXIgY29tcG9uZW50cyB0aGF0IGFyZSBzdGlsbFxuICAgIC8vIG9ic2VydmluZyB0aGUgc2FtZSBvYmplY3QsIGJ1dCB0aGF0IHNlZW1zIHRvIGJlIGFcbiAgICAvLyByZWFzb25hYmxlIHJlc3BvbnNpYmlsaXR5IGZvciB0aGUgdXNlciByYXRoZXIgdGhhblxuICAgIC8vIGFsd2F5cyB0aHJvd2luZyBhbiBlcnJvciBvbiB0aGVtLlxuICAgIHRoaXMuJGVsID0gdGhpcy4kcGFyZW50ID0gdGhpcy4kcm9vdCA9IHRoaXMuJGNoaWxkcmVuID0gdGhpcy5fd2F0Y2hlcnMgPSB0aGlzLl9jb250ZXh0ID0gdGhpcy5fc2NvcGUgPSB0aGlzLl9kaXJlY3RpdmVzID0gbnVsbDtcbiAgICAvLyBjYWxsIHRoZSBsYXN0IGhvb2suLi5cbiAgICB0aGlzLl9pc0Rlc3Ryb3llZCA9IHRydWU7XG4gICAgdGhpcy5fY2FsbEhvb2soJ2Rlc3Ryb3llZCcpO1xuICAgIC8vIHR1cm4gb2ZmIGFsbCBpbnN0YW5jZSBsaXN0ZW5lcnMuXG4gICAgdGhpcy4kb2ZmKCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIG1pc2NNaXhpbiAoVnVlKSB7XG4gIC8qKlxuICAgKiBBcHBseSBhIGxpc3Qgb2YgZmlsdGVyIChkZXNjcmlwdG9ycykgdG8gYSB2YWx1ZS5cbiAgICogVXNpbmcgcGxhaW4gZm9yIGxvb3BzIGhlcmUgYmVjYXVzZSB0aGlzIHdpbGwgYmUgY2FsbGVkIGluXG4gICAqIHRoZSBnZXR0ZXIgb2YgYW55IHdhdGNoZXIgd2l0aCBmaWx0ZXJzIHNvIGl0IGlzIHZlcnlcbiAgICogcGVyZm9ybWFuY2Ugc2Vuc2l0aXZlLlxuICAgKlxuICAgKiBAcGFyYW0geyp9IHZhbHVlXG4gICAqIEBwYXJhbSB7Kn0gW29sZFZhbHVlXVxuICAgKiBAcGFyYW0ge0FycmF5fSBmaWx0ZXJzXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gd3JpdGVcbiAgICogQHJldHVybiB7Kn1cbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS5fYXBwbHlGaWx0ZXJzID0gZnVuY3Rpb24gKHZhbHVlLCBvbGRWYWx1ZSwgZmlsdGVycywgd3JpdGUpIHtcbiAgICB2YXIgZmlsdGVyLCBmbiwgYXJncywgYXJnLCBvZmZzZXQsIGksIGwsIGosIGs7XG4gICAgZm9yIChpID0gMCwgbCA9IGZpbHRlcnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBmaWx0ZXIgPSBmaWx0ZXJzW2ldO1xuICAgICAgZm4gPSByZXNvbHZlQXNzZXQodGhpcy4kb3B0aW9ucywgJ2ZpbHRlcnMnLCBmaWx0ZXIubmFtZSk7XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgICBhc3NlcnRBc3NldChmbiwgJ2ZpbHRlcicsIGZpbHRlci5uYW1lKTtcbiAgICAgIH1cbiAgICAgIGlmICghZm4pIGNvbnRpbnVlO1xuICAgICAgZm4gPSB3cml0ZSA/IGZuLndyaXRlIDogZm4ucmVhZCB8fCBmbjtcbiAgICAgIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIGNvbnRpbnVlO1xuICAgICAgYXJncyA9IHdyaXRlID8gW3ZhbHVlLCBvbGRWYWx1ZV0gOiBbdmFsdWVdO1xuICAgICAgb2Zmc2V0ID0gd3JpdGUgPyAyIDogMTtcbiAgICAgIGlmIChmaWx0ZXIuYXJncykge1xuICAgICAgICBmb3IgKGogPSAwLCBrID0gZmlsdGVyLmFyZ3MubGVuZ3RoOyBqIDwgazsgaisrKSB7XG4gICAgICAgICAgYXJnID0gZmlsdGVyLmFyZ3Nbal07XG4gICAgICAgICAgYXJnc1tqICsgb2Zmc2V0XSA9IGFyZy5keW5hbWljID8gdGhpcy4kZ2V0KGFyZy52YWx1ZSkgOiBhcmcudmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhbHVlID0gZm4uYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfTtcblxuICAvKipcbiAgICogUmVzb2x2ZSBhIGNvbXBvbmVudCwgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIGNvbXBvbmVudFxuICAgKiBpcyBkZWZpbmVkIG5vcm1hbGx5IG9yIHVzaW5nIGFuIGFzeW5jIGZhY3RvcnkgZnVuY3Rpb24uXG4gICAqIFJlc29sdmVzIHN5bmNocm9ub3VzbHkgaWYgYWxyZWFkeSByZXNvbHZlZCwgb3RoZXJ3aXNlXG4gICAqIHJlc29sdmVzIGFzeW5jaHJvbm91c2x5IGFuZCBjYWNoZXMgdGhlIHJlc29sdmVkXG4gICAqIGNvbnN0cnVjdG9yIG9uIHRoZSBmYWN0b3J5LlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gaWRcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2JcbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS5fcmVzb2x2ZUNvbXBvbmVudCA9IGZ1bmN0aW9uIChpZCwgY2IpIHtcbiAgICB2YXIgZmFjdG9yeSA9IHJlc29sdmVBc3NldCh0aGlzLiRvcHRpb25zLCAnY29tcG9uZW50cycsIGlkKTtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgYXNzZXJ0QXNzZXQoZmFjdG9yeSwgJ2NvbXBvbmVudCcsIGlkKTtcbiAgICB9XG4gICAgaWYgKCFmYWN0b3J5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGFzeW5jIGNvbXBvbmVudCBmYWN0b3J5XG4gICAgaWYgKCFmYWN0b3J5Lm9wdGlvbnMpIHtcbiAgICAgIGlmIChmYWN0b3J5LnJlc29sdmVkKSB7XG4gICAgICAgIC8vIGNhY2hlZFxuICAgICAgICBjYihmYWN0b3J5LnJlc29sdmVkKTtcbiAgICAgIH0gZWxzZSBpZiAoZmFjdG9yeS5yZXF1ZXN0ZWQpIHtcbiAgICAgICAgLy8gcG9vbCBjYWxsYmFja3NcbiAgICAgICAgZmFjdG9yeS5wZW5kaW5nQ2FsbGJhY2tzLnB1c2goY2IpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZmFjdG9yeS5yZXF1ZXN0ZWQgPSB0cnVlO1xuICAgICAgICB2YXIgY2JzID0gZmFjdG9yeS5wZW5kaW5nQ2FsbGJhY2tzID0gW2NiXTtcbiAgICAgICAgZmFjdG9yeS5jYWxsKHRoaXMsIGZ1bmN0aW9uIHJlc29sdmUocmVzKSB7XG4gICAgICAgICAgaWYgKGlzUGxhaW5PYmplY3QocmVzKSkge1xuICAgICAgICAgICAgcmVzID0gVnVlLmV4dGVuZChyZXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBjYWNoZSByZXNvbHZlZFxuICAgICAgICAgIGZhY3RvcnkucmVzb2x2ZWQgPSByZXM7XG4gICAgICAgICAgLy8gaW52b2tlIGNhbGxiYWNrc1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gY2JzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgY2JzW2ldKHJlcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCBmdW5jdGlvbiByZWplY3QocmVhc29uKSB7XG4gICAgICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiB3YXJuKCdGYWlsZWQgdG8gcmVzb2x2ZSBhc3luYyBjb21wb25lbnQ6ICcgKyBpZCArICcuICcgKyAocmVhc29uID8gJ1xcblJlYXNvbjogJyArIHJlYXNvbiA6ICcnKSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBub3JtYWwgY29tcG9uZW50XG4gICAgICBjYihmYWN0b3J5KTtcbiAgICB9XG4gIH07XG59XG5cbnZhciBmaWx0ZXJSRSQxID0gL1tefF1cXHxbXnxdLztcblxuZnVuY3Rpb24gZGF0YUFQSSAoVnVlKSB7XG4gIC8qKlxuICAgKiBHZXQgdGhlIHZhbHVlIGZyb20gYW4gZXhwcmVzc2lvbiBvbiB0aGlzIHZtLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXhwXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gW2FzU3RhdGVtZW50XVxuICAgKiBAcmV0dXJuIHsqfVxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLiRnZXQgPSBmdW5jdGlvbiAoZXhwLCBhc1N0YXRlbWVudCkge1xuICAgIHZhciByZXMgPSBwYXJzZUV4cHJlc3Npb24oZXhwKTtcbiAgICBpZiAocmVzKSB7XG4gICAgICBpZiAoYXNTdGF0ZW1lbnQgJiYgIWlzU2ltcGxlUGF0aChleHApKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIHN0YXRlbWVudEhhbmRsZXIoKSB7XG4gICAgICAgICAgc2VsZi4kYXJndW1lbnRzID0gdG9BcnJheShhcmd1bWVudHMpO1xuICAgICAgICAgIHZhciByZXN1bHQgPSByZXMuZ2V0LmNhbGwoc2VsZiwgc2VsZik7XG4gICAgICAgICAgc2VsZi4kYXJndW1lbnRzID0gbnVsbDtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gcmVzLmdldC5jYWxsKHRoaXMsIHRoaXMpO1xuICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogU2V0IHRoZSB2YWx1ZSBmcm9tIGFuIGV4cHJlc3Npb24gb24gdGhpcyB2bS5cbiAgICogVGhlIGV4cHJlc3Npb24gbXVzdCBiZSBhIHZhbGlkIGxlZnQtaGFuZFxuICAgKiBleHByZXNzaW9uIGluIGFuIGFzc2lnbm1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBleHBcbiAgICogQHBhcmFtIHsqfSB2YWxcbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS4kc2V0ID0gZnVuY3Rpb24gKGV4cCwgdmFsKSB7XG4gICAgdmFyIHJlcyA9IHBhcnNlRXhwcmVzc2lvbihleHAsIHRydWUpO1xuICAgIGlmIChyZXMgJiYgcmVzLnNldCkge1xuICAgICAgcmVzLnNldC5jYWxsKHRoaXMsIHRoaXMsIHZhbCk7XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBEZWxldGUgYSBwcm9wZXJ0eSBvbiB0aGUgVk1cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGtleVxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLiRkZWxldGUgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgZGVsKHRoaXMuX2RhdGEsIGtleSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFdhdGNoIGFuIGV4cHJlc3Npb24sIHRyaWdnZXIgY2FsbGJhY2sgd2hlbiBpdHNcbiAgICogdmFsdWUgY2hhbmdlcy5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IGV4cE9yRm5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2JcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKiAgICAgICAgICAgICAgICAgLSB7Qm9vbGVhbn0gZGVlcFxuICAgKiAgICAgICAgICAgICAgICAgLSB7Qm9vbGVhbn0gaW1tZWRpYXRlXG4gICAqIEByZXR1cm4ge0Z1bmN0aW9ufSAtIHVud2F0Y2hGblxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLiR3YXRjaCA9IGZ1bmN0aW9uIChleHBPckZuLCBjYiwgb3B0aW9ucykge1xuICAgIHZhciB2bSA9IHRoaXM7XG4gICAgdmFyIHBhcnNlZDtcbiAgICBpZiAodHlwZW9mIGV4cE9yRm4gPT09ICdzdHJpbmcnKSB7XG4gICAgICBwYXJzZWQgPSBwYXJzZURpcmVjdGl2ZShleHBPckZuKTtcbiAgICAgIGV4cE9yRm4gPSBwYXJzZWQuZXhwcmVzc2lvbjtcbiAgICB9XG4gICAgdmFyIHdhdGNoZXIgPSBuZXcgV2F0Y2hlcih2bSwgZXhwT3JGbiwgY2IsIHtcbiAgICAgIGRlZXA6IG9wdGlvbnMgJiYgb3B0aW9ucy5kZWVwLFxuICAgICAgc3luYzogb3B0aW9ucyAmJiBvcHRpb25zLnN5bmMsXG4gICAgICBmaWx0ZXJzOiBwYXJzZWQgJiYgcGFyc2VkLmZpbHRlcnMsXG4gICAgICB1c2VyOiAhb3B0aW9ucyB8fCBvcHRpb25zLnVzZXIgIT09IGZhbHNlXG4gICAgfSk7XG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5pbW1lZGlhdGUpIHtcbiAgICAgIGNiLmNhbGwodm0sIHdhdGNoZXIudmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gZnVuY3Rpb24gdW53YXRjaEZuKCkge1xuICAgICAgd2F0Y2hlci50ZWFyZG93bigpO1xuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIEV2YWx1YXRlIGEgdGV4dCBkaXJlY3RpdmUsIGluY2x1ZGluZyBmaWx0ZXJzLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gdGV4dFxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IFthc1N0YXRlbWVudF1cbiAgICogQHJldHVybiB7U3RyaW5nfVxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLiRldmFsID0gZnVuY3Rpb24gKHRleHQsIGFzU3RhdGVtZW50KSB7XG4gICAgLy8gY2hlY2sgZm9yIGZpbHRlcnMuXG4gICAgaWYgKGZpbHRlclJFJDEudGVzdCh0ZXh0KSkge1xuICAgICAgdmFyIGRpciA9IHBhcnNlRGlyZWN0aXZlKHRleHQpO1xuICAgICAgLy8gdGhlIGZpbHRlciByZWdleCBjaGVjayBtaWdodCBnaXZlIGZhbHNlIHBvc2l0aXZlXG4gICAgICAvLyBmb3IgcGlwZXMgaW5zaWRlIHN0cmluZ3MsIHNvIGl0J3MgcG9zc2libGUgdGhhdFxuICAgICAgLy8gd2UgZG9uJ3QgZ2V0IGFueSBmaWx0ZXJzIGhlcmVcbiAgICAgIHZhciB2YWwgPSB0aGlzLiRnZXQoZGlyLmV4cHJlc3Npb24sIGFzU3RhdGVtZW50KTtcbiAgICAgIHJldHVybiBkaXIuZmlsdGVycyA/IHRoaXMuX2FwcGx5RmlsdGVycyh2YWwsIG51bGwsIGRpci5maWx0ZXJzKSA6IHZhbDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbm8gZmlsdGVyXG4gICAgICByZXR1cm4gdGhpcy4kZ2V0KHRleHQsIGFzU3RhdGVtZW50KTtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIEludGVycG9sYXRlIGEgcGllY2Ugb2YgdGVtcGxhdGUgdGV4dC5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IHRleHRcbiAgICogQHJldHVybiB7U3RyaW5nfVxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLiRpbnRlcnBvbGF0ZSA9IGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgdmFyIHRva2VucyA9IHBhcnNlVGV4dCh0ZXh0KTtcbiAgICB2YXIgdm0gPSB0aGlzO1xuICAgIGlmICh0b2tlbnMpIHtcbiAgICAgIGlmICh0b2tlbnMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHJldHVybiB2bS4kZXZhbCh0b2tlbnNbMF0udmFsdWUpICsgJyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdG9rZW5zLm1hcChmdW5jdGlvbiAodG9rZW4pIHtcbiAgICAgICAgICByZXR1cm4gdG9rZW4udGFnID8gdm0uJGV2YWwodG9rZW4udmFsdWUpIDogdG9rZW4udmFsdWU7XG4gICAgICAgIH0pLmpvaW4oJycpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGV4dDtcbiAgICB9XG4gIH07XG5cbiAgLyoqXG4gICAqIExvZyBpbnN0YW5jZSBkYXRhIGFzIGEgcGxhaW4gSlMgb2JqZWN0XG4gICAqIHNvIHRoYXQgaXQgaXMgZWFzaWVyIHRvIGluc3BlY3QgaW4gY29uc29sZS5cbiAgICogVGhpcyBtZXRob2QgYXNzdW1lcyBjb25zb2xlIGlzIGF2YWlsYWJsZS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IFtwYXRoXVxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLiRsb2cgPSBmdW5jdGlvbiAocGF0aCkge1xuICAgIHZhciBkYXRhID0gcGF0aCA/IGdldFBhdGgodGhpcy5fZGF0YSwgcGF0aCkgOiB0aGlzLl9kYXRhO1xuICAgIGlmIChkYXRhKSB7XG4gICAgICBkYXRhID0gY2xlYW4oZGF0YSk7XG4gICAgfVxuICAgIC8vIGluY2x1ZGUgY29tcHV0ZWQgZmllbGRzXG4gICAgaWYgKCFwYXRoKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gdGhpcy4kb3B0aW9ucy5jb21wdXRlZCkge1xuICAgICAgICBkYXRhW2tleV0gPSBjbGVhbih0aGlzW2tleV0pO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zb2xlLmxvZyhkYXRhKTtcbiAgfTtcblxuICAvKipcbiAgICogXCJjbGVhblwiIGEgZ2V0dGVyL3NldHRlciBjb252ZXJ0ZWQgb2JqZWN0IGludG8gYSBwbGFpblxuICAgKiBvYmplY3QgY29weS5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IC0gb2JqXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG5cbiAgZnVuY3Rpb24gY2xlYW4ob2JqKSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkob2JqKSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZG9tQVBJIChWdWUpIHtcbiAgLyoqXG4gICAqIENvbnZlbmllbmNlIG9uLWluc3RhbmNlIG5leHRUaWNrLiBUaGUgY2FsbGJhY2sgaXNcbiAgICogYXV0by1ib3VuZCB0byB0aGUgaW5zdGFuY2UsIGFuZCB0aGlzIGF2b2lkcyBjb21wb25lbnRcbiAgICogbW9kdWxlcyBoYXZpbmcgdG8gcmVseSBvbiB0aGUgZ2xvYmFsIFZ1ZS5cbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS4kbmV4dFRpY2sgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICBuZXh0VGljayhmbiwgdGhpcyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEFwcGVuZCBpbnN0YW5jZSB0byB0YXJnZXRcbiAgICpcbiAgICogQHBhcmFtIHtOb2RlfSB0YXJnZXRcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NiXVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IFt3aXRoVHJhbnNpdGlvbl0gLSBkZWZhdWx0cyB0byB0cnVlXG4gICAqL1xuXG4gIFZ1ZS5wcm90b3R5cGUuJGFwcGVuZFRvID0gZnVuY3Rpb24gKHRhcmdldCwgY2IsIHdpdGhUcmFuc2l0aW9uKSB7XG4gICAgcmV0dXJuIGluc2VydCh0aGlzLCB0YXJnZXQsIGNiLCB3aXRoVHJhbnNpdGlvbiwgYXBwZW5kLCBhcHBlbmRXaXRoVHJhbnNpdGlvbik7XG4gIH07XG5cbiAgLyoqXG4gICAqIFByZXBlbmQgaW5zdGFuY2UgdG8gdGFyZ2V0XG4gICAqXG4gICAqIEBwYXJhbSB7Tm9kZX0gdGFyZ2V0XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYl1cbiAgICogQHBhcmFtIHtCb29sZWFufSBbd2l0aFRyYW5zaXRpb25dIC0gZGVmYXVsdHMgdG8gdHJ1ZVxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLiRwcmVwZW5kVG8gPSBmdW5jdGlvbiAodGFyZ2V0LCBjYiwgd2l0aFRyYW5zaXRpb24pIHtcbiAgICB0YXJnZXQgPSBxdWVyeSh0YXJnZXQpO1xuICAgIGlmICh0YXJnZXQuaGFzQ2hpbGROb2RlcygpKSB7XG4gICAgICB0aGlzLiRiZWZvcmUodGFyZ2V0LmZpcnN0Q2hpbGQsIGNiLCB3aXRoVHJhbnNpdGlvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuJGFwcGVuZFRvKHRhcmdldCwgY2IsIHdpdGhUcmFuc2l0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLyoqXG4gICAqIEluc2VydCBpbnN0YW5jZSBiZWZvcmUgdGFyZ2V0XG4gICAqXG4gICAqIEBwYXJhbSB7Tm9kZX0gdGFyZ2V0XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYl1cbiAgICogQHBhcmFtIHtCb29sZWFufSBbd2l0aFRyYW5zaXRpb25dIC0gZGVmYXVsdHMgdG8gdHJ1ZVxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLiRiZWZvcmUgPSBmdW5jdGlvbiAodGFyZ2V0LCBjYiwgd2l0aFRyYW5zaXRpb24pIHtcbiAgICByZXR1cm4gaW5zZXJ0KHRoaXMsIHRhcmdldCwgY2IsIHdpdGhUcmFuc2l0aW9uLCBiZWZvcmVXaXRoQ2IsIGJlZm9yZVdpdGhUcmFuc2l0aW9uKTtcbiAgfTtcblxuICAvKipcbiAgICogSW5zZXJ0IGluc3RhbmNlIGFmdGVyIHRhcmdldFxuICAgKlxuICAgKiBAcGFyYW0ge05vZGV9IHRhcmdldFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2JdXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gW3dpdGhUcmFuc2l0aW9uXSAtIGRlZmF1bHRzIHRvIHRydWVcbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS4kYWZ0ZXIgPSBmdW5jdGlvbiAodGFyZ2V0LCBjYiwgd2l0aFRyYW5zaXRpb24pIHtcbiAgICB0YXJnZXQgPSBxdWVyeSh0YXJnZXQpO1xuICAgIGlmICh0YXJnZXQubmV4dFNpYmxpbmcpIHtcbiAgICAgIHRoaXMuJGJlZm9yZSh0YXJnZXQubmV4dFNpYmxpbmcsIGNiLCB3aXRoVHJhbnNpdGlvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuJGFwcGVuZFRvKHRhcmdldC5wYXJlbnROb2RlLCBjYiwgd2l0aFRyYW5zaXRpb24pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvKipcbiAgICogUmVtb3ZlIGluc3RhbmNlIGZyb20gRE9NXG4gICAqXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYl1cbiAgICogQHBhcmFtIHtCb29sZWFufSBbd2l0aFRyYW5zaXRpb25dIC0gZGVmYXVsdHMgdG8gdHJ1ZVxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLiRyZW1vdmUgPSBmdW5jdGlvbiAoY2IsIHdpdGhUcmFuc2l0aW9uKSB7XG4gICAgaWYgKCF0aGlzLiRlbC5wYXJlbnROb2RlKSB7XG4gICAgICByZXR1cm4gY2IgJiYgY2IoKTtcbiAgICB9XG4gICAgdmFyIGluRG9jdW1lbnQgPSB0aGlzLl9pc0F0dGFjaGVkICYmIGluRG9jKHRoaXMuJGVsKTtcbiAgICAvLyBpZiB3ZSBhcmUgbm90IGluIGRvY3VtZW50LCBubyBuZWVkIHRvIGNoZWNrXG4gICAgLy8gZm9yIHRyYW5zaXRpb25zXG4gICAgaWYgKCFpbkRvY3VtZW50KSB3aXRoVHJhbnNpdGlvbiA9IGZhbHNlO1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgcmVhbENiID0gZnVuY3Rpb24gcmVhbENiKCkge1xuICAgICAgaWYgKGluRG9jdW1lbnQpIHNlbGYuX2NhbGxIb29rKCdkZXRhY2hlZCcpO1xuICAgICAgaWYgKGNiKSBjYigpO1xuICAgIH07XG4gICAgaWYgKHRoaXMuX2lzRnJhZ21lbnQpIHtcbiAgICAgIHJlbW92ZU5vZGVSYW5nZSh0aGlzLl9mcmFnbWVudFN0YXJ0LCB0aGlzLl9mcmFnbWVudEVuZCwgdGhpcywgdGhpcy5fZnJhZ21lbnQsIHJlYWxDYik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBvcCA9IHdpdGhUcmFuc2l0aW9uID09PSBmYWxzZSA/IHJlbW92ZVdpdGhDYiA6IHJlbW92ZVdpdGhUcmFuc2l0aW9uO1xuICAgICAgb3AodGhpcy4kZWwsIHRoaXMsIHJlYWxDYik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8qKlxuICAgKiBTaGFyZWQgRE9NIGluc2VydGlvbiBmdW5jdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtWdWV9IHZtXG4gICAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYl1cbiAgICogQHBhcmFtIHtCb29sZWFufSBbd2l0aFRyYW5zaXRpb25dXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG9wMSAtIG9wIGZvciBub24tdHJhbnNpdGlvbiBpbnNlcnRcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gb3AyIC0gb3AgZm9yIHRyYW5zaXRpb24gaW5zZXJ0XG4gICAqIEByZXR1cm4gdm1cbiAgICovXG5cbiAgZnVuY3Rpb24gaW5zZXJ0KHZtLCB0YXJnZXQsIGNiLCB3aXRoVHJhbnNpdGlvbiwgb3AxLCBvcDIpIHtcbiAgICB0YXJnZXQgPSBxdWVyeSh0YXJnZXQpO1xuICAgIHZhciB0YXJnZXRJc0RldGFjaGVkID0gIWluRG9jKHRhcmdldCk7XG4gICAgdmFyIG9wID0gd2l0aFRyYW5zaXRpb24gPT09IGZhbHNlIHx8IHRhcmdldElzRGV0YWNoZWQgPyBvcDEgOiBvcDI7XG4gICAgdmFyIHNob3VsZENhbGxIb29rID0gIXRhcmdldElzRGV0YWNoZWQgJiYgIXZtLl9pc0F0dGFjaGVkICYmICFpbkRvYyh2bS4kZWwpO1xuICAgIGlmICh2bS5faXNGcmFnbWVudCkge1xuICAgICAgbWFwTm9kZVJhbmdlKHZtLl9mcmFnbWVudFN0YXJ0LCB2bS5fZnJhZ21lbnRFbmQsIGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICAgIG9wKG5vZGUsIHRhcmdldCwgdm0pO1xuICAgICAgfSk7XG4gICAgICBjYiAmJiBjYigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvcCh2bS4kZWwsIHRhcmdldCwgdm0sIGNiKTtcbiAgICB9XG4gICAgaWYgKHNob3VsZENhbGxIb29rKSB7XG4gICAgICB2bS5fY2FsbEhvb2soJ2F0dGFjaGVkJyk7XG4gICAgfVxuICAgIHJldHVybiB2bTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBmb3Igc2VsZWN0b3JzXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfEVsZW1lbnR9IGVsXG4gICAqL1xuXG4gIGZ1bmN0aW9uIHF1ZXJ5KGVsKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBlbCA9PT0gJ3N0cmluZycgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsKSA6IGVsO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZCBvcGVyYXRpb24gdGhhdCB0YWtlcyBhIGNhbGxiYWNrLlxuICAgKlxuICAgKiBAcGFyYW0ge05vZGV9IGVsXG4gICAqIEBwYXJhbSB7Tm9kZX0gdGFyZ2V0XG4gICAqIEBwYXJhbSB7VnVlfSB2bSAtIHVudXNlZFxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2JdXG4gICAqL1xuXG4gIGZ1bmN0aW9uIGFwcGVuZChlbCwgdGFyZ2V0LCB2bSwgY2IpIHtcbiAgICB0YXJnZXQuYXBwZW5kQ2hpbGQoZWwpO1xuICAgIGlmIChjYikgY2IoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnNlcnRCZWZvcmUgb3BlcmF0aW9uIHRoYXQgdGFrZXMgYSBjYWxsYmFjay5cbiAgICpcbiAgICogQHBhcmFtIHtOb2RlfSBlbFxuICAgKiBAcGFyYW0ge05vZGV9IHRhcmdldFxuICAgKiBAcGFyYW0ge1Z1ZX0gdm0gLSB1bnVzZWRcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NiXVxuICAgKi9cblxuICBmdW5jdGlvbiBiZWZvcmVXaXRoQ2IoZWwsIHRhcmdldCwgdm0sIGNiKSB7XG4gICAgYmVmb3JlKGVsLCB0YXJnZXQpO1xuICAgIGlmIChjYikgY2IoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgb3BlcmF0aW9uIHRoYXQgdGFrZXMgYSBjYWxsYmFjay5cbiAgICpcbiAgICogQHBhcmFtIHtOb2RlfSBlbFxuICAgKiBAcGFyYW0ge1Z1ZX0gdm0gLSB1bnVzZWRcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NiXVxuICAgKi9cblxuICBmdW5jdGlvbiByZW1vdmVXaXRoQ2IoZWwsIHZtLCBjYikge1xuICAgIHJlbW92ZShlbCk7XG4gICAgaWYgKGNiKSBjYigpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGV2ZW50c0FQSSAoVnVlKSB7XG4gIC8qKlxuICAgKiBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS4kb24gPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgKHRoaXMuX2V2ZW50c1tldmVudF0gfHwgKHRoaXMuX2V2ZW50c1tldmVudF0gPSBbXSkpLnB1c2goZm4pO1xuICAgIG1vZGlmeUxpc3RlbmVyQ291bnQodGhpcywgZXZlbnQsIDEpO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBZGRzIGFuIGBldmVudGAgbGlzdGVuZXIgdGhhdCB3aWxsIGJlIGludm9rZWQgYSBzaW5nbGVcbiAgICogdGltZSB0aGVuIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZC5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gICAqL1xuXG4gIFZ1ZS5wcm90b3R5cGUuJG9uY2UgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGZ1bmN0aW9uIG9uKCkge1xuICAgICAgc2VsZi4kb2ZmKGV2ZW50LCBvbik7XG4gICAgICBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgICBvbi5mbiA9IGZuO1xuICAgIHRoaXMuJG9uKGV2ZW50LCBvbik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlbW92ZSB0aGUgZ2l2ZW4gY2FsbGJhY2sgZm9yIGBldmVudGAgb3IgYWxsXG4gICAqIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS4kb2ZmID0gZnVuY3Rpb24gKGV2ZW50LCBmbikge1xuICAgIHZhciBjYnM7XG4gICAgLy8gYWxsXG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBpZiAodGhpcy4kcGFyZW50KSB7XG4gICAgICAgIGZvciAoZXZlbnQgaW4gdGhpcy5fZXZlbnRzKSB7XG4gICAgICAgICAgY2JzID0gdGhpcy5fZXZlbnRzW2V2ZW50XTtcbiAgICAgICAgICBpZiAoY2JzKSB7XG4gICAgICAgICAgICBtb2RpZnlMaXN0ZW5lckNvdW50KHRoaXMsIGV2ZW50LCAtY2JzLmxlbmd0aCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvLyBzcGVjaWZpYyBldmVudFxuICAgIGNicyA9IHRoaXMuX2V2ZW50c1tldmVudF07XG4gICAgaWYgKCFjYnMpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgbW9kaWZ5TGlzdGVuZXJDb3VudCh0aGlzLCBldmVudCwgLWNicy5sZW5ndGgpO1xuICAgICAgdGhpcy5fZXZlbnRzW2V2ZW50XSA9IG51bGw7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8gc3BlY2lmaWMgaGFuZGxlclxuICAgIHZhciBjYjtcbiAgICB2YXIgaSA9IGNicy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgY2IgPSBjYnNbaV07XG4gICAgICBpZiAoY2IgPT09IGZuIHx8IGNiLmZuID09PSBmbikge1xuICAgICAgICBtb2RpZnlMaXN0ZW5lckNvdW50KHRoaXMsIGV2ZW50LCAtMSk7XG4gICAgICAgIGNicy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvKipcbiAgICogVHJpZ2dlciBhbiBldmVudCBvbiBzZWxmLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IGV2ZW50XG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IHNob3VsZFByb3BhZ2F0ZVxuICAgKi9cblxuICBWdWUucHJvdG90eXBlLiRlbWl0ID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgdmFyIGlzU291cmNlID0gdHlwZW9mIGV2ZW50ID09PSAnc3RyaW5nJztcbiAgICBldmVudCA9IGlzU291cmNlID8gZXZlbnQgOiBldmVudC5uYW1lO1xuICAgIHZhciBjYnMgPSB0aGlzLl9ldmVudHNbZXZlbnRdO1xuICAgIHZhciBzaG91bGRQcm9wYWdhdGUgPSBpc1NvdXJjZSB8fCAhY2JzO1xuICAgIGlmIChjYnMpIHtcbiAgICAgIGNicyA9IGNicy5sZW5ndGggPiAxID8gdG9BcnJheShjYnMpIDogY2JzO1xuICAgICAgLy8gdGhpcyBpcyBhIHNvbWV3aGF0IGhhY2t5IHNvbHV0aW9uIHRvIHRoZSBxdWVzdGlvbiByYWlzZWRcbiAgICAgIC8vIGluICMyMTAyOiBmb3IgYW4gaW5saW5lIGNvbXBvbmVudCBsaXN0ZW5lciBsaWtlIDxjb21wIEB0ZXN0PVwiZG9UaGlzXCI+LFxuICAgICAgLy8gdGhlIHByb3BhZ2F0aW9uIGhhbmRsaW5nIGlzIHNvbWV3aGF0IGJyb2tlbi4gVGhlcmVmb3JlIHdlXG4gICAgICAvLyBuZWVkIHRvIHRyZWF0IHRoZXNlIGlubGluZSBjYWxsYmFja3MgZGlmZmVyZW50bHkuXG4gICAgICB2YXIgaGFzUGFyZW50Q2JzID0gaXNTb3VyY2UgJiYgY2JzLnNvbWUoZnVuY3Rpb24gKGNiKSB7XG4gICAgICAgIHJldHVybiBjYi5fZnJvbVBhcmVudDtcbiAgICAgIH0pO1xuICAgICAgaWYgKGhhc1BhcmVudENicykge1xuICAgICAgICBzaG91bGRQcm9wYWdhdGUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHZhciBhcmdzID0gdG9BcnJheShhcmd1bWVudHMsIDEpO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjYnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIHZhciBjYiA9IGNic1tpXTtcbiAgICAgICAgdmFyIHJlcyA9IGNiLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICBpZiAocmVzID09PSB0cnVlICYmICghaGFzUGFyZW50Q2JzIHx8IGNiLl9mcm9tUGFyZW50KSkge1xuICAgICAgICAgIHNob3VsZFByb3BhZ2F0ZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNob3VsZFByb3BhZ2F0ZTtcbiAgfTtcblxuICAvKipcbiAgICogUmVjdXJzaXZlbHkgYnJvYWRjYXN0IGFuIGV2ZW50IHRvIGFsbCBjaGlsZHJlbiBpbnN0YW5jZXMuXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdH0gZXZlbnRcbiAgICogQHBhcmFtIHsuLi4qfSBhZGRpdGlvbmFsIGFyZ3VtZW50c1xuICAgKi9cblxuICBWdWUucHJvdG90eXBlLiRicm9hZGNhc3QgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgaXNTb3VyY2UgPSB0eXBlb2YgZXZlbnQgPT09ICdzdHJpbmcnO1xuICAgIGV2ZW50ID0gaXNTb3VyY2UgPyBldmVudCA6IGV2ZW50Lm5hbWU7XG4gICAgLy8gaWYgbm8gY2hpbGQgaGFzIHJlZ2lzdGVyZWQgZm9yIHRoaXMgZXZlbnQsXG4gICAgLy8gdGhlbiB0aGVyZSdzIG5vIG5lZWQgdG8gYnJvYWRjYXN0LlxuICAgIGlmICghdGhpcy5fZXZlbnRzQ291bnRbZXZlbnRdKSByZXR1cm47XG4gICAgdmFyIGNoaWxkcmVuID0gdGhpcy4kY2hpbGRyZW47XG4gICAgdmFyIGFyZ3MgPSB0b0FycmF5KGFyZ3VtZW50cyk7XG4gICAgaWYgKGlzU291cmNlKSB7XG4gICAgICAvLyB1c2Ugb2JqZWN0IGV2ZW50IHRvIGluZGljYXRlIG5vbi1zb3VyY2UgZW1pdFxuICAgICAgLy8gb24gY2hpbGRyZW5cbiAgICAgIGFyZ3NbMF0gPSB7IG5hbWU6IGV2ZW50LCBzb3VyY2U6IHRoaXMgfTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDAsIGwgPSBjaGlsZHJlbi5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHZhciBjaGlsZCA9IGNoaWxkcmVuW2ldO1xuICAgICAgdmFyIHNob3VsZFByb3BhZ2F0ZSA9IGNoaWxkLiRlbWl0LmFwcGx5KGNoaWxkLCBhcmdzKTtcbiAgICAgIGlmIChzaG91bGRQcm9wYWdhdGUpIHtcbiAgICAgICAgY2hpbGQuJGJyb2FkY2FzdC5hcHBseShjaGlsZCwgYXJncyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZWN1cnNpdmVseSBwcm9wYWdhdGUgYW4gZXZlbnQgdXAgdGhlIHBhcmVudCBjaGFpbi5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7Li4uKn0gYWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICovXG5cbiAgVnVlLnByb3RvdHlwZS4kZGlzcGF0Y2ggPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICB2YXIgc2hvdWxkUHJvcGFnYXRlID0gdGhpcy4kZW1pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGlmICghc2hvdWxkUHJvcGFnYXRlKSByZXR1cm47XG4gICAgdmFyIHBhcmVudCA9IHRoaXMuJHBhcmVudDtcbiAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgICAvLyB1c2Ugb2JqZWN0IGV2ZW50IHRvIGluZGljYXRlIG5vbi1zb3VyY2UgZW1pdFxuICAgIC8vIG9uIHBhcmVudHNcbiAgICBhcmdzWzBdID0geyBuYW1lOiBldmVudCwgc291cmNlOiB0aGlzIH07XG4gICAgd2hpbGUgKHBhcmVudCkge1xuICAgICAgc2hvdWxkUHJvcGFnYXRlID0gcGFyZW50LiRlbWl0LmFwcGx5KHBhcmVudCwgYXJncyk7XG4gICAgICBwYXJlbnQgPSBzaG91bGRQcm9wYWdhdGUgPyBwYXJlbnQuJHBhcmVudCA6IG51bGw7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8qKlxuICAgKiBNb2RpZnkgdGhlIGxpc3RlbmVyIGNvdW50cyBvbiBhbGwgcGFyZW50cy5cbiAgICogVGhpcyBib29ra2VlcGluZyBhbGxvd3MgJGJyb2FkY2FzdCB0byByZXR1cm4gZWFybHkgd2hlblxuICAgKiBubyBjaGlsZCBoYXMgbGlzdGVuZWQgdG8gYSBjZXJ0YWluIGV2ZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge1Z1ZX0gdm1cbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gICAqIEBwYXJhbSB7TnVtYmVyfSBjb3VudFxuICAgKi9cblxuICB2YXIgaG9va1JFID0gL15ob29rOi87XG4gIGZ1bmN0aW9uIG1vZGlmeUxpc3RlbmVyQ291bnQodm0sIGV2ZW50LCBjb3VudCkge1xuICAgIHZhciBwYXJlbnQgPSB2bS4kcGFyZW50O1xuICAgIC8vIGhvb2tzIGRvIG5vdCBnZXQgYnJvYWRjYXN0ZWQgc28gbm8gbmVlZFxuICAgIC8vIHRvIGRvIGJvb2trZWVwaW5nIGZvciB0aGVtXG4gICAgaWYgKCFwYXJlbnQgfHwgIWNvdW50IHx8IGhvb2tSRS50ZXN0KGV2ZW50KSkgcmV0dXJuO1xuICAgIHdoaWxlIChwYXJlbnQpIHtcbiAgICAgIHBhcmVudC5fZXZlbnRzQ291bnRbZXZlbnRdID0gKHBhcmVudC5fZXZlbnRzQ291bnRbZXZlbnRdIHx8IDApICsgY291bnQ7XG4gICAgICBwYXJlbnQgPSBwYXJlbnQuJHBhcmVudDtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbGlmZWN5Y2xlQVBJIChWdWUpIHtcbiAgLyoqXG4gICAqIFNldCBpbnN0YW5jZSB0YXJnZXQgZWxlbWVudCBhbmQga2ljayBvZmYgdGhlIGNvbXBpbGF0aW9uXG4gICAqIHByb2Nlc3MuIFRoZSBwYXNzZWQgaW4gYGVsYCBjYW4gYmUgYSBzZWxlY3RvciBzdHJpbmcsIGFuXG4gICAqIGV4aXN0aW5nIEVsZW1lbnQsIG9yIGEgRG9jdW1lbnRGcmFnbWVudCAoZm9yIGJsb2NrXG4gICAqIGluc3RhbmNlcykuXG4gICAqXG4gICAqIEBwYXJhbSB7RWxlbWVudHxEb2N1bWVudEZyYWdtZW50fHN0cmluZ30gZWxcbiAgICogQHB1YmxpY1xuICAgKi9cblxuICBWdWUucHJvdG90eXBlLiRtb3VudCA9IGZ1bmN0aW9uIChlbCkge1xuICAgIGlmICh0aGlzLl9pc0NvbXBpbGVkKSB7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmIHdhcm4oJyRtb3VudCgpIHNob3VsZCBiZSBjYWxsZWQgb25seSBvbmNlLicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBlbCA9IHF1ZXJ5KGVsKTtcbiAgICBpZiAoIWVsKSB7XG4gICAgICBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIH1cbiAgICB0aGlzLl9jb21waWxlKGVsKTtcbiAgICB0aGlzLl9pbml0RE9NSG9va3MoKTtcbiAgICBpZiAoaW5Eb2ModGhpcy4kZWwpKSB7XG4gICAgICB0aGlzLl9jYWxsSG9vaygnYXR0YWNoZWQnKTtcbiAgICAgIHJlYWR5LmNhbGwodGhpcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuJG9uY2UoJ2hvb2s6YXR0YWNoZWQnLCByZWFkeSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8qKlxuICAgKiBNYXJrIGFuIGluc3RhbmNlIGFzIHJlYWR5LlxuICAgKi9cblxuICBmdW5jdGlvbiByZWFkeSgpIHtcbiAgICB0aGlzLl9pc0F0dGFjaGVkID0gdHJ1ZTtcbiAgICB0aGlzLl9pc1JlYWR5ID0gdHJ1ZTtcbiAgICB0aGlzLl9jYWxsSG9vaygncmVhZHknKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUZWFyZG93biB0aGUgaW5zdGFuY2UsIHNpbXBseSBkZWxlZ2F0ZSB0byB0aGUgaW50ZXJuYWxcbiAgICogX2Rlc3Ryb3kuXG4gICAqL1xuXG4gIFZ1ZS5wcm90b3R5cGUuJGRlc3Ryb3kgPSBmdW5jdGlvbiAocmVtb3ZlLCBkZWZlckNsZWFudXApIHtcbiAgICB0aGlzLl9kZXN0cm95KHJlbW92ZSwgZGVmZXJDbGVhbnVwKTtcbiAgfTtcblxuICAvKipcbiAgICogUGFydGlhbGx5IGNvbXBpbGUgYSBwaWVjZSBvZiBET00gYW5kIHJldHVybiBhXG4gICAqIGRlY29tcGlsZSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtFbGVtZW50fERvY3VtZW50RnJhZ21lbnR9IGVsXG4gICAqIEBwYXJhbSB7VnVlfSBbaG9zdF1cbiAgICogQHJldHVybiB7RnVuY3Rpb259XG4gICAqL1xuXG4gIFZ1ZS5wcm90b3R5cGUuJGNvbXBpbGUgPSBmdW5jdGlvbiAoZWwsIGhvc3QsIHNjb3BlLCBmcmFnKSB7XG4gICAgcmV0dXJuIGNvbXBpbGUoZWwsIHRoaXMuJG9wdGlvbnMsIHRydWUpKHRoaXMsIGVsLCBob3N0LCBzY29wZSwgZnJhZyk7XG4gIH07XG59XG5cbi8qKlxuICogVGhlIGV4cG9zZWQgVnVlIGNvbnN0cnVjdG9yLlxuICpcbiAqIEFQSSBjb252ZW50aW9uczpcbiAqIC0gcHVibGljIEFQSSBtZXRob2RzL3Byb3BlcnRpZXMgYXJlIHByZWZpeGVkIHdpdGggYCRgXG4gKiAtIGludGVybmFsIG1ldGhvZHMvcHJvcGVydGllcyBhcmUgcHJlZml4ZWQgd2l0aCBgX2BcbiAqIC0gbm9uLXByZWZpeGVkIHByb3BlcnRpZXMgYXJlIGFzc3VtZWQgdG8gYmUgcHJveGllZCB1c2VyXG4gKiAgIGRhdGEuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gKiBAcHVibGljXG4gKi9cblxuZnVuY3Rpb24gVnVlKG9wdGlvbnMpIHtcbiAgdGhpcy5faW5pdChvcHRpb25zKTtcbn1cblxuLy8gaW5zdGFsbCBpbnRlcm5hbHNcbmluaXRNaXhpbihWdWUpO1xuc3RhdGVNaXhpbihWdWUpO1xuZXZlbnRzTWl4aW4oVnVlKTtcbmxpZmVjeWNsZU1peGluKFZ1ZSk7XG5taXNjTWl4aW4oVnVlKTtcblxuLy8gaW5zdGFsbCBpbnN0YW5jZSBBUElzXG5kYXRhQVBJKFZ1ZSk7XG5kb21BUEkoVnVlKTtcbmV2ZW50c0FQSShWdWUpO1xubGlmZWN5Y2xlQVBJKFZ1ZSk7XG5cbnZhciBzbG90ID0ge1xuXG4gIHByaW9yaXR5OiBTTE9ULFxuICBwYXJhbXM6IFsnbmFtZSddLFxuXG4gIGJpbmQ6IGZ1bmN0aW9uIGJpbmQoKSB7XG4gICAgLy8gdGhpcyB3YXMgcmVzb2x2ZWQgZHVyaW5nIGNvbXBvbmVudCB0cmFuc2NsdXNpb25cbiAgICB2YXIgbmFtZSA9IHRoaXMucGFyYW1zLm5hbWUgfHwgJ2RlZmF1bHQnO1xuICAgIHZhciBjb250ZW50ID0gdGhpcy52bS5fc2xvdENvbnRlbnRzICYmIHRoaXMudm0uX3Nsb3RDb250ZW50c1tuYW1lXTtcbiAgICBpZiAoIWNvbnRlbnQgfHwgIWNvbnRlbnQuaGFzQ2hpbGROb2RlcygpKSB7XG4gICAgICB0aGlzLmZhbGxiYWNrKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29tcGlsZShjb250ZW50LmNsb25lTm9kZSh0cnVlKSwgdGhpcy52bS5fY29udGV4dCwgdGhpcy52bSk7XG4gICAgfVxuICB9LFxuXG4gIGNvbXBpbGU6IGZ1bmN0aW9uIGNvbXBpbGUoY29udGVudCwgY29udGV4dCwgaG9zdCkge1xuICAgIGlmIChjb250ZW50ICYmIGNvbnRleHQpIHtcbiAgICAgIGlmICh0aGlzLmVsLmhhc0NoaWxkTm9kZXMoKSAmJiBjb250ZW50LmNoaWxkTm9kZXMubGVuZ3RoID09PSAxICYmIGNvbnRlbnQuY2hpbGROb2Rlc1swXS5ub2RlVHlwZSA9PT0gMSAmJiBjb250ZW50LmNoaWxkTm9kZXNbMF0uaGFzQXR0cmlidXRlKCd2LWlmJykpIHtcbiAgICAgICAgLy8gaWYgdGhlIGluc2VydGVkIHNsb3QgaGFzIHYtaWZcbiAgICAgICAgLy8gaW5qZWN0IGZhbGxiYWNrIGNvbnRlbnQgYXMgdGhlIHYtZWxzZVxuICAgICAgICB2YXIgZWxzZUJsb2NrID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGVtcGxhdGUnKTtcbiAgICAgICAgZWxzZUJsb2NrLnNldEF0dHJpYnV0ZSgndi1lbHNlJywgJycpO1xuICAgICAgICBlbHNlQmxvY2suaW5uZXJIVE1MID0gdGhpcy5lbC5pbm5lckhUTUw7XG4gICAgICAgIC8vIHRoZSBlbHNlIGJsb2NrIHNob3VsZCBiZSBjb21waWxlZCBpbiBjaGlsZCBzY29wZVxuICAgICAgICBlbHNlQmxvY2suX2NvbnRleHQgPSB0aGlzLnZtO1xuICAgICAgICBjb250ZW50LmFwcGVuZENoaWxkKGVsc2VCbG9jayk7XG4gICAgICB9XG4gICAgICB2YXIgc2NvcGUgPSBob3N0ID8gaG9zdC5fc2NvcGUgOiB0aGlzLl9zY29wZTtcbiAgICAgIHRoaXMudW5saW5rID0gY29udGV4dC4kY29tcGlsZShjb250ZW50LCBob3N0LCBzY29wZSwgdGhpcy5fZnJhZyk7XG4gICAgfVxuICAgIGlmIChjb250ZW50KSB7XG4gICAgICByZXBsYWNlKHRoaXMuZWwsIGNvbnRlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZW1vdmUodGhpcy5lbCk7XG4gICAgfVxuICB9LFxuXG4gIGZhbGxiYWNrOiBmdW5jdGlvbiBmYWxsYmFjaygpIHtcbiAgICB0aGlzLmNvbXBpbGUoZXh0cmFjdENvbnRlbnQodGhpcy5lbCwgdHJ1ZSksIHRoaXMudm0pO1xuICB9LFxuXG4gIHVuYmluZDogZnVuY3Rpb24gdW5iaW5kKCkge1xuICAgIGlmICh0aGlzLnVubGluaykge1xuICAgICAgdGhpcy51bmxpbmsoKTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciBwYXJ0aWFsID0ge1xuXG4gIHByaW9yaXR5OiBQQVJUSUFMLFxuXG4gIHBhcmFtczogWyduYW1lJ10sXG5cbiAgLy8gd2F0Y2ggY2hhbmdlcyB0byBuYW1lIGZvciBkeW5hbWljIHBhcnRpYWxzXG4gIHBhcmFtV2F0Y2hlcnM6IHtcbiAgICBuYW1lOiBmdW5jdGlvbiBuYW1lKHZhbHVlKSB7XG4gICAgICB2SWYucmVtb3ZlLmNhbGwodGhpcyk7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5pbnNlcnQodmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICBiaW5kOiBmdW5jdGlvbiBiaW5kKCkge1xuICAgIHRoaXMuYW5jaG9yID0gY3JlYXRlQW5jaG9yKCd2LXBhcnRpYWwnKTtcbiAgICByZXBsYWNlKHRoaXMuZWwsIHRoaXMuYW5jaG9yKTtcbiAgICB0aGlzLmluc2VydCh0aGlzLnBhcmFtcy5uYW1lKTtcbiAgfSxcblxuICBpbnNlcnQ6IGZ1bmN0aW9uIGluc2VydChpZCkge1xuICAgIHZhciBwYXJ0aWFsID0gcmVzb2x2ZUFzc2V0KHRoaXMudm0uJG9wdGlvbnMsICdwYXJ0aWFscycsIGlkKTtcbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgICAgYXNzZXJ0QXNzZXQocGFydGlhbCwgJ3BhcnRpYWwnLCBpZCk7XG4gICAgfVxuICAgIGlmIChwYXJ0aWFsKSB7XG4gICAgICB0aGlzLmZhY3RvcnkgPSBuZXcgRnJhZ21lbnRGYWN0b3J5KHRoaXMudm0sIHBhcnRpYWwpO1xuICAgICAgdklmLmluc2VydC5jYWxsKHRoaXMpO1xuICAgIH1cbiAgfSxcblxuICB1bmJpbmQ6IGZ1bmN0aW9uIHVuYmluZCgpIHtcbiAgICBpZiAodGhpcy5mcmFnKSB7XG4gICAgICB0aGlzLmZyYWcuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxufTtcblxudmFyIGVsZW1lbnREaXJlY3RpdmVzID0ge1xuICBzbG90OiBzbG90LFxuICBwYXJ0aWFsOiBwYXJ0aWFsXG59O1xuXG52YXIgY29udmVydEFycmF5ID0gdkZvci5fcG9zdFByb2Nlc3M7XG5cbi8qKlxuICogTGltaXQgZmlsdGVyIGZvciBhcnJheXNcbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gblxuICogQHBhcmFtIHtOdW1iZXJ9IG9mZnNldCAoRGVjaW1hbCBleHBlY3RlZClcbiAqL1xuXG5mdW5jdGlvbiBsaW1pdEJ5KGFyciwgbiwgb2Zmc2V0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA/IHBhcnNlSW50KG9mZnNldCwgMTApIDogMDtcbiAgbiA9IHRvTnVtYmVyKG4pO1xuICByZXR1cm4gdHlwZW9mIG4gPT09ICdudW1iZXInID8gYXJyLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgbikgOiBhcnI7XG59XG5cbi8qKlxuICogRmlsdGVyIGZpbHRlciBmb3IgYXJyYXlzXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHNlYXJjaFxuICogQHBhcmFtIHtTdHJpbmd9IFtkZWxpbWl0ZXJdXG4gKiBAcGFyYW0ge1N0cmluZ30gLi4uZGF0YUtleXNcbiAqL1xuXG5mdW5jdGlvbiBmaWx0ZXJCeShhcnIsIHNlYXJjaCwgZGVsaW1pdGVyKSB7XG4gIGFyciA9IGNvbnZlcnRBcnJheShhcnIpO1xuICBpZiAoc2VhcmNoID09IG51bGwpIHtcbiAgICByZXR1cm4gYXJyO1xuICB9XG4gIGlmICh0eXBlb2Ygc2VhcmNoID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGFyci5maWx0ZXIoc2VhcmNoKTtcbiAgfVxuICAvLyBjYXN0IHRvIGxvd2VyY2FzZSBzdHJpbmdcbiAgc2VhcmNoID0gKCcnICsgc2VhcmNoKS50b0xvd2VyQ2FzZSgpO1xuICAvLyBhbGxvdyBvcHRpb25hbCBgaW5gIGRlbGltaXRlclxuICAvLyBiZWNhdXNlIHdoeSBub3RcbiAgdmFyIG4gPSBkZWxpbWl0ZXIgPT09ICdpbicgPyAzIDogMjtcbiAgLy8gZXh0cmFjdCBhbmQgZmxhdHRlbiBrZXlzXG4gIHZhciBrZXlzID0gdG9BcnJheShhcmd1bWVudHMsIG4pLnJlZHVjZShmdW5jdGlvbiAocHJldiwgY3VyKSB7XG4gICAgcmV0dXJuIHByZXYuY29uY2F0KGN1cik7XG4gIH0sIFtdKTtcbiAgdmFyIHJlcyA9IFtdO1xuICB2YXIgaXRlbSwga2V5LCB2YWwsIGo7XG4gIGZvciAodmFyIGkgPSAwLCBsID0gYXJyLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGl0ZW0gPSBhcnJbaV07XG4gICAgdmFsID0gaXRlbSAmJiBpdGVtLiR2YWx1ZSB8fCBpdGVtO1xuICAgIGogPSBrZXlzLmxlbmd0aDtcbiAgICBpZiAoaikge1xuICAgICAgd2hpbGUgKGotLSkge1xuICAgICAgICBrZXkgPSBrZXlzW2pdO1xuICAgICAgICBpZiAoa2V5ID09PSAnJGtleScgJiYgY29udGFpbnMkMShpdGVtLiRrZXksIHNlYXJjaCkgfHwgY29udGFpbnMkMShnZXRQYXRoKHZhbCwga2V5KSwgc2VhcmNoKSkge1xuICAgICAgICAgIHJlcy5wdXNoKGl0ZW0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjb250YWlucyQxKGl0ZW0sIHNlYXJjaCkpIHtcbiAgICAgIHJlcy5wdXNoKGl0ZW0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuXG4vKipcbiAqIEZpbHRlciBmaWx0ZXIgZm9yIGFycmF5c1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzb3J0S2V5XG4gKiBAcGFyYW0ge1N0cmluZ30gcmV2ZXJzZVxuICovXG5cbmZ1bmN0aW9uIG9yZGVyQnkoYXJyLCBzb3J0S2V5LCByZXZlcnNlKSB7XG4gIGFyciA9IGNvbnZlcnRBcnJheShhcnIpO1xuICBpZiAoIXNvcnRLZXkpIHtcbiAgICByZXR1cm4gYXJyO1xuICB9XG4gIHZhciBvcmRlciA9IHJldmVyc2UgJiYgcmV2ZXJzZSA8IDAgPyAtMSA6IDE7XG4gIC8vIHNvcnQgb24gYSBjb3B5IHRvIGF2b2lkIG11dGF0aW5nIG9yaWdpbmFsIGFycmF5XG4gIHJldHVybiBhcnIuc2xpY2UoKS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgaWYgKHNvcnRLZXkgIT09ICcka2V5Jykge1xuICAgICAgaWYgKGlzT2JqZWN0KGEpICYmICckdmFsdWUnIGluIGEpIGEgPSBhLiR2YWx1ZTtcbiAgICAgIGlmIChpc09iamVjdChiKSAmJiAnJHZhbHVlJyBpbiBiKSBiID0gYi4kdmFsdWU7XG4gICAgfVxuICAgIGEgPSBpc09iamVjdChhKSA/IGdldFBhdGgoYSwgc29ydEtleSkgOiBhO1xuICAgIGIgPSBpc09iamVjdChiKSA/IGdldFBhdGgoYiwgc29ydEtleSkgOiBiO1xuICAgIHJldHVybiBhID09PSBiID8gMCA6IGEgPiBiID8gb3JkZXIgOiAtb3JkZXI7XG4gIH0pO1xufVxuXG4vKipcbiAqIFN0cmluZyBjb250YWluIGhlbHBlclxuICpcbiAqIEBwYXJhbSB7Kn0gdmFsXG4gKiBAcGFyYW0ge1N0cmluZ30gc2VhcmNoXG4gKi9cblxuZnVuY3Rpb24gY29udGFpbnMkMSh2YWwsIHNlYXJjaCkge1xuICB2YXIgaTtcbiAgaWYgKGlzUGxhaW5PYmplY3QodmFsKSkge1xuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsKTtcbiAgICBpID0ga2V5cy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgaWYgKGNvbnRhaW5zJDEodmFsW2tleXNbaV1dLCBzZWFyY2gpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChpc0FycmF5KHZhbCkpIHtcbiAgICBpID0gdmFsLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICBpZiAoY29udGFpbnMkMSh2YWxbaV0sIHNlYXJjaCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKHZhbCAhPSBudWxsKSB7XG4gICAgcmV0dXJuIHZhbC50b1N0cmluZygpLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihzZWFyY2gpID4gLTE7XG4gIH1cbn1cblxudmFyIGRpZ2l0c1JFID0gLyhcXGR7M30pKD89XFxkKS9nO1xuXG4vLyBhc3NldCBjb2xsZWN0aW9ucyBtdXN0IGJlIGEgcGxhaW4gb2JqZWN0LlxudmFyIGZpbHRlcnMgPSB7XG5cbiAgb3JkZXJCeTogb3JkZXJCeSxcbiAgZmlsdGVyQnk6IGZpbHRlckJ5LFxuICBsaW1pdEJ5OiBsaW1pdEJ5LFxuXG4gIC8qKlxuICAgKiBTdHJpbmdpZnkgdmFsdWUuXG4gICAqXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBpbmRlbnRcbiAgICovXG5cbiAganNvbjoge1xuICAgIHJlYWQ6IGZ1bmN0aW9uIHJlYWQodmFsdWUsIGluZGVudCkge1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgPyB2YWx1ZSA6IEpTT04uc3RyaW5naWZ5KHZhbHVlLCBudWxsLCBOdW1iZXIoaW5kZW50KSB8fCAyKTtcbiAgICB9LFxuICAgIHdyaXRlOiBmdW5jdGlvbiB3cml0ZSh2YWx1ZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UodmFsdWUpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIC8qKlxuICAgKiAnYWJjJyA9PiAnQWJjJ1xuICAgKi9cblxuICBjYXBpdGFsaXplOiBmdW5jdGlvbiBjYXBpdGFsaXplKHZhbHVlKSB7XG4gICAgaWYgKCF2YWx1ZSAmJiB2YWx1ZSAhPT0gMCkgcmV0dXJuICcnO1xuICAgIHZhbHVlID0gdmFsdWUudG9TdHJpbmcoKTtcbiAgICByZXR1cm4gdmFsdWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyB2YWx1ZS5zbGljZSgxKTtcbiAgfSxcblxuICAvKipcbiAgICogJ2FiYycgPT4gJ0FCQydcbiAgICovXG5cbiAgdXBwZXJjYXNlOiBmdW5jdGlvbiB1cHBlcmNhc2UodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgfHwgdmFsdWUgPT09IDAgPyB2YWx1ZS50b1N0cmluZygpLnRvVXBwZXJDYXNlKCkgOiAnJztcbiAgfSxcblxuICAvKipcbiAgICogJ0FiQycgPT4gJ2FiYydcbiAgICovXG5cbiAgbG93ZXJjYXNlOiBmdW5jdGlvbiBsb3dlcmNhc2UodmFsdWUpIHtcbiAgICByZXR1cm4gdmFsdWUgfHwgdmFsdWUgPT09IDAgPyB2YWx1ZS50b1N0cmluZygpLnRvTG93ZXJDYXNlKCkgOiAnJztcbiAgfSxcblxuICAvKipcbiAgICogMTIzNDUgPT4gJDEyLDM0NS4wMFxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gc2lnblxuICAgKi9cblxuICBjdXJyZW5jeTogZnVuY3Rpb24gY3VycmVuY3kodmFsdWUsIF9jdXJyZW5jeSkge1xuICAgIHZhbHVlID0gcGFyc2VGbG9hdCh2YWx1ZSk7XG4gICAgaWYgKCFpc0Zpbml0ZSh2YWx1ZSkgfHwgIXZhbHVlICYmIHZhbHVlICE9PSAwKSByZXR1cm4gJyc7XG4gICAgX2N1cnJlbmN5ID0gX2N1cnJlbmN5ICE9IG51bGwgPyBfY3VycmVuY3kgOiAnJCc7XG4gICAgdmFyIHN0cmluZ2lmaWVkID0gTWF0aC5hYnModmFsdWUpLnRvRml4ZWQoMik7XG4gICAgdmFyIF9pbnQgPSBzdHJpbmdpZmllZC5zbGljZSgwLCAtMyk7XG4gICAgdmFyIGkgPSBfaW50Lmxlbmd0aCAlIDM7XG4gICAgdmFyIGhlYWQgPSBpID4gMCA/IF9pbnQuc2xpY2UoMCwgaSkgKyAoX2ludC5sZW5ndGggPiAzID8gJywnIDogJycpIDogJyc7XG4gICAgdmFyIF9mbG9hdCA9IHN0cmluZ2lmaWVkLnNsaWNlKC0zKTtcbiAgICB2YXIgc2lnbiA9IHZhbHVlIDwgMCA/ICctJyA6ICcnO1xuICAgIHJldHVybiBzaWduICsgX2N1cnJlbmN5ICsgaGVhZCArIF9pbnQuc2xpY2UoaSkucmVwbGFjZShkaWdpdHNSRSwgJyQxLCcpICsgX2Zsb2F0O1xuICB9LFxuXG4gIC8qKlxuICAgKiAnaXRlbScgPT4gJ2l0ZW1zJ1xuICAgKlxuICAgKiBAcGFyYW1zXG4gICAqICBhbiBhcnJheSBvZiBzdHJpbmdzIGNvcnJlc3BvbmRpbmcgdG9cbiAgICogIHRoZSBzaW5nbGUsIGRvdWJsZSwgdHJpcGxlIC4uLiBmb3JtcyBvZiB0aGUgd29yZCB0b1xuICAgKiAgYmUgcGx1cmFsaXplZC4gV2hlbiB0aGUgbnVtYmVyIHRvIGJlIHBsdXJhbGl6ZWRcbiAgICogIGV4Y2VlZHMgdGhlIGxlbmd0aCBvZiB0aGUgYXJncywgaXQgd2lsbCB1c2UgdGhlIGxhc3RcbiAgICogIGVudHJ5IGluIHRoZSBhcnJheS5cbiAgICpcbiAgICogIGUuZy4gWydzaW5nbGUnLCAnZG91YmxlJywgJ3RyaXBsZScsICdtdWx0aXBsZSddXG4gICAqL1xuXG4gIHBsdXJhbGl6ZTogZnVuY3Rpb24gcGx1cmFsaXplKHZhbHVlKSB7XG4gICAgdmFyIGFyZ3MgPSB0b0FycmF5KGFyZ3VtZW50cywgMSk7XG4gICAgcmV0dXJuIGFyZ3MubGVuZ3RoID4gMSA/IGFyZ3NbdmFsdWUgJSAxMCAtIDFdIHx8IGFyZ3NbYXJncy5sZW5ndGggLSAxXSA6IGFyZ3NbMF0gKyAodmFsdWUgPT09IDEgPyAnJyA6ICdzJyk7XG4gIH0sXG5cbiAgLyoqXG4gICAqIERlYm91bmNlIGEgaGFuZGxlciBmdW5jdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlclxuICAgKiBAcGFyYW0ge051bWJlcn0gZGVsYXkgPSAzMDBcbiAgICogQHJldHVybiB7RnVuY3Rpb259XG4gICAqL1xuXG4gIGRlYm91bmNlOiBmdW5jdGlvbiBkZWJvdW5jZShoYW5kbGVyLCBkZWxheSkge1xuICAgIGlmICghaGFuZGxlcikgcmV0dXJuO1xuICAgIGlmICghZGVsYXkpIHtcbiAgICAgIGRlbGF5ID0gMzAwO1xuICAgIH1cbiAgICByZXR1cm4gX2RlYm91bmNlKGhhbmRsZXIsIGRlbGF5KTtcbiAgfVxufTtcblxuZnVuY3Rpb24gaW5zdGFsbEdsb2JhbEFQSSAoVnVlKSB7XG4gIC8qKlxuICAgKiBWdWUgYW5kIGV2ZXJ5IGNvbnN0cnVjdG9yIHRoYXQgZXh0ZW5kcyBWdWUgaGFzIGFuXG4gICAqIGFzc29jaWF0ZWQgb3B0aW9ucyBvYmplY3QsIHdoaWNoIGNhbiBiZSBhY2Nlc3NlZCBkdXJpbmdcbiAgICogY29tcGlsYXRpb24gc3RlcHMgYXMgYHRoaXMuY29uc3RydWN0b3Iub3B0aW9uc2AuXG4gICAqXG4gICAqIFRoZXNlIGNhbiBiZSBzZWVuIGFzIHRoZSBkZWZhdWx0IG9wdGlvbnMgb2YgZXZlcnlcbiAgICogVnVlIGluc3RhbmNlLlxuICAgKi9cblxuICBWdWUub3B0aW9ucyA9IHtcbiAgICBkaXJlY3RpdmVzOiBkaXJlY3RpdmVzLFxuICAgIGVsZW1lbnREaXJlY3RpdmVzOiBlbGVtZW50RGlyZWN0aXZlcyxcbiAgICBmaWx0ZXJzOiBmaWx0ZXJzLFxuICAgIHRyYW5zaXRpb25zOiB7fSxcbiAgICBjb21wb25lbnRzOiB7fSxcbiAgICBwYXJ0aWFsczoge30sXG4gICAgcmVwbGFjZTogdHJ1ZVxuICB9O1xuXG4gIC8qKlxuICAgKiBFeHBvc2UgdXNlZnVsIGludGVybmFsc1xuICAgKi9cblxuICBWdWUudXRpbCA9IHV0aWw7XG4gIFZ1ZS5jb25maWcgPSBjb25maWc7XG4gIFZ1ZS5zZXQgPSBzZXQ7XG4gIFZ1ZVsnZGVsZXRlJ10gPSBkZWw7XG4gIFZ1ZS5uZXh0VGljayA9IG5leHRUaWNrO1xuXG4gIC8qKlxuICAgKiBUaGUgZm9sbG93aW5nIGFyZSBleHBvc2VkIGZvciBhZHZhbmNlZCB1c2FnZSAvIHBsdWdpbnNcbiAgICovXG5cbiAgVnVlLmNvbXBpbGVyID0gY29tcGlsZXI7XG4gIFZ1ZS5GcmFnbWVudEZhY3RvcnkgPSBGcmFnbWVudEZhY3Rvcnk7XG4gIFZ1ZS5pbnRlcm5hbERpcmVjdGl2ZXMgPSBpbnRlcm5hbERpcmVjdGl2ZXM7XG4gIFZ1ZS5wYXJzZXJzID0ge1xuICAgIHBhdGg6IHBhdGgsXG4gICAgdGV4dDogdGV4dCxcbiAgICB0ZW1wbGF0ZTogdGVtcGxhdGUsXG4gICAgZGlyZWN0aXZlOiBkaXJlY3RpdmUsXG4gICAgZXhwcmVzc2lvbjogZXhwcmVzc2lvblxuICB9O1xuXG4gIC8qKlxuICAgKiBFYWNoIGluc3RhbmNlIGNvbnN0cnVjdG9yLCBpbmNsdWRpbmcgVnVlLCBoYXMgYSB1bmlxdWVcbiAgICogY2lkLiBUaGlzIGVuYWJsZXMgdXMgdG8gY3JlYXRlIHdyYXBwZWQgXCJjaGlsZFxuICAgKiBjb25zdHJ1Y3RvcnNcIiBmb3IgcHJvdG90eXBhbCBpbmhlcml0YW5jZSBhbmQgY2FjaGUgdGhlbS5cbiAgICovXG5cbiAgVnVlLmNpZCA9IDA7XG4gIHZhciBjaWQgPSAxO1xuXG4gIC8qKlxuICAgKiBDbGFzcyBpbmhlcml0YW5jZVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gZXh0ZW5kT3B0aW9uc1xuICAgKi9cblxuICBWdWUuZXh0ZW5kID0gZnVuY3Rpb24gKGV4dGVuZE9wdGlvbnMpIHtcbiAgICBleHRlbmRPcHRpb25zID0gZXh0ZW5kT3B0aW9ucyB8fCB7fTtcbiAgICB2YXIgU3VwZXIgPSB0aGlzO1xuICAgIHZhciBpc0ZpcnN0RXh0ZW5kID0gU3VwZXIuY2lkID09PSAwO1xuICAgIGlmIChpc0ZpcnN0RXh0ZW5kICYmIGV4dGVuZE9wdGlvbnMuX0N0b3IpIHtcbiAgICAgIHJldHVybiBleHRlbmRPcHRpb25zLl9DdG9yO1xuICAgIH1cbiAgICB2YXIgbmFtZSA9IGV4dGVuZE9wdGlvbnMubmFtZSB8fCBTdXBlci5vcHRpb25zLm5hbWU7XG4gICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGlmICghL15bYS16QS1aXVtcXHctXSokLy50ZXN0KG5hbWUpKSB7XG4gICAgICAgIHdhcm4oJ0ludmFsaWQgY29tcG9uZW50IG5hbWU6IFwiJyArIG5hbWUgKyAnXCIuIENvbXBvbmVudCBuYW1lcyAnICsgJ2NhbiBvbmx5IGNvbnRhaW4gYWxwaGFudW1lcmljIGNoYXJhY2F0ZXJzIGFuZCB0aGUgaHlwaGVuLicpO1xuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIFN1YiA9IGNyZWF0ZUNsYXNzKG5hbWUgfHwgJ1Z1ZUNvbXBvbmVudCcpO1xuICAgIFN1Yi5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFN1cGVyLnByb3RvdHlwZSk7XG4gICAgU3ViLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFN1YjtcbiAgICBTdWIuY2lkID0gY2lkKys7XG4gICAgU3ViLm9wdGlvbnMgPSBtZXJnZU9wdGlvbnMoU3VwZXIub3B0aW9ucywgZXh0ZW5kT3B0aW9ucyk7XG4gICAgU3ViWydzdXBlciddID0gU3VwZXI7XG4gICAgLy8gYWxsb3cgZnVydGhlciBleHRlbnNpb25cbiAgICBTdWIuZXh0ZW5kID0gU3VwZXIuZXh0ZW5kO1xuICAgIC8vIGNyZWF0ZSBhc3NldCByZWdpc3RlcnMsIHNvIGV4dGVuZGVkIGNsYXNzZXNcbiAgICAvLyBjYW4gaGF2ZSB0aGVpciBwcml2YXRlIGFzc2V0cyB0b28uXG4gICAgY29uZmlnLl9hc3NldFR5cGVzLmZvckVhY2goZnVuY3Rpb24gKHR5cGUpIHtcbiAgICAgIFN1Ylt0eXBlXSA9IFN1cGVyW3R5cGVdO1xuICAgIH0pO1xuICAgIC8vIGVuYWJsZSByZWN1cnNpdmUgc2VsZi1sb29rdXBcbiAgICBpZiAobmFtZSkge1xuICAgICAgU3ViLm9wdGlvbnMuY29tcG9uZW50c1tuYW1lXSA9IFN1YjtcbiAgICB9XG4gICAgLy8gY2FjaGUgY29uc3RydWN0b3JcbiAgICBpZiAoaXNGaXJzdEV4dGVuZCkge1xuICAgICAgZXh0ZW5kT3B0aW9ucy5fQ3RvciA9IFN1YjtcbiAgICB9XG4gICAgcmV0dXJuIFN1YjtcbiAgfTtcblxuICAvKipcbiAgICogQSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBzdWItY2xhc3MgY29uc3RydWN0b3Igd2l0aCB0aGVcbiAgICogZ2l2ZW4gbmFtZS4gVGhpcyBnaXZlcyB1cyBtdWNoIG5pY2VyIG91dHB1dCB3aGVuXG4gICAqIGxvZ2dpbmcgaW5zdGFuY2VzIGluIHRoZSBjb25zb2xlLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICAgKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAgICovXG5cbiAgZnVuY3Rpb24gY3JlYXRlQ2xhc3MobmFtZSkge1xuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLW5ldy1mdW5jICovXG4gICAgcmV0dXJuIG5ldyBGdW5jdGlvbigncmV0dXJuIGZ1bmN0aW9uICcgKyBjbGFzc2lmeShuYW1lKSArICcgKG9wdGlvbnMpIHsgdGhpcy5faW5pdChvcHRpb25zKSB9JykoKTtcbiAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLW5ldy1mdW5jICovXG4gIH1cblxuICAvKipcbiAgICogUGx1Z2luIHN5c3RlbVxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gcGx1Z2luXG4gICAqL1xuXG4gIFZ1ZS51c2UgPSBmdW5jdGlvbiAocGx1Z2luKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgaWYgKHBsdWdpbi5pbnN0YWxsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gYWRkaXRpb25hbCBwYXJhbWV0ZXJzXG4gICAgdmFyIGFyZ3MgPSB0b0FycmF5KGFyZ3VtZW50cywgMSk7XG4gICAgYXJncy51bnNoaWZ0KHRoaXMpO1xuICAgIGlmICh0eXBlb2YgcGx1Z2luLmluc3RhbGwgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHBsdWdpbi5pbnN0YWxsLmFwcGx5KHBsdWdpbiwgYXJncyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBsdWdpbi5hcHBseShudWxsLCBhcmdzKTtcbiAgICB9XG4gICAgcGx1Z2luLmluc3RhbGxlZCA9IHRydWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLyoqXG4gICAqIEFwcGx5IGEgZ2xvYmFsIG1peGluIGJ5IG1lcmdpbmcgaXQgaW50byB0aGUgZGVmYXVsdFxuICAgKiBvcHRpb25zLlxuICAgKi9cblxuICBWdWUubWl4aW4gPSBmdW5jdGlvbiAobWl4aW4pIHtcbiAgICBWdWUub3B0aW9ucyA9IG1lcmdlT3B0aW9ucyhWdWUub3B0aW9ucywgbWl4aW4pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYXNzZXQgcmVnaXN0cmF0aW9uIG1ldGhvZHMgd2l0aCB0aGUgZm9sbG93aW5nXG4gICAqIHNpZ25hdHVyZTpcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGlkXG4gICAqIEBwYXJhbSB7Kn0gZGVmaW5pdGlvblxuICAgKi9cblxuICBjb25maWcuX2Fzc2V0VHlwZXMuZm9yRWFjaChmdW5jdGlvbiAodHlwZSkge1xuICAgIFZ1ZVt0eXBlXSA9IGZ1bmN0aW9uIChpZCwgZGVmaW5pdGlvbikge1xuICAgICAgaWYgKCFkZWZpbml0aW9uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnNbdHlwZSArICdzJ11baWRdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgICAgaWYgKHR5cGUgPT09ICdjb21wb25lbnQnICYmIChjb21tb25UYWdSRS50ZXN0KGlkKSB8fCByZXNlcnZlZFRhZ1JFLnRlc3QoaWQpKSkge1xuICAgICAgICAgICAgd2FybignRG8gbm90IHVzZSBidWlsdC1pbiBvciByZXNlcnZlZCBIVE1MIGVsZW1lbnRzIGFzIGNvbXBvbmVudCAnICsgJ2lkOiAnICsgaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2NvbXBvbmVudCcgJiYgaXNQbGFpbk9iamVjdChkZWZpbml0aW9uKSkge1xuICAgICAgICAgIGRlZmluaXRpb24ubmFtZSA9IGlkO1xuICAgICAgICAgIGRlZmluaXRpb24gPSBWdWUuZXh0ZW5kKGRlZmluaXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3B0aW9uc1t0eXBlICsgJ3MnXVtpZF0gPSBkZWZpbml0aW9uO1xuICAgICAgICByZXR1cm4gZGVmaW5pdGlvbjtcbiAgICAgIH1cbiAgICB9O1xuICB9KTtcblxuICAvLyBleHBvc2UgaW50ZXJuYWwgdHJhbnNpdGlvbiBBUElcbiAgZXh0ZW5kKFZ1ZS50cmFuc2l0aW9uLCB0cmFuc2l0aW9uKTtcbn1cblxuaW5zdGFsbEdsb2JhbEFQSShWdWUpO1xuXG5WdWUudmVyc2lvbiA9ICcxLjAuMTcnO1xuXG4vLyBkZXZ0b29scyBnbG9iYWwgaG9va1xuLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbmlmIChkZXZ0b29scykge1xuICBkZXZ0b29scy5lbWl0KCdpbml0JywgVnVlKTtcbn0gZWxzZSBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBpbkJyb3dzZXIgJiYgL0Nocm9tZVxcL1xcZCsvLnRlc3Qod2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG4gIGNvbnNvbGUubG9nKCdEb3dubG9hZCB0aGUgVnVlIERldnRvb2xzIGZvciBhIGJldHRlciBkZXZlbG9wbWVudCBleHBlcmllbmNlOlxcbicgKyAnaHR0cHM6Ly9naXRodWIuY29tL3Z1ZWpzL3Z1ZS1kZXZ0b29scycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFZ1ZTsiLCJ2YXIgaW5zZXJ0ZWQgPSBleHBvcnRzLmNhY2hlID0ge31cblxuZXhwb3J0cy5pbnNlcnQgPSBmdW5jdGlvbiAoY3NzKSB7XG4gIGlmIChpbnNlcnRlZFtjc3NdKSByZXR1cm5cbiAgaW5zZXJ0ZWRbY3NzXSA9IHRydWVcblxuICB2YXIgZWxlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJylcbiAgZWxlbS5zZXRBdHRyaWJ1dGUoJ3R5cGUnLCAndGV4dC9jc3MnKVxuXG4gIGlmICgndGV4dENvbnRlbnQnIGluIGVsZW0pIHtcbiAgICBlbGVtLnRleHRDb250ZW50ID0gY3NzXG4gIH0gZWxzZSB7XG4gICAgZWxlbS5zdHlsZVNoZWV0LmNzc1RleHQgPSBjc3NcbiAgfVxuXG4gIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF0uYXBwZW5kQ2hpbGQoZWxlbSlcbiAgcmV0dXJuIGVsZW1cbn1cbiIsIi8qIVxuICogVnVleCB2MC42LjJcbiAqIChjKSAyMDE2IEV2YW4gWW91XG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXG4gKi9cbihmdW5jdGlvbiAoZ2xvYmFsLCBmYWN0b3J5KSB7XG4gIHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpIDpcbiAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgKGdsb2JhbC5WdWV4ID0gZmFjdG9yeSgpKTtcbn0odGhpcywgZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7XG5cbiAgdmFyIGJhYmVsSGVscGVycyA9IHt9O1xuICBiYWJlbEhlbHBlcnMudHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIgPyBmdW5jdGlvbiAob2JqKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBvYmo7XG4gIH0gOiBmdW5jdGlvbiAob2JqKSB7XG4gICAgcmV0dXJuIG9iaiAmJiB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajtcbiAgfTtcblxuICBiYWJlbEhlbHBlcnMuY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7XG4gICAgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7XG4gICAgfVxuICB9O1xuXG4gIGJhYmVsSGVscGVycy5jcmVhdGVDbGFzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTtcbiAgICAgICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlO1xuICAgICAgICBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7XG4gICAgICAgIGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykge1xuICAgICAgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTtcbiAgICAgIGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpO1xuICAgICAgcmV0dXJuIENvbnN0cnVjdG9yO1xuICAgIH07XG4gIH0oKTtcblxuICBiYWJlbEhlbHBlcnMudG9Db25zdW1hYmxlQXJyYXkgPSBmdW5jdGlvbiAoYXJyKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBBcnJheShhcnIubGVuZ3RoKTsgaSA8IGFyci5sZW5ndGg7IGkrKykgYXJyMltpXSA9IGFycltpXTtcblxuICAgICAgcmV0dXJuIGFycjI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBBcnJheS5mcm9tKGFycik7XG4gICAgfVxuICB9O1xuXG4gIGJhYmVsSGVscGVycztcblxuICAvKipcbiAgICogTWVyZ2UgYW4gYXJyYXkgb2Ygb2JqZWN0cyBpbnRvIG9uZS5cbiAgICpcbiAgICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSBhcnJcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cblxuICBmdW5jdGlvbiBtZXJnZU9iamVjdHMoYXJyKSB7XG4gICAgcmV0dXJuIGFyci5yZWR1Y2UoZnVuY3Rpb24gKHByZXYsIG9iaikge1xuICAgICAgT2JqZWN0LmtleXMob2JqKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgdmFyIGV4aXN0aW5nID0gcHJldltrZXldO1xuICAgICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgICAvLyBhbGxvdyBtdWx0aXBsZSBtdXRhdGlvbiBvYmplY3RzIHRvIGNvbnRhaW4gZHVwbGljYXRlXG4gICAgICAgICAgLy8gaGFuZGxlcnMgZm9yIHRoZSBzYW1lIG11dGF0aW9uIHR5cGVcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShleGlzdGluZykpIHtcbiAgICAgICAgICAgIGV4aXN0aW5nLnB1c2gob2JqW2tleV0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcmV2W2tleV0gPSBbcHJldltrZXldLCBvYmpba2V5XV07XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByZXZba2V5XSA9IG9ialtrZXldO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBwcmV2O1xuICAgIH0sIHt9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWVwIGNsb25lIGFuIG9iamVjdC4gRmFzdGVyIHRoYW4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSgpKS5cbiAgICpcbiAgICogQHBhcmFtIHsqfSBvYmpcbiAgICogQHJldHVybiB7Kn1cbiAgICovXG5cbiAgZnVuY3Rpb24gZGVlcENsb25lKG9iaikge1xuICAgIGlmIChBcnJheS5pc0FycmF5KG9iaikpIHtcbiAgICAgIHJldHVybiBvYmoubWFwKGRlZXBDbG9uZSk7XG4gICAgfSBlbHNlIGlmIChvYmogJiYgKHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBiYWJlbEhlbHBlcnMudHlwZW9mKG9iaikpID09PSAnb2JqZWN0Jykge1xuICAgICAgdmFyIGNsb25lZCA9IHt9O1xuICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmopO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBrZXlzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgY2xvbmVkW2tleV0gPSBkZWVwQ2xvbmUob2JqW2tleV0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNsb25lZDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGFja3MgdG8gZ2V0IGFjY2VzcyB0byBWdWUgaW50ZXJuYWxzLlxuICAgKiBNYXliZSB3ZSBzaG91bGQgZXhwb3NlIHRoZXNlLi4uXG4gICAqL1xuXG4gIHZhciBXYXRjaGVyID0gdm9pZCAwO1xuICBmdW5jdGlvbiBnZXRXYXRjaGVyKHZtKSB7XG4gICAgaWYgKCFXYXRjaGVyKSB7XG4gICAgICB2YXIgdW53YXRjaCA9IHZtLiR3YXRjaCgnX192dWV4X18nLCBmdW5jdGlvbiAoYSkge1xuICAgICAgICByZXR1cm4gYTtcbiAgICAgIH0pO1xuICAgICAgV2F0Y2hlciA9IHZtLl93YXRjaGVyc1swXS5jb25zdHJ1Y3RvcjtcbiAgICAgIHVud2F0Y2goKTtcbiAgICB9XG4gICAgcmV0dXJuIFdhdGNoZXI7XG4gIH1cblxuICB2YXIgRGVwID0gdm9pZCAwO1xuICBmdW5jdGlvbiBnZXREZXAodm0pIHtcbiAgICBpZiAoIURlcCkge1xuICAgICAgRGVwID0gdm0uX2RhdGEuX19vYl9fLmRlcC5jb25zdHJ1Y3RvcjtcbiAgICB9XG4gICAgcmV0dXJuIERlcDtcbiAgfVxuXG4gIHZhciBob29rID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Ll9fVlVFX0RFVlRPT0xTX0dMT0JBTF9IT09LX187XG5cbiAgdmFyIGRldnRvb2xNaWRkbGV3YXJlID0ge1xuICAgIG9uSW5pdDogZnVuY3Rpb24gb25Jbml0KHN0YXRlLCBzdG9yZSkge1xuICAgICAgaWYgKCFob29rKSByZXR1cm47XG4gICAgICBob29rLmVtaXQoJ3Z1ZXg6aW5pdCcsIHN0b3JlKTtcbiAgICAgIGhvb2sub24oJ3Z1ZXg6dHJhdmVsLXRvLXN0YXRlJywgZnVuY3Rpb24gKHRhcmdldFN0YXRlKSB7XG4gICAgICAgIHZhciBjdXJyZW50U3RhdGUgPSBzdG9yZS5fdm0uX2RhdGE7XG4gICAgICAgIHN0b3JlLl9kaXNwYXRjaGluZyA9IHRydWU7XG4gICAgICAgIE9iamVjdC5rZXlzKHRhcmdldFN0YXRlKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICBjdXJyZW50U3RhdGVba2V5XSA9IHRhcmdldFN0YXRlW2tleV07XG4gICAgICAgIH0pO1xuICAgICAgICBzdG9yZS5fZGlzcGF0Y2hpbmcgPSBmYWxzZTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgb25NdXRhdGlvbjogZnVuY3Rpb24gb25NdXRhdGlvbihtdXRhdGlvbiwgc3RhdGUpIHtcbiAgICAgIGlmICghaG9vaykgcmV0dXJuO1xuICAgICAgaG9vay5lbWl0KCd2dWV4Om11dGF0aW9uJywgbXV0YXRpb24sIHN0YXRlKTtcbiAgICB9XG4gIH07XG5cbiAgZnVuY3Rpb24gb3ZlcnJpZGUgKFZ1ZSkge1xuICAgIC8vIG92ZXJyaWRlIGluaXQgYW5kIGluamVjdCB2dWV4IGluaXQgcHJvY2VkdXJlXG4gICAgdmFyIF9pbml0ID0gVnVlLnByb3RvdHlwZS5faW5pdDtcbiAgICBWdWUucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDAgfHwgYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyB7fSA6IGFyZ3VtZW50c1swXTtcblxuICAgICAgb3B0aW9ucy5pbml0ID0gb3B0aW9ucy5pbml0ID8gW3Z1ZXhJbml0XS5jb25jYXQob3B0aW9ucy5pbml0KSA6IHZ1ZXhJbml0O1xuICAgICAgX2luaXQuY2FsbCh0aGlzLCBvcHRpb25zKTtcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gdnVleEluaXQoKSB7XG4gICAgICB2YXIgb3B0aW9ucyA9IHRoaXMuJG9wdGlvbnM7XG4gICAgICB2YXIgc3RvcmUgPSBvcHRpb25zLnN0b3JlO1xuICAgICAgdmFyIHZ1ZXggPSBvcHRpb25zLnZ1ZXg7XG4gICAgICAvLyBzdG9yZSBpbmplY3Rpb25cblxuICAgICAgaWYgKHN0b3JlKSB7XG4gICAgICAgIHRoaXMuJHN0b3JlID0gc3RvcmU7XG4gICAgICB9IGVsc2UgaWYgKG9wdGlvbnMucGFyZW50ICYmIG9wdGlvbnMucGFyZW50LiRzdG9yZSkge1xuICAgICAgICB0aGlzLiRzdG9yZSA9IG9wdGlvbnMucGFyZW50LiRzdG9yZTtcbiAgICAgIH1cbiAgICAgIC8vIHZ1ZXggb3B0aW9uIGhhbmRsaW5nXG4gICAgICBpZiAodnVleCkge1xuICAgICAgICBpZiAoIXRoaXMuJHN0b3JlKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCdbdnVleF0gc3RvcmUgbm90IGluamVjdGVkLiBtYWtlIHN1cmUgdG8gJyArICdwcm92aWRlIHRoZSBzdG9yZSBvcHRpb24gaW4geW91ciByb290IGNvbXBvbmVudC4nKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc3RhdGUgPSB2dWV4LnN0YXRlO1xuICAgICAgICB2YXIgZ2V0dGVycyA9IHZ1ZXguZ2V0dGVycztcbiAgICAgICAgdmFyIGFjdGlvbnMgPSB2dWV4LmFjdGlvbnM7XG4gICAgICAgIC8vIGhhbmRsZSBkZXByZWNhdGVkIHN0YXRlIG9wdGlvblxuXG4gICAgICAgIGlmIChzdGF0ZSAmJiAhZ2V0dGVycykge1xuICAgICAgICAgIGNvbnNvbGUud2FybignW3Z1ZXhdIHZ1ZXguc3RhdGUgb3B0aW9uIHdpbGwgYmVlbiBkZXByZWNhdGVkIGluIDEuMC4gJyArICdVc2UgdnVleC5nZXR0ZXJzIGluc3RlYWQuJyk7XG4gICAgICAgICAgZ2V0dGVycyA9IHN0YXRlO1xuICAgICAgICB9XG4gICAgICAgIC8vIGdldHRlcnNcbiAgICAgICAgaWYgKGdldHRlcnMpIHtcbiAgICAgICAgICBvcHRpb25zLmNvbXB1dGVkID0gb3B0aW9ucy5jb21wdXRlZCB8fCB7fTtcbiAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gZ2V0dGVycykge1xuICAgICAgICAgICAgZGVmaW5lVnVleEdldHRlcih0aGlzLCBrZXksIGdldHRlcnNba2V5XSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGFjdGlvbnNcbiAgICAgICAgaWYgKGFjdGlvbnMpIHtcbiAgICAgICAgICBvcHRpb25zLm1ldGhvZHMgPSBvcHRpb25zLm1ldGhvZHMgfHwge307XG4gICAgICAgICAgZm9yICh2YXIgX2tleSBpbiBhY3Rpb25zKSB7XG4gICAgICAgICAgICBvcHRpb25zLm1ldGhvZHNbX2tleV0gPSBtYWtlQm91bmRBY3Rpb24oYWN0aW9uc1tfa2V5XSwgdGhpcy4kc3RvcmUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldHRlcigpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndnVleCBnZXR0ZXIgcHJvcGVydGllcyBhcmUgcmVhZC1vbmx5LicpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRlZmluZVZ1ZXhHZXR0ZXIodm0sIGtleSwgZ2V0dGVyKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodm0sIGtleSwge1xuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGdldDogbWFrZUNvbXB1dGVkR2V0dGVyKHZtLiRzdG9yZSwgZ2V0dGVyKSxcbiAgICAgICAgc2V0OiBzZXR0ZXJcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VDb21wdXRlZEdldHRlcihzdG9yZSwgZ2V0dGVyKSB7XG4gICAgICB2YXIgaWQgPSBzdG9yZS5fZ2V0dGVyQ2FjaGVJZDtcbiAgICAgIC8vIGNhY2hlZFxuICAgICAgaWYgKGdldHRlcltpZF0pIHtcbiAgICAgICAgcmV0dXJuIGdldHRlcltpZF07XG4gICAgICB9XG4gICAgICB2YXIgdm0gPSBzdG9yZS5fdm07XG4gICAgICB2YXIgV2F0Y2hlciA9IGdldFdhdGNoZXIodm0pO1xuICAgICAgdmFyIERlcCA9IGdldERlcCh2bSk7XG4gICAgICB2YXIgd2F0Y2hlciA9IG5ldyBXYXRjaGVyKHZtLCBmdW5jdGlvbiAoc3RhdGUpIHtcbiAgICAgICAgcmV0dXJuIGdldHRlcihzdGF0ZSk7XG4gICAgICB9LCBudWxsLCB7IGxhenk6IHRydWUgfSk7XG4gICAgICB2YXIgY29tcHV0ZWRHZXR0ZXIgPSBmdW5jdGlvbiBjb21wdXRlZEdldHRlcigpIHtcbiAgICAgICAgaWYgKHdhdGNoZXIuZGlydHkpIHtcbiAgICAgICAgICB3YXRjaGVyLmV2YWx1YXRlKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKERlcC50YXJnZXQpIHtcbiAgICAgICAgICB3YXRjaGVyLmRlcGVuZCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB3YXRjaGVyLnZhbHVlO1xuICAgICAgfTtcbiAgICAgIGdldHRlcltpZF0gPSBjb21wdXRlZEdldHRlcjtcbiAgICAgIHJldHVybiBjb21wdXRlZEdldHRlcjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlQm91bmRBY3Rpb24oYWN0aW9uLCBzdG9yZSkge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHZ1ZXhCb3VuZEFjdGlvbigpIHtcbiAgICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBBcnJheShfbGVuKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW47IF9rZXkyKyspIHtcbiAgICAgICAgICBhcmdzW19rZXkyXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYWN0aW9uLmNhbGwuYXBwbHkoYWN0aW9uLCBbdGhpcywgc3RvcmVdLmNvbmNhdChhcmdzKSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIG9wdGlvbiBtZXJnaW5nXG4gICAgdmFyIG1lcmdlID0gVnVlLmNvbmZpZy5vcHRpb25NZXJnZVN0cmF0ZWdpZXMuY29tcHV0ZWQ7XG4gICAgVnVlLmNvbmZpZy5vcHRpb25NZXJnZVN0cmF0ZWdpZXMudnVleCA9IGZ1bmN0aW9uICh0b1ZhbCwgZnJvbVZhbCkge1xuICAgICAgaWYgKCF0b1ZhbCkgcmV0dXJuIGZyb21WYWw7XG4gICAgICBpZiAoIWZyb21WYWwpIHJldHVybiB0b1ZhbDtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGdldHRlcnM6IG1lcmdlKHRvVmFsLmdldHRlcnMsIGZyb21WYWwuZ2V0dGVycyksXG4gICAgICAgIHN0YXRlOiBtZXJnZSh0b1ZhbC5zdGF0ZSwgZnJvbVZhbC5zdGF0ZSksXG4gICAgICAgIGFjdGlvbnM6IG1lcmdlKHRvVmFsLmFjdGlvbnMsIGZyb21WYWwuYWN0aW9ucylcbiAgICAgIH07XG4gICAgfTtcbiAgfVxuXG4gIHZhciBWdWUgPSB2b2lkIDA7XG4gIHZhciB1aWQgPSAwO1xuXG4gIHZhciBTdG9yZSA9IGZ1bmN0aW9uICgpIHtcblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAgICogICAgICAgIC0ge09iamVjdH0gc3RhdGVcbiAgICAgKiAgICAgICAgLSB7T2JqZWN0fSBhY3Rpb25zXG4gICAgICogICAgICAgIC0ge09iamVjdH0gbXV0YXRpb25zXG4gICAgICogICAgICAgIC0ge0FycmF5fSBtaWRkbGV3YXJlc1xuICAgICAqICAgICAgICAtIHtCb29sZWFufSBzdHJpY3RcbiAgICAgKi9cblxuICAgIGZ1bmN0aW9uIFN0b3JlKCkge1xuICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgdmFyIF9yZWYgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDAgfHwgYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyB7fSA6IGFyZ3VtZW50c1swXTtcblxuICAgICAgdmFyIF9yZWYkc3RhdGUgPSBfcmVmLnN0YXRlO1xuICAgICAgdmFyIHN0YXRlID0gX3JlZiRzdGF0ZSA9PT0gdW5kZWZpbmVkID8ge30gOiBfcmVmJHN0YXRlO1xuICAgICAgdmFyIF9yZWYkbXV0YXRpb25zID0gX3JlZi5tdXRhdGlvbnM7XG4gICAgICB2YXIgbXV0YXRpb25zID0gX3JlZiRtdXRhdGlvbnMgPT09IHVuZGVmaW5lZCA/IHt9IDogX3JlZiRtdXRhdGlvbnM7XG4gICAgICB2YXIgX3JlZiRtb2R1bGVzID0gX3JlZi5tb2R1bGVzO1xuICAgICAgdmFyIG1vZHVsZXMgPSBfcmVmJG1vZHVsZXMgPT09IHVuZGVmaW5lZCA/IHt9IDogX3JlZiRtb2R1bGVzO1xuICAgICAgdmFyIF9yZWYkbWlkZGxld2FyZXMgPSBfcmVmLm1pZGRsZXdhcmVzO1xuICAgICAgdmFyIG1pZGRsZXdhcmVzID0gX3JlZiRtaWRkbGV3YXJlcyA9PT0gdW5kZWZpbmVkID8gW10gOiBfcmVmJG1pZGRsZXdhcmVzO1xuICAgICAgdmFyIF9yZWYkc3RyaWN0ID0gX3JlZi5zdHJpY3Q7XG4gICAgICB2YXIgc3RyaWN0ID0gX3JlZiRzdHJpY3QgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogX3JlZiRzdHJpY3Q7XG4gICAgICBiYWJlbEhlbHBlcnMuY2xhc3NDYWxsQ2hlY2sodGhpcywgU3RvcmUpO1xuXG4gICAgICB0aGlzLl9nZXR0ZXJDYWNoZUlkID0gJ3Z1ZXhfc3RvcmVfJyArIHVpZCsrO1xuICAgICAgdGhpcy5fZGlzcGF0Y2hpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuX3Jvb3RNdXRhdGlvbnMgPSB0aGlzLl9tdXRhdGlvbnMgPSBtdXRhdGlvbnM7XG4gICAgICB0aGlzLl9tb2R1bGVzID0gbW9kdWxlcztcbiAgICAgIC8vIGJpbmQgZGlzcGF0Y2ggdG8gc2VsZlxuICAgICAgdmFyIGRpc3BhdGNoID0gdGhpcy5kaXNwYXRjaDtcbiAgICAgIHRoaXMuZGlzcGF0Y2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRpc3BhdGNoLmFwcGx5KF90aGlzLCBhcmdzKTtcbiAgICAgIH07XG4gICAgICAvLyB1c2UgYSBWdWUgaW5zdGFuY2UgdG8gc3RvcmUgdGhlIHN0YXRlIHRyZWVcbiAgICAgIC8vIHN1cHByZXNzIHdhcm5pbmdzIGp1c3QgaW4gY2FzZSB0aGUgdXNlciBoYXMgYWRkZWRcbiAgICAgIC8vIHNvbWUgZnVua3kgZ2xvYmFsIG1peGluc1xuICAgICAgaWYgKCFWdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdbdnVleF0gbXVzdCBjYWxsIFZ1ZS51c2UoVnVleCkgYmVmb3JlIGNyZWF0aW5nIGEgc3RvcmUgaW5zdGFuY2UuJyk7XG4gICAgICB9XG4gICAgICB2YXIgc2lsZW50ID0gVnVlLmNvbmZpZy5zaWxlbnQ7XG4gICAgICBWdWUuY29uZmlnLnNpbGVudCA9IHRydWU7XG4gICAgICB0aGlzLl92bSA9IG5ldyBWdWUoe1xuICAgICAgICBkYXRhOiBzdGF0ZVxuICAgICAgfSk7XG4gICAgICBWdWUuY29uZmlnLnNpbGVudCA9IHNpbGVudDtcbiAgICAgIHRoaXMuX3NldHVwTW9kdWxlU3RhdGUoc3RhdGUsIG1vZHVsZXMpO1xuICAgICAgdGhpcy5fc2V0dXBNb2R1bGVNdXRhdGlvbnMobW9kdWxlcyk7XG4gICAgICB0aGlzLl9zZXR1cE1pZGRsZXdhcmVzKG1pZGRsZXdhcmVzLCBzdGF0ZSk7XG4gICAgICAvLyBhZGQgZXh0cmEgd2FybmluZ3MgaW4gc3RyaWN0IG1vZGVcbiAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgdGhpcy5fc2V0dXBNdXRhdGlvbkNoZWNrKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0dGVyIGZvciB0aGUgZW50aXJlIHN0YXRlIHRyZWUuXG4gICAgICogUmVhZCBvbmx5LlxuICAgICAqXG4gICAgICogQHJldHVybiB7T2JqZWN0fVxuICAgICAqL1xuXG4gICAgYmFiZWxIZWxwZXJzLmNyZWF0ZUNsYXNzKFN0b3JlLCBbe1xuICAgICAga2V5OiAnZGlzcGF0Y2gnLFxuXG5cbiAgICAgIC8qKlxuICAgICAgICogRGlzcGF0Y2ggYW4gYWN0aW9uLlxuICAgICAgICpcbiAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gICAgICAgKi9cblxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRpc3BhdGNoKHR5cGUpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBwYXlsb2FkID0gQXJyYXkoX2xlbjIgPiAxID8gX2xlbjIgLSAxIDogMCksIF9rZXkyID0gMTsgX2tleTIgPCBfbGVuMjsgX2tleTIrKykge1xuICAgICAgICAgIHBheWxvYWRbX2tleTIgLSAxXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjb21wYXRpYmlsaXR5IGZvciBvYmplY3QgYWN0aW9ucywgZS5nLiBGU0FcbiAgICAgICAgaWYgKCh0eXBlb2YgdHlwZSA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IGJhYmVsSGVscGVycy50eXBlb2YodHlwZSkpID09PSAnb2JqZWN0JyAmJiB0eXBlLnR5cGUgJiYgYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIHBheWxvYWQgPSBbdHlwZV07XG4gICAgICAgICAgdHlwZSA9IHR5cGUudHlwZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbXV0YXRpb24gPSB0aGlzLl9tdXRhdGlvbnNbdHlwZV07XG4gICAgICAgIHZhciBwcmV2U25hcHNob3QgPSB0aGlzLl9wcmV2U25hcHNob3Q7XG4gICAgICAgIHZhciBzdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgICAgIHZhciBzbmFwc2hvdCA9IHZvaWQgMCxcbiAgICAgICAgICAgIGNsb25lZFBheWxvYWQgPSB2b2lkIDA7XG4gICAgICAgIGlmIChtdXRhdGlvbikge1xuICAgICAgICAgIHRoaXMuX2Rpc3BhdGNoaW5nID0gdHJ1ZTtcbiAgICAgICAgICAvLyBhcHBseSB0aGUgbXV0YXRpb25cbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShtdXRhdGlvbikpIHtcbiAgICAgICAgICAgIG11dGF0aW9uLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG0uYXBwbHkodW5kZWZpbmVkLCBbc3RhdGVdLmNvbmNhdChiYWJlbEhlbHBlcnMudG9Db25zdW1hYmxlQXJyYXkocGF5bG9hZCkpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtdXRhdGlvbi5hcHBseSh1bmRlZmluZWQsIFtzdGF0ZV0uY29uY2F0KGJhYmVsSGVscGVycy50b0NvbnN1bWFibGVBcnJheShwYXlsb2FkKSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLl9kaXNwYXRjaGluZyA9IGZhbHNlO1xuICAgICAgICAgIC8vIGludm9rZSBtaWRkbGV3YXJlc1xuICAgICAgICAgIGlmICh0aGlzLl9uZWVkU25hcHNob3RzKSB7XG4gICAgICAgICAgICBzbmFwc2hvdCA9IHRoaXMuX3ByZXZTbmFwc2hvdCA9IGRlZXBDbG9uZShzdGF0ZSk7XG4gICAgICAgICAgICBjbG9uZWRQYXlsb2FkID0gZGVlcENsb25lKHBheWxvYWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLl9taWRkbGV3YXJlcy5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICBpZiAobS5vbk11dGF0aW9uKSB7XG4gICAgICAgICAgICAgIGlmIChtLnNuYXBzaG90KSB7XG4gICAgICAgICAgICAgICAgbS5vbk11dGF0aW9uKHsgdHlwZTogdHlwZSwgcGF5bG9hZDogY2xvbmVkUGF5bG9hZCB9LCBzbmFwc2hvdCwgcHJldlNuYXBzaG90LCBfdGhpczIpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG0ub25NdXRhdGlvbih7IHR5cGU6IHR5cGUsIHBheWxvYWQ6IHBheWxvYWQgfSwgc3RhdGUsIF90aGlzMik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oJ1t2dWV4XSBVbmtub3duIG11dGF0aW9uOiAnICsgdHlwZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBXYXRjaCBzdGF0ZSBjaGFuZ2VzIG9uIHRoZSBzdG9yZS5cbiAgICAgICAqIFNhbWUgQVBJIGFzIFZ1ZSdzICR3YXRjaCwgZXhjZXB0IHdoZW4gd2F0Y2hpbmcgYSBmdW5jdGlvbixcbiAgICAgICAqIHRoZSBmdW5jdGlvbiBnZXRzIHRoZSBzdGF0ZSBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4gICAgICAgKlxuICAgICAgICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IGV4cE9yRm5cbiAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNiXG4gICAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgIGtleTogJ3dhdGNoJyxcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiB3YXRjaChleHBPckZuLCBjYiwgb3B0aW9ucykge1xuICAgICAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgICAgICByZXR1cm4gdGhpcy5fdm0uJHdhdGNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gdHlwZW9mIGV4cE9yRm4gPT09ICdmdW5jdGlvbicgPyBleHBPckZuKF90aGlzMy5zdGF0ZSkgOiBfdGhpczMuX3ZtLiRnZXQoZXhwT3JGbik7XG4gICAgICAgIH0sIGNiLCBvcHRpb25zKTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBIb3QgdXBkYXRlIG11dGF0aW9ucyAmIG1vZHVsZXMuXG4gICAgICAgKlxuICAgICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICAgICAqICAgICAgICAtIHtPYmplY3R9IFttdXRhdGlvbnNdXG4gICAgICAgKiAgICAgICAgLSB7T2JqZWN0fSBbbW9kdWxlc11cbiAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAga2V5OiAnaG90VXBkYXRlJyxcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBob3RVcGRhdGUoKSB7XG4gICAgICAgIHZhciBfcmVmMiA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMCB8fCBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IHt9IDogYXJndW1lbnRzWzBdO1xuXG4gICAgICAgIHZhciBtdXRhdGlvbnMgPSBfcmVmMi5tdXRhdGlvbnM7XG4gICAgICAgIHZhciBtb2R1bGVzID0gX3JlZjIubW9kdWxlcztcblxuICAgICAgICB0aGlzLl9yb290TXV0YXRpb25zID0gdGhpcy5fbXV0YXRpb25zID0gbXV0YXRpb25zIHx8IHRoaXMuX3Jvb3RNdXRhdGlvbnM7XG4gICAgICAgIHRoaXMuX3NldHVwTW9kdWxlTXV0YXRpb25zKG1vZHVsZXMgfHwgdGhpcy5fbW9kdWxlcyk7XG4gICAgICB9XG5cbiAgICAgIC8qKlxuICAgICAgICogQXR0YWNoIHN1YiBzdGF0ZSB0cmVlIG9mIGVhY2ggbW9kdWxlIHRvIHRoZSByb290IHRyZWUuXG4gICAgICAgKlxuICAgICAgICogQHBhcmFtIHtPYmplY3R9IHN0YXRlXG4gICAgICAgKiBAcGFyYW0ge09iamVjdH0gbW9kdWxlc1xuICAgICAgICovXG5cbiAgICB9LCB7XG4gICAgICBrZXk6ICdfc2V0dXBNb2R1bGVTdGF0ZScsXG4gICAgICB2YWx1ZTogZnVuY3Rpb24gX3NldHVwTW9kdWxlU3RhdGUoc3RhdGUsIG1vZHVsZXMpIHtcbiAgICAgICAgdmFyIHNldFBhdGggPSBWdWUucGFyc2Vycy5wYXRoLnNldFBhdGg7XG5cbiAgICAgICAgT2JqZWN0LmtleXMobW9kdWxlcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgc2V0UGF0aChzdGF0ZSwga2V5LCBtb2R1bGVzW2tleV0uc3RhdGUgfHwge30pO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBCaW5kIG11dGF0aW9ucyBmb3IgZWFjaCBtb2R1bGUgdG8gaXRzIHN1YiB0cmVlIGFuZFxuICAgICAgICogbWVyZ2UgdGhlbSBhbGwgaW50byBvbmUgZmluYWwgbXV0YXRpb25zIG1hcC5cbiAgICAgICAqXG4gICAgICAgKiBAcGFyYW0ge09iamVjdH0gdXBkYXRlZE1vZHVsZXNcbiAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAga2V5OiAnX3NldHVwTW9kdWxlTXV0YXRpb25zJyxcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBfc2V0dXBNb2R1bGVNdXRhdGlvbnModXBkYXRlZE1vZHVsZXMpIHtcbiAgICAgICAgdmFyIG1vZHVsZXMgPSB0aGlzLl9tb2R1bGVzO1xuICAgICAgICB2YXIgZ2V0UGF0aCA9IFZ1ZS5wYXJzZXJzLnBhdGguZ2V0UGF0aDtcblxuICAgICAgICB2YXIgYWxsTXV0YXRpb25zID0gW3RoaXMuX3Jvb3RNdXRhdGlvbnNdO1xuICAgICAgICBPYmplY3Qua2V5cyh1cGRhdGVkTW9kdWxlcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgbW9kdWxlc1trZXldID0gdXBkYXRlZE1vZHVsZXNba2V5XTtcbiAgICAgICAgfSk7XG4gICAgICAgIE9iamVjdC5rZXlzKG1vZHVsZXMpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgIHZhciBtb2R1bGUgPSBtb2R1bGVzW2tleV07XG4gICAgICAgICAgaWYgKCFtb2R1bGUgfHwgIW1vZHVsZS5tdXRhdGlvbnMpIHJldHVybjtcbiAgICAgICAgICAvLyBiaW5kIG11dGF0aW9ucyB0byBzdWIgc3RhdGUgdHJlZVxuICAgICAgICAgIHZhciBtdXRhdGlvbnMgPSB7fTtcbiAgICAgICAgICBPYmplY3Qua2V5cyhtb2R1bGUubXV0YXRpb25zKS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgICAgICB2YXIgb3JpZ2luYWwgPSBtb2R1bGUubXV0YXRpb25zW25hbWVdO1xuICAgICAgICAgICAgbXV0YXRpb25zW25hbWVdID0gZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgICAgICAgICAgIGZvciAodmFyIF9sZW4zID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4zID4gMSA/IF9sZW4zIC0gMSA6IDApLCBfa2V5MyA9IDE7IF9rZXkzIDwgX2xlbjM7IF9rZXkzKyspIHtcbiAgICAgICAgICAgICAgICBhcmdzW19rZXkzIC0gMV0gPSBhcmd1bWVudHNbX2tleTNdO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgb3JpZ2luYWwuYXBwbHkodW5kZWZpbmVkLCBbZ2V0UGF0aChzdGF0ZSwga2V5KV0uY29uY2F0KGFyZ3MpKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYWxsTXV0YXRpb25zLnB1c2gobXV0YXRpb25zKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX211dGF0aW9ucyA9IG1lcmdlT2JqZWN0cyhhbGxNdXRhdGlvbnMpO1xuICAgICAgfVxuXG4gICAgICAvKipcbiAgICAgICAqIFNldHVwIG11dGF0aW9uIGNoZWNrOiBpZiB0aGUgdnVleCBpbnN0YW5jZSdzIHN0YXRlIGlzIG11dGF0ZWRcbiAgICAgICAqIG91dHNpZGUgb2YgYSBtdXRhdGlvbiBoYW5kbGVyLCB3ZSB0aHJvdyBlbiBlcnJvci4gVGhpcyBlZmZlY3RpdmVseVxuICAgICAgICogZW5mb3JjZXMgYWxsIG11dGF0aW9ucyB0byB0aGUgc3RhdGUgdG8gYmUgdHJhY2thYmxlIGFuZCBob3QtcmVsb2FkYmxlLlxuICAgICAgICogSG93ZXZlciwgdGhpcyBjb21lcyBhdCBhIHJ1biB0aW1lIGNvc3Qgc2luY2Ugd2UgYXJlIGRvaW5nIGEgZGVlcFxuICAgICAgICogd2F0Y2ggb24gdGhlIGVudGlyZSBzdGF0ZSB0cmVlLCBzbyBpdCBpcyBvbmx5IGVuYWxiZWQgd2l0aCB0aGVcbiAgICAgICAqIHN0cmljdCBvcHRpb24gaXMgc2V0IHRvIHRydWUuXG4gICAgICAgKi9cblxuICAgIH0sIHtcbiAgICAgIGtleTogJ19zZXR1cE11dGF0aW9uQ2hlY2snLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9zZXR1cE11dGF0aW9uQ2hlY2soKSB7XG4gICAgICAgIHZhciBfdGhpczQgPSB0aGlzO1xuXG4gICAgICAgIHZhciBXYXRjaGVyID0gZ2V0V2F0Y2hlcih0aGlzLl92bSk7XG4gICAgICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLW5ldyAqL1xuICAgICAgICBuZXcgV2F0Y2hlcih0aGlzLl92bSwgJyRkYXRhJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmICghX3RoaXM0Ll9kaXNwYXRjaGluZykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdbdnVleF0gRG8gbm90IG11dGF0ZSB2dWV4IHN0b3JlIHN0YXRlIG91dHNpZGUgbXV0YXRpb24gaGFuZGxlcnMuJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCB7IGRlZXA6IHRydWUsIHN5bmM6IHRydWUgfSk7XG4gICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tbmV3ICovXG4gICAgICB9XG5cbiAgICAgIC8qKlxuICAgICAgICogU2V0dXAgdGhlIG1pZGRsZXdhcmVzLiBUaGUgZGV2dG9vbHMgbWlkZGxld2FyZSBpcyBhbHdheXNcbiAgICAgICAqIGluY2x1ZGVkLCBzaW5jZSBpdCBkb2VzIG5vdGhpbmcgaWYgbm8gZGV2dG9vbCBpcyBkZXRlY3RlZC5cbiAgICAgICAqXG4gICAgICAgKiBBIG1pZGRsZXdhcmUgY2FuIGRlbWFuZCB0aGUgc3RhdGUgaXQgcmVjZWl2ZXMgdG8gYmVcbiAgICAgICAqIFwic25hcHNob3RzXCIsIGkuZS4gZGVlcCBjbG9uZXMgb2YgdGhlIGFjdHVhbCBzdGF0ZSB0cmVlLlxuICAgICAgICpcbiAgICAgICAqIEBwYXJhbSB7QXJyYXl9IG1pZGRsZXdhcmVzXG4gICAgICAgKiBAcGFyYW0ge09iamVjdH0gc3RhdGVcbiAgICAgICAqL1xuXG4gICAgfSwge1xuICAgICAga2V5OiAnX3NldHVwTWlkZGxld2FyZXMnLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIF9zZXR1cE1pZGRsZXdhcmVzKG1pZGRsZXdhcmVzLCBzdGF0ZSkge1xuICAgICAgICB2YXIgX3RoaXM1ID0gdGhpcztcblxuICAgICAgICB0aGlzLl9taWRkbGV3YXJlcyA9IFtkZXZ0b29sTWlkZGxld2FyZV0uY29uY2F0KG1pZGRsZXdhcmVzKTtcbiAgICAgICAgdGhpcy5fbmVlZFNuYXBzaG90cyA9IG1pZGRsZXdhcmVzLnNvbWUoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICByZXR1cm4gbS5zbmFwc2hvdDtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLl9uZWVkU25hcHNob3RzKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ1t2dWV4XSBPbmUgb3IgbW9yZSBvZiB5b3VyIG1pZGRsZXdhcmVzIGFyZSB0YWtpbmcgc3RhdGUgc25hcHNob3RzICcgKyAnZm9yIGVhY2ggbXV0YXRpb24uIE1ha2Ugc3VyZSB0byB1c2UgdGhlbSBvbmx5IGR1cmluZyBkZXZlbG9wbWVudC4nKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaW5pdGlhbFNuYXBzaG90ID0gdGhpcy5fcHJldlNuYXBzaG90ID0gdGhpcy5fbmVlZFNuYXBzaG90cyA/IGRlZXBDbG9uZShzdGF0ZSkgOiBudWxsO1xuICAgICAgICAvLyBjYWxsIGluaXQgaG9va3NcbiAgICAgICAgdGhpcy5fbWlkZGxld2FyZXMuZm9yRWFjaChmdW5jdGlvbiAobSkge1xuICAgICAgICAgIGlmIChtLm9uSW5pdCkge1xuICAgICAgICAgICAgbS5vbkluaXQobS5zbmFwc2hvdCA/IGluaXRpYWxTbmFwc2hvdCA6IHN0YXRlLCBfdGhpczUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSwge1xuICAgICAga2V5OiAnc3RhdGUnLFxuICAgICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92bS5fZGF0YTtcbiAgICAgIH0sXG4gICAgICBzZXQ6IGZ1bmN0aW9uIHNldCh2KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignW3Z1ZXhdIFZ1ZXggcm9vdCBzdGF0ZSBpcyByZWFkIG9ubHkuJyk7XG4gICAgICB9XG4gICAgfV0pO1xuICAgIHJldHVybiBTdG9yZTtcbiAgfSgpO1xuXG4gIGZ1bmN0aW9uIGluc3RhbGwoX1Z1ZSkge1xuICAgIFZ1ZSA9IF9WdWU7XG4gICAgb3ZlcnJpZGUoVnVlKTtcbiAgfVxuXG4gIC8vIGF1dG8gaW5zdGFsbCBpbiBkaXN0IG1vZGVcbiAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5WdWUpIHtcbiAgICBpbnN0YWxsKHdpbmRvdy5WdWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlTG9nZ2VyKCkge1xuICAgIGNvbnNvbGUud2FybignW3Z1ZXhdIFZ1ZXguY3JlYXRlTG9nZ2VyIGhhcyBiZWVuIGRlcHJlY2F0ZWQuJyArICdVc2UgYGltcG9ydCBjcmVhdGVMb2dnZXIgZnJvbSBcXCd2dWV4L2xvZ2dlclxcJyBpbnN0ZWFkLicpO1xuICB9XG5cbiAgdmFyIGluZGV4ID0ge1xuICAgIFN0b3JlOiBTdG9yZSxcbiAgICBpbnN0YWxsOiBpbnN0YWxsLFxuICAgIGNyZWF0ZUxvZ2dlcjogY3JlYXRlTG9nZ2VyXG4gIH07XG5cbiAgcmV0dXJuIGluZGV4O1xuXG59KSk7IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWxwaGFiZXQgPSAnMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXotXycuc3BsaXQoJycpXG4gICwgbGVuZ3RoID0gNjRcbiAgLCBtYXAgPSB7fVxuICAsIHNlZWQgPSAwXG4gICwgaSA9IDBcbiAgLCBwcmV2O1xuXG4vKipcbiAqIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHNwZWNpZmllZCBudW1iZXIuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG51bSBUaGUgbnVtYmVyIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7U3RyaW5nfSBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBudW1iZXIuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBlbmNvZGUobnVtKSB7XG4gIHZhciBlbmNvZGVkID0gJyc7XG5cbiAgZG8ge1xuICAgIGVuY29kZWQgPSBhbHBoYWJldFtudW0gJSBsZW5ndGhdICsgZW5jb2RlZDtcbiAgICBudW0gPSBNYXRoLmZsb29yKG51bSAvIGxlbmd0aCk7XG4gIH0gd2hpbGUgKG51bSA+IDApO1xuXG4gIHJldHVybiBlbmNvZGVkO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgaW50ZWdlciB2YWx1ZSBzcGVjaWZpZWQgYnkgdGhlIGdpdmVuIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFRoZSBpbnRlZ2VyIHZhbHVlIHJlcHJlc2VudGVkIGJ5IHRoZSBzdHJpbmcuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBkZWNvZGUoc3RyKSB7XG4gIHZhciBkZWNvZGVkID0gMDtcblxuICBmb3IgKGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG4gICAgZGVjb2RlZCA9IGRlY29kZWQgKiBsZW5ndGggKyBtYXBbc3RyLmNoYXJBdChpKV07XG4gIH1cblxuICByZXR1cm4gZGVjb2RlZDtcbn1cblxuLyoqXG4gKiBZZWFzdDogQSB0aW55IGdyb3dpbmcgaWQgZ2VuZXJhdG9yLlxuICpcbiAqIEByZXR1cm5zIHtTdHJpbmd9IEEgdW5pcXVlIGlkLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuZnVuY3Rpb24geWVhc3QoKSB7XG4gIHZhciBub3cgPSBlbmNvZGUoK25ldyBEYXRlKCkpO1xuXG4gIGlmIChub3cgIT09IHByZXYpIHJldHVybiBzZWVkID0gMCwgcHJldiA9IG5vdztcbiAgcmV0dXJuIG5vdyArJy4nKyBlbmNvZGUoc2VlZCsrKTtcbn1cblxuLy9cbi8vIE1hcCBlYWNoIGNoYXJhY3RlciB0byBpdHMgaW5kZXguXG4vL1xuZm9yICg7IGkgPCBsZW5ndGg7IGkrKykgbWFwW2FscGhhYmV0W2ldXSA9IGk7XG5cbi8vXG4vLyBFeHBvc2UgdGhlIGB5ZWFzdGAsIGBlbmNvZGVgIGFuZCBgZGVjb2RlYCBmdW5jdGlvbnMuXG4vL1xueWVhc3QuZW5jb2RlID0gZW5jb2RlO1xueWVhc3QuZGVjb2RlID0gZGVjb2RlO1xubW9kdWxlLmV4cG9ydHMgPSB5ZWFzdDtcbiIsInZhciBfX3Z1ZWlmeV9zdHlsZV9fID0gcmVxdWlyZShcInZ1ZWlmeS1pbnNlcnQtY3NzXCIpLmluc2VydChcIlxcblxcbi8qICAjRjE2NzQ1ICNGRkM2NUQgIzdCQzhBNCAjNENDM0Q5ICM5MzY0OEQgIzQwNDA0MCAgKi9cXG5cXG4gIGJvZHkge1xcbiAgICBjb2xvcjogIzQwNDA0MDtcXG4gIH1cXG5cXG4gIC5qdW1ib3Ryb24tdG9wIHtcXG4gICAgY29sb3I6ICNmZmY7XFxuICAgIGJhY2tncm91bmQ6ICM0Q0MzRDk7XFxuICAgIG1hcmdpbi1ib3R0b206IDA7XFxuICB9XFxuXFxuICAuYnRuLWN1c3RvbSB7XFxuICAgIGNvbG9yOiAjZmZmO1xcbiAgICBiYWNrZ3JvdW5kOiAjRjE2NzQ1O1xcbiAgfVxcblxcbiAgLmp1bWJvdHJvbi5qdW1ib3Ryb24tZ3JlZW4ge1xcbiAgICBwYWRkaW5nOiA3NXB4IDA7XFxuICAgIC8qYmFja2dyb3VuZDogIzQwNDA0MDsqL1xcbiAgICAvKmNvbG9yOiAjZmZmOyovXFxuICB9XFxuXFxuICAjdi1zZWxlY3QgLmRyb3Bkb3duLXRvZ2dsZSB7XFxuICAgIC8qYm9yZGVyLWNvbG9yOiNmZmY7Ki9cXG4gICAgYmFja2dyb3VuZDogI2ZmZjtcXG4gIH1cXG5cXG4gICN2LXNlbGVjdCAuZHJvcGRvd24tdG9nZ2xlOmFmdGVyIHtcXG4gICAgY29sb3I6ICM0MDQwNDA7XFxuICB9XFxuXFxuICAvKiBDeWFuIHRoZW1lICovXFxuICAjdi1zZWxlY3QgLnNlbGVjdGVkLXRhZyB7XFxuICAgIGNvbG9yOiAjMTQ3Njg4O1xcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZDdmM2Y5O1xcbiAgICBib3JkZXItY29sb3I6ICM5MWRkZWM7XFxuICB9XFxuXFxuICAjdi1zZWxlY3QuZHJvcGRvd24ub3BlbiAuZHJvcGRvd24tdG9nZ2xlLFxcbiAgI3Ytc2VsZWN0LmRyb3Bkb3duLm9wZW4gLmRyb3Bkb3duLW1lbnUge1xcbiAgICBib3JkZXItY29sb3I6ICM0Q0MzRDk7XFxuICB9XFxuXFxuICAjdi1zZWxlY3QgLmFjdGl2ZSBhIHtcXG4gICAgYmFja2dyb3VuZDogcmdiYSg1MCw1MCw1MCwuMSk7XFxuICAgIGNvbG9yOiAjMzMzO1xcbiAgfVxcblxcbiAgI3Ytc2VsZWN0LmRyb3Bkb3duIC5oaWdobGlnaHQgYSxcXG4gICN2LXNlbGVjdC5kcm9wZG93biBsaTpob3ZlciBhIHtcXG4gICAgYmFja2dyb3VuZDogIzRDQzNEOTtcXG4gICAgY29sb3I6ICNmZmY7XFxuICB9XFxuXFxuICAjb3V0cHV0IHtcXG4gICAgaGVpZ2h0OiAyMDBweDtcXG4gICAgYm9yZGVyOiBub25lO1xcbiAgICBjb2xvcjogIzQwNDA0MDtcXG4gIH1cXG5cIilcbid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF9KdW1ib3Ryb24gPSByZXF1aXJlKCcuL2NvbXBvbmVudHMvSnVtYm90cm9uLnZ1ZScpO1xuXG52YXIgX0p1bWJvdHJvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9KdW1ib3Ryb24pO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5leHBvcnRzLmRlZmF1bHQgPSB7XG4gIGNvbXBvbmVudHM6IHsgSnVtYm90cm9uOiBfSnVtYm90cm9uMi5kZWZhdWx0IH1cbn07XG5pZiAobW9kdWxlLmV4cG9ydHMuX19lc01vZHVsZSkgbW9kdWxlLmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cy5kZWZhdWx0XG47KHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJmdW5jdGlvblwiPyBtb2R1bGUuZXhwb3J0cy5vcHRpb25zOiBtb2R1bGUuZXhwb3J0cykudGVtcGxhdGUgPSBcIlxcbjxkaXYgY2xhc3M9XFxcImp1bWJvdHJvbiBqdW1ib3Ryb24tdG9wXFxcIj5cXG4gIDxkaXYgY2xhc3M9XFxcImNvbnRhaW5lclxcXCI+XFxuICAgIDxoMT5WdWUgU2VsZWN0PC9oMT5cXG4gICAgPHAgY2xhc3M9XFxcImxlYWRcXFwiPkEgc2ltcGxlIGNvbXBvbmVudCB0aGF0IHByb3ZpZGVzIHNpbWlsYXIgZnVuY3Rpb25hbGl0eSB0byBTZWxlY3QyIHdpdGhvdXQgdGhlIG92ZXJoZWFkIG9mIGpRdWVyeS48L3A+XFxuICAgIDxhIGNsYXNzPVxcXCJidG4gYnRuLWN1c3RvbVxcXCIgaHJlZj1cXFwiaHR0cHM6Ly9naXRodWIuY29tL3NhZ2FsYm90L3Z1ZS1zZWxlY3RcXFwiPlZpZXcgb24gR2l0SHViPC9hPlxcbiAgPC9kaXY+XFxuPC9kaXY+XFxuXFxuICA8anVtYm90cm9uPjwvanVtYm90cm9uPlxcblxcbiAgPGRpdiBpZD1cXFwiYXBwXFxcIiBjbGFzcz1cXFwiY29udGFpbmVyXFxcIj5cXG4gIDxoMiBjbGFzcz1cXFwicGFnZS1oZWFkZXJcXFwiPkxpdmUgRWRpdCA8c21hbGw+cGxheSBhcm91bmQgd2l0aCB0aGUgYWJvdmUgdnVlLXNlbGVjdDwvc21hbGw+PC9oMj5cXG5cXG4gIDxkaXYgY2xhc3M9XFxcInJvd1xcXCI+XFxuICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC02XFxcIj5cXG4gICAgICA8bGFiZWwgY2xhc3M9XFxcImNvbnRyb2wtbGFiZWxcXFwiPk9wdGlvbnM8L2xhYmVsPjxicj5cXG4gICAgICA8ZGl2IGNsYXNzPVxcXCJyYWRpb1xcXCI+XFxuICAgICAgICA8bGFiZWwgZm9yPVxcXCJhZHZhbmNlZFxcXCI+XFxuICAgICAgICAgIDxpbnB1dCBpZD1cXFwiYWR2YW5jZWRcXFwiIHR5cGU9XFxcInJhZGlvXFxcIiB2LW1vZGVsPVxcXCJvcHRpb25UeXBlXFxcIiB2YWx1ZT1cXFwiYWR2YW5jZWRcXFwiPiBPYmplY3RzXFxuICAgICAgICAgIDxwcmU+PGNvZGUgY2xhc3M9XFxcImxhbmd1YWdlLWphdmFzY3JpcHRcXFwiPlt7dmFsdWU6ICdmb28nLCBsYWJlbDogJ0Zvbyd9XTwvY29kZT48L3ByZT5cXG4gICAgICAgIDwvbGFiZWw+XFxuICAgICAgICA8YnI+XFxuICAgICAgICA8bGFiZWwgZm9yPVxcXCJzaW1wbGVcXFwiPlxcbiAgICAgICAgICA8aW5wdXQgaWQ9XFxcInNpbXBsZVxcXCIgdHlwZT1cXFwicmFkaW9cXFwiIHYtbW9kZWw9XFxcIm9wdGlvblR5cGVcXFwiIHZhbHVlPVxcXCJzaW1wbGVcXFwiPiBTdHJpbmdzXFxuICAgICAgICAgIDxwcmU+PGNvZGUgY2xhc3M9XFxcImxhbmd1YWdlLWphdmFzY3JpcHRcXFwiPlsnZm9vJywgJ2JhciddPC9jb2RlPjwvcHJlPlxcbiAgICAgICAgPC9sYWJlbD5cXG4gICAgICAgIDxzcGFuIGNsYXNzPVxcXCJoZWxwLWJsb2NrXFxcIj5UaGUgPGNvZGU+b3B0aW9uczwvY29kZT4gcHJvcGVydHkgaXMgd2F0Y2hlZCBmb3IgY2hhbmdlcywgYW5kIHRoZSB2YWx1ZSBpcyByZXNldCBhbnl0aW1lIHRoZSBvcHRpb25zIGNoYW5nZS4gVGhpcyBpcyB1c2VmdWwgaWYgeW91IGhhdmUgbXVsdGlwbGUgc2VsZWN0aW9uIGJveGVzIHRoYXQgZGVwZW5kIG9uIGl0cyBhbmNlc3RvcnMgdmFsdWVzLjwvc3Bhbj5cXG4gICAgICA8L2Rpdj5cXG4gICAgPC9kaXY+XFxuXFxuICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC02XFxcIj5cXG5cXG4gICAgICA8ZGl2IGNsYXNzPVxcXCJmb3JtLWdyb3VwXFxcIj5cXG4gICAgICAgIDxsYWJlbCBjbGFzcz1cXFwiY29udHJvbC1sYWJlbFxcXCI+QWxsb3cgTXVsdGlwbGU8L2xhYmVsPlxcbiAgICAgICAgPGRpdiBjbGFzcz1cXFwiY2hlY2tib3hcXFwiPlxcbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XFxcImNvbnRyb2wtbGFiZWxcXFwiPlxcbiAgICAgICAgICAgIDxpbnB1dCB2LW1vZGVsPVxcXCJtdWx0aXBsZVxcXCIgdHlwZT1cXFwiY2hlY2tib3hcXFwiPiBUcnVlXFxuICAgICAgICAgIDwvbGFiZWw+XFxuICAgICAgICAgIDxzcGFuIGNsYXNzPVxcXCJoZWxwLWJsb2NrXFxcIj5FcXVpdmFsZW50IHRvIHRoZSA8Y29kZT5tdWx0aXBsZTwvY29kZT4gYXR0cmlidXRlIHRvIGEgPGNvZGU+Jmx0O3NlbGVjdCZndDs8L2NvZGU+LiBZb3UnbGwgd2FudCB0byBjbGVhciBhbnkgc2VsZWN0aW9ucyB5b3UgaGF2ZSBtYWRlIGJlZm9yZSBjaGFuZ2luZyB0aGlzIG9wdGlvbi4gSXQncyBub3Qgb25lIHRoYXQgc2hvdWxkIGJlIGNoYW5nZWQgYWZ0ZXIgcmVuZGVyLjwvc3Bhbj5cXG4gICAgICAgIDwvZGl2PlxcbiAgICAgIDwvZGl2PlxcblxcbiAgICAgIDxkaXYgY2xhc3M9XFxcImZvcm0tZ3JvdXBcXFwiPlxcbiAgICAgICAgPGxhYmVsIGNsYXNzPVxcXCJjb250cm9sLWxhYmVsXFxcIj5NYXggSGVpZ2h0PC9sYWJlbD5cXG4gICAgICAgIDxpbnB1dCB0eXBlPVxcXCJ0ZXh0XFxcIiB2LW1vZGVsPVxcXCJtYXhIZWlnaHRcXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiPlxcbiAgICAgICAgPHNwYW4gY2xhc3M9XFxcImhlbHAtYmxvY2tcXFwiPkxpbWl0IHRoZSBoZWlnaHQgb2YgdGhlIGRyb3Bkb3duIG1lbnUuPC9zcGFuPlxcbiAgICAgIDwvZGl2PlxcblxcbiAgICAgIDxkaXYgY2xhc3M9XFxcImZvcm0tZ3JvdXBcXFwiPlxcbiAgICAgICAgPGxhYmVsIGNsYXNzPVxcXCJjb250cm9sLWxhYmVsXFxcIj5QbGFjZWhvbGRlcjwvbGFiZWw+XFxuICAgICAgICA8aW5wdXQgdHlwZT1cXFwidGV4dFxcXCIgdi1tb2RlbD1cXFwicGxhY2Vob2xkZXJcXFwiIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiPlxcbiAgICAgICAgPHNwYW4gY2xhc3M9XFxcImhlbHAtYmxvY2tcXFwiPkVxdWl2YWxlbnQgdG8gdGhlIDxjb2RlPnBsYWNlaG9sZGVyPC9jb2RlPiBhdHRyaWJ1dGUuPC9zcGFuPlxcbiAgICAgIDwvZGl2PlxcbiAgICA8L2Rpdj5cXG4gIDwvZGl2PlxcblxcbiAgPGRpdiBjbGFzcz1cXFwicm93XFxcIj5cXG4gICAgPGRpdiBjbGFzcz1cXFwiY29sLW1kLTZcXFwiPlxcbiAgICAgIDxoMiBjbGFzcz1cXFwicGFnZS1oZWFkZXJcXFwiPkluc3RhbGwgJmFtcDsgVXNhZ2U8L2gyPlxcbiAgICAgIDxoNT5JbnN0YWxsIGZyb20gR2l0SHViIHVzaW5nIE5QTTwvaDU+XFxuICAgICAgPHByZT48Y29kZSBjbGFzcz1cXFwibGFuZ3VhZ2UtYy1saWtlXFxcIj4kIG5wbSBpbnN0YWxsIHNhZ2FsYm90L3Z1ZS1zZWxlY3Q8L2NvZGU+PC9wcmU+XFxuXFxuICAgICAgPHByZSB2LXByZT1cXFwiXFxcIj4gIDxjb2RlIGNsYXNzPVxcXCJsYW5ndWFnZS1tYXJrdXBcXFwiPiZsdDt0ZW1wbGF0ZSZndDtcXG4gICAgJmx0O2RpdiBpZD1cXFwibXlBcHBcXFwiJmd0O1xcbiAgICAgICZsdDt2LXNlbGVjdCA6dmFsdWUuc3luYz1cXFwic2VsZWN0ZWRcXFwiIDpvcHRpb25zPVxcXCJvcHRpb25zXFxcIiZndDsmbHQ7L3Ytc2VsZWN0Jmd0O1xcbiAgICAmbHQ7L2RpdiZndDtcXG4gICZsdDsvdGVtcGxhdGUmZ3Q7PC9jb2RlPlxcblxcbiAgPGNvZGUgY2xhc3M9XFxcImxhbmd1YWdlLW1hcmt1cFxcXCI+Jmx0O3NjcmlwdCZndDs8L2NvZGU+XFxuICAgIDxjb2RlIGNsYXNzPVxcXCJsYW5ndWFnZS1qYXZhc2NyaXB0XFxcIj5pbXBvcnQgdlNlbGVjdCBmcm9tICd2dWUtc2VsZWN0J1xcbiAgICBleHBvcnQgZGVmYXVsdCB7XFxuICAgICAgY29tcG9uZW50czoge3ZTZWxlY3R9LFxcblxcbiAgICAgIGRhdGEoKSB7XFxuICAgICAgICByZXR1cm4ge1xcbiAgICAgICAgICBzZWxlY3RlZDogbnVsbCxcXG4gICAgICAgICAgb3B0aW9uczogWydmb28nLCdiYXInLCdiYXonXVxcbiAgICAgICAgfVxcbiAgICAgIH1cXG4gICAgfTwvY29kZT5cXG4gIDxjb2RlIGNsYXNzPVxcXCJsYW5ndWFnZS1tYXJrdXBcXFwiPiZsdDsvc2NyaXB0Jmd0OzwvY29kZT5cXG4gICAgICA8L3ByZT5cXG4gICAgPC9kaXY+XFxuICAgIDxkaXYgY2xhc3M9XFxcImNvbC1tZC02XFxcIj5cXG4gICAgICA8aDIgY2xhc3M9XFxcInBhZ2UtaGVhZGVyXFxcIj5QYXJhbWV0ZXJzPC9oMj5cXG4gICAgICA8dWw+XFxuICAgICAgICA8bGk+XFxuICAgICAgICAgIDxjb2RlPnZhbHVlPC9jb2RlPiBSZXByZXNlbnRzIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgdmFsdWUocylcXG4gICAgICAgICAgPHVsPlxcbiAgICAgICAgICAgIDxsaT50eXBlOiBTdHJpbmc8L2xpPlxcbiAgICAgICAgICAgIDxsaT5yZXF1aXJlZDogdHJ1ZSA8L2xpPlxcbiAgICAgICAgICA8L3VsPlxcbiAgICAgICAgPC9saT5cXG5cXG4gICAgICAgIDxsaT5cXG4gICAgICAgICAgPGNvZGU+b3B0aW9uczwvY29kZT4gQW4gYXJyYXkgb2Ygc3RyaW5ncyBvciBvYmplY3RzIHRvIGJlIHVzZWQgYXMgZHJvcGRvd24gY2hvaWNlcy4gU3VwcG9ydHMgPGNvZGU+Wydmb28nLCdiYXInXTwvY29kZT4gJmFtcDsgPGNvZGU+W3tsYWJlbDogJ0ZvbycsIHZhbHVlOiAnZm9vJ31dPC9jb2RlPi4gV2hlbiB1c2luZyB0aGUgPGNvZGU+W3t9XTwvY29kZT4gc3ludGF4LCB0aGUgb2JqZWN0cyBpbiB0aGUgYXJyYXkgY2FuIGhhdmUgYXMgbWFueSBwcm9wZXJ0aWVzIGFzIHlvdSBuZWVkLCBhcyBsb25nIGFzIHRoZSBvYmplY3QgY29udGFpbnMgPGNvZGU+dmFsdWU8L2NvZGU+IGFuZCA8Y29kZT5sYWJlbDwvY29kZT4ga2V5cy5cXG4gICAgICAgICAgPHVsPlxcbiAgICAgICAgICAgIDxsaT50eXBlOiBBcnJheTwvbGk+XFxuICAgICAgICAgICAgPGxpPmRlZmF1bHQ6IFtdPC9saT5cXG4gICAgICAgICAgPC91bD5cXG4gICAgICAgIDwvbGk+XFxuXFxuICAgICAgICAgIDxsaT5cXG4gICAgICAgICAgICA8Y29kZT5tYXhIZWlnaHQ8L2NvZGU+IExpbWl0IHRoZSBoZWlnaHQgb2YgdGhlIGRyb3Bkb3duIG1lbnVcXG4gICAgICAgICAgICA8dWw+XFxuICAgICAgICAgICAgICA8bGk+dHlwZTogU3RyaW5nPC9saT5cXG4gICAgICAgICAgICAgIDxsaT5kZWZhdWx0OiAnNDAwcHgnPC9saT5cXG4gICAgICAgICAgICA8L3VsPlxcbiAgICAgICAgICA8L2xpPlxcblxcbiAgICAgICAgICA8bGk+XFxuICAgICAgICAgICAgPGNvZGU+c2VhcmNoYWJsZTwvY29kZT4gVG9nZ2xlIGZpbHRlcmluZyBvZiBvcHRpb25zXFxuICAgICAgICAgICAgPHVsPlxcbiAgICAgICAgICAgICAgPGxpPnR5cGU6IEJvb2xlYW48L2xpPlxcbiAgICAgICAgICAgICAgPGxpPmRlZmF1bHQ6IHRydWU8L2xpPlxcbiAgICAgICAgICAgIDwvdWw+XFxuICAgICAgICAgIDwvbGk+XFxuXFxuICAgICAgICAgIDxsaT5cXG4gICAgICAgICAgICA8Y29kZT5tdWx0aXBsZTwvY29kZT4gRXF1aXZhbGVudCB0byA8Y29kZT5tdWx0aXBsZTwvY29kZT4gYXR0cmlidXRlIG9uIGEgPGNvZGU+Jmx0O3NlbGVjdCZndDs8L2NvZGU+XFxuICAgICAgICAgICAgICA8dWw+XFxuICAgICAgICAgICAgICAgIDxsaT50eXBlOiBCb29sZWFuPC9saT5cXG4gICAgICAgICAgICAgICAgPGxpPmRlZmF1bHQ6IHRydWU8L2xpPlxcbiAgICAgICAgICAgICAgPC91bD5cXG4gICAgICAgICAgICA8L2xpPlxcblxcbiAgICAgICAgICA8bGk+XFxuICAgICAgICAgICAgPGNvZGU+cGxhY2Vob2xkZXI8L2NvZGU+IEVxdWl2YWxlbnQgdG8gPGNvZGU+cGxhY2Vob2xkZXI8L2NvZGU+IGF0dHJpYnV0ZSBvbiBhbiA8Y29kZT4mbHQ7aW5wdXQmZ3Q7PC9jb2RlPlxcbiAgICAgICAgICAgIDx1bD5cXG4gICAgICAgICAgICAgIDxsaT50eXBlOiBTdHJpbmc8L2xpPlxcbiAgICAgICAgICAgICAgPGxpPmRlZmF1bHQ6ICcnPC9saT5cXG4gICAgICAgICAgICA8L3VsPlxcbiAgICAgICAgICA8L2xpPlxcblxcbiAgICAgICAgICA8bGk+XFxuICAgICAgICAgICAgPGNvZGU+dHJhbnNpdGlvbjwvY29kZT4gVnVlIDxjb2RlPnRyYW5zaXRpb248L2NvZGU+IHByb3AgYXBwbGllZCB0byB0aGUgPGNvZGU+LmRyb3Bkb3duLW1lbnU8L2NvZGU+XFxuICAgICAgICAgICAgPHVsPlxcbiAgICAgICAgICAgICAgPGxpPnR5cGU6IEJvb2xlYW48L2xpPlxcbiAgICAgICAgICAgICAgPGxpPmRlZmF1bHQ6IHRydWU8L2xpPlxcbiAgICAgICAgICAgIDwvdWw+XFxuICAgICAgICAgIDwvbGk+XFxuICAgICAgPC91bD5cXG5cXG4gICAgPC9kaXY+XFxuICA8L2Rpdj5cXG5cXG48L2Rpdj5cXG5cIlxuaWYgKG1vZHVsZS5ob3QpIHsoZnVuY3Rpb24gKCkgeyAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCB0cnVlKVxuICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cbiAgdmFyIGlkID0gXCIvVm9sdW1lcy9Eb2N1bWVudHMvRHJvcGJveC9odGRvY3MvdnVlLXNlbGVjdC9zcmMvQXBwLnZ1ZVwiXG4gIG1vZHVsZS5ob3QuZGlzcG9zZShmdW5jdGlvbiAoKSB7XG4gICAgcmVxdWlyZShcInZ1ZWlmeS1pbnNlcnQtY3NzXCIpLmNhY2hlW1wiXFxuXFxuLyogICNGMTY3NDUgI0ZGQzY1RCAjN0JDOEE0ICM0Q0MzRDkgIzkzNjQ4RCAjNDA0MDQwICAqL1xcblxcbiAgYm9keSB7XFxuICAgIGNvbG9yOiAjNDA0MDQwO1xcbiAgfVxcblxcbiAgLmp1bWJvdHJvbi10b3Age1xcbiAgICBjb2xvcjogI2ZmZjtcXG4gICAgYmFja2dyb3VuZDogIzRDQzNEOTtcXG4gICAgbWFyZ2luLWJvdHRvbTogMDtcXG4gIH1cXG5cXG4gIC5idG4tY3VzdG9tIHtcXG4gICAgY29sb3I6ICNmZmY7XFxuICAgIGJhY2tncm91bmQ6ICNGMTY3NDU7XFxuICB9XFxuXFxuICAuanVtYm90cm9uLmp1bWJvdHJvbi1ncmVlbiB7XFxuICAgIHBhZGRpbmc6IDc1cHggMDtcXG4gICAgLypiYWNrZ3JvdW5kOiAjNDA0MDQwOyovXFxuICAgIC8qY29sb3I6ICNmZmY7Ki9cXG4gIH1cXG5cXG4gICN2LXNlbGVjdCAuZHJvcGRvd24tdG9nZ2xlIHtcXG4gICAgLypib3JkZXItY29sb3I6I2ZmZjsqL1xcbiAgICBiYWNrZ3JvdW5kOiAjZmZmO1xcbiAgfVxcblxcbiAgI3Ytc2VsZWN0IC5kcm9wZG93bi10b2dnbGU6YWZ0ZXIge1xcbiAgICBjb2xvcjogIzQwNDA0MDtcXG4gIH1cXG5cXG4gIC8qIEN5YW4gdGhlbWUgKi9cXG4gICN2LXNlbGVjdCAuc2VsZWN0ZWQtdGFnIHtcXG4gICAgY29sb3I6ICMxNDc2ODg7XFxuICAgIGJhY2tncm91bmQtY29sb3I6ICNkN2YzZjk7XFxuICAgIGJvcmRlci1jb2xvcjogIzkxZGRlYztcXG4gIH1cXG5cXG4gICN2LXNlbGVjdC5kcm9wZG93bi5vcGVuIC5kcm9wZG93bi10b2dnbGUsXFxuICAjdi1zZWxlY3QuZHJvcGRvd24ub3BlbiAuZHJvcGRvd24tbWVudSB7XFxuICAgIGJvcmRlci1jb2xvcjogIzRDQzNEOTtcXG4gIH1cXG5cXG4gICN2LXNlbGVjdCAuYWN0aXZlIGEge1xcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDUwLDUwLDUwLC4xKTtcXG4gICAgY29sb3I6ICMzMzM7XFxuICB9XFxuXFxuICAjdi1zZWxlY3QuZHJvcGRvd24gLmhpZ2hsaWdodCBhLFxcbiAgI3Ytc2VsZWN0LmRyb3Bkb3duIGxpOmhvdmVyIGEge1xcbiAgICBiYWNrZ3JvdW5kOiAjNENDM0Q5O1xcbiAgICBjb2xvcjogI2ZmZjtcXG4gIH1cXG5cXG4gICNvdXRwdXQge1xcbiAgICBoZWlnaHQ6IDIwMHB4O1xcbiAgICBib3JkZXI6IG5vbmU7XFxuICAgIGNvbG9yOiAjNDA0MDQwO1xcbiAgfVxcblwiXSA9IGZhbHNlXG4gICAgZG9jdW1lbnQuaGVhZC5yZW1vdmVDaGlsZChfX3Z1ZWlmeV9zdHlsZV9fKVxuICB9KVxuICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoaWQsIG1vZHVsZS5leHBvcnRzKVxuICB9IGVsc2Uge1xuICAgIGhvdEFQSS51cGRhdGUoaWQsIG1vZHVsZS5leHBvcnRzLCAodHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSBcImZ1bmN0aW9uXCIgPyBtb2R1bGUuZXhwb3J0cy5vcHRpb25zIDogbW9kdWxlLmV4cG9ydHMpLnRlbXBsYXRlKVxuICB9XG59KSgpfSIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF9TZWxlY3QgPSByZXF1aXJlKCcuL1NlbGVjdC52dWUnKTtcblxudmFyIF9TZWxlY3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2VsZWN0KTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZXhwb3J0cy5kZWZhdWx0ID0ge1xuICBjb21wb25lbnRzOiB7IHZTZWxlY3Q6IF9TZWxlY3QyLmRlZmF1bHQgfSxcblxuICBkYXRhOiBmdW5jdGlvbiBkYXRhKCkge1xuICAgIHJldHVybiB7XG4gICAgICBzZWxlY3Q6IG51bGwsXG4gICAgICBwbGFjZWhvbGRlcjogJ0Nob29zZSBhIENvdW50cnknLFxuICAgICAgbXVsdGlwbGU6IHRydWUsXG4gICAgICBtYXhIZWlnaHQ6ICc0MDBweCcsXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIGFkdmFuY2VkOiByZXF1aXJlKCcuLi9jb3VudHJpZXMvY291bnRyaWVzLmpzJyksXG4gICAgICAgIHNpbXBsZTogcmVxdWlyZSgnLi4vY291bnRyaWVzL3NpbXBsZUNvdW50cmllcy5qcycpLFxuICAgICAgICBzaW1wbGVyOiBbeyBsYWJlbDogJ1RoaXMgaXMgRm9vJywgdmFsdWU6ICdmb28nIH0sIHsgbGFiZWw6ICdUaGlzIGlzIEJhcicsIHZhbHVlOiAnYmFyJyB9LCB7IGxhYmVsOiAnVGhpcyBpcyBCYXonLCB2YWx1ZTogJ2JheicgfV1cbiAgICAgIH0sXG4gICAgICBvcHRpb25UeXBlOiAnc2ltcGxlJ1xuICAgIH07XG4gIH1cbn07XG5pZiAobW9kdWxlLmV4cG9ydHMuX19lc01vZHVsZSkgbW9kdWxlLmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cy5kZWZhdWx0XG47KHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJmdW5jdGlvblwiPyBtb2R1bGUuZXhwb3J0cy5vcHRpb25zOiBtb2R1bGUuZXhwb3J0cykudGVtcGxhdGUgPSBcIlxcbjxkaXYgY2xhc3M9XFxcImp1bWJvdHJvbiBqdW1ib3Ryb24tZ3JlZW5cXFwiPlxcbiAgPGRpdiBjbGFzcz1cXFwiY29udGFpbmVyXFxcIj5cXG4gICAgPGRpdiBjbGFzcz1cXFwicm93XFxcIj5cXG4gICAgICA8ZGl2IGNsYXNzPVxcXCJjb2wtbWQtNiBjb2wtbWQtb2Zmc2V0LTFcXFwiPlxcblxcbiAgICAgICAgPHYtc2VsZWN0IGlkPVxcXCJ2LXNlbGVjdFxcXCIgOnBsYWNlaG9sZGVyPVxcXCJwbGFjZWhvbGRlclxcXCIgOnZhbHVlLnN5bmM9XFxcInNlbGVjdFxcXCIgOm9wdGlvbnM9XFxcIm9wdGlvbnNbb3B0aW9uVHlwZV1cXFwiIDptdWx0aXBsZT1cXFwibXVsdGlwbGVcXFwiPlxcbiAgICAgICAgPC92LXNlbGVjdD5cXG5cXG4gICAgICA8L2Rpdj5cXG5cXG4gICAgICA8cHJlIGlkPVxcXCJvdXRwdXRcXFwiIGNsYXNzPVxcXCJjb2wtbWQtNFxcXCI+e3sgc2VsZWN0IHwganNvbiB9fTwvcHJlPlxcbiAgICA8L2Rpdj5cXG4gIDwvZGl2PlxcbjwvZGl2PlxcblwiXG5pZiAobW9kdWxlLmhvdCkgeyhmdW5jdGlvbiAoKSB7ICBtb2R1bGUuaG90LmFjY2VwdCgpXG4gIHZhciBob3RBUEkgPSByZXF1aXJlKFwidnVlLWhvdC1yZWxvYWQtYXBpXCIpXG4gIGhvdEFQSS5pbnN0YWxsKHJlcXVpcmUoXCJ2dWVcIiksIHRydWUpXG4gIGlmICghaG90QVBJLmNvbXBhdGlibGUpIHJldHVyblxuICB2YXIgaWQgPSBcIi9Wb2x1bWVzL0RvY3VtZW50cy9Ecm9wYm94L2h0ZG9jcy92dWUtc2VsZWN0L3NyYy9jb21wb25lbnRzL0p1bWJvdHJvbi52dWVcIlxuICBpZiAoIW1vZHVsZS5ob3QuZGF0YSkge1xuICAgIGhvdEFQSS5jcmVhdGVSZWNvcmQoaWQsIG1vZHVsZS5leHBvcnRzKVxuICB9IGVsc2Uge1xuICAgIGhvdEFQSS51cGRhdGUoaWQsIG1vZHVsZS5leHBvcnRzLCAodHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSBcImZ1bmN0aW9uXCIgPyBtb2R1bGUuZXhwb3J0cy5vcHRpb25zIDogbW9kdWxlLmV4cG9ydHMpLnRlbXBsYXRlKVxuICB9XG59KSgpfSIsInZhciBfX3Z1ZWlmeV9zdHlsZV9fID0gcmVxdWlyZShcInZ1ZWlmeS1pbnNlcnQtY3NzXCIpLmluc2VydChcIlxcbi5kcm9wZG93bltfdi0zZDQ1MGFiNl0ge1xcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcbn1cXG5cXG4ub3BlbiAuZHJvcGRvd24tdG9nZ2xlW192LTNkNDUwYWI2XSxcXG4ub3BlbiAuZHJvcGRvd24tbWVudVtfdi0zZDQ1MGFiNl0ge1xcbiAgYm9yZGVyLWNvbG9yOiByZ2JhKDYwLDYwLDYwLC4yNik7XFxufVxcblxcbi5vcGVuLWluZGljYXRvcltfdi0zZDQ1MGFiNl0ge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgdG9wOiAxMHB4O1xcbiAgcmlnaHQ6IDEwcHg7XFxuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XFxuICBjdXJzb3I6IHBvaW50ZXI7XFxuICBwb2ludGVyLWV2ZW50czogYWxsO1xcbiAgLXdlYmtpdC10cmFuc2l0aW9uOiBhbGwgMTUwbXMgY3ViaWMtYmV6aWVyKDEuMDAwLCAtMC4xMTUsIDAuOTc1LCAwLjg1NSk7XFxuICB0cmFuc2l0aW9uOiBhbGwgMTUwbXMgY3ViaWMtYmV6aWVyKDEuMDAwLCAtMC4xMTUsIDAuOTc1LCAwLjg1NSk7XFxuICAtd2Via2l0LXRyYW5zaXRpb24tdGltaW5nLWZ1bmN0aW9uOiBjdWJpYy1iZXppZXIoMS4wMDAsIC0wLjExNSwgMC45NzUsIDAuODU1KTtcXG4gICAgICAgICAgdHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb246IGN1YmljLWJlemllcigxLjAwMCwgLTAuMTE1LCAwLjk3NSwgMC44NTUpO1xcbn1cXG5cXG4ub3BlbiAub3Blbi1pbmRpY2F0b3JbX3YtM2Q0NTBhYjZdIHtcXG4gIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoMTgwZGVnKTtcXG4gICAgICAgICAgdHJhbnNmb3JtOiByb3RhdGUoMTgwZGVnKTtcXG59XFxuXFxuLmRyb3Bkb3duLXRvZ2dsZVtfdi0zZDQ1MGFiNl0ge1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICBwYWRkaW5nOiAwO1xcbiAgYmFja2dyb3VuZDogbm9uZTtcXG4gIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoNjAsNjAsNjAsLjI2KTtcXG4gIGJvcmRlci1yYWRpdXM6IDRweDtcXG4gIHdoaXRlLXNwYWNlOiBub3JtYWw7XFxufVxcbi5zZWFyY2hhYmxlIC5kcm9wZG93bi10b2dnbGVbX3YtM2Q0NTBhYjZdIHtcXG4gIGN1cnNvcjogdGV4dDtcXG59XFxuXFxuLm9wZW4gLmRyb3Bkb3duLXRvZ2dsZVtfdi0zZDQ1MGFiNl0ge1xcbiAgYm9yZGVyLWJvdHRvbTogbm9uZTtcXG4gIGJvcmRlci1ib3R0b20tbGVmdC1yYWRpdXM6IDA7XFxuICBib3JkZXItYm90dG9tLXJpZ2h0LXJhZGl1czogMDtcXG59XFxuXFxuLmRyb3Bkb3duLW1lbnVbX3YtM2Q0NTBhYjZdIHtcXG4gIG1hcmdpbjogMDtcXG4gIHdpZHRoOiAxMDAlO1xcbiAgb3ZlcmZsb3cteTogc2Nyb2xsO1xcbiAgYm9yZGVyLXRvcDogbm9uZTtcXG4gIGJvcmRlci10b3AtbGVmdC1yYWRpdXM6IDA7XFxuICBib3JkZXItdG9wLXJpZ2h0LXJhZGl1czogMDtcXG59XFxuXFxuLnNlbGVjdGVkLXRhZ1tfdi0zZDQ1MGFiNl0ge1xcbiAgY29sb3I6ICMzMzM7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjBmMGYwO1xcbiAgYm9yZGVyOiAxcHggc29saWQgI2NjYztcXG4gIGJvcmRlci1yYWRpdXM6IDRweDtcXG4gIGhlaWdodDogMjZweDtcXG4gIG1hcmdpbjogNHB4IDFweCAwcHggM3B4O1xcbiAgcGFkZGluZzogMCAwLjI1ZW07XFxuICBmbG9hdDogbGVmdDtcXG4gIGxpbmUtaGVpZ2h0OiAxLjdlbTtcXG59XFxuXFxuLnNlbGVjdGVkLXRhZyAuY2xvc2VbX3YtM2Q0NTBhYjZdIHtcXG4gIGZsb2F0OiBub25lO1xcbiAgbWFyZ2luLXJpZ2h0OiAwO1xcbiAgZm9udC1zaXplOiAyMHB4O1xcbn1cXG5cXG5pbnB1dFt0eXBlPXNlYXJjaF1bX3YtM2Q0NTBhYjZdLFxcbmlucHV0W3R5cGU9c2VhcmNoXVtfdi0zZDQ1MGFiNl06Zm9jdXMge1xcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xcbiAgYm9yZGVyOiBub25lO1xcbiAgb3V0bGluZTogbm9uZTtcXG4gIG1hcmdpbjogMDtcXG4gIHdpZHRoOiAxMGVtO1xcbiAgbWF4LXdpZHRoOiAxMDAlO1xcbiAgYmFja2dyb3VuZDogbm9uZTtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gIGJveC1zaGFkb3c6IG5vbmU7XFxuICBmbG9hdDogbGVmdDtcXG4gIGNsZWFyOiBub25lO1xcbn1cXG5cXG5pbnB1dFt0eXBlPXNlYXJjaF1bX3YtM2Q0NTBhYjZdOmRpc2FibGVkIHtcXG4gIGN1cnNvcjogcG9pbnRlcjtcXG59XFxuXFxubGkgYVtfdi0zZDQ1MGFiNl0ge1xcbiAgY3Vyc29yOiBwb2ludGVyO1xcbn1cXG5cXG4uYWN0aXZlIGFbX3YtM2Q0NTBhYjZdIHtcXG4gIGJhY2tncm91bmQ6IHJnYmEoNTAsNTAsNTAsLjEpO1xcbiAgY29sb3I6ICMzMzM7XFxufVxcblxcbi5oaWdobGlnaHQgYVtfdi0zZDQ1MGFiNl0sXFxubGk6aG92ZXIgYVtfdi0zZDQ1MGFiNl0ge1xcbiAgYmFja2dyb3VuZDogI2YwZjBmMDtcXG4gIGNvbG9yOiAjMzMzO1xcbn1cXG5cIilcbid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF90eXBlb2YyID0gcmVxdWlyZSgnYmFiZWwtcnVudGltZS9oZWxwZXJzL3R5cGVvZicpO1xuXG52YXIgX3R5cGVvZjMgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF90eXBlb2YyKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZXhwb3J0cy5kZWZhdWx0ID0ge1xuICBwcm9wczoge1xuICAgIHZhbHVlOiB7XG4gICAgICB0d293YXk6IHRydWUsXG4gICAgICByZXF1aXJlZDogdHJ1ZVxuICAgIH0sXG4gICAgb3B0aW9uczoge1xuICAgICAgdHlwZTogQXJyYXksXG4gICAgICBkZWZhdWx0OiBmdW5jdGlvbiBfZGVmYXVsdCgpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH0sXG4gICAgbWF4SGVpZ2h0OiB7XG4gICAgICB0eXBlOiBTdHJpbmcsXG4gICAgICBkZWZhdWx0OiAnNDAwcHgnXG4gICAgfSxcbiAgICBzZWFyY2hhYmxlOiB7XG4gICAgICB0eXBlOiBCb29sZWFuLFxuICAgICAgZGVmYXVsdDogdHJ1ZVxuICAgIH0sXG4gICAgbXVsdGlwbGU6IHtcbiAgICAgIHR5cGU6IEJvb2xlYW4sXG4gICAgICBkZWZhdWx0OiBmYWxzZVxuICAgIH0sXG4gICAgcGxhY2Vob2xkZXI6IHtcbiAgICAgIHR5cGU6IFN0cmluZyxcbiAgICAgIGRlZmF1bHQ6ICcnXG4gICAgfSxcbiAgICB0cmFuc2l0aW9uOiB7XG4gICAgICB0eXBlOiBTdHJpbmcsXG4gICAgICBkZWZhdWx0OiAnZXhwYW5kJ1xuICAgIH0sXG4gICAgY2xlYXJTZWFyY2hPblNlbGVjdDoge1xuICAgICAgdHlwZTogQm9vbGVhbixcbiAgICAgIGRlZmF1bHQ6IHRydWVcbiAgICB9XG4gIH0sXG5cbiAgZGF0YTogZnVuY3Rpb24gZGF0YSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2VhcmNoOiAnJyxcbiAgICAgIG9wZW46IGZhbHNlLFxuICAgICAgdHlwZUFoZWFkUG9pbnRlcjogLTFcbiAgICB9O1xuICB9LFxuXG5cbiAgd2F0Y2g6IHtcbiAgICBvcHRpb25zOiBmdW5jdGlvbiBvcHRpb25zKCkge1xuICAgICAgdGhpcy4kc2V0KCd2YWx1ZScsIHRoaXMubXVsdGlwbGUgPyBbXSA6IG51bGwpO1xuICAgIH0sXG4gICAgbXVsdGlwbGU6IGZ1bmN0aW9uIG11bHRpcGxlKHZhbCkge1xuICAgICAgdGhpcy4kc2V0KCd2YWx1ZScsIHZhbCA/IFtdIDogbnVsbCk7XG4gICAgfSxcbiAgICBmaWx0ZXJlZE9wdGlvbnM6IGZ1bmN0aW9uIGZpbHRlcmVkT3B0aW9ucygpIHtcbiAgICAgIHRoaXMudHlwZUFoZWFkUG9pbnRlciA9IDA7XG4gICAgfVxuICB9LFxuXG4gIG1ldGhvZHM6IHtcbiAgICBzZWxlY3Q6IGZ1bmN0aW9uIHNlbGVjdChvcHRpb24pIHtcbiAgICAgIGlmICghdGhpcy5pc09wdGlvblNlbGVjdGVkKG9wdGlvbikpIHtcbiAgICAgICAgaWYgKHRoaXMubXVsdGlwbGUpIHtcblxuICAgICAgICAgIGlmICghdGhpcy52YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy4kc2V0KCd2YWx1ZScsIFtvcHRpb25dKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52YWx1ZS5wdXNoKG9wdGlvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMudmFsdWUgPSBvcHRpb247XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLm11bHRpcGxlKSB7XG4gICAgICAgICAgdGhpcy52YWx1ZS4kcmVtb3ZlKG9wdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLm11bHRpcGxlKSB7XG4gICAgICAgIHRoaXMub3BlbiA9ICF0aGlzLm9wZW47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmNsZWFyU2VhcmNoT25TZWxlY3QpIHtcbiAgICAgICAgdGhpcy5zZWFyY2ggPSAnJztcbiAgICAgIH1cbiAgICB9LFxuICAgIHRvZ2dsZURyb3Bkb3duOiBmdW5jdGlvbiB0b2dnbGVEcm9wZG93bihlKSB7XG4gICAgICBpZiAoZS50YXJnZXQgPT09IHRoaXMuJGVscy5vcGVuSW5kaWNhdG9yIHx8IGUudGFyZ2V0ID09PSB0aGlzLiRlbHMuc2VhcmNoIHx8IGUudGFyZ2V0ID09PSB0aGlzLiRlbHMudG9nZ2xlIHx8IGUudGFyZ2V0ID09PSB0aGlzLiRlbCkge1xuICAgICAgICBpZiAodGhpcy5vcGVuKSB7XG4gICAgICAgICAgdGhpcy4kZWxzLnNlYXJjaC5ibHVyKCk7IC8vIGRyb3Bkb3duIHdpbGwgY2xvc2Ugb24gYmx1clxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5vcGVuID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuJGVscy5zZWFyY2guZm9jdXMoKTtcbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICBpc09wdGlvblNlbGVjdGVkOiBmdW5jdGlvbiBpc09wdGlvblNlbGVjdGVkKG9wdGlvbikge1xuICAgICAgaWYgKHRoaXMubXVsdGlwbGUgJiYgdGhpcy52YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZS5pbmRleE9mKG9wdGlvbikgIT09IC0xO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy52YWx1ZSA9PT0gb3B0aW9uO1xuICAgIH0sXG4gICAgZ2V0T3B0aW9uVmFsdWU6IGZ1bmN0aW9uIGdldE9wdGlvblZhbHVlKG9wdGlvbikge1xuICAgICAgaWYgKCh0eXBlb2Ygb3B0aW9uID09PSAndW5kZWZpbmVkJyA/ICd1bmRlZmluZWQnIDogKDAsIF90eXBlb2YzLmRlZmF1bHQpKG9wdGlvbikpID09PSAnb2JqZWN0JyAmJiBvcHRpb24udmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIG9wdGlvbi52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG9wdGlvbjtcbiAgICB9LFxuICAgIGdldE9wdGlvbkxhYmVsOiBmdW5jdGlvbiBnZXRPcHRpb25MYWJlbChvcHRpb24pIHtcbiAgICAgIGlmICgodHlwZW9mIG9wdGlvbiA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6ICgwLCBfdHlwZW9mMy5kZWZhdWx0KShvcHRpb24pKSA9PT0gJ29iamVjdCcgJiYgb3B0aW9uLmxhYmVsKSB7XG4gICAgICAgIHJldHVybiBvcHRpb24ubGFiZWw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBvcHRpb247XG4gICAgfSxcbiAgICB0eXBlQWhlYWRVcDogZnVuY3Rpb24gdHlwZUFoZWFkVXAoKSB7XG4gICAgICBpZiAodGhpcy50eXBlQWhlYWRQb2ludGVyID4gMCkgdGhpcy50eXBlQWhlYWRQb2ludGVyLS07XG4gICAgfSxcbiAgICB0eXBlQWhlYWREb3duOiBmdW5jdGlvbiB0eXBlQWhlYWREb3duKCkge1xuICAgICAgaWYgKHRoaXMudHlwZUFoZWFkUG9pbnRlciA8IHRoaXMuZmlsdGVyZWRPcHRpb25zLmxlbmd0aCAtIDEpIHRoaXMudHlwZUFoZWFkUG9pbnRlcisrO1xuICAgIH0sXG4gICAgdHlwZUFoZWFkU2VsZWN0OiBmdW5jdGlvbiB0eXBlQWhlYWRTZWxlY3QoKSB7XG4gICAgICBpZiAodGhpcy5maWx0ZXJlZE9wdGlvbnNbdGhpcy50eXBlQWhlYWRQb2ludGVyXSkge1xuICAgICAgICB0aGlzLnNlbGVjdCh0aGlzLmZpbHRlcmVkT3B0aW9uc1t0aGlzLnR5cGVBaGVhZFBvaW50ZXJdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuY2xlYXJTZWFyY2hPblNlbGVjdCkge1xuICAgICAgICB0aGlzLnNlYXJjaCA9IFwiXCI7XG4gICAgICB9XG4gICAgfSxcbiAgICBvbkVzY2FwZTogZnVuY3Rpb24gb25Fc2NhcGUoKSB7XG4gICAgICBpZiAoIXRoaXMuc2VhcmNoLmxlbmd0aCkge1xuICAgICAgICB0aGlzLiRlbHMuc2VhcmNoLmJsdXIoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuJHNldCgnc2VhcmNoJywgJycpO1xuICAgICAgfVxuICAgIH0sXG4gICAgbWF5YmVEZWxldGVWYWx1ZTogZnVuY3Rpb24gbWF5YmVEZWxldGVWYWx1ZSgpIHtcbiAgICAgIGlmICghdGhpcy4kZWxzLnNlYXJjaC52YWx1ZS5sZW5ndGggJiYgdGhpcy52YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tdWx0aXBsZSA/IHRoaXMudmFsdWUucG9wKCkgOiB0aGlzLiRzZXQoJ3ZhbHVlJywgbnVsbCk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIGNvbXB1dGVkOiB7XG4gICAgY3NzQ2xhc3NlczogZnVuY3Rpb24gY3NzQ2xhc3NlcygpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9wZW46IHRoaXMub3BlbixcbiAgICAgICAgc2VhcmNoYWJsZTogdGhpcy5zZWFyY2hhYmxlXG4gICAgICB9O1xuICAgIH0sXG4gICAgc2VhcmNoUGxhY2Vob2xkZXI6IGZ1bmN0aW9uIHNlYXJjaFBsYWNlaG9sZGVyKCkge1xuICAgICAgaWYgKHRoaXMuaXNWYWx1ZUVtcHR5ICYmIHRoaXMucGxhY2Vob2xkZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGxhY2Vob2xkZXI7XG4gICAgICB9XG4gICAgfSxcbiAgICBmaWx0ZXJlZE9wdGlvbnM6IGZ1bmN0aW9uIGZpbHRlcmVkT3B0aW9ucygpIHtcbiAgICAgIHJldHVybiB0aGlzLiRvcHRpb25zLmZpbHRlcnMuZmlsdGVyQnkodGhpcy5vcHRpb25zLCB0aGlzLnNlYXJjaCk7XG4gICAgfSxcbiAgICBpc1ZhbHVlRW1wdHk6IGZ1bmN0aW9uIGlzVmFsdWVFbXB0eSgpIHtcbiAgICAgIGlmICh0aGlzLnZhbHVlKSB7XG4gICAgICAgIHJldHVybiAhdGhpcy52YWx1ZS5sZW5ndGg7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG4gICAgdmFsdWVBc0FycmF5OiBmdW5jdGlvbiB2YWx1ZUFzQXJyYXkoKSB7XG4gICAgICBpZiAodGhpcy5tdWx0aXBsZSkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy52YWx1ZSkge1xuICAgICAgICByZXR1cm4gW3RoaXMudmFsdWVdO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICB9XG5cbn07XG5pZiAobW9kdWxlLmV4cG9ydHMuX19lc01vZHVsZSkgbW9kdWxlLmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cy5kZWZhdWx0XG47KHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJmdW5jdGlvblwiPyBtb2R1bGUuZXhwb3J0cy5vcHRpb25zOiBtb2R1bGUuZXhwb3J0cykudGVtcGxhdGUgPSBcIlxcbjxkaXYgY2xhc3M9XFxcImRyb3Bkb3duXFxcIiA6Y2xhc3M9XFxcImNzc0NsYXNzZXNcXFwiIF92LTNkNDUwYWI2PVxcXCJcXFwiPlxcbiAgPGRpdiB2LWVsOnRvZ2dsZT1cXFwiXFxcIiBAbW91c2Vkb3duLnByZXZlbnQ9XFxcInRvZ2dsZURyb3Bkb3duXFxcIiBjbGFzcz1cXFwiZHJvcGRvd24tdG9nZ2xlIGNsZWFyZml4XFxcIiB0eXBlPVxcXCJidXR0b25cXFwiIF92LTNkNDUwYWI2PVxcXCJcXFwiPlxcbiAgICAgIDxzcGFuIGNsYXNzPVxcXCJmb3JtLWNvbnRyb2xcXFwiIHYtaWY9XFxcIiFzZWFyY2hhYmxlICZhbXA7JmFtcDsgaXNWYWx1ZUVtcHR5XFxcIiBfdi0zZDQ1MGFiNj1cXFwiXFxcIj5cXG4gICAgICAgIHt7IHBsYWNlaG9sZGVyIH19XFxuICAgICAgPC9zcGFuPlxcblxcbiAgICAgIDxzcGFuIGNsYXNzPVxcXCJzZWxlY3RlZC10YWdcXFwiIHYtZm9yPVxcXCJvcHRpb24gaW4gdmFsdWVBc0FycmF5XFxcIiBfdi0zZDQ1MGFiNj1cXFwiXFxcIj5cXG4gICAgICAgIHt7IGdldE9wdGlvbkxhYmVsKG9wdGlvbikgfX1cXG4gICAgICAgIDxidXR0b24gdi1pZj1cXFwibXVsdGlwbGVcXFwiIEBjbGljaz1cXFwic2VsZWN0KG9wdGlvbilcXFwiIHR5cGU9XFxcImJ1dHRvblxcXCIgY2xhc3M9XFxcImNsb3NlXFxcIiBfdi0zZDQ1MGFiNj1cXFwiXFxcIj5cXG4gICAgICAgICAgPHNwYW4gYXJpYS1oaWRkZW49XFxcInRydWVcXFwiIF92LTNkNDUwYWI2PVxcXCJcXFwiPsOXPC9zcGFuPlxcbiAgICAgICAgPC9idXR0b24+XFxuICAgICAgPC9zcGFuPlxcblxcbiAgICAgIDxpbnB1dCB2LWVsOnNlYXJjaD1cXFwiXFxcIiB2LXNob3c9XFxcInNlYXJjaGFibGVcXFwiIHYtbW9kZWw9XFxcInNlYXJjaFxcXCIgQGtleWRvd24uZGVsZXRlPVxcXCJtYXliZURlbGV0ZVZhbHVlXFxcIiBAa2V5ZG93bi5lc2M9XFxcIm9uRXNjYXBlXFxcIiBAa2V5ZG93bi51cC5wcmV2ZW50PVxcXCJ0eXBlQWhlYWRVcFxcXCIgQGtleWRvd24uZG93bi5wcmV2ZW50PVxcXCJ0eXBlQWhlYWREb3duXFxcIiBAa2V5ZG93bi5lbnRlci5wcmV2ZW50PVxcXCJ0eXBlQWhlYWRTZWxlY3RcXFwiIEBibHVyPVxcXCJvcGVuID0gZmFsc2VcXFwiIEBmb2N1cz1cXFwib3BlbiA9IHRydWVcXFwiIHR5cGU9XFxcInNlYXJjaFxcXCIgY2xhc3M9XFxcImZvcm0tY29udHJvbFxcXCIgOnBsYWNlaG9sZGVyPVxcXCJzZWFyY2hQbGFjZWhvbGRlclxcXCIgX3YtM2Q0NTBhYjY9XFxcIlxcXCI+XFxuXFxuICAgICAgPGkgdi1lbDpvcGVuLWluZGljYXRvcj1cXFwiXFxcIiByb2xlPVxcXCJwcmVzZW50YXRpb25cXFwiIGNsYXNzPVxcXCJvcGVuLWluZGljYXRvciBnbHlwaGljb24tY2hldnJvbi1kb3duIGdseXBoaWNvblxcXCIgX3YtM2Q0NTBhYjY9XFxcIlxcXCI+PC9pPlxcbiAgPC9kaXY+XFxuXFxuICA8dWwgdi1zaG93PVxcXCJvcGVuXFxcIiB2LWVsOmRyb3Bkb3duLW1lbnU9XFxcIlxcXCIgOnRyYW5zaXRpb249XFxcInRyYW5zaXRpb25cXFwiIDpzdHlsZT1cXFwieyAnbWF4LWhlaWdodCc6IG1heEhlaWdodCB9XFxcIiBjbGFzcz1cXFwiZHJvcGRvd24tbWVudSBhbmltYXRlZFxcXCIgX3YtM2Q0NTBhYjY9XFxcIlxcXCI+XFxuICAgIDxsaSB2LWZvcj1cXFwib3B0aW9uIGluIGZpbHRlcmVkT3B0aW9uc1xcXCIgOmNsYXNzPVxcXCJ7IGFjdGl2ZTogaXNPcHRpb25TZWxlY3RlZChvcHRpb24pLCBoaWdobGlnaHQ6ICRpbmRleCA9PT0gdHlwZUFoZWFkUG9pbnRlciB9XFxcIiBAbW91c2VvdmVyPVxcXCJ0eXBlQWhlYWRQb2ludGVyID0gJGluZGV4XFxcIiBfdi0zZDQ1MGFiNj1cXFwiXFxcIj5cXG4gICAgICA8YSBAbW91c2Vkb3duLnByZXZlbnQ9XFxcInNlbGVjdChvcHRpb24pXFxcIiBfdi0zZDQ1MGFiNj1cXFwiXFxcIj5cXG4gICAgICAgIHt7IGdldE9wdGlvbkxhYmVsKG9wdGlvbikgfX1cXG4gICAgICA8L2E+XFxuICAgIDwvbGk+XFxuICAgIDxsaSB0cmFuc2l0aW9uPVxcXCJmYWRlXFxcIiB2LWlmPVxcXCIhZmlsdGVyZWRPcHRpb25zLmxlbmd0aFxcXCIgY2xhc3M9XFxcImRpdmlkZXJcXFwiIF92LTNkNDUwYWI2PVxcXCJcXFwiPjwvbGk+XFxuICAgIDxsaSB0cmFuc2l0aW9uPVxcXCJmYWRlXFxcIiB2LWlmPVxcXCIhZmlsdGVyZWRPcHRpb25zLmxlbmd0aFxcXCIgY2xhc3M9XFxcInRleHQtY2VudGVyXFxcIiBfdi0zZDQ1MGFiNj1cXFwiXFxcIj5Tb3JyeSwgbm8gbWF0Y2hpbmcgb3B0aW9ucy48L2xpPlxcbiAgPC91bD5cXG48L2Rpdj5cXG5cIlxuaWYgKG1vZHVsZS5ob3QpIHsoZnVuY3Rpb24gKCkgeyAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICB2YXIgaG90QVBJID0gcmVxdWlyZShcInZ1ZS1ob3QtcmVsb2FkLWFwaVwiKVxuICBob3RBUEkuaW5zdGFsbChyZXF1aXJlKFwidnVlXCIpLCB0cnVlKVxuICBpZiAoIWhvdEFQSS5jb21wYXRpYmxlKSByZXR1cm5cbiAgdmFyIGlkID0gXCIvVm9sdW1lcy9Eb2N1bWVudHMvRHJvcGJveC9odGRvY3MvdnVlLXNlbGVjdC9zcmMvY29tcG9uZW50cy9TZWxlY3QudnVlXCJcbiAgbW9kdWxlLmhvdC5kaXNwb3NlKGZ1bmN0aW9uICgpIHtcbiAgICByZXF1aXJlKFwidnVlaWZ5LWluc2VydC1jc3NcIikuY2FjaGVbXCJcXG4uZHJvcGRvd25bX3YtM2Q0NTBhYjZdIHtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG59XFxuXFxuLm9wZW4gLmRyb3Bkb3duLXRvZ2dsZVtfdi0zZDQ1MGFiNl0sXFxuLm9wZW4gLmRyb3Bkb3duLW1lbnVbX3YtM2Q0NTBhYjZdIHtcXG4gIGJvcmRlci1jb2xvcjogcmdiYSg2MCw2MCw2MCwuMjYpO1xcbn1cXG5cXG4ub3Blbi1pbmRpY2F0b3JbX3YtM2Q0NTBhYjZdIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHRvcDogMTBweDtcXG4gIHJpZ2h0OiAxMHB4O1xcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xcbiAgY3Vyc29yOiBwb2ludGVyO1xcbiAgcG9pbnRlci1ldmVudHM6IGFsbDtcXG4gIC13ZWJraXQtdHJhbnNpdGlvbjogYWxsIDE1MG1zIGN1YmljLWJlemllcigxLjAwMCwgLTAuMTE1LCAwLjk3NSwgMC44NTUpO1xcbiAgdHJhbnNpdGlvbjogYWxsIDE1MG1zIGN1YmljLWJlemllcigxLjAwMCwgLTAuMTE1LCAwLjk3NSwgMC44NTUpO1xcbiAgLXdlYmtpdC10cmFuc2l0aW9uLXRpbWluZy1mdW5jdGlvbjogY3ViaWMtYmV6aWVyKDEuMDAwLCAtMC4xMTUsIDAuOTc1LCAwLjg1NSk7XFxuICAgICAgICAgIHRyYW5zaXRpb24tdGltaW5nLWZ1bmN0aW9uOiBjdWJpYy1iZXppZXIoMS4wMDAsIC0wLjExNSwgMC45NzUsIDAuODU1KTtcXG59XFxuXFxuLm9wZW4gLm9wZW4taW5kaWNhdG9yW192LTNkNDUwYWI2XSB7XFxuICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDE4MGRlZyk7XFxuICAgICAgICAgIHRyYW5zZm9ybTogcm90YXRlKDE4MGRlZyk7XFxufVxcblxcbi5kcm9wZG93bi10b2dnbGVbX3YtM2Q0NTBhYjZdIHtcXG4gIGRpc3BsYXk6IGJsb2NrO1xcbiAgcGFkZGluZzogMDtcXG4gIGJhY2tncm91bmQ6IG5vbmU7XFxuICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDYwLDYwLDYwLC4yNik7XFxuICBib3JkZXItcmFkaXVzOiA0cHg7XFxuICB3aGl0ZS1zcGFjZTogbm9ybWFsO1xcbn1cXG4uc2VhcmNoYWJsZSAuZHJvcGRvd24tdG9nZ2xlW192LTNkNDUwYWI2XSB7XFxuICBjdXJzb3I6IHRleHQ7XFxufVxcblxcbi5vcGVuIC5kcm9wZG93bi10b2dnbGVbX3YtM2Q0NTBhYjZdIHtcXG4gIGJvcmRlci1ib3R0b206IG5vbmU7XFxuICBib3JkZXItYm90dG9tLWxlZnQtcmFkaXVzOiAwO1xcbiAgYm9yZGVyLWJvdHRvbS1yaWdodC1yYWRpdXM6IDA7XFxufVxcblxcbi5kcm9wZG93bi1tZW51W192LTNkNDUwYWI2XSB7XFxuICBtYXJnaW46IDA7XFxuICB3aWR0aDogMTAwJTtcXG4gIG92ZXJmbG93LXk6IHNjcm9sbDtcXG4gIGJvcmRlci10b3A6IG5vbmU7XFxuICBib3JkZXItdG9wLWxlZnQtcmFkaXVzOiAwO1xcbiAgYm9yZGVyLXRvcC1yaWdodC1yYWRpdXM6IDA7XFxufVxcblxcbi5zZWxlY3RlZC10YWdbX3YtM2Q0NTBhYjZdIHtcXG4gIGNvbG9yOiAjMzMzO1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2YwZjBmMDtcXG4gIGJvcmRlcjogMXB4IHNvbGlkICNjY2M7XFxuICBib3JkZXItcmFkaXVzOiA0cHg7XFxuICBoZWlnaHQ6IDI2cHg7XFxuICBtYXJnaW46IDRweCAxcHggMHB4IDNweDtcXG4gIHBhZGRpbmc6IDAgMC4yNWVtO1xcbiAgZmxvYXQ6IGxlZnQ7XFxuICBsaW5lLWhlaWdodDogMS43ZW07XFxufVxcblxcbi5zZWxlY3RlZC10YWcgLmNsb3NlW192LTNkNDUwYWI2XSB7XFxuICBmbG9hdDogbm9uZTtcXG4gIG1hcmdpbi1yaWdodDogMDtcXG4gIGZvbnQtc2l6ZTogMjBweDtcXG59XFxuXFxuaW5wdXRbdHlwZT1zZWFyY2hdW192LTNkNDUwYWI2XSxcXG5pbnB1dFt0eXBlPXNlYXJjaF1bX3YtM2Q0NTBhYjZdOmZvY3VzIHtcXG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcXG4gIGJvcmRlcjogbm9uZTtcXG4gIG91dGxpbmU6IG5vbmU7XFxuICBtYXJnaW46IDA7XFxuICB3aWR0aDogMTBlbTtcXG4gIG1heC13aWR0aDogMTAwJTtcXG4gIGJhY2tncm91bmQ6IG5vbmU7XFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICBib3gtc2hhZG93OiBub25lO1xcbiAgZmxvYXQ6IGxlZnQ7XFxuICBjbGVhcjogbm9uZTtcXG59XFxuXFxuaW5wdXRbdHlwZT1zZWFyY2hdW192LTNkNDUwYWI2XTpkaXNhYmxlZCB7XFxuICBjdXJzb3I6IHBvaW50ZXI7XFxufVxcblxcbmxpIGFbX3YtM2Q0NTBhYjZdIHtcXG4gIGN1cnNvcjogcG9pbnRlcjtcXG59XFxuXFxuLmFjdGl2ZSBhW192LTNkNDUwYWI2XSB7XFxuICBiYWNrZ3JvdW5kOiByZ2JhKDUwLDUwLDUwLC4xKTtcXG4gIGNvbG9yOiAjMzMzO1xcbn1cXG5cXG4uaGlnaGxpZ2h0IGFbX3YtM2Q0NTBhYjZdLFxcbmxpOmhvdmVyIGFbX3YtM2Q0NTBhYjZdIHtcXG4gIGJhY2tncm91bmQ6ICNmMGYwZjA7XFxuICBjb2xvcjogIzMzMztcXG59XFxuXCJdID0gZmFsc2VcbiAgICBkb2N1bWVudC5oZWFkLnJlbW92ZUNoaWxkKF9fdnVlaWZ5X3N0eWxlX18pXG4gIH0pXG4gIGlmICghbW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgaG90QVBJLmNyZWF0ZVJlY29yZChpZCwgbW9kdWxlLmV4cG9ydHMpXG4gIH0gZWxzZSB7XG4gICAgaG90QVBJLnVwZGF0ZShpZCwgbW9kdWxlLmV4cG9ydHMsICh0eXBlb2YgbW9kdWxlLmV4cG9ydHMgPT09IFwiZnVuY3Rpb25cIiA/IG1vZHVsZS5leHBvcnRzLm9wdGlvbnMgOiBtb2R1bGUuZXhwb3J0cykudGVtcGxhdGUpXG4gIH1cbn0pKCl9IiwibW9kdWxlLmV4cG9ydHMgPSBbXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJBRlwiLCBsYWJlbDogXCJBZmdoYW5pc3RhblwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkFYXCIsIGxhYmVsOiBcIsOFbGFuZCBJc2xhbmRzXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQUxcIiwgbGFiZWw6IFwiQWxiYW5pYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkRaXCIsIGxhYmVsOiBcIkFsZ2VyaWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJBU1wiLCBsYWJlbDogXCJBbWVyaWNhbiBTYW1vYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkFEXCIsIGxhYmVsOiBcIkFuZG9ycmFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJBT1wiLCBsYWJlbDogXCJBbmdvbGFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJBSVwiLCBsYWJlbDogXCJBbmd1aWxsYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkFRXCIsIGxhYmVsOiBcIkFudGFyY3RpY2FcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJBR1wiLCBsYWJlbDogXCJBbnRpZ3VhIGFuZCBCYXJidWRhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQVJcIiwgbGFiZWw6IFwiQXJnZW50aW5hXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQU1cIiwgbGFiZWw6IFwiQXJtZW5pYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkFXXCIsIGxhYmVsOiBcIkFydWJhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQVVcIiwgbGFiZWw6IFwiQXVzdHJhbGlhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQVRcIiwgbGFiZWw6IFwiQXVzdHJpYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkFaXCIsIGxhYmVsOiBcIkF6ZXJiYWlqYW5cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJCU1wiLCBsYWJlbDogXCJCYWhhbWFzXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQkhcIiwgbGFiZWw6IFwiQmFocmFpblwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkJEXCIsIGxhYmVsOiBcIkJhbmdsYWRlc2hcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJCQlwiLCBsYWJlbDogXCJCYXJiYWRvc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkJZXCIsIGxhYmVsOiBcIkJlbGFydXNcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJCRVwiLCBsYWJlbDogXCJCZWxnaXVtXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQlpcIiwgbGFiZWw6IFwiQmVsaXplXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQkpcIiwgbGFiZWw6IFwiQmVuaW5cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJCTVwiLCBsYWJlbDogXCJCZXJtdWRhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQlRcIiwgbGFiZWw6IFwiQmh1dGFuXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQk9cIiwgbGFiZWw6IFwiQm9saXZpYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkJBXCIsIGxhYmVsOiBcIkJvc25pYSBhbmQgSGVyemVnb3ZpbmFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJCV1wiLCBsYWJlbDogXCJCb3Rzd2FuYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkJWXCIsIGxhYmVsOiBcIkJvdXZldCBJc2xhbmRcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJCUlwiLCBsYWJlbDogXCJCcmF6aWxcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJJT1wiLCBsYWJlbDogXCJCcml0aXNoIEluZGlhbiBPY2VhbiBUZXJyaXRvcnlcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJCTlwiLCBsYWJlbDogXCJCcnVuZWkgRGFydXNzYWxhbVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkJHXCIsIGxhYmVsOiBcIkJ1bGdhcmlhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQkZcIiwgbGFiZWw6IFwiQnVya2luYSBGYXNvXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQklcIiwgbGFiZWw6IFwiQnVydW5kaVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIktIXCIsIGxhYmVsOiBcIkNhbWJvZGlhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQ01cIiwgbGFiZWw6IFwiQ2FtZXJvb25cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJDQVwiLCBsYWJlbDogXCJDYW5hZGFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJDVlwiLCBsYWJlbDogXCJDYXBlIFZlcmRlXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiS1lcIiwgbGFiZWw6IFwiQ2F5bWFuIElzbGFuZHNcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJDRlwiLCBsYWJlbDogXCJDZW50cmFsIEFmcmljYW4gUmVwdWJsaWNcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJURFwiLCBsYWJlbDogXCJDaGFkXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQ0xcIiwgbGFiZWw6IFwiQ2hpbGVcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJDTlwiLCBsYWJlbDogXCJDaGluYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkNYXCIsIGxhYmVsOiBcIkNocmlzdG1hcyBJc2xhbmRcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJDQ1wiLCBsYWJlbDogXCJDb2NvcyAoS2VlbGluZykgSXNsYW5kc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkNPXCIsIGxhYmVsOiBcIkNvbG9tYmlhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiS01cIiwgbGFiZWw6IFwiQ29tb3Jvc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkNHXCIsIGxhYmVsOiBcIkNvbmdvXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiQ0RcIiwgbGFiZWw6IFwiQ29uZ28sIFRoZSBEZW1vY3JhdGljIFJlcHVibGljIG9mIFRoZVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkNLXCIsIGxhYmVsOiBcIkNvb2sgSXNsYW5kc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkNSXCIsIGxhYmVsOiBcIkNvc3RhIFJpY2FcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJDSVwiLCBsYWJlbDogXCJDb3RlIEQnaXZvaXJlXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiSFJcIiwgbGFiZWw6IFwiQ3JvYXRpYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkNVXCIsIGxhYmVsOiBcIkN1YmFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJDWVwiLCBsYWJlbDogXCJDeXBydXNcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJDWlwiLCBsYWJlbDogXCJDemVjaCBSZXB1YmxpY1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkRLXCIsIGxhYmVsOiBcIkRlbm1hcmtcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJESlwiLCBsYWJlbDogXCJEamlib3V0aVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkRNXCIsIGxhYmVsOiBcIkRvbWluaWNhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiRE9cIiwgbGFiZWw6IFwiRG9taW5pY2FuIFJlcHVibGljXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiRUNcIiwgbGFiZWw6IFwiRWN1YWRvclwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkVHXCIsIGxhYmVsOiBcIkVneXB0XCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiU1ZcIiwgbGFiZWw6IFwiRWwgU2FsdmFkb3JcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJHUVwiLCBsYWJlbDogXCJFcXVhdG9yaWFsIEd1aW5lYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkVSXCIsIGxhYmVsOiBcIkVyaXRyZWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJFRVwiLCBsYWJlbDogXCJFc3RvbmlhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiRVRcIiwgbGFiZWw6IFwiRXRoaW9waWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJGS1wiLCBsYWJlbDogXCJGYWxrbGFuZCBJc2xhbmRzIChNYWx2aW5hcylcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJGT1wiLCBsYWJlbDogXCJGYXJvZSBJc2xhbmRzXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiRkpcIiwgbGFiZWw6IFwiRmlqaVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkZJXCIsIGxhYmVsOiBcIkZpbmxhbmRcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJGUlwiLCBsYWJlbDogXCJGcmFuY2VcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJHRlwiLCBsYWJlbDogXCJGcmVuY2ggR3VpYW5hXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiUEZcIiwgbGFiZWw6IFwiRnJlbmNoIFBvbHluZXNpYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlRGXCIsIGxhYmVsOiBcIkZyZW5jaCBTb3V0aGVybiBUZXJyaXRvcmllc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkdBXCIsIGxhYmVsOiBcIkdhYm9uXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiR01cIiwgbGFiZWw6IFwiR2FtYmlhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiR0VcIiwgbGFiZWw6IFwiR2VvcmdpYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkRFXCIsIGxhYmVsOiBcIkdlcm1hbnlcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJHSFwiLCBsYWJlbDogXCJHaGFuYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkdJXCIsIGxhYmVsOiBcIkdpYnJhbHRhclwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkdSXCIsIGxhYmVsOiBcIkdyZWVjZVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkdMXCIsIGxhYmVsOiBcIkdyZWVubGFuZFwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkdEXCIsIGxhYmVsOiBcIkdyZW5hZGFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJHUFwiLCBsYWJlbDogXCJHdWFkZWxvdXBlXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiR1VcIiwgbGFiZWw6IFwiR3VhbVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkdUXCIsIGxhYmVsOiBcIkd1YXRlbWFsYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkdHXCIsIGxhYmVsOiBcIkd1ZXJuc2V5XCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiR05cIiwgbGFiZWw6IFwiR3VpbmVhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiR1dcIiwgbGFiZWw6IFwiR3VpbmVhLWJpc3NhdVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkdZXCIsIGxhYmVsOiBcIkd1eWFuYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkhUXCIsIGxhYmVsOiBcIkhhaXRpXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiSE1cIiwgbGFiZWw6IFwiSGVhcmQgSXNsYW5kIGFuZCBNY2RvbmFsZCBJc2xhbmRzXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiVkFcIiwgbGFiZWw6IFwiSG9seSBTZWUgKFZhdGljYW4gQ2l0eSBTdGF0ZSlcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJITlwiLCBsYWJlbDogXCJIb25kdXJhc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkhLXCIsIGxhYmVsOiBcIkhvbmcgS29uZ1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkhVXCIsIGxhYmVsOiBcIkh1bmdhcnlcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJJU1wiLCBsYWJlbDogXCJJY2VsYW5kXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiSU5cIiwgbGFiZWw6IFwiSW5kaWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJJRFwiLCBsYWJlbDogXCJJbmRvbmVzaWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJJUlwiLCBsYWJlbDogXCJJcmFuLCBJc2xhbWljIFJlcHVibGljIG9mXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiSVFcIiwgbGFiZWw6IFwiSXJhcVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIklFXCIsIGxhYmVsOiBcIklyZWxhbmRcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJJTVwiLCBsYWJlbDogXCJJc2xlIG9mIE1hblwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIklMXCIsIGxhYmVsOiBcIklzcmFlbFwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIklUXCIsIGxhYmVsOiBcIkl0YWx5XCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiSk1cIiwgbGFiZWw6IFwiSmFtYWljYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkpQXCIsIGxhYmVsOiBcIkphcGFuXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiSkVcIiwgbGFiZWw6IFwiSmVyc2V5XCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiSk9cIiwgbGFiZWw6IFwiSm9yZGFuXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiS1pcIiwgbGFiZWw6IFwiS2F6YWtoc3RhblwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIktFXCIsIGxhYmVsOiBcIktlbnlhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiS0lcIiwgbGFiZWw6IFwiS2lyaWJhdGlcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJLUFwiLCBsYWJlbDogXCJLb3JlYSwgRGVtb2NyYXRpYyBQZW9wbGUncyBSZXB1YmxpYyBvZlwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIktSXCIsIGxhYmVsOiBcIktvcmVhLCBSZXB1YmxpYyBvZlwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIktXXCIsIGxhYmVsOiBcIkt1d2FpdFwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIktHXCIsIGxhYmVsOiBcIkt5cmd5enN0YW5cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJMQVwiLCBsYWJlbDogXCJMYW8gUGVvcGxlJ3MgRGVtb2NyYXRpYyBSZXB1YmxpY1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkxWXCIsIGxhYmVsOiBcIkxhdHZpYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkxCXCIsIGxhYmVsOiBcIkxlYmFub25cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJMU1wiLCBsYWJlbDogXCJMZXNvdGhvXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTFJcIiwgbGFiZWw6IFwiTGliZXJpYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkxZXCIsIGxhYmVsOiBcIkxpYnlhbiBBcmFiIEphbWFoaXJpeWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJMSVwiLCBsYWJlbDogXCJMaWVjaHRlbnN0ZWluXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTFRcIiwgbGFiZWw6IFwiTGl0aHVhbmlhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTFVcIiwgbGFiZWw6IFwiTHV4ZW1ib3VyZ1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk1PXCIsIGxhYmVsOiBcIk1hY2FvXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTUtcIiwgbGFiZWw6IFwiTWFjZWRvbmlhLCBUaGUgRm9ybWVyIFl1Z29zbGF2IFJlcHVibGljIG9mXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTUdcIiwgbGFiZWw6IFwiTWFkYWdhc2NhclwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk1XXCIsIGxhYmVsOiBcIk1hbGF3aVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk1ZXCIsIGxhYmVsOiBcIk1hbGF5c2lhXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTVZcIiwgbGFiZWw6IFwiTWFsZGl2ZXNcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJNTFwiLCBsYWJlbDogXCJNYWxpXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTVRcIiwgbGFiZWw6IFwiTWFsdGFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJNSFwiLCBsYWJlbDogXCJNYXJzaGFsbCBJc2xhbmRzXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTVFcIiwgbGFiZWw6IFwiTWFydGluaXF1ZVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk1SXCIsIGxhYmVsOiBcIk1hdXJpdGFuaWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJNVVwiLCBsYWJlbDogXCJNYXVyaXRpdXNcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJZVFwiLCBsYWJlbDogXCJNYXlvdHRlXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTVhcIiwgbGFiZWw6IFwiTWV4aWNvXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiRk1cIiwgbGFiZWw6IFwiTWljcm9uZXNpYSwgRmVkZXJhdGVkIFN0YXRlcyBvZlwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk1EXCIsIGxhYmVsOiBcIk1vbGRvdmEsIFJlcHVibGljIG9mXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTUNcIiwgbGFiZWw6IFwiTW9uYWNvXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTU5cIiwgbGFiZWw6IFwiTW9uZ29saWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJNRVwiLCBsYWJlbDogXCJNb250ZW5lZ3JvXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTVNcIiwgbGFiZWw6IFwiTW9udHNlcnJhdFwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk1BXCIsIGxhYmVsOiBcIk1vcm9jY29cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJNWlwiLCBsYWJlbDogXCJNb3phbWJpcXVlXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTU1cIiwgbGFiZWw6IFwiTXlhbm1hclwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk5BXCIsIGxhYmVsOiBcIk5hbWliaWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJOUlwiLCBsYWJlbDogXCJOYXVydVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk5QXCIsIGxhYmVsOiBcIk5lcGFsXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTkxcIiwgbGFiZWw6IFwiTmV0aGVybGFuZHNcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJBTlwiLCBsYWJlbDogXCJOZXRoZXJsYW5kcyBBbnRpbGxlc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk5DXCIsIGxhYmVsOiBcIk5ldyBDYWxlZG9uaWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJOWlwiLCBsYWJlbDogXCJOZXcgWmVhbGFuZFwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk5JXCIsIGxhYmVsOiBcIk5pY2FyYWd1YVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk5FXCIsIGxhYmVsOiBcIk5pZ2VyXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTkdcIiwgbGFiZWw6IFwiTmlnZXJpYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk5VXCIsIGxhYmVsOiBcIk5pdWVcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJORlwiLCBsYWJlbDogXCJOb3Jmb2xrIElzbGFuZFwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk1QXCIsIGxhYmVsOiBcIk5vcnRoZXJuIE1hcmlhbmEgSXNsYW5kc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk5PXCIsIGxhYmVsOiBcIk5vcndheVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIk9NXCIsIGxhYmVsOiBcIk9tYW5cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJQS1wiLCBsYWJlbDogXCJQYWtpc3RhblwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlBXXCIsIGxhYmVsOiBcIlBhbGF1XCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiUFNcIiwgbGFiZWw6IFwiUGFsZXN0aW5pYW4gVGVycml0b3J5LCBPY2N1cGllZFwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlBBXCIsIGxhYmVsOiBcIlBhbmFtYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlBHXCIsIGxhYmVsOiBcIlBhcHVhIE5ldyBHdWluZWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJQWVwiLCBsYWJlbDogXCJQYXJhZ3VheVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlBFXCIsIGxhYmVsOiBcIlBlcnVcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJQSFwiLCBsYWJlbDogXCJQaGlsaXBwaW5lc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlBOXCIsIGxhYmVsOiBcIlBpdGNhaXJuXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiUExcIiwgbGFiZWw6IFwiUG9sYW5kXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiUFRcIiwgbGFiZWw6IFwiUG9ydHVnYWxcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJQUlwiLCBsYWJlbDogXCJQdWVydG8gUmljb1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlFBXCIsIGxhYmVsOiBcIlFhdGFyXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiUkVcIiwgbGFiZWw6IFwiUmV1bmlvblwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlJPXCIsIGxhYmVsOiBcIlJvbWFuaWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJSVVwiLCBsYWJlbDogXCJSdXNzaWFuIEZlZGVyYXRpb25cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJSV1wiLCBsYWJlbDogXCJSd2FuZGFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJTSFwiLCBsYWJlbDogXCJTYWludCBIZWxlbmFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJLTlwiLCBsYWJlbDogXCJTYWludCBLaXR0cyBhbmQgTmV2aXNcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJMQ1wiLCBsYWJlbDogXCJTYWludCBMdWNpYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlBNXCIsIGxhYmVsOiBcIlNhaW50IFBpZXJyZSBhbmQgTWlxdWVsb25cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJWQ1wiLCBsYWJlbDogXCJTYWludCBWaW5jZW50IGFuZCBUaGUgR3JlbmFkaW5lc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIldTXCIsIGxhYmVsOiBcIlNhbW9hXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiU01cIiwgbGFiZWw6IFwiU2FuIE1hcmlub1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlNUXCIsIGxhYmVsOiBcIlNhbyBUb21lIGFuZCBQcmluY2lwZVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlNBXCIsIGxhYmVsOiBcIlNhdWRpIEFyYWJpYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlNOXCIsIGxhYmVsOiBcIlNlbmVnYWxcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJSU1wiLCBsYWJlbDogXCJTZXJiaWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJTQ1wiLCBsYWJlbDogXCJTZXljaGVsbGVzXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiU0xcIiwgbGFiZWw6IFwiU2llcnJhIExlb25lXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiU0dcIiwgbGFiZWw6IFwiU2luZ2Fwb3JlXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiU0tcIiwgbGFiZWw6IFwiU2xvdmFraWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJTSVwiLCBsYWJlbDogXCJTbG92ZW5pYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlNCXCIsIGxhYmVsOiBcIlNvbG9tb24gSXNsYW5kc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlNPXCIsIGxhYmVsOiBcIlNvbWFsaWFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJaQVwiLCBsYWJlbDogXCJTb3V0aCBBZnJpY2FcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJHU1wiLCBsYWJlbDogXCJTb3V0aCBHZW9yZ2lhIGFuZCBUaGUgU291dGggU2FuZHdpY2ggSXNsYW5kc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkVTXCIsIGxhYmVsOiBcIlNwYWluXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiTEtcIiwgbGFiZWw6IFwiU3JpIExhbmthXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiU0RcIiwgbGFiZWw6IFwiU3VkYW5cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJTUlwiLCBsYWJlbDogXCJTdXJpbmFtZVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlNKXCIsIGxhYmVsOiBcIlN2YWxiYXJkIGFuZCBKYW4gTWF5ZW5cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJTWlwiLCBsYWJlbDogXCJTd2F6aWxhbmRcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJTRVwiLCBsYWJlbDogXCJTd2VkZW5cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJDSFwiLCBsYWJlbDogXCJTd2l0emVybGFuZFwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlNZXCIsIGxhYmVsOiBcIlN5cmlhbiBBcmFiIFJlcHVibGljXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiVFdcIiwgbGFiZWw6IFwiVGFpd2FuLCBQcm92aW5jZSBvZiBDaGluYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlRKXCIsIGxhYmVsOiBcIlRhamlraXN0YW5cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJUWlwiLCBsYWJlbDogXCJUYW56YW5pYSwgVW5pdGVkIFJlcHVibGljIG9mXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiVEhcIiwgbGFiZWw6IFwiVGhhaWxhbmRcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJUTFwiLCBsYWJlbDogXCJUaW1vci1sZXN0ZVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlRHXCIsIGxhYmVsOiBcIlRvZ29cIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJUS1wiLCBsYWJlbDogXCJUb2tlbGF1XCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiVE9cIiwgbGFiZWw6IFwiVG9uZ2FcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJUVFwiLCBsYWJlbDogXCJUcmluaWRhZCBhbmQgVG9iYWdvXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiVE5cIiwgbGFiZWw6IFwiVHVuaXNpYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlRSXCIsIGxhYmVsOiBcIlR1cmtleVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlRNXCIsIGxhYmVsOiBcIlR1cmttZW5pc3RhblwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlRDXCIsIGxhYmVsOiBcIlR1cmtzIGFuZCBDYWljb3MgSXNsYW5kc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlRWXCIsIGxhYmVsOiBcIlR1dmFsdVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlVHXCIsIGxhYmVsOiBcIlVnYW5kYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlVBXCIsIGxhYmVsOiBcIlVrcmFpbmVcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJBRVwiLCBsYWJlbDogXCJVbml0ZWQgQXJhYiBFbWlyYXRlc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIkdCXCIsIGxhYmVsOiBcIlVuaXRlZCBLaW5nZG9tXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiVVNcIiwgbGFiZWw6IFwiVW5pdGVkIFN0YXRlc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlVNXCIsIGxhYmVsOiBcIlVuaXRlZCBTdGF0ZXMgTWlub3IgT3V0bHlpbmcgSXNsYW5kc1wifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlVZXCIsIGxhYmVsOiBcIlVydWd1YXlcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJVWlwiLCBsYWJlbDogXCJVemJla2lzdGFuXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiVlVcIiwgbGFiZWw6IFwiVmFudWF0dVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlZFXCIsIGxhYmVsOiBcIlZlbmV6dWVsYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlZOXCIsIGxhYmVsOiBcIlZpZXQgTmFtXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiVkdcIiwgbGFiZWw6IFwiVmlyZ2luIElzbGFuZHMsIEJyaXRpc2hcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJWSVwiLCBsYWJlbDogXCJWaXJnaW4gSXNsYW5kcywgVS5TLlwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIldGXCIsIGxhYmVsOiBcIldhbGxpcyBhbmQgRnV0dW5hXCJ9LFxuICAgICAgICAgICAgICB7dmFsdWU6IFwiRUhcIiwgbGFiZWw6IFwiV2VzdGVybiBTYWhhcmFcIn0sXG4gICAgICAgICAgICAgIHt2YWx1ZTogXCJZRVwiLCBsYWJlbDogXCJZZW1lblwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlpNXCIsIGxhYmVsOiBcIlphbWJpYVwifSxcbiAgICAgICAgICAgICAge3ZhbHVlOiBcIlpXXCIsIGxhYmVsOiBcIlppbWJhYndlXCJ9LFxuICAgICAgICAgIF07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IFtcIkFmZ2hhbmlzdGFuXCIsXCLDhWxhbmQgSXNsYW5kc1wiLFwiQWxiYW5pYVwiLFwiQWxnZXJpYVwiLFwiQW1lcmljYW4gU2Ftb2FcIixcIkFuZG9ycmFcIixcIkFuZ29sYVwiLFwiQW5ndWlsbGFcIixcIkFudGFyY3RpY2FcIixcIkFudGlndWEgYW5kIEJhcmJ1ZGFcIixcIkFyZ2VudGluYVwiLFwiQXJtZW5pYVwiLFwiQXJ1YmFcIixcIkF1c3RyYWxpYVwiLFwiQXVzdHJpYVwiLFwiQXplcmJhaWphblwiLFwiQmFoYW1hc1wiLFwiQmFocmFpblwiLFwiQmFuZ2xhZGVzaFwiLFwiQmFyYmFkb3NcIixcIkJlbGFydXNcIixcIkJlbGdpdW1cIixcIkJlbGl6ZVwiLFwiQmVuaW5cIixcIkJlcm11ZGFcIixcIkJodXRhblwiLFwiQm9saXZpYVwiLFwiQm9zbmlhIGFuZCBIZXJ6ZWdvdmluYVwiLFwiQm90c3dhbmFcIixcIkJvdXZldCBJc2xhbmRcIixcIkJyYXppbFwiLFwiQnJpdGlzaCBJbmRpYW4gT2NlYW4gVGVycml0b3J5XCIsXCJCcnVuZWkgRGFydXNzYWxhbVwiLFwiQnVsZ2FyaWFcIixcIkJ1cmtpbmEgRmFzb1wiLFwiQnVydW5kaVwiLFwiQ2FtYm9kaWFcIixcIkNhbWVyb29uXCIsXCJDYW5hZGFcIixcIkNhcGUgVmVyZGVcIixcIkNheW1hbiBJc2xhbmRzXCIsXCJDZW50cmFsIEFmcmljYW4gUmVwdWJsaWNcIixcIkNoYWRcIixcIkNoaWxlXCIsXCJDaGluYVwiLFwiQ2hyaXN0bWFzIElzbGFuZFwiLFwiQ29jb3MgKEtlZWxpbmcpIElzbGFuZHNcIixcIkNvbG9tYmlhXCIsXCJDb21vcm9zXCIsXCJDb25nb1wiLFwiQ29uZ28sIFRoZSBEZW1vY3JhdGljIFJlcHVibGljIG9mIFRoZVwiLFwiQ29vayBJc2xhbmRzXCIsXCJDb3N0YSBSaWNhXCIsXCJDb3RlIEQnaXZvaXJlXCIsXCJDcm9hdGlhXCIsXCJDdWJhXCIsXCJDeXBydXNcIixcIkN6ZWNoIFJlcHVibGljXCIsXCJEZW5tYXJrXCIsXCJEamlib3V0aVwiLFwiRG9taW5pY2FcIixcIkRvbWluaWNhbiBSZXB1YmxpY1wiLFwiRWN1YWRvclwiLFwiRWd5cHRcIixcIkVsIFNhbHZhZG9yXCIsXCJFcXVhdG9yaWFsIEd1aW5lYVwiLFwiRXJpdHJlYVwiLFwiRXN0b25pYVwiLFwiRXRoaW9waWFcIixcIkZhbGtsYW5kIElzbGFuZHMgKE1hbHZpbmFzKVwiLFwiRmFyb2UgSXNsYW5kc1wiLFwiRmlqaVwiLFwiRmlubGFuZFwiLFwiRnJhbmNlXCIsXCJGcmVuY2ggR3VpYW5hXCIsXCJGcmVuY2ggUG9seW5lc2lhXCIsXCJGcmVuY2ggU291dGhlcm4gVGVycml0b3JpZXNcIixcIkdhYm9uXCIsXCJHYW1iaWFcIixcIkdlb3JnaWFcIixcIkdlcm1hbnlcIixcIkdoYW5hXCIsXCJHaWJyYWx0YXJcIixcIkdyZWVjZVwiLFwiR3JlZW5sYW5kXCIsXCJHcmVuYWRhXCIsXCJHdWFkZWxvdXBlXCIsXCJHdWFtXCIsXCJHdWF0ZW1hbGFcIixcIkd1ZXJuc2V5XCIsXCJHdWluZWFcIixcIkd1aW5lYS1iaXNzYXVcIixcIkd1eWFuYVwiLFwiSGFpdGlcIixcIkhlYXJkIElzbGFuZCBhbmQgTWNkb25hbGQgSXNsYW5kc1wiLFwiSG9seSBTZWUgKFZhdGljYW4gQ2l0eSBTdGF0ZSlcIixcIkhvbmR1cmFzXCIsXCJIb25nIEtvbmdcIixcIkh1bmdhcnlcIixcIkljZWxhbmRcIixcIkluZGlhXCIsXCJJbmRvbmVzaWFcIixcIklyYW4sIElzbGFtaWMgUmVwdWJsaWMgb2ZcIixcIklyYXFcIixcIklyZWxhbmRcIixcIklzbGUgb2YgTWFuXCIsXCJJc3JhZWxcIixcIkl0YWx5XCIsXCJKYW1haWNhXCIsXCJKYXBhblwiLFwiSmVyc2V5XCIsXCJKb3JkYW5cIixcIkthemFraHN0YW5cIixcIktlbnlhXCIsXCJLaXJpYmF0aVwiLFwiS29yZWEsIERlbW9jcmF0aWMgUGVvcGxlJ3MgUmVwdWJsaWMgb2ZcIixcIktvcmVhLCBSZXB1YmxpYyBvZlwiLFwiS3V3YWl0XCIsXCJLeXJneXpzdGFuXCIsXCJMYW8gUGVvcGxlJ3MgRGVtb2NyYXRpYyBSZXB1YmxpY1wiLFwiTGF0dmlhXCIsXCJMZWJhbm9uXCIsXCJMZXNvdGhvXCIsXCJMaWJlcmlhXCIsXCJMaWJ5YW4gQXJhYiBKYW1haGlyaXlhXCIsXCJMaWVjaHRlbnN0ZWluXCIsXCJMaXRodWFuaWFcIixcIkx1eGVtYm91cmdcIixcIk1hY2FvXCIsXCJNYWNlZG9uaWEsIFRoZSBGb3JtZXIgWXVnb3NsYXYgUmVwdWJsaWMgb2ZcIixcIk1hZGFnYXNjYXJcIixcIk1hbGF3aVwiLFwiTWFsYXlzaWFcIixcIk1hbGRpdmVzXCIsXCJNYWxpXCIsXCJNYWx0YVwiLFwiTWFyc2hhbGwgSXNsYW5kc1wiLFwiTWFydGluaXF1ZVwiLFwiTWF1cml0YW5pYVwiLFwiTWF1cml0aXVzXCIsXCJNYXlvdHRlXCIsXCJNZXhpY29cIixcIk1pY3JvbmVzaWEsIEZlZGVyYXRlZCBTdGF0ZXMgb2ZcIixcIk1vbGRvdmEsIFJlcHVibGljIG9mXCIsXCJNb25hY29cIixcIk1vbmdvbGlhXCIsXCJNb250ZW5lZ3JvXCIsXCJNb250c2VycmF0XCIsXCJNb3JvY2NvXCIsXCJNb3phbWJpcXVlXCIsXCJNeWFubWFyXCIsXCJOYW1pYmlhXCIsXCJOYXVydVwiLFwiTmVwYWxcIixcIk5ldGhlcmxhbmRzXCIsXCJOZXRoZXJsYW5kcyBBbnRpbGxlc1wiLFwiTmV3IENhbGVkb25pYVwiLFwiTmV3IFplYWxhbmRcIixcIk5pY2FyYWd1YVwiLFwiTmlnZXJcIixcIk5pZ2VyaWFcIixcIk5pdWVcIixcIk5vcmZvbGsgSXNsYW5kXCIsXCJOb3J0aGVybiBNYXJpYW5hIElzbGFuZHNcIixcIk5vcndheVwiLFwiT21hblwiLFwiUGFraXN0YW5cIixcIlBhbGF1XCIsXCJQYWxlc3RpbmlhbiBUZXJyaXRvcnksIE9jY3VwaWVkXCIsXCJQYW5hbWFcIixcIlBhcHVhIE5ldyBHdWluZWFcIixcIlBhcmFndWF5XCIsXCJQZXJ1XCIsXCJQaGlsaXBwaW5lc1wiLFwiUGl0Y2Fpcm5cIixcIlBvbGFuZFwiLFwiUG9ydHVnYWxcIixcIlB1ZXJ0byBSaWNvXCIsXCJRYXRhclwiLFwiUmV1bmlvblwiLFwiUm9tYW5pYVwiLFwiUnVzc2lhbiBGZWRlcmF0aW9uXCIsXCJSd2FuZGFcIixcIlNhaW50IEhlbGVuYVwiLFwiU2FpbnQgS2l0dHMgYW5kIE5ldmlzXCIsXCJTYWludCBMdWNpYVwiLFwiU2FpbnQgUGllcnJlIGFuZCBNaXF1ZWxvblwiLFwiU2FpbnQgVmluY2VudCBhbmQgVGhlIEdyZW5hZGluZXNcIixcIlNhbW9hXCIsXCJTYW4gTWFyaW5vXCIsXCJTYW8gVG9tZSBhbmQgUHJpbmNpcGVcIixcIlNhdWRpIEFyYWJpYVwiLFwiU2VuZWdhbFwiLFwiU2VyYmlhXCIsXCJTZXljaGVsbGVzXCIsXCJTaWVycmEgTGVvbmVcIixcIlNpbmdhcG9yZVwiLFwiU2xvdmFraWFcIixcIlNsb3ZlbmlhXCIsXCJTb2xvbW9uIElzbGFuZHNcIixcIlNvbWFsaWFcIixcIlNvdXRoIEFmcmljYVwiLFwiU291dGggR2VvcmdpYSBhbmQgVGhlIFNvdXRoIFNhbmR3aWNoIElzbGFuZHNcIixcIlNwYWluXCIsXCJTcmkgTGFua2FcIixcIlN1ZGFuXCIsXCJTdXJpbmFtZVwiLFwiU3ZhbGJhcmQgYW5kIEphbiBNYXllblwiLFwiU3dhemlsYW5kXCIsXCJTd2VkZW5cIixcIlN3aXR6ZXJsYW5kXCIsXCJTeXJpYW4gQXJhYiBSZXB1YmxpY1wiLFwiVGFpd2FuLCBQcm92aW5jZSBvZiBDaGluYVwiLFwiVGFqaWtpc3RhblwiLFwiVGFuemFuaWEsIFVuaXRlZCBSZXB1YmxpYyBvZlwiLFwiVGhhaWxhbmRcIixcIlRpbW9yLWxlc3RlXCIsXCJUb2dvXCIsXCJUb2tlbGF1XCIsXCJUb25nYVwiLFwiVHJpbmlkYWQgYW5kIFRvYmFnb1wiLFwiVHVuaXNpYVwiLFwiVHVya2V5XCIsXCJUdXJrbWVuaXN0YW5cIixcIlR1cmtzIGFuZCBDYWljb3MgSXNsYW5kc1wiLFwiVHV2YWx1XCIsXCJVZ2FuZGFcIixcIlVrcmFpbmVcIixcIlVuaXRlZCBBcmFiIEVtaXJhdGVzXCIsXCJVbml0ZWQgS2luZ2RvbVwiLFwiVW5pdGVkIFN0YXRlc1wiLFwiVW5pdGVkIFN0YXRlcyBNaW5vciBPdXRseWluZyBJc2xhbmRzXCIsXCJVcnVndWF5XCIsXCJVemJla2lzdGFuXCIsXCJWYW51YXR1XCIsXCJWZW5lenVlbGFcIixcIlZpZXQgTmFtXCIsXCJWaXJnaW4gSXNsYW5kcywgQnJpdGlzaFwiLFwiVmlyZ2luIElzbGFuZHMsIFUuUy5cIixcIldhbGxpcyBhbmQgRnV0dW5hXCIsXCJXZXN0ZXJuIFNhaGFyYVwiLFwiWWVtZW5cIixcIlphbWJpYVwiLFwiWmltYmFid2VcIl07XG4iLCJpbXBvcnQgVnVlIGZyb20gJ3Z1ZSdcbmltcG9ydCBBcHAgZnJvbSAnLi9BcHAudnVlJ1xuaW1wb3J0IHN0b3JlIGZyb20gJy4vdnVleC9zdG9yZSdcblxuLyogZXNsaW50LWRpc2FibGUgbm8tbmV3ICovXG5uZXcgVnVlKHtcbiAgZWw6ICdib2R5JyxcbiAgc3RvcmUsXG4gIGNvbXBvbmVudHM6IHsgQXBwIH1cbn0pXG4iLCJpbXBvcnQgVnVlIGZyb20gJ3Z1ZSdcbmltcG9ydCBWdWV4IGZyb20gJ3Z1ZXgnXG5cblZ1ZS51c2UoVnVleClcblZ1ZS5jb25maWcuZGVidWcgPSB0cnVlXG5cbmNvbnN0IHN0YXRlID0ge1xuICBjb3VudDogMFxufVxuXG5jb25zdCBtdXRhdGlvbnMgPSB7XG4gIElOQ1JFTUVOVCAoc3RhdGUpIHtcbiAgICBzdGF0ZS5jb3VudCsrXG4gIH0sXG4gIERFQ1JFTUVOVCAoc3RhdGUpIHtcbiAgICBzdGF0ZS5jb3VudC0tXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgbmV3IFZ1ZXguU3RvcmUoe1xuICBzdGF0ZSxcbiAgbXV0YXRpb25zXG59KVxuIiwiKGZ1bmN0aW9uKGdsb2JhbCwgX21haW4sIG1vZHVsZURlZnMsIGNhY2hlZE1vZHVsZXMsIF9lbnRyaWVzKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICB2YXIgbW9kdWxlTWV0YSA9IHtcIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWhtci9saWIvaGFzLmpzXCI6e1wiaW5kZXhcIjoxMSxcImhhc2hcIjpcIkhreTRRWVZyVTEra0ZISUV1eFB5XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktaG1yL2xpYi9zdHItc2V0LmpzXCIsXCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1obXIvaW5jL2luZGV4LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanNcIjp7XCJpbmRleFwiOjEzNyxcImhhc2hcIjpcImQvRGlvNDNRRFgzWHQ3Tll2YnI2XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL3Z1ZS9kaXN0L3Z1ZS5jb21tb24uanNcIl19LFwibm9kZV9tb2R1bGVzL3Z1ZS9kaXN0L3Z1ZS5jb21tb24uanNcIjp7XCJpbmRleFwiOjE1MSxcImhhc2hcIjpcIjFWcXo4ZnhtS0hTdW8vN1lFVXBvXCIsXCJwYXJlbnRzXCI6W1wic3JjL2NvbXBvbmVudHMvU2VsZWN0LnZ1ZVwiLFwic3JjL2NvbXBvbmVudHMvSnVtYm90cm9uLnZ1ZVwiLFwic3JjL0FwcC52dWVcIixcInNyYy92dWV4L3N0b3JlLmpzXCIsXCJzcmMvbWFpbi5qc1wiXX0sXCJub2RlX21vZHVsZXMvcGFyc2V1cmkvaW5kZXguanNcIjp7XCJpbmRleFwiOjEzNixcImhhc2hcIjpcImMvYzdYZnRTSTZDbEZjOWgyak9oXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL3VybC5qc1wiLFwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3NvY2tldC5qc1wiXX0sXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvdXJsLmpzXCI6e1wiaW5kZXhcIjoxNDIsXCJoYXNoXCI6XCJlQTJmZnBVN21qU0xsWVR2ejZrMFwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi9pbmRleC5qc1wiXX0sXCJub2RlX21vZHVsZXMvZGVidWcvYnJvd3Nlci5qc1wiOntcImluZGV4XCI6NDYsXCJoYXNoXCI6XCJTNzZxMjhmMVZQSkljQ3RKbjFlcVwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi91cmwuanNcIixcIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi9zb2NrZXQuanNcIixcIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tcGFyc2VyL2luZGV4LmpzXCIsXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy93ZWJzb2NrZXQuanNcIixcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3BvbGxpbmcuanNcIixcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3BvbGxpbmcteGhyLmpzXCIsXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvc29ja2V0LmpzXCIsXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvbWFuYWdlci5qc1wiLFwibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL2luZGV4LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi9vbi5qc1wiOntcImluZGV4XCI6MTQwLFwiaGFzaFwiOlwieTVNT29GcFRLS0JId0U4cThqYWVcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvc29ja2V0LmpzXCIsXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvbWFuYWdlci5qc1wiXX0sXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvY29tcG9uZW50LWVtaXR0ZXIvaW5kZXguanNcIjp7XCJpbmRleFwiOjE0MyxcImhhc2hcIjpcImFzeE5lS0tFWW1ueG5BeElDVFM2XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL3NvY2tldC5qc1wiLFwibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL21hbmFnZXIuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvbXBvbmVudC1iaW5kL2luZGV4LmpzXCI6e1wiaW5kZXhcIjoxMyxcImhhc2hcIjpcIjR5SWNWdythZndVc25UUXlJMGEzXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL3NvY2tldC5qc1wiLFwibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL21hbmFnZXIuanNcIl19LFwibm9kZV9tb2R1bGVzL3RvLWFycmF5L2luZGV4LmpzXCI6e1wiaW5kZXhcIjoxNDgsXCJoYXNoXCI6XCIyRW9nZ2FmeFgrR0xYa1hpYUdqbVwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi9zb2NrZXQuanNcIl19LFwibm9kZV9tb2R1bGVzL3NvY2tldC5pby1wYXJzZXIvaXMtYnVmZmVyLmpzXCI6e1wiaW5kZXhcIjoxNDYsXCJoYXNoXCI6XCJGNDIvRVdTeldjTDFJdktoK3l3NFwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tcGFyc2VyL2JpbmFyeS5qc1wiLFwibm9kZV9tb2R1bGVzL3NvY2tldC5pby1wYXJzZXIvaW5kZXguanNcIl19LFwibm9kZV9tb2R1bGVzL2lzYXJyYXkvaW5kZXguanNcIjp7XCJpbmRleFwiOjY0LFwiaGFzaFwiOlwiZEt0ZXdzMVM0c0h2YVpoWitjZXFcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvaGFzLWJpbmFyeS9pbmRleC5qc1wiLFwibm9kZV9tb2R1bGVzL3NvY2tldC5pby1wYXJzZXIvYmluYXJ5LmpzXCIsXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9pbmRleC5qc1wiLFwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbm9kZV9tb2R1bGVzL2hhcy1iaW5hcnkvaW5kZXguanNcIl19LFwibm9kZV9tb2R1bGVzL2NvbXBvbmVudC1lbWl0dGVyL2luZGV4LmpzXCI6e1wiaW5kZXhcIjoxNCxcImhhc2hcIjpcIjB1TDFMU2EvbU9qK0xsdStIVFo3XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL3NvY2tldC5pby1wYXJzZXIvaW5kZXguanNcIixcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnQuanNcIixcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3BvbGxpbmcteGhyLmpzXCIsXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvc29ja2V0LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tcGFyc2VyL25vZGVfbW9kdWxlcy9qc29uMy9saWIvanNvbjMuanNcIjp7XCJpbmRleFwiOjE0NyxcImhhc2hcIjpcIm5ONUd1Uy9DaDlvblVwWDRXVDA4XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL3NvY2tldC5pby1wYXJzZXIvaW5kZXguanNcIl19LFwibm9kZV9tb2R1bGVzL2JhY2tvMi9pbmRleC5qc1wiOntcImluZGV4XCI6NixcImhhc2hcIjpcIkw1cnkzbWZWRXcxd2dteDlTYStxXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL21hbmFnZXIuanNcIl19LFwibm9kZV9tb2R1bGVzL2luZGV4b2YvaW5kZXguanNcIjp7XCJpbmRleFwiOjYzLFwiaGFzaFwiOlwiOHpNR1YwajBJRDViVUllVDdyK01cIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvc29ja2V0LmpzXCIsXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvbWFuYWdlci5qc1wiXX0sXCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1obXIvbGliL3N0ci1zZXQuanNcIjp7XCJpbmRleFwiOjEyLFwiaGFzaFwiOlwibGNyRG1RSzR1YXFPcU4rRlY0LzlcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1obXIvaW5jL2luZGV4LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYXJyYXlGaWx0ZXIuanNcIjp7XCJpbmRleFwiOjczLFwiaGFzaFwiOlwiQkd1bnowdzFRekpYeXFRU09kWmJcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2NvbGxlY3Rpb24vZmlsdGVyLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYXJyYXlTb21lLmpzXCI6e1wiaW5kZXhcIjo3NSxcImhhc2hcIjpcIkd4ZUpQeEpqMmpVZzVUelY1Z0x2XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9jb2xsZWN0aW9uL3NvbWUuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvZXF1YWxBcnJheXMuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9hcnJheUVhY2guanNcIjp7XCJpbmRleFwiOjcyLFwiaGFzaFwiOlwiZUx4VUJWc2I4dnBGYnUwVk40S0xcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2NvbGxlY3Rpb24vZm9yRWFjaC5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2FycmF5TWFwLmpzXCI6e1wiaW5kZXhcIjo3NCxcImhhc2hcIjpcInhkcjhjMEpzVUZhcElIVHVNNVZFXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9jb2xsZWN0aW9uL21hcC5qc1wiXX0sXCJub2RlX21vZHVsZXMvdnVlaWZ5LWluc2VydC1jc3MvaW5kZXguanNcIjp7XCJpbmRleFwiOjE1MixcImhhc2hcIjpcImZ2VFVpakE2eXlCcHA2OEgrSlgyXCIsXCJwYXJlbnRzXCI6W1wic3JjL2NvbXBvbmVudHMvU2VsZWN0LnZ1ZVwiLFwic3JjL0FwcC52dWVcIl19LFwibm9kZV9tb2R1bGVzL3Z1ZS1ob3QtcmVsb2FkLWFwaS9pbmRleC5qc1wiOntcImluZGV4XCI6MTUwLFwiaGFzaFwiOlwiZjFGZEMwQVgwR3Y2enlEVTRxT3NcIixcInBhcmVudHNcIjpbXCJzcmMvY29tcG9uZW50cy9TZWxlY3QudnVlXCIsXCJzcmMvY29tcG9uZW50cy9KdW1ib3Ryb24udnVlXCIsXCJzcmMvQXBwLnZ1ZVwiXX0sXCJub2RlX21vZHVsZXMvbXMvaW5kZXguanNcIjp7XCJpbmRleFwiOjEzMyxcImhhc2hcIjpcIkhhblZLbTVBa1Y2TU9kSFJBTUNUXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2RlYnVnL2RlYnVnLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9kZWJ1Zy9kZWJ1Zy5qc1wiOntcImluZGV4XCI6NDcsXCJoYXNoXCI6XCJ5cWRSN25KYzd3eElIekZETnpHK1wiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9kZWJ1Zy9icm93c2VyLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9oYXMtYmluYXJ5L2luZGV4LmpzXCI6e1wiaW5kZXhcIjo2MSxcImhhc2hcIjpcImdoTTZzN0p3STVWWTJJTU1iWTFvXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL3NvY2tldC5qc1wiXX0sXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvc29ja2V0LmpzXCI6e1wiaW5kZXhcIjoxNDEsXCJoYXNoXCI6XCJkWmh3ckYzNnVGSUdiRFpNaHNzNlwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi9tYW5hZ2VyLmpzXCIsXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvaW5kZXguanNcIl19LFwibm9kZV9tb2R1bGVzL3NvY2tldC5pby1wYXJzZXIvaW5kZXguanNcIjp7XCJpbmRleFwiOjE0NSxcImhhc2hcIjpcIjdQcmdPUlk5ZmFJYTNRdlhlSGpVXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL3NvY2tldC5qc1wiLFwibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL21hbmFnZXIuanNcIixcIm5vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi9pbmRleC5qc1wiXX0sXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9iaW5hcnkuanNcIjp7XCJpbmRleFwiOjE0NCxcImhhc2hcIjpcIjhJNU5SQTFybEd0c3FzQlZNcHJ5XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL3NvY2tldC5pby1wYXJzZXIvaW5kZXguanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9pc0xlbmd0aC5qc1wiOntcImluZGV4XCI6MTEzLFwiaGFzaFwiOlwiREZJS0kxMjFWemVFK3BCYngxT2FcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2NyZWF0ZUJhc2VFYWNoLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2lzQXJyYXlMaWtlLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2xhbmcvaXNBcnJheS5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9vYmplY3Qva2V5c0luLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL3NoaW1LZXlzLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2xhbmcvaXNUeXBlZEFycmF5LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvaXNPYmplY3RMaWtlLmpzXCI6e1wiaW5kZXhcIjoxMTQsXCJoYXNoXCI6XCJxRUduQVdKTm9BZXRPSUo3WUtpVlwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvbGFuZy9pc05hdGl2ZS5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9sYW5nL2lzQXJyYXkuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvbGFuZy9pc0FyZ3VtZW50cy5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9sYW5nL2lzVHlwZWRBcnJheS5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlSXNFcXVhbC5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2NyZWF0ZU9iamVjdE1hcHBlci5qc1wiOntcImluZGV4XCI6MTAyLFwiaGFzaFwiOlwiY3A4cytaNmtoaUtkSzVRQ1ErTXNcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL29iamVjdC9tYXBWYWx1ZXMuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlQ2FsbGJhY2suanNcIjp7XCJpbmRleFwiOjc4LFwiaGFzaFwiOlwiRkRFbXhvaDFjWFkvaGRkZ1BOR1dcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2NyZWF0ZU9iamVjdE1hcHBlci5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9jb2xsZWN0aW9uL21hcC5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9jb2xsZWN0aW9uL3NvbWUuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvY29sbGVjdGlvbi9maWx0ZXIuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlRm9yT3duLmpzXCI6e1wiaW5kZXhcIjo4MyxcImhhc2hcIjpcInNPTG1ISDJPb3NtZVc5MllhTEsvXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVPYmplY3RNYXBwZXIuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUVhY2guanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L2Zvck93bi5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL29iamVjdC9tYXBWYWx1ZXMuanNcIjp7XCJpbmRleFwiOjEyOSxcImhhc2hcIjpcIjJIZkFtVnVhVkdmYzhwZDV6SWFDXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktaG1yL2luYy9pbmRleC5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL3V0aWxpdHkvaWRlbnRpdHkuanNcIjp7XCJpbmRleFwiOjEzMSxcImhhc2hcIjpcIkEvY3o1TzRubmhvMngyZTVLSVdTXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iaW5kQ2FsbGJhY2suanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUNhbGxiYWNrLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUZpbHRlci5qc1wiOntcImluZGV4XCI6ODEsXCJoYXNoXCI6XCJ5eXZRYWc0aHc4c0l0QkZmMy85VFwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvY29sbGVjdGlvbi9maWx0ZXIuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlRWFjaC5qc1wiOntcImluZGV4XCI6ODAsXCJoYXNoXCI6XCJKaTdOTENKaGR6U0JscERJK3FDM1wiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUZpbHRlci5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlU29tZS5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlTWFwLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2NvbGxlY3Rpb24vZm9yRWFjaC5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VTb21lLmpzXCI6e1wiaW5kZXhcIjo5NCxcImhhc2hcIjpcImxDVzVBdEhuOVgydlN1UGdTOHBrXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9jb2xsZWN0aW9uL3NvbWUuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9pc0luZGV4LmpzXCI6e1wiaW5kZXhcIjoxMTAsXCJoYXNoXCI6XCJJOHk1QXNqTC9sd0RsT1JET3FxTVwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvaXNJdGVyYXRlZUNhbGwuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L2tleXNJbi5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9zaGltS2V5cy5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2xhbmcvaXNPYmplY3QuanNcIjp7XCJpbmRleFwiOjEyMyxcImhhc2hcIjpcIkdvK2RUTEZxTzFLSk4rdVFMYjhzXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC90b09iamVjdC5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9pc1N0cmljdENvbXBhcmFibGUuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvaXNJdGVyYXRlZUNhbGwuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvbGFuZy9pc0Z1bmN0aW9uLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL29iamVjdC9rZXlzSW4uanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L2tleXMuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUlzRXF1YWwuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoLmpzXCI6e1wiaW5kZXhcIjoxMDAsXCJoYXNoXCI6XCJpSnRXQkN6eCtienpTTHdsYWFSdlwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvY29sbGVjdGlvbi9mb3JFYWNoLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvbGFuZy9pc0FycmF5LmpzXCI6e1wiaW5kZXhcIjoxMjAsXCJoYXNoXCI6XCJycE1pRTFaMTk5L1haQ2pubzRLTlwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvY3JlYXRlRm9yRWFjaC5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9jb2xsZWN0aW9uL21hcC5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9pc0tleS5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC90b1BhdGguanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvY29sbGVjdGlvbi9zb21lLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2FycmF5L3ppcE9iamVjdC5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9vYmplY3Qva2V5c0luLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL3NoaW1LZXlzLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VJc0VxdWFsRGVlcC5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlTWF0Y2hlc1Byb3BlcnR5LmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2NvbGxlY3Rpb24vZmlsdGVyLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmluZENhbGxiYWNrLmpzXCI6e1wiaW5kZXhcIjo5NixcImhhc2hcIjpcIlM2aXkxSSs1M0lFekRMU0d1VzBqXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVGb3JFYWNoLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2NyZWF0ZUZvck93bi5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVBc3NpZ25lci5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlQ2FsbGJhY2suanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVGb3JPd24uanNcIjp7XCJpbmRleFwiOjEwMSxcImhhc2hcIjpcIktKcWlqanZKTzdkMW5VMTdTejNjXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9vYmplY3QvZm9yT3duLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvZnVuY3Rpb24vcmVzdFBhcmFtLmpzXCI6e1wiaW5kZXhcIjo3MSxcImhhc2hcIjpcIi9SUkg5TUN0akFycjFwM1FlaDYzXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVBc3NpZ25lci5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2NyZWF0ZUFzc2lnbmVyLmpzXCI6e1wiaW5kZXhcIjo5NyxcImhhc2hcIjpcIlg4UjgxanZSQ29mWTFCbkcrQS9MXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9vYmplY3QvYXNzaWduLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvaXNJdGVyYXRlZUNhbGwuanNcIjp7XCJpbmRleFwiOjExMSxcImhhc2hcIjpcImRYTW5OUmV2QWl6T0Jpc0tDRWVzXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVBc3NpZ25lci5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9jb2xsZWN0aW9uL3NvbWUuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9hc3NpZ25XaXRoLmpzXCI6e1wiaW5kZXhcIjo3NixcImhhc2hcIjpcImFLQkt5ZklLcVpzTk9IQWJKVEFJXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9vYmplY3QvYXNzaWduLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L2tleXMuanNcIjp7XCJpbmRleFwiOjEyNyxcImhhc2hcIjpcIkJiWEdOSWNmYXRTcDMydVdPQkFWXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9hc3NpZ25XaXRoLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VBc3NpZ24uanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L3BhaXJzLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VGb3JPd24uanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvZXF1YWxPYmplY3RzLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUNvcHkuanNcIjp7XCJpbmRleFwiOjc5LFwiaGFzaFwiOlwiV3ZHaThJeXdNNnU3Wk5Ydnp0d2dcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VBc3NpZ24uanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlQXNzaWduLmpzXCI6e1wiaW5kZXhcIjo3NyxcImhhc2hcIjpcIjZWWDg3WW9lTmdEdk1VeWlBYy83XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9vYmplY3QvYXNzaWduLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L2Fzc2lnbi5qc1wiOntcImluZGV4XCI6MTI1LFwiaGFzaFwiOlwiOVdPaEpCUkVsOEFPOUhzNkNyK1FcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1obXIvaW5jL2luZGV4LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZU1hcC5qc1wiOntcImluZGV4XCI6ODgsXCJoYXNoXCI6XCJvZnYyakNFNVFsYWhweW5HNHJrTlwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvY29sbGVjdGlvbi9tYXAuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9pc0FycmF5TGlrZS5qc1wiOntcImluZGV4XCI6MTA5LFwiaGFzaFwiOlwiNzZBd3RoejhDaFRnakdrMEpaNllcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VNYXAuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvaXNJdGVyYXRlZUNhbGwuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvbGFuZy9pc0FyZ3VtZW50cy5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9vYmplY3Qva2V5cy5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2NvbGxlY3Rpb24vbWFwLmpzXCI6e1wiaW5kZXhcIjo2OSxcImhhc2hcIjpcIjYzbjV4OEdUaVdQdXhpWnptOVRNXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktaG1yL2luYy9pbmRleC5qc1wiXX0sXCJzcmMvY291bnRyaWVzL3NpbXBsZUNvdW50cmllcy5qc1wiOntcImluZGV4XCI6MTU5LFwiaGFzaFwiOlwiaExZV2tDWlI1V0d6VEJDTTdTaTRcIixcInBhcmVudHNcIjpbXCJzcmMvY29tcG9uZW50cy9KdW1ib3Ryb24udnVlXCJdfSxcInNyYy9jb3VudHJpZXMvY291bnRyaWVzLmpzXCI6e1wiaW5kZXhcIjoxNTgsXCJoYXNoXCI6XCJYOHVZNDhaQ2U5cThzcERPaVpnaVwiLFwicGFyZW50c1wiOltcInNyYy9jb21wb25lbnRzL0p1bWJvdHJvbi52dWVcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlUHJvcGVydHkuanNcIjp7XCJpbmRleFwiOjkxLFwiaGFzaFwiOlwiWXVrMnRwb2YyMXEwWGwyc1FnODlcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL3V0aWxpdHkvcHJvcGVydHkuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvZ2V0TGVuZ3RoLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZVNsaWNlLmpzXCI6e1wiaW5kZXhcIjo5MyxcImhhc2hcIjpcIk9MZ3c5WFZpYzFXMEFLamVoekhCXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlTWF0Y2hlc1Byb3BlcnR5LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvYXJyYXkvbGFzdC5qc1wiOntcImluZGV4XCI6NjUsXCJoYXNoXCI6XCIzb1hYYTJpZFdiS3lTVkxjcTNvc1wiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZU1hdGNoZXNQcm9wZXJ0eS5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2NyZWF0ZUJhc2VFYWNoLmpzXCI6e1wiaW5kZXhcIjo5OCxcImhhc2hcIjpcIis1WDNadG03OE5OUHI5dlFaN2ZCXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlRWFjaC5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2dldExlbmd0aC5qc1wiOntcImluZGV4XCI6MTA2LFwiaGFzaFwiOlwiVWlaNkYwK25YWjBmaUtja1Rxbk1cIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2NyZWF0ZUJhc2VFYWNoLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2lzQXJyYXlMaWtlLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvdG9PYmplY3QuanNcIjp7XCJpbmRleFwiOjExNyxcImhhc2hcIjpcIjhmM2V1bEI5N0RkZEJSZGNVKzd2XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9jcmVhdGVCYXNlRWFjaC5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9pc0tleS5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlSXNNYXRjaC5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlR2V0LmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2NyZWF0ZUJhc2VGb3IuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L3BhaXJzLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VNYXRjaGVzLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VNYXRjaGVzUHJvcGVydHkuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9jb2xsZWN0aW9uL2ZvckVhY2guanNcIjp7XCJpbmRleFwiOjY4LFwiaGFzaFwiOlwiMExvMVJOdDE4UE1vL0hBS2JIRXVcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1obXIvaW5jL2luZGV4LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tcGFyc2VyL2xpYi9rZXlzLmpzXCI6e1wiaW5kZXhcIjo1OSxcImhhc2hcIjpcIm9GeUtOVEEwdHdseVFWaFZ6cDluXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbGliL2Jyb3dzZXIuanNcIl19LFwibm9kZV9tb2R1bGVzL2FycmF5YnVmZmVyLnNsaWNlL2luZGV4LmpzXCI6e1wiaW5kZXhcIjozLFwiaGFzaFwiOlwiUlNiNVp4OUNnWDNhZGp6YnZmL2tcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIvYnJvd3Nlci5qc1wiXX0sXCJub2RlX21vZHVsZXMvYmxvYi9pbmRleC5qc1wiOntcImluZGV4XCI6OCxcImhhc2hcIjpcIm9Kd2dGQ1ByN0F1Nk9ISm5tMG5yXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbGliL2Jyb3dzZXIuanNcIl19LFwibm9kZV9tb2R1bGVzL3V0ZjgvdXRmOC5qc1wiOntcImluZGV4XCI6MTQ5LFwiaGFzaFwiOlwiSGJjMFVIM3JFcWpwNzJtZnpuTnJcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIvYnJvd3Nlci5qc1wiXX0sXCJub2RlX21vZHVsZXMvYWZ0ZXIvaW5kZXguanNcIjp7XCJpbmRleFwiOjIsXCJoYXNoXCI6XCJOelBmWFdFQ21NOHJXLzZmZGtjalwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tcGFyc2VyL2xpYi9icm93c2VyLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9iYXNlNjQtYXJyYXlidWZmZXIvbGliL2Jhc2U2NC1hcnJheWJ1ZmZlci5qc1wiOntcImluZGV4XCI6NyxcImhhc2hcIjpcImRXNmNua3RqQkl5WjZidjl2UnAyXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbGliL2Jyb3dzZXIuanNcIl19LFwibm9kZV9tb2R1bGVzL3BhcnNlcXMvaW5kZXguanNcIjp7XCJpbmRleFwiOjEzNSxcImhhc2hcIjpcIkZJNHRSRUx3STVJdHorY2t3UittXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvd2Vic29ja2V0LmpzXCIsXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLmpzXCIsXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvc29ja2V0LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9wYXJzZWpzb24vaW5kZXguanNcIjp7XCJpbmRleFwiOjEzNCxcImhhc2hcIjpcInQ5MjU1NUtmbzNrdmJLemR0VS9QXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3NvY2tldC5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2lzS2V5LmpzXCI6e1wiaW5kZXhcIjoxMTIsXCJoYXNoXCI6XCJsRHB3NWNyY1JtVFJFeFRMVlRLY1wiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvdXRpbGl0eS9wcm9wZXJ0eS5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlTWF0Y2hlc1Byb3BlcnR5LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZVByb3BlcnR5RGVlcC5qc1wiOntcImluZGV4XCI6OTIsXCJoYXNoXCI6XCJtcVgxT3lZZG5kSjE4M2x5bC9zblwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvdXRpbGl0eS9wcm9wZXJ0eS5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VHZXQuanNcIjp7XCJpbmRleFwiOjg0LFwiaGFzaFwiOlwiSDlFaU1kM3VsbFFwUmt2b29MZ3pcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VQcm9wZXJ0eURlZXAuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZU1hdGNoZXNQcm9wZXJ0eS5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL3RvUGF0aC5qc1wiOntcImluZGV4XCI6MTE4LFwiaGFzaFwiOlwiZmFWUXZzYitMU0xJNHVhTWd0clFcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VQcm9wZXJ0eURlZXAuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZU1hdGNoZXNQcm9wZXJ0eS5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL3V0aWxpdHkvcHJvcGVydHkuanNcIjp7XCJpbmRleFwiOjEzMixcImhhc2hcIjpcIjdJb09JL3VHWkN4YmNZMjN1UURLXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlQ2FsbGJhY2suanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlSXNNYXRjaC5qc1wiOntcImluZGV4XCI6ODcsXCJoYXNoXCI6XCJFcHVKemxnMjA0YVIzNVQ0UUtjU1wiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZU1hdGNoZXMuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlSXNFcXVhbC5qc1wiOntcImluZGV4XCI6ODUsXCJoYXNoXCI6XCJkQmdvRlhuaGo5S0g2b1gzZFF3YVwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUlzTWF0Y2guanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZU1hdGNoZXNQcm9wZXJ0eS5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2lzU3RyaWN0Q29tcGFyYWJsZS5qc1wiOntcImluZGV4XCI6MTE1LFwiaGFzaFwiOlwib2ZOUDQvbkZyejVSa2Iza0dPaG5cIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2dldE1hdGNoRGF0YS5qc1wiLFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlTWF0Y2hlc1Byb3BlcnR5LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZVRvU3RyaW5nLmpzXCI6e1wiaW5kZXhcIjo5NSxcImhhc2hcIjpcIkFCRlFGZjE0cFJFQ2kzc3c4b0tWXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC90b1BhdGguanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9jb2xsZWN0aW9uL3NvbWUuanNcIjp7XCJpbmRleFwiOjcwLFwiaGFzaFwiOlwiOUp5SkZmZEN4NTZwbVI2ZndNOXFcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1obXIvaW5jL2luZGV4LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvY3JlYXRlQmFzZUZvci5qc1wiOntcImluZGV4XCI6OTksXCJoYXNoXCI6XCI5UldsRmFCT3VlbHZ3Z2toWWdQR1wiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUZvci5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VGb3IuanNcIjp7XCJpbmRleFwiOjgyLFwiaGFzaFwiOlwiTkd4Y1owbjAxK3cyRzFQenlCbFlcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VGb3JPd24uanNcIl19LFwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbm9kZV9tb2R1bGVzL2hhcy1iaW5hcnkvaW5kZXguanNcIjp7XCJpbmRleFwiOjYwLFwiaGFzaFwiOlwiYVdjY2laZ3ZFUDR0ZHhZRTJMZmRcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIvYnJvd3Nlci5qc1wiXX0sXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9saWIvYnJvd3Nlci5qc1wiOntcImluZGV4XCI6NTgsXCJoYXNoXCI6XCJYM1EzbTJDL3pKYkpxemVwWUNqeVwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnQuanNcIixcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3dlYnNvY2tldC5qc1wiLFwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvcG9sbGluZy5qc1wiLFwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3NvY2tldC5qc1wiLFwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL2luZGV4LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnQuanNcIjp7XCJpbmRleFwiOjUxLFwiaGFzaFwiOlwicUFTMWpDOGdWVEc0eWIvQWFub0JcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy93ZWJzb2NrZXQuanNcIixcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3BvbGxpbmcuanNcIixcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi9zb2NrZXQuanNcIl19LFwibm9kZV9tb2R1bGVzL2Jyb3dzZXItcmVzb2x2ZS9lbXB0eS5qc1wiOntcImluZGV4XCI6OSxcImhhc2hcIjpcIjQ3REVRcGo4SEJTYSsvVEltVys1XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvd2Vic29ja2V0LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvbGFuZy9pc0Z1bmN0aW9uLmpzXCI6e1wiaW5kZXhcIjoxMjEsXCJoYXNoXCI6XCJ4a2Z6clpOWlBHR09JZjBrRThZOVwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvbGFuZy9pc05hdGl2ZS5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2xhbmcvaXNOYXRpdmUuanNcIjp7XCJpbmRleFwiOjEyMixcImhhc2hcIjpcIjJyc3RhQUx5MURXMEpTRGRpanBzXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9nZXROYXRpdmUuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9nZXROYXRpdmUuanNcIjp7XCJpbmRleFwiOjEwOCxcImhhc2hcIjpcIjdHUlo3MTE1QlN1b2MvMWJkYUJLXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9sYW5nL2lzQXJyYXkuanNcIixcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L2tleXMuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9hcnJheS96aXBPYmplY3QuanNcIjp7XCJpbmRleFwiOjY2LFwiaGFzaFwiOlwiZktmU3dJelBvNVNVeDlkMERrZ05cIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS1obXIvaW5jL2luZGV4LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L3BhaXJzLmpzXCI6e1wiaW5kZXhcIjoxMzAsXCJoYXNoXCI6XCJ4Nklsd3g4ZW5jdmcvQlc1QVBJMlwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvZ2V0TWF0Y2hEYXRhLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvZ2V0TWF0Y2hEYXRhLmpzXCI6e1wiaW5kZXhcIjoxMDcsXCJoYXNoXCI6XCJuMFBIV2hOczZZWitEemdZTUhQeFwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZU1hdGNoZXMuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlTWF0Y2hlcy5qc1wiOntcImluZGV4XCI6ODksXCJoYXNoXCI6XCJDd2o1R1NpUXY5L0U4blNGQm9YMlwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUNhbGxiYWNrLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvZXF1YWxCeVRhZy5qc1wiOntcImluZGV4XCI6MTA0LFwiaGFzaFwiOlwiK3krK2dlc0pwUHZ5TSsyRThhTkJcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VJc0VxdWFsRGVlcC5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2xhbmcvaXNBcmd1bWVudHMuanNcIjp7XCJpbmRleFwiOjExOSxcImhhc2hcIjpcInhRNG1xYnNLUU1DbXRzUGJmUWM2XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9vYmplY3Qva2V5c0luLmpzXCIsXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL3NoaW1LZXlzLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvb2JqZWN0L2tleXNJbi5qc1wiOntcImluZGV4XCI6MTI4LFwiaGFzaFwiOlwiOFBPWmlHUjFmUkhzbzU3OUc0NlpcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL3NoaW1LZXlzLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvc2hpbUtleXMuanNcIjp7XCJpbmRleFwiOjExNixcImhhc2hcIjpcIm9PNGFLb3BteFJmUHh5S2dSWDlGXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9vYmplY3Qva2V5cy5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL29iamVjdC9mb3JPd24uanNcIjp7XCJpbmRleFwiOjEyNixcImhhc2hcIjpcIkxaNzdQenVKVy93bGdWUGR2bEdjXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktaG1yL2luYy9pbmRleC5qc1wiXX0sXCJub2RlX21vZHVsZXMvaGFzLWNvcnMvaW5kZXguanNcIjp7XCJpbmRleFwiOjYyLFwiaGFzaFwiOlwiSHdUYjRVRi9TMDg5WllBOGhyUmxcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIveG1saHR0cHJlcXVlc3QuanNcIl19LFwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3htbGh0dHByZXF1ZXN0LmpzXCI6e1wiaW5kZXhcIjo1NyxcImhhc2hcIjpcInVzMEZzTjVzN2hpVDNocVZWNWx4XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvcG9sbGluZy5qc1wiLFwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvcG9sbGluZy14aHIuanNcIixcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL2luZGV4LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy95ZWFzdC9pbmRleC5qc1wiOntcImluZGV4XCI6MTU0LFwiaGFzaFwiOlwiWk0zKzV3NGwvRDJmNng3c3Z5U0ZcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy93ZWJzb2NrZXQuanNcIixcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3BvbGxpbmcuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvbXBvbmVudC1pbmhlcml0L2luZGV4LmpzXCI6e1wiaW5kZXhcIjoxNSxcImhhc2hcIjpcIlQwRnFjaDRkNGFrdmxyOGJoN2xjXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvd2Vic29ja2V0LmpzXCIsXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLWpzb25wLmpzXCIsXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLmpzXCIsXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLXhoci5qc1wiXX0sXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy93ZWJzb2NrZXQuanNcIjp7XCJpbmRleFwiOjU2LFwiaGFzaFwiOlwiWlJTVVgxaUFVVTVrTUM5b045aGNcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9pbmRleC5qc1wiXX0sXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLWpzb25wLmpzXCI6e1wiaW5kZXhcIjo1MyxcImhhc2hcIjpcImN3MGowbjlKaVpBRy9BbDM0Z0JrXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvaW5kZXguanNcIl19LFwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvcG9sbGluZy5qc1wiOntcImluZGV4XCI6NTUsXCJoYXNoXCI6XCJ2ZGdTdEpQSnpaclhUUWVzcU44elwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3BvbGxpbmctanNvbnAuanNcIixcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3BvbGxpbmcteGhyLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvZXF1YWxBcnJheXMuanNcIjp7XCJpbmRleFwiOjEwMyxcImhhc2hcIjpcIk9CSkw2dnVhT290dTVmbFVlQ252XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlSXNFcXVhbERlZXAuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9lcXVhbE9iamVjdHMuanNcIjp7XCJpbmRleFwiOjEwNSxcImhhc2hcIjpcIjQ0SXk0OWtEY2FBWnN5a0VkYUgzXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlSXNFcXVhbERlZXAuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9sYW5nL2lzVHlwZWRBcnJheS5qc1wiOntcImluZGV4XCI6MTI0LFwiaGFzaFwiOlwiYVZlWnlJRkdhZHJFaDdFc2FEUnVcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VJc0VxdWFsRGVlcC5qc1wiXX0sXCJub2RlX21vZHVsZXMvbG9kYXNoL2ludGVybmFsL2Jhc2VJc0VxdWFsRGVlcC5qc1wiOntcImluZGV4XCI6ODYsXCJoYXNoXCI6XCJsdFpaYU1IbXpwNmQ5akJsdFYzWVwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaW50ZXJuYWwvYmFzZUlzRXF1YWwuanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlTWF0Y2hlc1Byb3BlcnR5LmpzXCI6e1wiaW5kZXhcIjo5MCxcImhhc2hcIjpcIk91ZG5Tb2VxMkE0cWw1bGc1MWtjXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2xvZGFzaC9pbnRlcm5hbC9iYXNlQ2FsbGJhY2suanNcIl19LFwibm9kZV9tb2R1bGVzL2xvZGFzaC9jb2xsZWN0aW9uL2ZpbHRlci5qc1wiOntcImluZGV4XCI6NjcsXCJoYXNoXCI6XCJYdFU1empDcVNEbFljd09MVUMxM1wiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWhtci9pbmMvaW5kZXguanNcIl19LFwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnktaG1yL2luYy9pbmRleC5qc1wiOntcImluZGV4XCI6MTAsXCJoYXNoXCI6XCJhenlHbkV4WDJ1VmxQSTdvTTkyYlwiLFwicGFyZW50c1wiOltdfSxcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmNvcmUuanNcIjp7XCJpbmRleFwiOjIwLFwiaGFzaFwiOlwiak82ejVQVno4ZjZhVFVqbTVIcnhcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5leHBvcnQuanNcIixcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvZm4vc3ltYm9sL2luZGV4LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZy5qc1wiOntcImluZGV4XCI6NDQsXCJoYXNoXCI6XCI0N0RFUXBqOEhCU2ErL1RJbVcrNVwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvZm4vc3ltYm9sL2luZGV4LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3BvbGxpbmcteGhyLmpzXCI6e1wiaW5kZXhcIjo1NCxcImhhc2hcIjpcImlkZy9ENUJPbHNLQjYrMlY2cFBlXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvaW5kZXguanNcIl19LFwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvaW5kZXguanNcIjp7XCJpbmRleFwiOjUyLFwiaGFzaFwiOlwiVDJEaVAwUlkrdE02eitPUU5GNzVcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvc29ja2V0LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi9zb2NrZXQuanNcIjp7XCJpbmRleFwiOjUwLFwiaGFzaFwiOlwiWFNHbEV3bmZKK1lHcVJJMDMzK2RcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvaW5kZXguanNcIl19LFwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL2luZGV4LmpzXCI6e1wiaW5kZXhcIjo0OSxcImhhc2hcIjpcIkc2UVl1U051MEVjUytHNXRSOU5FXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvaW5kZXguanNcIl19LFwibm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvaW5kZXguanNcIjp7XCJpbmRleFwiOjQ4LFwiaGFzaFwiOlwiSFFhdTRNa0Q0bEF5bkI5dHQwV2xcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvbWFuYWdlci5qc1wiXX0sXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvbWFuYWdlci5qc1wiOntcImluZGV4XCI6MTM5LFwiaGFzaFwiOlwieWNhemZ5ejBMUUdQdGQvUDFJaDlcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvaW5kZXguanNcIl19LFwibm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL2luZGV4LmpzXCI6e1wiaW5kZXhcIjoxMzgsXCJoYXNoXCI6XCI2TzIxWi9TSlRvTG9BeWZWa1MxK1wiLFwicGFyZW50c1wiOltdfSxcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmhhcy5qc1wiOntcImluZGV4XCI6MjksXCJoYXNoXCI6XCJ5NGlkaUgyU2ovcm1acWQzOUNISFwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnNldC10by1zdHJpbmctdGFnLmpzXCIsXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM2LnN5bWJvbC5qc1wiXX0sXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5qc1wiOntcImluZGV4XCI6MzQsXCJoYXNoXCI6XCJVSTF5bVJndXJVMDdzb1JwaW9ielwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnNldC10by1zdHJpbmctdGFnLmpzXCIsXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5rZXlvZi5qc1wiLFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuZW51bS1rZXlzLmpzXCIsXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5nZXQtbmFtZXMuanNcIixcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmhpZGUuanNcIixcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYuc3ltYm9sLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmZhaWxzLmpzXCI6e1wiaW5kZXhcIjoyNixcImhhc2hcIjpcIjZHNCtZWGFSZ2hUR1FRbmttL3FwXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuZGVzY3JpcHRvcnMuanNcIixcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYuc3ltYm9sLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmdsb2JhbC5qc1wiOntcImluZGV4XCI6MjgsXCJoYXNoXCI6XCJ0N1FLa3llVkVVK2dHU3kvbDVDY1wiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnNoYXJlZC5qc1wiLFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQud2tzLmpzXCIsXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5leHBvcnQuanNcIixcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYuc3ltYm9sLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnVpZC5qc1wiOntcImluZGV4XCI6NDIsXCJoYXNoXCI6XCJhdXkwYTVLQnh1VTdRQWRKN3dlL1wiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLndrcy5qc1wiLFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zeW1ib2wuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQucHJvcGVydHktZGVzYy5qc1wiOntcImluZGV4XCI6MzcsXCJoYXNoXCI6XCJpU3M5anBBdzFKVDJaV1dMU2NTSFwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmhpZGUuanNcIixcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYuc3ltYm9sLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmxpYnJhcnkuanNcIjp7XCJpbmRleFwiOjM2LFwiaGFzaFwiOlwiQmhnbjVScE83cERjUW5TVmFJNUNcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM2LnN5bWJvbC5qc1wiXX0sXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5kZXNjcmlwdG9ycy5qc1wiOntcImluZGV4XCI6MjMsXCJoYXNoXCI6XCJOSnFuQU9WczU1YktlYStnS0lHdFwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmhpZGUuanNcIixcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYuc3ltYm9sLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnNoYXJlZC5qc1wiOntcImluZGV4XCI6NDAsXCJoYXNoXCI6XCJaSytUbjJMQU5iQjRPcWtzY00zTlwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLndrcy5qc1wiLFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zeW1ib2wuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuc2V0LXRvLXN0cmluZy10YWcuanNcIjp7XCJpbmRleFwiOjM5LFwiaGFzaFwiOlwiM0cwcGp6NDJlUGZMUCsrY2FFSDNcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM2LnN5bWJvbC5qc1wiXX0sXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC53a3MuanNcIjp7XCJpbmRleFwiOjQzLFwiaGFzaFwiOlwicU1saXN6ZmZYNmt5U0hwdEpUSXBcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5zZXQtdG8tc3RyaW5nLXRhZy5qc1wiLFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zeW1ib2wuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQua2V5b2YuanNcIjp7XCJpbmRleFwiOjM1LFwiaGFzaFwiOlwiUUFrRDg5WDNrL25FZDR2QW15Q3pcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvZXM2LnN5bWJvbC5qc1wiXX0sXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC50by1pb2JqZWN0LmpzXCI6e1wiaW5kZXhcIjo0MSxcImhhc2hcIjpcInlwNFVPdUNMUlZPMXRxbGdwcHc1XCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQua2V5b2YuanNcIixcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmdldC1uYW1lcy5qc1wiLFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zeW1ib2wuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuZW51bS1rZXlzLmpzXCI6e1wiaW5kZXhcIjoyNCxcImhhc2hcIjpcImQvSWIya2N2b2Z3djVNMzlPMTRZXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zeW1ib2wuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuZ2V0LW5hbWVzLmpzXCI6e1wiaW5kZXhcIjoyNyxcImhhc2hcIjpcIllIYXp4dmxsUzJVQkUrOFZVL3VIXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zeW1ib2wuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuaXMtb2JqZWN0LmpzXCI6e1wiaW5kZXhcIjozMyxcImhhc2hcIjpcIkZrYU9PTUltMHV3NFQvcVVFWGVkXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuYW4tb2JqZWN0LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmFuLW9iamVjdC5qc1wiOntcImluZGV4XCI6MTgsXCJoYXNoXCI6XCJkN3BDeW5YSmhLcEsydTFTMGZwaFwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy9lczYuc3ltYm9sLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmNvZi5qc1wiOntcImluZGV4XCI6MTksXCJoYXNoXCI6XCJGWTZ0ZzB5bWRDUy9yRXdwQWE3UlwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmlzLWFycmF5LmpzXCIsXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5pb2JqZWN0LmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmlzLWFycmF5LmpzXCI6e1wiaW5kZXhcIjozMixcImhhc2hcIjpcInhOOUZ3ZDZZakJVV21WekJ4Y1ZtXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zeW1ib2wuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuZGVmaW5lZC5qc1wiOntcImluZGV4XCI6MjIsXCJoYXNoXCI6XCJSWnI4dUZsK1dycmp2R3pQU3ozY1wiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnRvLWlvYmplY3QuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuaW9iamVjdC5qc1wiOntcImluZGV4XCI6MzEsXCJoYXNoXCI6XCJIdkVUcDVwMHpNQmpoK3d2anhTbVwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnRvLWlvYmplY3QuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuaGlkZS5qc1wiOntcImluZGV4XCI6MzAsXCJoYXNoXCI6XCIySEJ3dnhFdGJ0NFVwc2tPV3k2MlwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnJlZGVmaW5lLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLnJlZGVmaW5lLmpzXCI6e1wiaW5kZXhcIjozOCxcImhhc2hcIjpcInY0ejU5S2llNldQVk8xaCs4b0pQXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zeW1ib2wuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuYS1mdW5jdGlvbi5qc1wiOntcImluZGV4XCI6MTcsXCJoYXNoXCI6XCJ2STdOQlZOb0tpencvVDdhYmxZdFwiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9jb3JlLWpzL2xpYnJhcnkvbW9kdWxlcy8kLmN0eC5qc1wiXX0sXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5jdHguanNcIjp7XCJpbmRleFwiOjIxLFwiaGFzaFwiOlwiSUJBcW95c3hmNnVHZTRxSXNsRldcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L21vZHVsZXMvJC5leHBvcnQuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzLyQuZXhwb3J0LmpzXCI6e1wiaW5kZXhcIjoyNSxcImhhc2hcIjpcInRGNlR1d3FBM2ZMZGVGS3FTSTluXCIsXCJwYXJlbnRzXCI6W1wibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zeW1ib2wuanNcIl19LFwibm9kZV9tb2R1bGVzL2NvcmUtanMvbGlicmFyeS9tb2R1bGVzL2VzNi5zeW1ib2wuanNcIjp7XCJpbmRleFwiOjQ1LFwiaGFzaFwiOlwiUkIzVS8zWlN3Zld1Q3ZhYVcyQTRcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L2ZuL3N5bWJvbC9pbmRleC5qc1wiXX0sXCJub2RlX21vZHVsZXMvY29yZS1qcy9saWJyYXJ5L2ZuL3N5bWJvbC9pbmRleC5qc1wiOntcImluZGV4XCI6MTYsXCJoYXNoXCI6XCIyRW55dUpZOFQrWVNqTDdYUHlUc1wiLFwicGFyZW50c1wiOltcIm5vZGVfbW9kdWxlcy9iYWJlbC1ydW50aW1lL2NvcmUtanMvc3ltYm9sLmpzXCJdfSxcIm5vZGVfbW9kdWxlcy9iYWJlbC1ydW50aW1lL2NvcmUtanMvc3ltYm9sLmpzXCI6e1wiaW5kZXhcIjo0LFwiaGFzaFwiOlwiYWlXZVoybmRSTGkrVlNsOEErajZcIixcInBhcmVudHNcIjpbXCJub2RlX21vZHVsZXMvYmFiZWwtcnVudGltZS9oZWxwZXJzL3R5cGVvZi5qc1wiXX0sXCJub2RlX21vZHVsZXMvYmFiZWwtcnVudGltZS9oZWxwZXJzL3R5cGVvZi5qc1wiOntcImluZGV4XCI6NSxcImhhc2hcIjpcIkVtWE53bHlnYW41bXZzZFZwRXpJXCIsXCJwYXJlbnRzXCI6W1wic3JjL2NvbXBvbmVudHMvU2VsZWN0LnZ1ZVwiXX0sXCJzcmMvY29tcG9uZW50cy9TZWxlY3QudnVlXCI6e1wiaW5kZXhcIjoxNTcsXCJoYXNoXCI6XCJ3bGc4YW5Qem84Z3hETTZwMENzN1wiLFwicGFyZW50c1wiOltcInNyYy9jb21wb25lbnRzL0p1bWJvdHJvbi52dWVcIl19LFwic3JjL2NvbXBvbmVudHMvSnVtYm90cm9uLnZ1ZVwiOntcImluZGV4XCI6MTU2LFwiaGFzaFwiOlwiWFRmZnJGa1FDUnhYSWIwVkpXTG5cIixcInBhcmVudHNcIjpbXCJzcmMvQXBwLnZ1ZVwiXX0sXCJzcmMvQXBwLnZ1ZVwiOntcImluZGV4XCI6MTU1LFwiaGFzaFwiOlwiQ2FtU2dCeXNrZWR4ZHVNYm9sN3pcIixcInBhcmVudHNcIjpbXCJzcmMvbWFpbi5qc1wiXX0sXCJub2RlX21vZHVsZXMvdnVleC9kaXN0L3Z1ZXguanNcIjp7XCJpbmRleFwiOjE1MyxcImhhc2hcIjpcImdYLy9XNnlIcy9JRlkva2tNL2xJXCIsXCJwYXJlbnRzXCI6W1wic3JjL3Z1ZXgvc3RvcmUuanNcIl19LFwic3JjL3Z1ZXgvc3RvcmUuanNcIjp7XCJpbmRleFwiOjE2MSxcImhhc2hcIjpcImh3SGQ0QXh2TFlyMUMrTkJPZ2gvXCIsXCJwYXJlbnRzXCI6W1wic3JjL21haW4uanNcIl19LFwic3JjL21haW4uanNcIjp7XCJpbmRleFwiOjE2MCxcImhhc2hcIjpcInoyc2RZaUl0c2hCTlJXdnNVd0ZkXCIsXCJwYXJlbnRzXCI6W119fTtcbiAgdmFyIG9yaWdpbmFsRW50cmllcyA9IFtcIi9Wb2x1bWVzL0RvY3VtZW50cy9Ecm9wYm94L2h0ZG9jcy92dWUtc2VsZWN0L3NyYy9tYWluLmpzXCJdO1xuICB2YXIgdXBkYXRlVXJsID0gbnVsbDtcbiAgdmFyIHVwZGF0ZU1vZGUgPSBcIndlYnNvY2tldFwiO1xuICB2YXIgc3VwcG9ydE1vZGVzID0gW1wibm9uZVwiLFwid2Vic29ja2V0XCJdO1xuICB2YXIgaWdub3JlVW5hY2NlcHRlZCA9IHRydWU7XG4gIHZhciB1cGRhdGVDYWNoZUJ1c3QgPSBmYWxzZTtcbiAgdmFyIGJ1bmRsZUtleSA9IFwid2Vic29ja2V0Om51bGxcIjtcbiAgdmFyIHNpb1BhdGggPSBcIi4vbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL2luZGV4LmpzXCI7XG4gIHZhciBpbmNQYXRoID0gXCIuL25vZGVfbW9kdWxlcy9icm93c2VyaWZ5LWhtci9pbmMvaW5kZXguanNcIjtcblxuICBpZiAoIWdsb2JhbC5faG1yKSB7XG4gICAgdHJ5IHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWwsICdfaG1yJywge3ZhbHVlOiB7fX0pO1xuICAgIH0gY2F0Y2goZSkge1xuICAgICAgZ2xvYmFsLl9obXIgPSB7fTtcbiAgICB9XG4gIH1cblxuICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChnbG9iYWwuX2htciwgYnVuZGxlS2V5KSkge1xuICAgIC8vIFRlbXBvcmFyeSBoYWNrIHNvIHJlcXVpcmluZyBtb2R1bGVzIHdvcmtzIGJlZm9yZSB0aGUgX2htciB2YWx1ZXMgYXJlXG4gICAgLy8gY29ycmVjdGx5IGluaXRpYWxpemVkLlxuICAgIGdsb2JhbC5faG1yW2J1bmRsZUtleV0gPSB7aW5pdE1vZHVsZTogZnVuY3Rpb24oKXt9fTtcbiAgfVxuXG4gIHZhciBtYWluID0gcmVxdWlyZShpbmNQYXRoKTtcbiAgdmFyIGlzRmlyc3RSdW4gPSBtYWluKFxuICAgIG1vZHVsZURlZnMsIGNhY2hlZE1vZHVsZXMsIG1vZHVsZU1ldGEsIHVwZGF0ZVVybCxcbiAgICB1cGRhdGVNb2RlLCBzdXBwb3J0TW9kZXMsIGlnbm9yZVVuYWNjZXB0ZWQsIHVwZGF0ZUNhY2hlQnVzdCwgYnVuZGxlS2V5LFxuICAgIHNpb1BhdGggPyByZXF1aXJlKHNpb1BhdGgpIDogbnVsbCxcbiAgICB0eXBlb2YgX19maWxlbmFtZSAhPT0gJ3VuZGVmaW5lZCcgJiYgX19maWxlbmFtZSxcbiAgICB0eXBlb2YgX19kaXJuYW1lICE9PSAndW5kZWZpbmVkJyAmJiBfX2Rpcm5hbWVcbiAgKTtcbiAgaWYgKGlzRmlyc3RSdW4pIHtcbiAgICBmb3IgKHZhciBpPTAsIGxlbj1vcmlnaW5hbEVudHJpZXMubGVuZ3RoOyBpPGxlbjsgaSsrKSB7XG4gICAgICByZXF1aXJlKG9yaWdpbmFsRW50cmllc1tpXSk7XG4gICAgfVxuICB9XG59KS5jYWxsKFxuICB0aGlzLFxuICB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDogdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LFxuICBhcmd1bWVudHNbM10sIGFyZ3VtZW50c1s0XSwgYXJndW1lbnRzWzVdLCBhcmd1bWVudHNbNl1cbik7XG4iXX0=
|