openvidu-livekit-tutorials/openvidu-js/web/openvidu-browser-2.25.0.js
2022-12-22 15:39:44 +01:00

14120 lines
1.9 MiB

(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
var R = typeof Reflect === 'object' ? Reflect : null
var ReflectApply = R && typeof R.apply === 'function'
? R.apply
: function ReflectApply(target, receiver, args) {
return Function.prototype.apply.call(target, receiver, args);
}
var ReflectOwnKeys
if (R && typeof R.ownKeys === 'function') {
ReflectOwnKeys = R.ownKeys
} else if (Object.getOwnPropertySymbols) {
ReflectOwnKeys = function ReflectOwnKeys(target) {
return Object.getOwnPropertyNames(target)
.concat(Object.getOwnPropertySymbols(target));
};
} else {
ReflectOwnKeys = function ReflectOwnKeys(target) {
return Object.getOwnPropertyNames(target);
};
}
function ProcessEmitWarning(warning) {
if (console && console.warn) console.warn(warning);
}
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
return value !== value;
}
function EventEmitter() {
EventEmitter.init.call(this);
}
module.exports = EventEmitter;
module.exports.once = once;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._eventsCount = 0;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
var defaultMaxListeners = 10;
function checkListener(listener) {
if (typeof listener !== 'function') {
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
}
}
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
enumerable: true,
get: function() {
return defaultMaxListeners;
},
set: function(arg) {
if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
}
defaultMaxListeners = arg;
}
});
EventEmitter.init = function() {
if (this._events === undefined ||
this._events === Object.getPrototypeOf(this)._events) {
this._events = Object.create(null);
this._eventsCount = 0;
}
this._maxListeners = this._maxListeners || undefined;
};
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
}
this._maxListeners = n;
return this;
};
function _getMaxListeners(that) {
if (that._maxListeners === undefined)
return EventEmitter.defaultMaxListeners;
return that._maxListeners;
}
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
return _getMaxListeners(this);
};
EventEmitter.prototype.emit = function emit(type) {
var args = [];
for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
var doError = (type === 'error');
var events = this._events;
if (events !== undefined)
doError = (doError && events.error === undefined);
else if (!doError)
return false;
// If there is no 'error' event listener then throw.
if (doError) {
var er;
if (args.length > 0)
er = args[0];
if (er instanceof Error) {
// Note: The comments on the `throw` lines are intentional, they show
// up in Node's output if this results in an unhandled exception.
throw er; // Unhandled 'error' event
}
// At least give some kind of context to the user
var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
err.context = er;
throw err; // Unhandled 'error' event
}
var handler = events[type];
if (handler === undefined)
return false;
if (typeof handler === 'function') {
ReflectApply(handler, this, args);
} else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
ReflectApply(listeners[i], this, args);
}
return true;
};
function _addListener(target, type, listener, prepend) {
var m;
var events;
var existing;
checkListener(listener);
events = target._events;
if (events === undefined) {
events = target._events = Object.create(null);
target._eventsCount = 0;
} else {
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (events.newListener !== undefined) {
target.emit('newListener', type,
listener.listener ? listener.listener : listener);
// Re-assign `events` because a newListener handler could have caused the
// this._events to be assigned to a new object
events = target._events;
}
existing = events[type];
}
if (existing === undefined) {
// Optimize the case of one listener. Don't need the extra array object.
existing = events[type] = listener;
++target._eventsCount;
} else {
if (typeof existing === 'function') {
// Adding the second element, need to change to array.
existing = events[type] =
prepend ? [listener, existing] : [existing, listener];
// If we've already got an array, just append.
} else if (prepend) {
existing.unshift(listener);
} else {
existing.push(listener);
}
// Check for listener leak
m = _getMaxListeners(target);
if (m > 0 && existing.length > m && !existing.warned) {
existing.warned = true;
// No error code for this since it is a Warning
// eslint-disable-next-line no-restricted-syntax
var w = new Error('Possible EventEmitter memory leak detected. ' +
existing.length + ' ' + String(type) + ' listeners ' +
'added. Use emitter.setMaxListeners() to ' +
'increase limit');
w.name = 'MaxListenersExceededWarning';
w.emitter = target;
w.type = type;
w.count = existing.length;
ProcessEmitWarning(w);
}
}
return target;
}
EventEmitter.prototype.addListener = function addListener(type, listener) {
return _addListener(this, type, listener, false);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.prependListener =
function prependListener(type, listener) {
return _addListener(this, type, listener, true);
};
function onceWrapper() {
if (!this.fired) {
this.target.removeListener(this.type, this.wrapFn);
this.fired = true;
if (arguments.length === 0)
return this.listener.call(this.target);
return this.listener.apply(this.target, arguments);
}
}
function _onceWrap(target, type, listener) {
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
var wrapped = onceWrapper.bind(state);
wrapped.listener = listener;
state.wrapFn = wrapped;
return wrapped;
}
EventEmitter.prototype.once = function once(type, listener) {
checkListener(listener);
this.on(type, _onceWrap(this, type, listener));
return this;
};
EventEmitter.prototype.prependOnceListener =
function prependOnceListener(type, listener) {
checkListener(listener);
this.prependListener(type, _onceWrap(this, type, listener));
return this;
};
// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener =
function removeListener(type, listener) {
var list, events, position, i, originalListener;
checkListener(listener);
events = this._events;
if (events === undefined)
return this;
list = events[type];
if (list === undefined)
return this;
if (list === listener || list.listener === listener) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else {
delete events[type];
if (events.removeListener)
this.emit('removeListener', type, list.listener || listener);
}
} else if (typeof list !== 'function') {
position = -1;
for (i = list.length - 1; i >= 0; i--) {
if (list[i] === listener || list[i].listener === listener) {
originalListener = list[i].listener;
position = i;
break;
}
}
if (position < 0)
return this;
if (position === 0)
list.shift();
else {
spliceOne(list, position);
}
if (list.length === 1)
events[type] = list[0];
if (events.removeListener !== undefined)
this.emit('removeListener', type, originalListener || listener);
}
return this;
};
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.removeAllListeners =
function removeAllListeners(type) {
var listeners, events, i;
events = this._events;
if (events === undefined)
return this;
// not listening for removeListener, no need to emit
if (events.removeListener === undefined) {
if (arguments.length === 0) {
this._events = Object.create(null);
this._eventsCount = 0;
} else if (events[type] !== undefined) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else
delete events[type];
}
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
var keys = Object.keys(events);
var key;
for (i = 0; i < keys.length; ++i) {
key = keys[i];
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = Object.create(null);
this._eventsCount = 0;
return this;
}
listeners = events[type];
if (typeof listeners === 'function') {
this.removeListener(type, listeners);
} else if (listeners !== undefined) {
// LIFO order
for (i = listeners.length - 1; i >= 0; i--) {
this.removeListener(type, listeners[i]);
}
}
return this;
};
function _listeners(target, type, unwrap) {
var events = target._events;
if (events === undefined)
return [];
var evlistener = events[type];
if (evlistener === undefined)
return [];
if (typeof evlistener === 'function')
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
return unwrap ?
unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}
EventEmitter.prototype.listeners = function listeners(type) {
return _listeners(this, type, true);
};
EventEmitter.prototype.rawListeners = function rawListeners(type) {
return _listeners(this, type, false);
};
EventEmitter.listenerCount = function(emitter, type) {
if (typeof emitter.listenerCount === 'function') {
return emitter.listenerCount(type);
} else {
return listenerCount.call(emitter, type);
}
};
EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
var events = this._events;
if (events !== undefined) {
var evlistener = events[type];
if (typeof evlistener === 'function') {
return 1;
} else if (evlistener !== undefined) {
return evlistener.length;
}
}
return 0;
}
EventEmitter.prototype.eventNames = function eventNames() {
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
};
function arrayClone(arr, n) {
var copy = new Array(n);
for (var i = 0; i < n; ++i)
copy[i] = arr[i];
return copy;
}
function spliceOne(list, index) {
for (; index + 1 < list.length; index++)
list[index] = list[index + 1];
list.pop();
}
function unwrapListeners(arr) {
var ret = new Array(arr.length);
for (var i = 0; i < ret.length; ++i) {
ret[i] = arr[i].listener || arr[i];
}
return ret;
}
function once(emitter, name) {
return new Promise(function (resolve, reject) {
function errorListener(err) {
emitter.removeListener(name, resolver);
reject(err);
}
function resolver() {
if (typeof emitter.removeListener === 'function') {
emitter.removeListener('error', errorListener);
}
resolve([].slice.call(arguments));
};
eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
if (name !== 'error') {
addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
}
});
}
function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
if (typeof emitter.on === 'function') {
eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
}
}
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
if (typeof emitter.on === 'function') {
if (flags.once) {
emitter.once(name, listener);
} else {
emitter.on(name, listener);
}
} else if (typeof emitter.addEventListener === 'function') {
// EventTarget does not have `error` event semantics like Node
// EventEmitters, we do not listen for `error` events here.
emitter.addEventListener(name, function wrapListener(arg) {
// IE does not have builtin `{ once: true }` support so we
// have to do it manually.
if (flags.once) {
emitter.removeEventListener(name, wrapListener);
}
listener(arg);
});
} else {
throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
}
}
},{}],2:[function(require,module,exports){
/* jshint node: true */
'use strict';
var normalice = require('normalice');
/**
# freeice
The `freeice` module is a simple way of getting random STUN or TURN server
for your WebRTC application. The list of servers (just STUN at this stage)
were sourced from this [gist](https://gist.github.com/zziuni/3741933).
## Example Use
The following demonstrates how you can use `freeice` with
[rtc-quickconnect](https://github.com/rtc-io/rtc-quickconnect):
<<< examples/quickconnect.js
As the `freeice` module generates ice servers in a list compliant with the
WebRTC spec you will be able to use it with raw `RTCPeerConnection`
constructors and other WebRTC libraries.
## Hey, don't use my STUN/TURN server!
If for some reason your free STUN or TURN server ends up in the
list of servers ([stun](https://github.com/DamonOehlman/freeice/blob/master/stun.json) or
[turn](https://github.com/DamonOehlman/freeice/blob/master/turn.json))
that is used in this module, you can feel
free to open an issue on this repository and those servers will be removed
within 24 hours (or sooner). This is the quickest and probably the most
polite way to have something removed (and provides us some visibility
if someone opens a pull request requesting that a server is added).
## Please add my server!
If you have a server that you wish to add to the list, that's awesome! I'm
sure I speak on behalf of a whole pile of WebRTC developers who say thanks.
To get it into the list, feel free to either open a pull request or if you
find that process a bit daunting then just create an issue requesting
the addition of the server (make sure you provide all the details, and if
you have a Terms of Service then including that in the PR/issue would be
awesome).
## I know of a free server, can I add it?
Sure, if you do your homework and make sure it is ok to use (I'm currently
in the process of reviewing the terms of those STUN servers included from
the original list). If it's ok to go, then please see the previous entry
for how to add it.
## Current List of Servers
* current as at the time of last `README.md` file generation
### STUN
<<< stun.json
### TURN
<<< turn.json
**/
var freeice = function(opts) {
// if a list of servers has been provided, then use it instead of defaults
var servers = {
stun: (opts || {}).stun || require('./stun.json'),
turn: (opts || {}).turn || require('./turn.json')
};
var stunCount = (opts || {}).stunCount || 2;
var turnCount = (opts || {}).turnCount || 0;
var selected;
function getServers(type, count) {
var out = [];
var input = [].concat(servers[type]);
var idx;
while (input.length && out.length < count) {
idx = (Math.random() * input.length) | 0;
out = out.concat(input.splice(idx, 1));
}
return out.map(function(url) {
//If it's a not a string, don't try to "normalice" it otherwise using type:url will screw it up
if ((typeof url !== 'string') && (! (url instanceof String))) {
return url;
} else {
return normalice(type + ':' + url);
}
});
}
// add stun servers
selected = [].concat(getServers('stun', stunCount));
if (turnCount) {
selected = selected.concat(getServers('turn', turnCount));
}
return selected;
};
module.exports = freeice;
},{"./stun.json":3,"./turn.json":4,"normalice":11}],3:[function(require,module,exports){
module.exports=[
"stun.l.google.com:19302",
"stun1.l.google.com:19302",
"stun2.l.google.com:19302",
"stun3.l.google.com:19302",
"stun4.l.google.com:19302",
"stun.ekiga.net",
"stun.ideasip.com",
"stun.schlund.de",
"stun.stunprotocol.org:3478",
"stun.voiparound.com",
"stun.voipbuster.com",
"stun.voipstunt.com",
"stun.voxgratia.org"
]
},{}],4:[function(require,module,exports){
module.exports=[]
},{}],5:[function(require,module,exports){
var WildEmitter = require('wildemitter');
function getMaxVolume (analyser, fftBins) {
var maxVolume = -Infinity;
analyser.getFloatFrequencyData(fftBins);
for(var i=4, ii=fftBins.length; i < ii; i++) {
if (fftBins[i] > maxVolume && fftBins[i] < 0) {
maxVolume = fftBins[i];
}
};
return maxVolume;
}
var audioContextType;
if (typeof window !== 'undefined') {
audioContextType = window.AudioContext || window.webkitAudioContext;
}
// use a single audio context due to hardware limits
var audioContext = null;
module.exports = function(stream, options) {
var harker = new WildEmitter();
// make it not break in non-supported browsers
if (!audioContextType) return harker;
//Config
var options = options || {},
smoothing = (options.smoothing || 0.1),
interval = (options.interval || 50),
threshold = options.threshold,
play = options.play,
history = options.history || 10,
running = true;
// Ensure that just a single AudioContext is internally created
audioContext = options.audioContext || audioContext || new audioContextType();
var sourceNode, fftBins, analyser;
analyser = audioContext.createAnalyser();
analyser.fftSize = 512;
analyser.smoothingTimeConstant = smoothing;
fftBins = new Float32Array(analyser.frequencyBinCount);
if (stream.jquery) stream = stream[0];
if (stream instanceof HTMLAudioElement || stream instanceof HTMLVideoElement) {
//Audio Tag
sourceNode = audioContext.createMediaElementSource(stream);
if (typeof play === 'undefined') play = true;
threshold = threshold || -50;
} else {
//WebRTC Stream
sourceNode = audioContext.createMediaStreamSource(stream);
threshold = threshold || -50;
}
sourceNode.connect(analyser);
if (play) analyser.connect(audioContext.destination);
harker.speaking = false;
harker.suspend = function() {
return audioContext.suspend();
}
harker.resume = function() {
return audioContext.resume();
}
Object.defineProperty(harker, 'state', { get: function() {
return audioContext.state;
}});
audioContext.onstatechange = function() {
harker.emit('state_change', audioContext.state);
}
harker.setThreshold = function(t) {
threshold = t;
};
harker.setInterval = function(i) {
interval = i;
};
harker.stop = function() {
running = false;
harker.emit('volume_change', -100, threshold);
if (harker.speaking) {
harker.speaking = false;
harker.emit('stopped_speaking');
}
analyser.disconnect();
sourceNode.disconnect();
};
harker.speakingHistory = [];
for (var i = 0; i < history; i++) {
harker.speakingHistory.push(0);
}
// Poll the analyser node to determine if speaking
// and emit events if changed
var looper = function() {
setTimeout(function() {
//check if stop has been called
if(!running) {
return;
}
var currentVolume = getMaxVolume(analyser, fftBins);
harker.emit('volume_change', currentVolume, threshold);
var history = 0;
if (currentVolume > threshold && !harker.speaking) {
// trigger quickly, short history
for (var i = harker.speakingHistory.length - 3; i < harker.speakingHistory.length; i++) {
history += harker.speakingHistory[i];
}
if (history >= 2) {
harker.speaking = true;
harker.emit('speaking');
}
} else if (currentVolume < threshold && harker.speaking) {
for (var i = 0; i < harker.speakingHistory.length; i++) {
history += harker.speakingHistory[i];
}
if (history == 0) {
harker.speaking = false;
harker.emit('stopped_speaking');
}
}
harker.speakingHistory.shift();
harker.speakingHistory.push(0 + (currentVolume > threshold));
looper();
}, interval);
};
looper();
return harker;
}
},{"wildemitter":38}],6:[function(require,module,exports){
if (typeof Object.create === 'function') {
// implementation from standard node.js 'util' module
module.exports = function inherits(ctor, superCtor) {
if (superCtor) {
ctor.super_ = superCtor
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
})
}
};
} else {
// old school shim for old browsers
module.exports = function inherits(ctor, superCtor) {
if (superCtor) {
ctor.super_ = superCtor
var TempCtor = function () {}
TempCtor.prototype = superCtor.prototype
ctor.prototype = new TempCtor()
ctor.prototype.constructor = ctor
}
}
}
},{}],7:[function(require,module,exports){
/*
* JSNLog 2.30.0
* Open source under the MIT License.
* Copyright 2012-2017 Mattijs Perdeck All rights reserved.
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
function JL(loggerName) {
// If name is empty, return the root logger
if (!loggerName) {
return JL.__;
}
// Implements Array.reduce. JSNLog supports IE8+ and reduce is not supported in that browser.
// Same interface as the standard reduce, except that
if (!Array.prototype.reduce) {
Array.prototype.reduce = function (callback, initialValue) {
var previousValue = initialValue;
for (var i = 0; i < this.length; i++) {
previousValue = callback(previousValue, this[i], i, this);
}
return previousValue;
};
}
var accumulatedLoggerName = '';
var logger = ('.' + loggerName).split('.').reduce(function (prev, curr, idx, arr) {
// if loggername is a.b.c, than currentLogger will be set to the loggers
// root (prev: JL, curr: '')
// a (prev: JL.__, curr: 'a')
// a.b (prev: JL.__.__a, curr: 'b')
// a.b.c (prev: JL.__.__a.__a.b, curr: 'c')
// Note that when a new logger name is encountered (such as 'a.b.c'),
// a new logger object is created and added as a property to the parent ('a.b').
// The root logger is added as a property of the JL object itself.
// It is essential that the name of the property containing the child logger
// contains the full 'path' name of the child logger ('a.b.c') instead of
// just the bit after the last period ('c').
// This is because the parent inherits properties from its ancestors.
// So if the root has a child logger 'c' (stored in a property 'c' of the root logger),
// then logger 'a.b' has that same property 'c' through inheritance.
// The names of the logger properties start with __, so the root logger
// (which has name ''), has a nice property name '__'.
// accumulatedLoggerName evaluates false ('' is falsy) in first iteration when prev is the root logger.
// accumulatedLoggerName will be the logger name corresponding with the logger in currentLogger.
// Keep in mind that the currentLogger may not be defined yet, so can't get the name from
// the currentLogger object itself.
if (accumulatedLoggerName) {
accumulatedLoggerName += '.' + curr;
}
else {
accumulatedLoggerName = curr;
}
var currentLogger = prev['__' + accumulatedLoggerName];
// If the currentLogger (or the actual logger being sought) does not yet exist,
// create it now.
if (currentLogger === undefined) {
// Set the prototype of the Logger constructor function to the parent of the logger
// to be created. This way, __proto of the new logger object will point at the parent.
// When logger.level is evaluated and is not present, the JavaScript runtime will
// walk down the prototype chain to find the first ancestor with a level property.
//
// Note that prev at this point refers to the parent logger.
JL.Logger.prototype = prev;
currentLogger = new JL.Logger(accumulatedLoggerName);
prev['__' + accumulatedLoggerName] = currentLogger;
}
return currentLogger;
}, JL.__);
return logger;
}
(function (JL) {
// Initialise requestId to empty string. If you don't do this and the user
// does not set it via setOptions, then the JSNLog-RequestId header will
// have value "undefined", which doesn't look good in a log.
//
// Note that you always want to send a requestId as part of log requests,
// otherwise the server side component doesn't know this is a log request
// and may create a new request id for the log request, causing confusion
// in the log.
JL.requestId = '';
// Number uniquely identifying every log entry within the request.
JL.entryId = 0;
// Allow property injection of these classes, to enable unit testing
JL._createXMLHttpRequest = function () { return new XMLHttpRequest(); };
JL._getTime = function () { return (new Date).getTime(); };
JL._console = console;
// ----- private variables
JL._appenderNames = [];
/**
Copies the value of a property from one object to the other.
This is used to copy property values as part of setOption for loggers and appenders.
Because loggers inherit property values from their parents, it is important never to
create a property on a logger if the intent is to inherit from the parent.
Copying rules:
1) if the from property is undefined (for example, not mentioned in a JSON object), the
to property is not affected at all.
2) if the from property is null, the to property is deleted (so the logger will inherit from
its parent).
3) Otherwise, the from property is copied to the to property.
*/
function copyProperty(propertyName, from, to) {
if (from[propertyName] === undefined) {
return;
}
if (from[propertyName] === null) {
delete to[propertyName];
return;
}
to[propertyName] = from[propertyName];
}
/**
Returns true if a log should go ahead.
Does not check level.
@param filters
Filters that determine whether a log can go ahead.
*/
function allow(filters) {
// If enabled is not null or undefined, then if it is false, then return false
// Note that undefined==null (!)
if (!(JL.enabled == null)) {
if (!JL.enabled) {
return false;
}
}
// If the regex contains a bug, that will throw an exception.
// Ignore this, and pass the log item (better too much than too little).
try {
if (filters.userAgentRegex) {
if (!new RegExp(filters.userAgentRegex).test(navigator.userAgent)) {
return false;
}
}
}
catch (e) { }
try {
if (filters.ipRegex && JL.clientIP) {
if (!new RegExp(filters.ipRegex).test(JL.clientIP)) {
return false;
}
}
}
catch (e) { }
return true;
}
/**
Returns true if a log should go ahead, based on the message.
@param filters
Filters that determine whether a log can go ahead.
@param message
Message to be logged.
*/
function allowMessage(filters, message) {
// If the regex contains a bug, that will throw an exception.
// Ignore this, and pass the log item (better too much than too little).
try {
if (filters.disallow) {
if (new RegExp(filters.disallow).test(message)) {
return false;
}
}
}
catch (e) { }
return true;
}
// If logObject is a function, the function is evaluated (without parameters)
// and the result returned.
// Otherwise, logObject itself is returned.
function stringifyLogObjectFunction(logObject) {
if (typeof logObject == "function") {
if (logObject instanceof RegExp) {
return logObject.toString();
}
else {
return logObject();
}
}
return logObject;
}
var StringifiedLogObject = /** @class */ (function () {
// * msg -
// if the logObject is a scalar (after possible function evaluation), this is set to
// string representing the scalar. Otherwise it is left undefined.
// * meta -
// if the logObject is an object (after possible function evaluation), this is set to
// that object. Otherwise it is left undefined.
// * finalString -
// This is set to the string representation of logObject (after possible function evaluation),
// regardless of whether it is an scalar or an object. An object is stringified to a JSON string.
// Note that you can't call this field "final", because as some point this was a reserved
// JavaScript keyword and using final trips up some minifiers.
function StringifiedLogObject(msg, meta, finalString) {
this.msg = msg;
this.meta = meta;
this.finalString = finalString;
}
return StringifiedLogObject;
}());
// Takes a logObject, which can be
// * a scalar
// * an object
// * a parameterless function, which returns the scalar or object to log.
// Returns a stringifiedLogObject
function stringifyLogObject(logObject) {
// Note that this works if logObject is null.
// typeof null is object.
// JSON.stringify(null) returns "null".
var actualLogObject = stringifyLogObjectFunction(logObject);
var finalString;
// Note that typeof actualLogObject should not be "function", because that has
// been resolved with stringifyLogObjectFunction.
switch (typeof actualLogObject) {
case "string":
return new StringifiedLogObject(actualLogObject, null, actualLogObject);
case "number":
finalString = actualLogObject.toString();
return new StringifiedLogObject(finalString, null, finalString);
case "boolean":
finalString = actualLogObject.toString();
return new StringifiedLogObject(finalString, null, finalString);
case "undefined":
return new StringifiedLogObject("undefined", null, "undefined");
case "object":
if ((actualLogObject instanceof RegExp) ||
(actualLogObject instanceof String) ||
(actualLogObject instanceof Number) ||
(actualLogObject instanceof Boolean)) {
finalString = actualLogObject.toString();
return new StringifiedLogObject(finalString, null, finalString);
}
else {
if (typeof JL.serialize === 'function') {
finalString = JL.serialize.call(this, actualLogObject);
}
else {
finalString = JSON.stringify(actualLogObject);
}
// Set the msg field to "" instead of null. Some Winston transports
// assume that the msg field is not null.
return new StringifiedLogObject("", actualLogObject, finalString);
}
default:
return new StringifiedLogObject("unknown", null, "unknown");
}
}
function setOptions(options) {
copyProperty("enabled", options, this);
copyProperty("maxMessages", options, this);
copyProperty("defaultAjaxUrl", options, this);
copyProperty("clientIP", options, this);
copyProperty("requestId", options, this);
copyProperty("defaultBeforeSend", options, this);
copyProperty("serialize", options, this);
return this;
}
JL.setOptions = setOptions;
function getAllLevel() { return -2147483648; }
JL.getAllLevel = getAllLevel;
function getTraceLevel() { return 1000; }
JL.getTraceLevel = getTraceLevel;
function getDebugLevel() { return 2000; }
JL.getDebugLevel = getDebugLevel;
function getInfoLevel() { return 3000; }
JL.getInfoLevel = getInfoLevel;
function getWarnLevel() { return 4000; }
JL.getWarnLevel = getWarnLevel;
function getErrorLevel() { return 5000; }
JL.getErrorLevel = getErrorLevel;
function getFatalLevel() { return 6000; }
JL.getFatalLevel = getFatalLevel;
function getOffLevel() { return 2147483647; }
JL.getOffLevel = getOffLevel;
function levelToString(level) {
if (level <= 1000) {
return "trace";
}
if (level <= 2000) {
return "debug";
}
if (level <= 3000) {
return "info";
}
if (level <= 4000) {
return "warn";
}
if (level <= 5000) {
return "error";
}
return "fatal";
}
// ---------------------
var Exception = /** @class */ (function () {
// data replaces message. It takes not just strings, but also objects and functions, just like the log function.
// internally, the string representation is stored in the message property (inherited from Error)
//
// inner: inner exception. Can be null or undefined.
function Exception(data, inner) {
this.inner = inner;
this.name = "JL.Exception";
this.message = stringifyLogObject(data).finalString;
}
return Exception;
}());
JL.Exception = Exception;
// Derive Exception from Error (a Host object), so browsers
// are more likely to produce a stack trace for it in their console.
//
// Note that instanceof against an object created with this constructor
// will return true in these cases:
// <object> instanceof JL.Exception);
// <object> instanceof Error);
Exception.prototype = new Error();
// ---------------------
var LogItem = /** @class */ (function () {
// l: level
// m: message
// n: logger name
// t (timeStamp) is number of milliseconds since 1 January 1970 00:00:00 UTC
// u: number uniquely identifying this entry for this request.
//
// Keeping the property names really short, because they will be sent in the
// JSON payload to the server.
function LogItem(l, m, n, t, u) {
this.l = l;
this.m = m;
this.n = n;
this.t = t;
this.u = u;
}
return LogItem;
}());
JL.LogItem = LogItem;
function newLogItem(levelNbr, message, loggerName) {
JL.entryId++;
return new LogItem(levelNbr, message, loggerName, JL._getTime(), JL.entryId);
}
function clearTimer(timer) {
if (timer.id) {
clearTimeout(timer.id);
timer.id = null;
}
}
function setTimer(timer, timeoutMs, callback) {
var that = this;
if (!timer.id) {
timer.id = setTimeout(function () {
// use call to ensure that the this as used inside sendBatch when it runs is the
// same this at this point.
callback.call(that);
}, timeoutMs);
}
}
var Appender = /** @class */ (function () {
// sendLogItems takes an array of log items. It will be called when
// the appender has items to process (such as, send to the server).
// sendLogItems will call successCallback after the items have been successfully sent.
//
// Note that after sendLogItems returns, the appender may truncate
// the LogItem array, so the function has to copy the content of the array
// in some fashion (eg. serialize) before returning.
function Appender(appenderName, sendLogItems) {
this.appenderName = appenderName;
this.sendLogItems = sendLogItems;
this.level = JL.getTraceLevel();
// set to super high level, so if user increases level, level is unlikely to get
// above sendWithBufferLevel
this.sendWithBufferLevel = 2147483647;
this.storeInBufferLevel = -2147483648;
this.bufferSize = 0; // buffering switch off by default
this.batchSize = 1;
this.maxBatchSize = 20;
this.batchTimeout = 2147483647;
this.sendTimeout = 5000;
// Holds all log items with levels higher than storeInBufferLevel
// but lower than level. These items may never be sent.
this.buffer = [];
// Holds all items that we do want to send, until we have a full
// batch (as determined by batchSize).
this.batchBuffer = [];
// Holds the id of the timer implementing the batch timeout.
// Can be null.
// This is an object, so it can be passed to a method that updated the timer variable.
this.batchTimeoutTimer = { id: null };
// Holds the id of the timer implementing the send timeout.
// Can be null.
this.sendTimeoutTimer = { id: null };
// Number of log items that has been skipped due to batch buffer at max size,
// since appender creation or since creation of the last "skipped" warning log entry.
this.nbrLogItemsSkipped = 0;
// Will be 0 if no log request is outstanding at the moment.
// Otherwise the number of log items in the outstanding request.
this.nbrLogItemsBeingSent = 0;
var emptyNameErrorMessage = "Trying to create an appender without a name or with an empty name";
// This evaluates to true if appenderName is either null or undefined!
// Do not check here if the name is "", because that would stop you creating the
// default appender.
if (appenderName == undefined) {
throw emptyNameErrorMessage;
}
if (JL._appenderNames.indexOf(appenderName) != -1) {
// If user passed in "", that will now have been picked up as a duplicate
// because default appender also uses "".
if (!appenderName) {
throw emptyNameErrorMessage;
}
throw "Multiple appenders use the same name " + appenderName;
}
JL._appenderNames.push(appenderName);
}
Appender.prototype.addLogItemsToBuffer = function (logItems) {
// If the batch buffer has reached its maximum limit,
// skip the log item and increase the "skipped items" counter.
if (this.batchBuffer.length >= this.maxBatchSize) {
this.nbrLogItemsSkipped += logItems.length;
return;
}
// If maxMessages is not null or undefined, then decrease it by the batch size.
// This can result in a negative maxMessages.
// Note that undefined==null (!)
//
// Note that we may be sending more messages than the maxMessages limit allows,
// if we stored trace messages. Rationale is the buffer for trace messages is limited,
// and if we cut off at exactly maxMessages, we'd also loose the high severity message
// that caused the trace messages to be sent (unless we cater for this specifically, which
// is more complexity).
//
// If there are multiple appenders sending the same message, maxMessage will be decreased
// by each appender for the same message. This is:
// 1) only appenders know whether a message will actually be sent (based on storeInBufferLevel),
// so the loggers couldn't do this update;
// 2) if you have multiple appenders hitting the same server, this may be what you want.
//
// In most cases there is only 1 appender, so this then doesn't matter.
if (!(JL.maxMessages == null)) {
if (JL.maxMessages < 1) {
return;
}
JL.maxMessages -= logItems.length;
}
this.batchBuffer = this.batchBuffer.concat(logItems);
// If this is the first item in the buffer, set the timer
// to ensure it will be sent within the timeout period.
// If it is not the first item, leave the timer alone so to not to
// increase the timeout for the first item.
//
// To determine if this is the first item, look at the timer variable.
// Do not look at the buffer length, because we also put items in the buffer
// via a concat (bypassing this function).
//
// The setTimer method only sets the timer if it is not already running.
var that = this;
setTimer(this.batchTimeoutTimer, this.batchTimeout, function () {
that.sendBatch.call(that);
});
};
;
Appender.prototype.batchBufferHasOverdueMessages = function () {
for (var i = 0; i < this.batchBuffer.length; i++) {
var messageAgeMs = JL._getTime() - this.batchBuffer[i].t;
if (messageAgeMs > this.batchTimeout) {
return true;
}
}
return false;
};
// Returns true if no more message will ever be added to the batch buffer,
// but the batch buffer has messages now - so if there are not enough to make up a batch,
// and there is no batch timeout, then they will never be sent. This is especially important if
// maxMessages was reached while jsnlog.js was retrying sending messages to the server.
Appender.prototype.batchBufferHasStrandedMessage = function () {
return (!(JL.maxMessages == null)) && (JL.maxMessages < 1) && (this.batchBuffer.length > 0);
};
Appender.prototype.sendBatchIfComplete = function () {
if ((this.batchBuffer.length >= this.batchSize) ||
this.batchBufferHasOverdueMessages() ||
this.batchBufferHasStrandedMessage()) {
this.sendBatch();
}
};
Appender.prototype.onSendingEnded = function () {
clearTimer(this.sendTimeoutTimer);
this.nbrLogItemsBeingSent = 0;
this.sendBatchIfComplete();
};
Appender.prototype.setOptions = function (options) {
copyProperty("level", options, this);
copyProperty("ipRegex", options, this);
copyProperty("userAgentRegex", options, this);
copyProperty("disallow", options, this);
copyProperty("sendWithBufferLevel", options, this);
copyProperty("storeInBufferLevel", options, this);
copyProperty("bufferSize", options, this);
copyProperty("batchSize", options, this);
copyProperty("maxBatchSize", options, this);
copyProperty("batchTimeout", options, this);
copyProperty("sendTimeout", options, this);
if (this.bufferSize < this.buffer.length) {
this.buffer.length = this.bufferSize;
}
if (this.maxBatchSize < this.batchSize) {
throw new JL.Exception({
"message": "maxBatchSize cannot be smaller than batchSize",
"maxBatchSize": this.maxBatchSize,
"batchSize": this.batchSize
});
}
return this;
};
/**
Called by a logger to log a log item.
If in response to this call one or more log items need to be processed
(eg., sent to the server), this method calls this.sendLogItems
with an array with all items to be processed.
Note that the name and parameters of this function must match those of the log function of
a Winston transport object, so that users can use these transports as appenders.
That is why there are many parameters that are not actually used by this function.
level - string with the level ("trace", "debug", etc.) Only used by Winston transports.
msg - human readable message. Undefined if the log item is an object. Only used by Winston transports.
meta - log object. Always defined, because at least it contains the logger name. Only used by Winston transports.
callback - function that is called when the log item has been logged. Only used by Winston transports.
levelNbr - level as a number. Not used by Winston transports.
message - log item. If the user logged an object, this is the JSON string. Not used by Winston transports.
loggerName: name of the logger. Not used by Winston transports.
*/
Appender.prototype.log = function (level, msg, meta, callback, levelNbr, message, loggerName) {
var logItem;
if (!allow(this)) {
return;
}
if (!allowMessage(this, message)) {
return;
}
if (levelNbr < this.storeInBufferLevel) {
// Ignore the log item completely
return;
}
logItem = newLogItem(levelNbr, message, loggerName);
if (levelNbr < this.level) {
// Store in the hold buffer. Do not send.
if (this.bufferSize > 0) {
this.buffer.push(logItem);
// If we exceeded max buffer size, remove oldest item
if (this.buffer.length > this.bufferSize) {
this.buffer.shift();
}
}
return;
}
// Want to send the item
this.addLogItemsToBuffer([logItem]);
if (levelNbr >= this.sendWithBufferLevel) {
// Want to send the contents of the buffer.
//
// Send the buffer AFTER sending the high priority item.
// If you were to send the high priority item after the buffer,
// if we're close to maxMessages or maxBatchSize,
// then the trace messages in the buffer could crowd out the actual high priority item.
if (this.buffer.length) {
this.addLogItemsToBuffer(this.buffer);
this.buffer.length = 0;
}
}
this.sendBatchIfComplete();
};
;
// Processes the batch buffer
//
// Make this public, so it can be called from outside the library,
// when the page is unloaded.
Appender.prototype.sendBatch = function () {
// Do not clear the batch timer if you don't go ahead here because
// a send is already in progress. Otherwise the messages that were stopped from going out
// may get ignored because the batch timer never went off.
if (this.nbrLogItemsBeingSent > 0) {
return;
}
clearTimer(this.batchTimeoutTimer);
if (this.batchBuffer.length == 0) {
return;
}
// Decided at this point to send contents of the buffer
this.nbrLogItemsBeingSent = this.batchBuffer.length;
var that = this;
setTimer(this.sendTimeoutTimer, this.sendTimeout, function () {
that.onSendingEnded.call(that);
});
this.sendLogItems(this.batchBuffer, function () {
// Log entries have been successfully sent to server
// Remove the first (nbrLogItemsBeingSent) items in the batch buffer, because they are the ones
// that were sent.
that.batchBuffer.splice(0, that.nbrLogItemsBeingSent);
// If items had to be skipped, add a WARN message
if (that.nbrLogItemsSkipped > 0) {
that.batchBuffer.push(newLogItem(getWarnLevel(), "Lost " + that.nbrLogItemsSkipped + " messages. Either connection with the server was down or logging was disabled via the enabled option. Reduce lost messages by increasing the ajaxAppender option maxBatchSize.", that.appenderName));
that.nbrLogItemsSkipped = 0;
}
that.onSendingEnded.call(that);
});
};
return Appender;
}());
JL.Appender = Appender;
// ---------------------
var AjaxAppender = /** @class */ (function (_super) {
__extends(AjaxAppender, _super);
function AjaxAppender(appenderName) {
return _super.call(this, appenderName, AjaxAppender.prototype.sendLogItemsAjax) || this;
}
AjaxAppender.prototype.setOptions = function (options) {
copyProperty("url", options, this);
copyProperty("beforeSend", options, this);
_super.prototype.setOptions.call(this, options);
return this;
};
AjaxAppender.prototype.sendLogItemsAjax = function (logItems, successCallback) {
// JSON.stringify is only supported on IE8+
// Use try-catch in case we get an exception here.
//
// The "r" field is now obsolete. When writing a server side component,
// read the HTTP header "JSNLog-RequestId"
// to get the request id.
//
// The .Net server side component
// now uses the JSNLog-RequestId HTTP Header, because this allows it to
// detect whether the incoming request has a request id.
// If the request id were in the json payload, it would have to read the json
// from the stream, interfering with normal non-logging requests.
//
// To see what characters you can use in the HTTP header, visit:
// http://stackoverflow.com/questions/3561381/custom-http-headers-naming-conventions/3561399#3561399
//
// It needs this ability, so users of NLog can set a requestId variable in NLog
// before the server side component tries to log the client side log message
// through an NLog logger.
// Unlike Log4Net, NLog doesn't allow you to register an object whose ToString()
// is only called when it tries to log something, so the requestId has to be
// determined right at the start of request processing.
try {
// Do not send logs, if JL.enabled is set to false.
//
// Do not call successCallback here. After each timeout, jsnlog will retry sending the message.
// If jsnlog gets re-enabled, it will then log the number of messages logged.
// If it doesn't get re-enabled, amount of cpu cycles wasted is minimal.
if (!allow(this)) {
return;
}
// If a request is in progress, abort it.
// Otherwise, it may call the success callback, which will be very confusing.
// It may also stop the inflight request from resulting in a log at the server.
if (this.xhr && (this.xhr.readyState != 0) && (this.xhr.readyState != 4)) {
this.xhr.abort();
}
// Because a react-native XMLHttpRequest cannot be reused it needs to be recreated with each request
this.xhr = JL._createXMLHttpRequest();
// Only determine the url right before you send a log request.
// Do not set the url when constructing the appender.
//
// This is because the server side component sets defaultAjaxUrl
// in a call to setOptions, AFTER the JL object and the default appender
// have been created.
var ajaxUrl = "/jsnlog.logger";
// This evaluates to true if defaultAjaxUrl is null or undefined
if (!(JL.defaultAjaxUrl == null)) {
ajaxUrl = JL.defaultAjaxUrl;
}
if (this.url) {
ajaxUrl = this.url;
}
this.xhr.open('POST', ajaxUrl);
this.xhr.setRequestHeader('Content-Type', 'application/json');
this.xhr.setRequestHeader('JSNLog-RequestId', JL.requestId);
var that = this;
this.xhr.onreadystatechange = function () {
// On most browsers, if the request fails (eg. internet is gone),
// it will set xhr.readyState == 4 and xhr.status != 200 (0 if request could not be sent) immediately.
// However, Edge and IE will not change the readyState at all if the internet goes away while waiting
// for a response.
// Some servers will return a 204 (success, no content) when the JSNLog endpoint
// returns the empty response. So check on any code in the 2.. range, not just 200.
if ((that.xhr.readyState == 4) && (that.xhr.status >= 200 && that.xhr.status < 300)) {
successCallback();
}
};
var json = {
r: JL.requestId,
lg: logItems
};
// call beforeSend callback
// first try the callback on the appender
// then the global defaultBeforeSend callback
if (typeof this.beforeSend === 'function') {
this.beforeSend.call(this, this.xhr, json);
}
else if (typeof JL.defaultBeforeSend === 'function') {
JL.defaultBeforeSend.call(this, this.xhr, json);
}
var finalmsg = JSON.stringify(json);
this.xhr.send(finalmsg);
}
catch (e) { }
};
return AjaxAppender;
}(Appender));
JL.AjaxAppender = AjaxAppender;
// ---------------------
var ConsoleAppender = /** @class */ (function (_super) {
__extends(ConsoleAppender, _super);
function ConsoleAppender(appenderName) {
return _super.call(this, appenderName, ConsoleAppender.prototype.sendLogItemsConsole) || this;
}
ConsoleAppender.prototype.clog = function (logEntry) {
JL._console.log(logEntry);
};
ConsoleAppender.prototype.cerror = function (logEntry) {
if (JL._console.error) {
JL._console.error(logEntry);
}
else {
this.clog(logEntry);
}
};
ConsoleAppender.prototype.cwarn = function (logEntry) {
if (JL._console.warn) {
JL._console.warn(logEntry);
}
else {
this.clog(logEntry);
}
};
ConsoleAppender.prototype.cinfo = function (logEntry) {
if (JL._console.info) {
JL._console.info(logEntry);
}
else {
this.clog(logEntry);
}
};
// IE11 has a console.debug function. But its console doesn't have
// the option to show/hide debug messages (the same way Chrome and FF do),
// even though it does have such buttons for Error, Warn, Info.
//
// For now, this means that debug messages can not be hidden on IE.
// Live with this, seeing that it works fine on FF and Chrome, which
// will be much more popular with developers.
ConsoleAppender.prototype.cdebug = function (logEntry) {
if (JL._console.debug) {
JL._console.debug(logEntry);
}
else {
this.cinfo(logEntry);
}
};
ConsoleAppender.prototype.sendLogItemsConsole = function (logItems, successCallback) {
try {
// Do not send logs, if JL.enabled is set to false
//
// Do not call successCallback here. After each timeout, jsnlog will retry sending the message.
// If jsnlog gets re-enabled, it will then log the number of messages logged.
// If it doesn't get re-enabled, amount of cpu cycles wasted is minimal.
if (!allow(this)) {
return;
}
if (!JL._console) {
return;
}
var i;
for (i = 0; i < logItems.length; ++i) {
var li = logItems[i];
var msg = li.n + ": " + li.m;
// Only log the timestamp if we're on the server
// (window is undefined). On the browser, the user
// sees the log entry probably immediately, so in that case
// the timestamp is clutter.
if (typeof window === 'undefined') {
msg = new Date(li.t) + " | " + msg;
}
if (li.l <= JL.getDebugLevel()) {
this.cdebug(msg);
}
else if (li.l <= JL.getInfoLevel()) {
this.cinfo(msg);
}
else if (li.l <= JL.getWarnLevel()) {
this.cwarn(msg);
}
else {
this.cerror(msg);
}
}
}
catch (e) {
}
successCallback();
};
return ConsoleAppender;
}(Appender));
JL.ConsoleAppender = ConsoleAppender;
// --------------------
var Logger = /** @class */ (function () {
function Logger(loggerName) {
this.loggerName = loggerName;
// Create seenRexes, otherwise this logger will use the seenRexes
// of its parent via the prototype chain.
this.seenRegexes = [];
}
Logger.prototype.setOptions = function (options) {
copyProperty("level", options, this);
copyProperty("userAgentRegex", options, this);
copyProperty("disallow", options, this);
copyProperty("ipRegex", options, this);
copyProperty("appenders", options, this);
copyProperty("onceOnly", options, this);
// Reset seenRegexes, in case onceOnly has been changed.
this.seenRegexes = [];
return this;
};
// Turns an exception into an object that can be sent to the server.
Logger.prototype.buildExceptionObject = function (e) {
var excObject = {};
if (e.stack) {
excObject.stack = e.stack;
}
else {
excObject.e = e;
}
if (e.message) {
excObject.message = e.message;
}
if (e.name) {
excObject.name = e.name;
}
if (e.data) {
excObject.data = e.data;
}
if (e.inner) {
excObject.inner = this.buildExceptionObject(e.inner);
}
return excObject;
};
// Logs a log item.
// Parameter e contains an exception (or null or undefined).
//
// Reason that processing exceptions is done at this low level is that
// 1) no need to spend the cpu cycles if the logger is switched off
// 2) fatalException takes both a logObject and an exception, and the logObject
// may be a function that should only be executed if the logger is switched on.
//
// If an exception is passed in, the contents of logObject is attached to the exception
// object in a new property logData.
// The resulting exception object is than worked into a message to the server.
//
// If there is no exception, logObject itself is worked into the message to the server.
Logger.prototype.log = function (level, logObject, e) {
var i = 0;
var compositeMessage;
var excObject;
// If we can't find any appenders, do nothing
if (!this.appenders) {
return this;
}
if (((level >= this.level)) && allow(this)) {
if (e) {
excObject = this.buildExceptionObject(e);
excObject.logData = stringifyLogObjectFunction(logObject);
}
else {
excObject = logObject;
}
compositeMessage = stringifyLogObject(excObject);
if (allowMessage(this, compositeMessage.finalString)) {
// See whether message is a duplicate
if (this.onceOnly) {
i = this.onceOnly.length - 1;
while (i >= 0) {
if (new RegExp(this.onceOnly[i]).test(compositeMessage.finalString)) {
if (this.seenRegexes[i]) {
return this;
}
this.seenRegexes[i] = true;
}
i--;
}
}
// Pass message to all appenders
// Note that these appenders could be Winston transports
// https://github.com/flatiron/winston
compositeMessage.meta = compositeMessage.meta || {};
// Note that if the user is logging an object, compositeMessage.meta will hold a reference to that object.
// Do not add fields to compositeMessage.meta, otherwise the user's object will get that field out of the blue.
i = this.appenders.length - 1;
while (i >= 0) {
this.appenders[i].log(levelToString(level), compositeMessage.msg, compositeMessage.meta, function () { }, level, compositeMessage.finalString, this.loggerName);
i--;
}
}
}
return this;
};
Logger.prototype.trace = function (logObject) { return this.log(getTraceLevel(), logObject); };
Logger.prototype.debug = function (logObject) { return this.log(getDebugLevel(), logObject); };
Logger.prototype.info = function (logObject) { return this.log(getInfoLevel(), logObject); };
Logger.prototype.warn = function (logObject) { return this.log(getWarnLevel(), logObject); };
Logger.prototype.error = function (logObject) { return this.log(getErrorLevel(), logObject); };
Logger.prototype.fatal = function (logObject) { return this.log(getFatalLevel(), logObject); };
Logger.prototype.fatalException = function (logObject, e) { return this.log(getFatalLevel(), logObject, e); };
return Logger;
}());
JL.Logger = Logger;
function createAjaxAppender(appenderName) {
return new AjaxAppender(appenderName);
}
JL.createAjaxAppender = createAjaxAppender;
function createConsoleAppender(appenderName) {
return new ConsoleAppender(appenderName);
}
JL.createConsoleAppender = createConsoleAppender;
// -----------------------
// In the browser, the default appender is the AjaxAppender.
// Under nodejs (where there is no "window"), use the ConsoleAppender instead.
//
// Do NOT create an AjaxAppender object if you are not on a browser (that is, window is not defined).
// That would try to create an XmlHttpRequest object, which will crash outside a browser.
var defaultAppender;
if (typeof window !== 'undefined') {
defaultAppender = new AjaxAppender("");
}
else {
defaultAppender = new ConsoleAppender("");
}
// Create root logger
//
// Note that this is the parent of all other loggers.
// Logger "x" will be stored at
// JL.__.x
// Logger "x.y" at
// JL.__.x.y
JL.__ = new JL.Logger("");
JL.__.setOptions({
level: JL.getDebugLevel(),
appenders: [defaultAppender]
});
})(JL || (JL = {}));
if (typeof exports !== 'undefined') {
// Allows SystemJs to import jsnlog.js. See
// https://github.com/mperdeck/jsnlog.js/issues/56
exports.__esModule = true;
exports.JL = JL;
}
// Support AMD module format
var define;
if (typeof define == 'function' && define.amd) {
define('jsnlog', [], function () {
return JL;
});
}
// If the __jsnlog_configure global function has been
// created, call it now. This allows you to create a global function
// setting logger options etc. inline in the page before jsnlog.js
// has been loaded.
if (typeof __jsnlog_configure == 'function') {
__jsnlog_configure(JL);
}
// Create onerror handler to log uncaught exceptions to the server side log, but only if there
// is no such handler already.
// Must use "typeof window" here, because in NodeJs, window is not defined at all, so cannot refer to window in any way.
if (typeof window !== 'undefined' && !window.onerror) {
window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
// Send object with all data to server side log, using severity fatal,
// from logger "onerrorLogger"
//
// Use errorMsg.message if available, so Angular 4 template errors will be logged.
// See https://github.com/mperdeck/jsnlog.js/pull/68
JL("onerrorLogger").fatalException({
"msg": "Uncaught Exception",
"errorMsg": errorMsg ? (errorMsg.message || errorMsg) : '',
"url": url,
"line number": lineNumber, "column": column
}, errorObj);
// Tell browser to run its own error handler as well
return false;
};
}
// Deal with unhandled exceptions thrown in promises
if (typeof window !== 'undefined' && !window.onunhandledrejection) {
window.onunhandledrejection = function (event) {
// Send object with all data to server side log, using severity fatal,
// from logger "onerrorLogger".
// Need to check both event.reason.message and event.message,
// because SystemJs wraps exceptions and throws a new object which doesn't have a reason property.
// See https://github.com/systemjs/systemjs/issues/1309
JL("onerrorLogger").fatalException({
"msg": "unhandledrejection",
"errorMsg": event.reason ? event.reason.message : event.message || null
}, event.reason);
};
}
},{}],8:[function(require,module,exports){
'use strict';
/**
* @param typeMap [Object] Map of MIME type -> Array[extensions]
* @param ...
*/
function Mime() {
this._types = Object.create(null);
this._extensions = Object.create(null);
for (let i = 0; i < arguments.length; i++) {
this.define(arguments[i]);
}
this.define = this.define.bind(this);
this.getType = this.getType.bind(this);
this.getExtension = this.getExtension.bind(this);
}
/**
* Define mimetype -> extension mappings. Each key is a mime-type that maps
* to an array of extensions associated with the type. The first extension is
* used as the default extension for the type.
*
* e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
*
* If a type declares an extension that has already been defined, an error will
* be thrown. To suppress this error and force the extension to be associated
* with the new type, pass `force`=true. Alternatively, you may prefix the
* extension with "*" to map the type to extension, without mapping the
* extension to the type.
*
* e.g. mime.define({'audio/wav', ['wav']}, {'audio/x-wav', ['*wav']});
*
*
* @param map (Object) type definitions
* @param force (Boolean) if true, force overriding of existing definitions
*/
Mime.prototype.define = function(typeMap, force) {
for (let type in typeMap) {
let extensions = typeMap[type].map(function(t) {
return t.toLowerCase();
});
type = type.toLowerCase();
for (let i = 0; i < extensions.length; i++) {
const ext = extensions[i];
// '*' prefix = not the preferred type for this extension. So fixup the
// extension, and skip it.
if (ext[0] === '*') {
continue;
}
if (!force && (ext in this._types)) {
throw new Error(
'Attempt to change mapping for "' + ext +
'" extension from "' + this._types[ext] + '" to "' + type +
'". Pass `force=true` to allow this, otherwise remove "' + ext +
'" from the list of extensions for "' + type + '".'
);
}
this._types[ext] = type;
}
// Use first extension as default
if (force || !this._extensions[type]) {
const ext = extensions[0];
this._extensions[type] = (ext[0] !== '*') ? ext : ext.substr(1);
}
}
};
/**
* Lookup a mime type based on extension
*/
Mime.prototype.getType = function(path) {
path = String(path);
let last = path.replace(/^.*[/\\]/, '').toLowerCase();
let ext = last.replace(/^.*\./, '').toLowerCase();
let hasPath = last.length < path.length;
let hasDot = ext.length < last.length - 1;
return (hasDot || !hasPath) && this._types[ext] || null;
};
/**
* Return file extension associated with a mime type
*/
Mime.prototype.getExtension = function(type) {
type = /^\s*([^;\s]*)/.test(type) && RegExp.$1;
return type && this._extensions[type.toLowerCase()] || null;
};
module.exports = Mime;
},{}],9:[function(require,module,exports){
'use strict';
let Mime = require('./Mime');
module.exports = new Mime(require('./types/standard'));
},{"./Mime":8,"./types/standard":10}],10:[function(require,module,exports){
module.exports = {"application/andrew-inset":["ez"],"application/applixware":["aw"],"application/atom+xml":["atom"],"application/atomcat+xml":["atomcat"],"application/atomdeleted+xml":["atomdeleted"],"application/atomsvc+xml":["atomsvc"],"application/atsc-dwd+xml":["dwd"],"application/atsc-held+xml":["held"],"application/atsc-rsat+xml":["rsat"],"application/bdoc":["bdoc"],"application/calendar+xml":["xcs"],"application/ccxml+xml":["ccxml"],"application/cdfx+xml":["cdfx"],"application/cdmi-capability":["cdmia"],"application/cdmi-container":["cdmic"],"application/cdmi-domain":["cdmid"],"application/cdmi-object":["cdmio"],"application/cdmi-queue":["cdmiq"],"application/cu-seeme":["cu"],"application/dash+xml":["mpd"],"application/davmount+xml":["davmount"],"application/docbook+xml":["dbk"],"application/dssc+der":["dssc"],"application/dssc+xml":["xdssc"],"application/ecmascript":["es","ecma"],"application/emma+xml":["emma"],"application/emotionml+xml":["emotionml"],"application/epub+zip":["epub"],"application/exi":["exi"],"application/express":["exp"],"application/fdt+xml":["fdt"],"application/font-tdpfr":["pfr"],"application/geo+json":["geojson"],"application/gml+xml":["gml"],"application/gpx+xml":["gpx"],"application/gxf":["gxf"],"application/gzip":["gz"],"application/hjson":["hjson"],"application/hyperstudio":["stk"],"application/inkml+xml":["ink","inkml"],"application/ipfix":["ipfix"],"application/its+xml":["its"],"application/java-archive":["jar","war","ear"],"application/java-serialized-object":["ser"],"application/java-vm":["class"],"application/javascript":["js","mjs"],"application/json":["json","map"],"application/json5":["json5"],"application/jsonml+json":["jsonml"],"application/ld+json":["jsonld"],"application/lgr+xml":["lgr"],"application/lost+xml":["lostxml"],"application/mac-binhex40":["hqx"],"application/mac-compactpro":["cpt"],"application/mads+xml":["mads"],"application/manifest+json":["webmanifest"],"application/marc":["mrc"],"application/marcxml+xml":["mrcx"],"application/mathematica":["ma","nb","mb"],"application/mathml+xml":["mathml"],"application/mbox":["mbox"],"application/mediaservercontrol+xml":["mscml"],"application/metalink+xml":["metalink"],"application/metalink4+xml":["meta4"],"application/mets+xml":["mets"],"application/mmt-aei+xml":["maei"],"application/mmt-usd+xml":["musd"],"application/mods+xml":["mods"],"application/mp21":["m21","mp21"],"application/mp4":["mp4s","m4p"],"application/msword":["doc","dot"],"application/mxf":["mxf"],"application/n-quads":["nq"],"application/n-triples":["nt"],"application/node":["cjs"],"application/octet-stream":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"],"application/oda":["oda"],"application/oebps-package+xml":["opf"],"application/ogg":["ogx"],"application/omdoc+xml":["omdoc"],"application/onenote":["onetoc","onetoc2","onetmp","onepkg"],"application/oxps":["oxps"],"application/p2p-overlay+xml":["relo"],"application/patch-ops-error+xml":["xer"],"application/pdf":["pdf"],"application/pgp-encrypted":["pgp"],"application/pgp-signature":["asc","sig"],"application/pics-rules":["prf"],"application/pkcs10":["p10"],"application/pkcs7-mime":["p7m","p7c"],"application/pkcs7-signature":["p7s"],"application/pkcs8":["p8"],"application/pkix-attr-cert":["ac"],"application/pkix-cert":["cer"],"application/pkix-crl":["crl"],"application/pkix-pkipath":["pkipath"],"application/pkixcmp":["pki"],"application/pls+xml":["pls"],"application/postscript":["ai","eps","ps"],"application/provenance+xml":["provx"],"application/pskc+xml":["pskcxml"],"application/raml+yaml":["raml"],"application/rdf+xml":["rdf","owl"],"application/reginfo+xml":["rif"],"application/relax-ng-compact-syntax":["rnc"],"application/resource-lists+xml":["rl"],"application/resource-lists-diff+xml":["rld"],"application/rls-services+xml":["rs"],"application/route-apd+xml":["rapd"],"application/route-s-tsid+xml":["sls"],"application/route-usd+xml":["rusd"],"application/rpki-ghostbusters":["gbr"],"application/rpki-manifest":["mft"],"application/rpki-roa":["roa"],"application/rsd+xml":["rsd"],"application/rss+xml":["rss"],"application/rtf":["rtf"],"application/sbml+xml":["sbml"],"application/scvp-cv-request":["scq"],"application/scvp-cv-response":["scs"],"application/scvp-vp-request":["spq"],"application/scvp-vp-response":["spp"],"application/sdp":["sdp"],"application/senml+xml":["senmlx"],"application/sensml+xml":["sensmlx"],"application/set-payment-initiation":["setpay"],"application/set-registration-initiation":["setreg"],"application/shf+xml":["shf"],"application/sieve":["siv","sieve"],"application/smil+xml":["smi","smil"],"application/sparql-query":["rq"],"application/sparql-results+xml":["srx"],"application/srgs":["gram"],"application/srgs+xml":["grxml"],"application/sru+xml":["sru"],"application/ssdl+xml":["ssdl"],"application/ssml+xml":["ssml"],"application/swid+xml":["swidtag"],"application/tei+xml":["tei","teicorpus"],"application/thraud+xml":["tfi"],"application/timestamped-data":["tsd"],"application/toml":["toml"],"application/trig":["trig"],"application/ttml+xml":["ttml"],"application/ubjson":["ubj"],"application/urc-ressheet+xml":["rsheet"],"application/urc-targetdesc+xml":["td"],"application/voicexml+xml":["vxml"],"application/wasm":["wasm"],"application/widget":["wgt"],"application/winhlp":["hlp"],"application/wsdl+xml":["wsdl"],"application/wspolicy+xml":["wspolicy"],"application/xaml+xml":["xaml"],"application/xcap-att+xml":["xav"],"application/xcap-caps+xml":["xca"],"application/xcap-diff+xml":["xdf"],"application/xcap-el+xml":["xel"],"application/xcap-ns+xml":["xns"],"application/xenc+xml":["xenc"],"application/xhtml+xml":["xhtml","xht"],"application/xliff+xml":["xlf"],"application/xml":["xml","xsl","xsd","rng"],"application/xml-dtd":["dtd"],"application/xop+xml":["xop"],"application/xproc+xml":["xpl"],"application/xslt+xml":["*xsl","xslt"],"application/xspf+xml":["xspf"],"application/xv+xml":["mxml","xhvml","xvml","xvm"],"application/yang":["yang"],"application/yin+xml":["yin"],"application/zip":["zip"],"audio/3gpp":["*3gpp"],"audio/adpcm":["adp"],"audio/amr":["amr"],"audio/basic":["au","snd"],"audio/midi":["mid","midi","kar","rmi"],"audio/mobile-xmf":["mxmf"],"audio/mp3":["*mp3"],"audio/mp4":["m4a","mp4a"],"audio/mpeg":["mpga","mp2","mp2a","mp3","m2a","m3a"],"audio/ogg":["oga","ogg","spx","opus"],"audio/s3m":["s3m"],"audio/silk":["sil"],"audio/wav":["wav"],"audio/wave":["*wav"],"audio/webm":["weba"],"audio/xm":["xm"],"font/collection":["ttc"],"font/otf":["otf"],"font/ttf":["ttf"],"font/woff":["woff"],"font/woff2":["woff2"],"image/aces":["exr"],"image/apng":["apng"],"image/avif":["avif"],"image/bmp":["bmp"],"image/cgm":["cgm"],"image/dicom-rle":["drle"],"image/emf":["emf"],"image/fits":["fits"],"image/g3fax":["g3"],"image/gif":["gif"],"image/heic":["heic"],"image/heic-sequence":["heics"],"image/heif":["heif"],"image/heif-sequence":["heifs"],"image/hej2k":["hej2"],"image/hsj2":["hsj2"],"image/ief":["ief"],"image/jls":["jls"],"image/jp2":["jp2","jpg2"],"image/jpeg":["jpeg","jpg","jpe"],"image/jph":["jph"],"image/jphc":["jhc"],"image/jpm":["jpm"],"image/jpx":["jpx","jpf"],"image/jxr":["jxr"],"image/jxra":["jxra"],"image/jxrs":["jxrs"],"image/jxs":["jxs"],"image/jxsc":["jxsc"],"image/jxsi":["jxsi"],"image/jxss":["jxss"],"image/ktx":["ktx"],"image/ktx2":["ktx2"],"image/png":["png"],"image/sgi":["sgi"],"image/svg+xml":["svg","svgz"],"image/t38":["t38"],"image/tiff":["tif","tiff"],"image/tiff-fx":["tfx"],"image/webp":["webp"],"image/wmf":["wmf"],"message/disposition-notification":["disposition-notification"],"message/global":["u8msg"],"message/global-delivery-status":["u8dsn"],"message/global-disposition-notification":["u8mdn"],"message/global-headers":["u8hdr"],"message/rfc822":["eml","mime"],"model/3mf":["3mf"],"model/gltf+json":["gltf"],"model/gltf-binary":["glb"],"model/iges":["igs","iges"],"model/mesh":["msh","mesh","silo"],"model/mtl":["mtl"],"model/obj":["obj"],"model/step+xml":["stpx"],"model/step+zip":["stpz"],"model/step-xml+zip":["stpxz"],"model/stl":["stl"],"model/vrml":["wrl","vrml"],"model/x3d+binary":["*x3db","x3dbz"],"model/x3d+fastinfoset":["x3db"],"model/x3d+vrml":["*x3dv","x3dvz"],"model/x3d+xml":["x3d","x3dz"],"model/x3d-vrml":["x3dv"],"text/cache-manifest":["appcache","manifest"],"text/calendar":["ics","ifb"],"text/coffeescript":["coffee","litcoffee"],"text/css":["css"],"text/csv":["csv"],"text/html":["html","htm","shtml"],"text/jade":["jade"],"text/jsx":["jsx"],"text/less":["less"],"text/markdown":["markdown","md"],"text/mathml":["mml"],"text/mdx":["mdx"],"text/n3":["n3"],"text/plain":["txt","text","conf","def","list","log","in","ini"],"text/richtext":["rtx"],"text/rtf":["*rtf"],"text/sgml":["sgml","sgm"],"text/shex":["shex"],"text/slim":["slim","slm"],"text/spdx":["spdx"],"text/stylus":["stylus","styl"],"text/tab-separated-values":["tsv"],"text/troff":["t","tr","roff","man","me","ms"],"text/turtle":["ttl"],"text/uri-list":["uri","uris","urls"],"text/vcard":["vcard"],"text/vtt":["vtt"],"text/xml":["*xml"],"text/yaml":["yaml","yml"],"video/3gpp":["3gp","3gpp"],"video/3gpp2":["3g2"],"video/h261":["h261"],"video/h263":["h263"],"video/h264":["h264"],"video/iso.segment":["m4s"],"video/jpeg":["jpgv"],"video/jpm":["*jpm","jpgm"],"video/mj2":["mj2","mjp2"],"video/mp2t":["ts"],"video/mp4":["mp4","mp4v","mpg4"],"video/mpeg":["mpeg","mpg","mpe","m1v","m2v"],"video/ogg":["ogv"],"video/quicktime":["qt","mov"],"video/webm":["webm"]};
},{}],11:[function(require,module,exports){
/**
# normalice
Normalize an ice server configuration object (or plain old string) into a format
that is usable in all browsers supporting WebRTC. Primarily this module is designed
to help with the transition of the `url` attribute of the configuration object to
the `urls` attribute.
## Example Usage
<<< examples/simple.js
**/
var protocols = [
'stun:',
'turn:'
];
module.exports = function(input) {
var url = (input || {}).url || input;
var protocol;
var parts;
var output = {};
// if we don't have a string url, then allow the input to passthrough
if (typeof url != 'string' && (! (url instanceof String))) {
return input;
}
// trim the url string, and convert to an array
url = url.trim();
// if the protocol is not known, then passthrough
protocol = protocols[protocols.indexOf(url.slice(0, 5))];
if (! protocol) {
return input;
}
// now let's attack the remaining url parts
url = url.slice(5);
parts = url.split('@');
output.username = input.username;
output.credential = input.credential;
// if we have an authentication part, then set the credentials
if (parts.length > 1) {
url = parts[1];
parts = parts[0].split(':');
// add the output credential and username
output.username = parts[0];
output.credential = (input || {}).credential || parts[1] || '';
}
output.url = protocol + url;
output.urls = [ output.url ];
return output;
};
},{}],12:[function(require,module,exports){
(function (global){(function (){
/*!
* Platform.js v1.3.6
* Copyright 2014-2020 Benjamin Tan
* Copyright 2011-2013 John-David Dalton
* Available under MIT license
*/
;(function() {
'use strict';
/** Used to determine if values are of the language type `Object`. */
var objectTypes = {
'function': true,
'object': true
};
/** Used as a reference to the global object. */
var root = (objectTypes[typeof window] && window) || this;
/** Backup possible global object. */
var oldRoot = root;
/** Detect free variable `exports`. */
var freeExports = objectTypes[typeof exports] && exports;
/** Detect free variable `module`. */
var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
/** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */
var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) {
root = freeGlobal;
}
/**
* Used as the maximum length of an array-like object.
* See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
* for more details.
*/
var maxSafeInteger = Math.pow(2, 53) - 1;
/** Regular expression to detect Opera. */
var reOpera = /\bOpera/;
/** Possible global object. */
var thisBinding = this;
/** Used for native method references. */
var objectProto = Object.prototype;
/** Used to check for own properties of an object. */
var hasOwnProperty = objectProto.hasOwnProperty;
/** Used to resolve the internal `[[Class]]` of values. */
var toString = objectProto.toString;
/*--------------------------------------------------------------------------*/
/**
* Capitalizes a string value.
*
* @private
* @param {string} string The string to capitalize.
* @returns {string} The capitalized string.
*/
function capitalize(string) {
string = String(string);
return string.charAt(0).toUpperCase() + string.slice(1);
}
/**
* A utility function to clean up the OS name.
*
* @private
* @param {string} os The OS name to clean up.
* @param {string} [pattern] A `RegExp` pattern matching the OS name.
* @param {string} [label] A label for the OS.
*/
function cleanupOS(os, pattern, label) {
// Platform tokens are defined at:
// http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
// http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx
var data = {
'10.0': '10',
'6.4': '10 Technical Preview',
'6.3': '8.1',
'6.2': '8',
'6.1': 'Server 2008 R2 / 7',
'6.0': 'Server 2008 / Vista',
'5.2': 'Server 2003 / XP 64-bit',
'5.1': 'XP',
'5.01': '2000 SP1',
'5.0': '2000',
'4.0': 'NT',
'4.90': 'ME'
};
// Detect Windows version from platform tokens.
if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) &&
(data = data[/[\d.]+$/.exec(os)])) {
os = 'Windows ' + data;
}
// Correct character case and cleanup string.
os = String(os);
if (pattern && label) {
os = os.replace(RegExp(pattern, 'i'), label);
}
os = format(
os.replace(/ ce$/i, ' CE')
.replace(/\bhpw/i, 'web')
.replace(/\bMacintosh\b/, 'Mac OS')
.replace(/_PowerPC\b/i, ' OS')
.replace(/\b(OS X) [^ \d]+/i, '$1')
.replace(/\bMac (OS X)\b/, '$1')
.replace(/\/(\d)/, ' $1')
.replace(/_/g, '.')
.replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '')
.replace(/\bx86\.64\b/gi, 'x86_64')
.replace(/\b(Windows Phone) OS\b/, '$1')
.replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1')
.split(' on ')[0]
);
return os;
}
/**
* An iteration utility for arrays and objects.
*
* @private
* @param {Array|Object} object The object to iterate over.
* @param {Function} callback The function called per iteration.
*/
function each(object, callback) {
var index = -1,
length = object ? object.length : 0;
if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) {
while (++index < length) {
callback(object[index], index, object);
}
} else {
forOwn(object, callback);
}
}
/**
* Trim and conditionally capitalize string values.
*
* @private
* @param {string} string The string to format.
* @returns {string} The formatted string.
*/
function format(string) {
string = trim(string);
return /^(?:webOS|i(?:OS|P))/.test(string)
? string
: capitalize(string);
}
/**
* Iterates over an object's own properties, executing the `callback` for each.
*
* @private
* @param {Object} object The object to iterate over.
* @param {Function} callback The function executed per own property.
*/
function forOwn(object, callback) {
for (var key in object) {
if (hasOwnProperty.call(object, key)) {
callback(object[key], key, object);
}
}
}
/**
* Gets the internal `[[Class]]` of a value.
*
* @private
* @param {*} value The value.
* @returns {string} The `[[Class]]`.
*/
function getClassOf(value) {
return value == null
? capitalize(value)
: toString.call(value).slice(8, -1);
}
/**
* Host objects can return type values that are different from their actual
* data type. The objects we are concerned with usually return non-primitive
* types of "object", "function", or "unknown".
*
* @private
* @param {*} object The owner of the property.
* @param {string} property The property to check.
* @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`.
*/
function isHostType(object, property) {
var type = object != null ? typeof object[property] : 'number';
return !/^(?:boolean|number|string|undefined)$/.test(type) &&
(type == 'object' ? !!object[property] : true);
}
/**
* Prepares a string for use in a `RegExp` by making hyphens and spaces optional.
*
* @private
* @param {string} string The string to qualify.
* @returns {string} The qualified string.
*/
function qualify(string) {
return String(string).replace(/([ -])(?!$)/g, '$1?');
}
/**
* A bare-bones `Array#reduce` like utility function.
*
* @private
* @param {Array} array The array to iterate over.
* @param {Function} callback The function called per iteration.
* @returns {*} The accumulated result.
*/
function reduce(array, callback) {
var accumulator = null;
each(array, function(value, index) {
accumulator = callback(accumulator, value, index, array);
});
return accumulator;
}
/**
* Removes leading and trailing whitespace from a string.
*
* @private
* @param {string} string The string to trim.
* @returns {string} The trimmed string.
*/
function trim(string) {
return String(string).replace(/^ +| +$/g, '');
}
/*--------------------------------------------------------------------------*/
/**
* Creates a new platform object.
*
* @memberOf platform
* @param {Object|string} [ua=navigator.userAgent] The user agent string or
* context object.
* @returns {Object} A platform object.
*/
function parse(ua) {
/** The environment context object. */
var context = root;
/** Used to flag when a custom context is provided. */
var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String';
// Juggle arguments.
if (isCustomContext) {
context = ua;
ua = null;
}
/** Browser navigator object. */
var nav = context.navigator || {};
/** Browser user agent string. */
var userAgent = nav.userAgent || '';
ua || (ua = userAgent);
/** Used to flag when `thisBinding` is the [ModuleScope]. */
var isModuleScope = isCustomContext || thisBinding == oldRoot;
/** Used to detect if browser is like Chrome. */
var likeChrome = isCustomContext
? !!nav.likeChrome
: /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString());
/** Internal `[[Class]]` value shortcuts. */
var objectClass = 'Object',
airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject',
enviroClass = isCustomContext ? objectClass : 'Environment',
javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java),
phantomClass = isCustomContext ? objectClass : 'RuntimeObject';
/** Detect Java environments. */
var java = /\bJava/.test(javaClass) && context.java;
/** Detect Rhino. */
var rhino = java && getClassOf(context.environment) == enviroClass;
/** A character to represent alpha. */
var alpha = java ? 'a' : '\u03b1';
/** A character to represent beta. */
var beta = java ? 'b' : '\u03b2';
/** Browser document object. */
var doc = context.document || {};
/**
* Detect Opera browser (Presto-based).
* http://www.howtocreate.co.uk/operaStuff/operaObject.html
* http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini
*/
var opera = context.operamini || context.opera;
/** Opera `[[Class]]`. */
var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera))
? operaClass
: (opera = null);
/*------------------------------------------------------------------------*/
/** Temporary variable used over the script's lifetime. */
var data;
/** The CPU architecture. */
var arch = ua;
/** Platform description array. */
var description = [];
/** Platform alpha/beta indicator. */
var prerelease = null;
/** A flag to indicate that environment features should be used to resolve the platform. */
var useFeatures = ua == userAgent;
/** The browser/environment version. */
var version = useFeatures && opera && typeof opera.version == 'function' && opera.version();
/** A flag to indicate if the OS ends with "/ Version" */
var isSpecialCasedOS;
/* Detectable layout engines (order is important). */
var layout = getLayout([
{ 'label': 'EdgeHTML', 'pattern': 'Edge' },
'Trident',
{ 'label': 'WebKit', 'pattern': 'AppleWebKit' },
'iCab',
'Presto',
'NetFront',
'Tasman',
'KHTML',
'Gecko'
]);
/* Detectable browser names (order is important). */
var name = getName([
'Adobe AIR',
'Arora',
'Avant Browser',
'Breach',
'Camino',
'Electron',
'Epiphany',
'Fennec',
'Flock',
'Galeon',
'GreenBrowser',
'iCab',
'Iceweasel',
'K-Meleon',
'Konqueror',
'Lunascape',
'Maxthon',
{ 'label': 'Microsoft Edge', 'pattern': '(?:Edge|Edg|EdgA|EdgiOS)' },
'Midori',
'Nook Browser',
'PaleMoon',
'PhantomJS',
'Raven',
'Rekonq',
'RockMelt',
{ 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' },
'SeaMonkey',
{ 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
'Sleipnir',
'SlimBrowser',
{ 'label': 'SRWare Iron', 'pattern': 'Iron' },
'Sunrise',
'Swiftfox',
'Vivaldi',
'Waterfox',
'WebPositive',
{ 'label': 'Yandex Browser', 'pattern': 'YaBrowser' },
{ 'label': 'UC Browser', 'pattern': 'UCBrowser' },
'Opera Mini',
{ 'label': 'Opera Mini', 'pattern': 'OPiOS' },
'Opera',
{ 'label': 'Opera', 'pattern': 'OPR' },
'Chromium',
'Chrome',
{ 'label': 'Chrome', 'pattern': '(?:HeadlessChrome)' },
{ 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' },
{ 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' },
{ 'label': 'Firefox for iOS', 'pattern': 'FxiOS' },
{ 'label': 'IE', 'pattern': 'IEMobile' },
{ 'label': 'IE', 'pattern': 'MSIE' },
'Safari'
]);
/* Detectable products (order is important). */
var product = getProduct([
{ 'label': 'BlackBerry', 'pattern': 'BB10' },
'BlackBerry',
{ 'label': 'Galaxy S', 'pattern': 'GT-I9000' },
{ 'label': 'Galaxy S2', 'pattern': 'GT-I9100' },
{ 'label': 'Galaxy S3', 'pattern': 'GT-I9300' },
{ 'label': 'Galaxy S4', 'pattern': 'GT-I9500' },
{ 'label': 'Galaxy S5', 'pattern': 'SM-G900' },
{ 'label': 'Galaxy S6', 'pattern': 'SM-G920' },
{ 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' },
{ 'label': 'Galaxy S7', 'pattern': 'SM-G930' },
{ 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' },
'Google TV',
'Lumia',
'iPad',
'iPod',
'iPhone',
'Kindle',
{ 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
'Nexus',
'Nook',
'PlayBook',
'PlayStation Vita',
'PlayStation',
'TouchPad',
'Transformer',
{ 'label': 'Wii U', 'pattern': 'WiiU' },
'Wii',
'Xbox One',
{ 'label': 'Xbox 360', 'pattern': 'Xbox' },
'Xoom'
]);
/* Detectable manufacturers. */
var manufacturer = getManufacturer({
'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 },
'Alcatel': {},
'Archos': {},
'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 },
'Asus': { 'Transformer': 1 },
'Barnes & Noble': { 'Nook': 1 },
'BlackBerry': { 'PlayBook': 1 },
'Google': { 'Google TV': 1, 'Nexus': 1 },
'HP': { 'TouchPad': 1 },
'HTC': {},
'Huawei': {},
'Lenovo': {},
'LG': {},
'Microsoft': { 'Xbox': 1, 'Xbox One': 1 },
'Motorola': { 'Xoom': 1 },
'Nintendo': { 'Wii U': 1, 'Wii': 1 },
'Nokia': { 'Lumia': 1 },
'Oppo': {},
'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 },
'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 },
'Xiaomi': { 'Mi': 1, 'Redmi': 1 }
});
/* Detectable operating systems (order is important). */
var os = getOS([
'Windows Phone',
'KaiOS',
'Android',
'CentOS',
{ 'label': 'Chrome OS', 'pattern': 'CrOS' },
'Debian',
{ 'label': 'DragonFly BSD', 'pattern': 'DragonFly' },
'Fedora',
'FreeBSD',
'Gentoo',
'Haiku',
'Kubuntu',
'Linux Mint',
'OpenBSD',
'Red Hat',
'SuSE',
'Ubuntu',
'Xubuntu',
'Cygwin',
'Symbian OS',
'hpwOS',
'webOS ',
'webOS',
'Tablet OS',
'Tizen',
'Linux',
'Mac OS X',
'Macintosh',
'Mac',
'Windows 98;',
'Windows '
]);
/*------------------------------------------------------------------------*/
/**
* Picks the layout engine from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {null|string} The detected layout engine.
*/
function getLayout(guesses) {
return reduce(guesses, function(result, guess) {
return result || RegExp('\\b' + (
guess.pattern || qualify(guess)
) + '\\b', 'i').exec(ua) && (guess.label || guess);
});
}
/**
* Picks the manufacturer from an array of guesses.
*
* @private
* @param {Array} guesses An object of guesses.
* @returns {null|string} The detected manufacturer.
*/
function getManufacturer(guesses) {
return reduce(guesses, function(result, value, key) {
// Lookup the manufacturer by product or scan the UA for the manufacturer.
return result || (
value[product] ||
value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] ||
RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua)
) && key;
});
}
/**
* Picks the browser name from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {null|string} The detected browser name.
*/
function getName(guesses) {
return reduce(guesses, function(result, guess) {
return result || RegExp('\\b' + (
guess.pattern || qualify(guess)
) + '\\b', 'i').exec(ua) && (guess.label || guess);
});
}
/**
* Picks the OS name from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {null|string} The detected OS name.
*/
function getOS(guesses) {
return reduce(guesses, function(result, guess) {
var pattern = guess.pattern || qualify(guess);
if (!result && (result =
RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua)
)) {
result = cleanupOS(result, pattern, guess.label || guess);
}
return result;
});
}
/**
* Picks the product name from an array of guesses.
*
* @private
* @param {Array} guesses An array of guesses.
* @returns {null|string} The detected product name.
*/
function getProduct(guesses) {
return reduce(guesses, function(result, guess) {
var pattern = guess.pattern || qualify(guess);
if (!result && (result =
RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) ||
RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) ||
RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua)
)) {
// Split by forward slash and append product version if needed.
if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) {
result[0] += ' ' + result[1];
}
// Correct character case and cleanup string.
guess = guess.label || guess;
result = format(result[0]
.replace(RegExp(pattern, 'i'), guess)
.replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ')
.replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2'));
}
return result;
});
}
/**
* Resolves the version using an array of UA patterns.
*
* @private
* @param {Array} patterns An array of UA patterns.
* @returns {null|string} The detected version.
*/
function getVersion(patterns) {
return reduce(patterns, function(result, pattern) {
return result || (RegExp(pattern +
'(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null;
});
}
/**
* Returns `platform.description` when the platform object is coerced to a string.
*
* @name toString
* @memberOf platform
* @returns {string} Returns `platform.description` if available, else an empty string.
*/
function toStringPlatform() {
return this.description || '';
}
/*------------------------------------------------------------------------*/
// Convert layout to an array so we can add extra details.
layout && (layout = [layout]);
// Detect Android products.
// Browsers on Android devices typically provide their product IDS after "Android;"
// up to "Build" or ") AppleWebKit".
// Example:
// "Mozilla/5.0 (Linux; Android 8.1.0; Moto G (5) Plus) AppleWebKit/537.36
// (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36"
if (/\bAndroid\b/.test(os) && !product &&
(data = /\bAndroid[^;]*;(.*?)(?:Build|\) AppleWebKit)\b/i.exec(ua))) {
product = trim(data[1])
// Replace any language codes (eg. "en-US").
.replace(/^[a-z]{2}-[a-z]{2};\s*/i, '')
|| null;
}
// Detect product names that contain their manufacturer's name.
if (manufacturer && !product) {
product = getProduct([manufacturer]);
} else if (manufacturer && product) {
product = product
.replace(RegExp('^(' + qualify(manufacturer) + ')[-_.\\s]', 'i'), manufacturer + ' ')
.replace(RegExp('^(' + qualify(manufacturer) + ')[-_.]?(\\w)', 'i'), manufacturer + ' $2');
}
// Clean up Google TV.
if ((data = /\bGoogle TV\b/.exec(product))) {
product = data[0];
}
// Detect simulators.
if (/\bSimulator\b/i.test(ua)) {
product = (product ? product + ' ' : '') + 'Simulator';
}
// Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS.
if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) {
description.push('running in Turbo/Uncompressed mode');
}
// Detect IE Mobile 11.
if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) {
data = parse(ua.replace(/like iPhone OS/, ''));
manufacturer = data.manufacturer;
product = data.product;
}
// Detect iOS.
else if (/^iP/.test(product)) {
name || (name = 'Safari');
os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua))
? ' ' + data[1].replace(/_/g, '.')
: '');
}
// Detect Kubuntu.
else if (name == 'Konqueror' && /^Linux\b/i.test(os)) {
os = 'Kubuntu';
}
// Detect Android browsers.
else if ((manufacturer && manufacturer != 'Google' &&
((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) ||
(/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) {
name = 'Android Browser';
os = /\bAndroid\b/.test(os) ? os : 'Android';
}
// Detect Silk desktop/accelerated modes.
else if (name == 'Silk') {
if (!/\bMobi/i.test(ua)) {
os = 'Android';
description.unshift('desktop mode');
}
if (/Accelerated *= *true/i.test(ua)) {
description.unshift('accelerated');
}
}
// Detect UC Browser speed mode.
else if (name == 'UC Browser' && /\bUCWEB\b/.test(ua)) {
description.push('speed mode');
}
// Detect PaleMoon identifying as Firefox.
else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) {
description.push('identifying as Firefox ' + data[1]);
}
// Detect Firefox OS and products running Firefox.
else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) {
os || (os = 'Firefox OS');
product || (product = data[1]);
}
// Detect false positives for Firefox/Safari.
else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) {
// Escape the `/` for Firefox 1.
if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) {
// Clear name of false positives.
name = null;
}
// Reassign a generic name.
if ((data = product || manufacturer || os) &&
(product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) {
name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser';
}
}
// Add Chrome version to description for Electron.
else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) {
description.push('Chromium ' + data);
}
// Detect non-Opera (Presto-based) versions (order is important).
if (!version) {
version = getVersion([
'(?:Cloud9|CriOS|CrMo|Edge|Edg|EdgA|EdgiOS|FxiOS|HeadlessChrome|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$)|UCBrowser|YaBrowser)',
'Version',
qualify(name),
'(?:Firefox|Minefield|NetFront)'
]);
}
// Detect stubborn layout engines.
if ((data =
layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' ||
/\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') ||
/\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' ||
!layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') ||
layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront'
)) {
layout = [data];
}
// Detect Windows Phone 7 desktop mode.
if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) {
name += ' Mobile';
os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x');
description.unshift('desktop mode');
}
// Detect Windows Phone 8.x desktop mode.
else if (/\bWPDesktop\b/i.test(ua)) {
name = 'IE Mobile';
os = 'Windows Phone 8.x';
description.unshift('desktop mode');
version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]);
}
// Detect IE 11 identifying as other browsers.
else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) {
if (name) {
description.push('identifying as ' + name + (version ? ' ' + version : ''));
}
name = 'IE';
version = data[1];
}
// Leverage environment features.
if (useFeatures) {
// Detect server-side environments.
// Rhino has a global function while others have a global object.
if (isHostType(context, 'global')) {
if (java) {
data = java.lang.System;
arch = data.getProperty('os.arch');
os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version');
}
if (rhino) {
try {
version = context.require('ringo/engine').version.join('.');
name = 'RingoJS';
} catch(e) {
if ((data = context.system) && data.global.system == context.system) {
name = 'Narwhal';
os || (os = data[0].os || null);
}
}
if (!name) {
name = 'Rhino';
}
}
else if (
typeof context.process == 'object' && !context.process.browser &&
(data = context.process)
) {
if (typeof data.versions == 'object') {
if (typeof data.versions.electron == 'string') {
description.push('Node ' + data.versions.node);
name = 'Electron';
version = data.versions.electron;
} else if (typeof data.versions.nw == 'string') {
description.push('Chromium ' + version, 'Node ' + data.versions.node);
name = 'NW.js';
version = data.versions.nw;
}
}
if (!name) {
name = 'Node.js';
arch = data.arch;
os = data.platform;
version = /[\d.]+/.exec(data.version);
version = version ? version[0] : null;
}
}
}
// Detect Adobe AIR.
else if (getClassOf((data = context.runtime)) == airRuntimeClass) {
name = 'Adobe AIR';
os = data.flash.system.Capabilities.os;
}
// Detect PhantomJS.
else if (getClassOf((data = context.phantom)) == phantomClass) {
name = 'PhantomJS';
version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch);
}
// Detect IE compatibility modes.
else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) {
// We're in compatibility mode when the Trident version + 4 doesn't
// equal the document mode.
version = [version, doc.documentMode];
if ((data = +data[1] + 4) != version[1]) {
description.push('IE ' + version[1] + ' mode');
layout && (layout[1] = '');
version[1] = data;
}
version = name == 'IE' ? String(version[1].toFixed(1)) : version[0];
}
// Detect IE 11 masking as other browsers.
else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) {
description.push('masking as ' + name + ' ' + version);
name = 'IE';
version = '11.0';
layout = ['Trident'];
os = 'Windows';
}
os = os && format(os);
}
// Detect prerelease phases.
if (version && (data =
/(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) ||
/(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) ||
/\bMinefield\b/i.test(ua) && 'a'
)) {
prerelease = /b/i.test(data) ? 'beta' : 'alpha';
version = version.replace(RegExp(data + '\\+?$'), '') +
(prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || '');
}
// Detect Firefox Mobile.
if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS|KaiOS)\b/.test(os)) {
name = 'Firefox Mobile';
}
// Obscure Maxthon's unreliable version.
else if (name == 'Maxthon' && version) {
version = version.replace(/\.[\d.]+/, '.x');
}
// Detect Xbox 360 and Xbox One.
else if (/\bXbox\b/i.test(product)) {
if (product == 'Xbox 360') {
os = null;
}
if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) {
description.unshift('mobile mode');
}
}
// Add mobile postfix.
else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) &&
(os == 'Windows CE' || /Mobi/i.test(ua))) {
name += ' Mobile';
}
// Detect IE platform preview.
else if (name == 'IE' && useFeatures) {
try {
if (context.external === null) {
description.unshift('platform preview');
}
} catch(e) {
description.unshift('embedded');
}
}
// Detect BlackBerry OS version.
// http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp
else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data =
(RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
version
)) {
data = [data, /BB10/.test(ua)];
os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0];
version = null;
}
// Detect Opera identifying/masking itself as another browser.
// http://www.opera.com/support/kb/view/843/
else if (this != forOwn && product != 'Wii' && (
(useFeatures && opera) ||
(/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) ||
(name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) ||
(name == 'IE' && (
(os && !/^Win/.test(os) && version > 5.5) ||
/\bWindows XP\b/.test(os) && version > 8 ||
version == 8 && !/\bTrident\b/.test(ua)
))
) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) {
// When "identifying", the UA contains both Opera and the other browser's name.
data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : '');
if (reOpera.test(name)) {
if (/\bIE\b/.test(data) && os == 'Mac OS') {
os = null;
}
data = 'identify' + data;
}
// When "masking", the UA contains only the other browser's name.
else {
data = 'mask' + data;
if (operaClass) {
name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2'));
} else {
name = 'Opera';
}
if (/\bIE\b/.test(data)) {
os = null;
}
if (!useFeatures) {
version = null;
}
}
layout = ['Presto'];
description.push(data);
}
// Detect WebKit Nightly and approximate Chrome/Safari versions.
if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
// Correct build number for numeric comparison.
// (e.g. "532.5" becomes "532.05")
data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data];
// Nightly builds are postfixed with a "+".
if (name == 'Safari' && data[1].slice(-1) == '+') {
name = 'WebKit Nightly';
prerelease = 'alpha';
version = data[1].slice(0, -1);
}
// Clear incorrect browser versions.
else if (version == data[1] ||
version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
version = null;
}
// Use the full Chrome version when available.
data[1] = (/\b(?:Headless)?Chrome\/([\d.]+)/i.exec(ua) || 0)[1];
// Detect Blink layout engine.
if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') {
layout = ['Blink'];
}
// Detect JavaScriptCore.
// http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi
if (!useFeatures || (!likeChrome && !data[1])) {
layout && (layout[1] = 'like Safari');
data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : data < 602 ? 9 : data < 604 ? 10 : data < 606 ? 11 : data < 608 ? 12 : '12');
} else {
layout && (layout[1] = 'like Chrome');
data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28');
}
// Add the postfix of ".x" or "+" for approximate versions.
layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+'));
// Obscure version for some Safari 1-2 releases.
if (name == 'Safari' && (!version || parseInt(version) > 45)) {
version = data;
} else if (name == 'Chrome' && /\bHeadlessChrome/i.test(ua)) {
description.unshift('headless');
}
}
// Detect Opera desktop modes.
if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) {
name += ' ';
description.unshift('desktop mode');
if (data == 'zvav') {
name += 'Mini';
version = null;
} else {
name += 'Mobile';
}
os = os.replace(RegExp(' *' + data + '$'), '');
}
// Detect Chrome desktop mode.
else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) {
description.unshift('desktop mode');
name = 'Chrome Mobile';
version = null;
if (/\bOS X\b/.test(os)) {
manufacturer = 'Apple';
os = 'iOS 4.3+';
} else {
os = null;
}
}
// Newer versions of SRWare Iron uses the Chrome tag to indicate its version number.
else if (/\bSRWare Iron\b/.test(name) && !version) {
version = getVersion('Chrome');
}
// Strip incorrect OS versions.
if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 &&
ua.indexOf('/' + data + '-') > -1) {
os = trim(os.replace(data, ''));
}
// Ensure OS does not include the browser name.
if (os && os.indexOf(name) != -1 && !RegExp(name + ' OS').test(os)) {
os = os.replace(RegExp(' *' + qualify(name) + ' *'), '');
}
// Add layout engine.
if (layout && !/\b(?:Avant|Nook)\b/.test(name) && (
/Browser|Lunascape|Maxthon/.test(name) ||
name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) ||
/^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|SRWare Iron|Vivaldi|Web)/.test(name) && layout[1])) {
// Don't add layout details to description if they are falsey.
(data = layout[layout.length - 1]) && description.push(data);
}
// Combine contextual information.
if (description.length) {
description = ['(' + description.join('; ') + ')'];
}
// Append manufacturer to description.
if (manufacturer && product && product.indexOf(manufacturer) < 0) {
description.push('on ' + manufacturer);
}
// Append product to description.
if (product) {
description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product);
}
// Parse the OS into an object.
if (os) {
data = / ([\d.+]+)$/.exec(os);
isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/';
os = {
'architecture': 32,
'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os,
'version': data ? data[1] : null,
'toString': function() {
var version = this.version;
return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : '');
}
};
}
// Add browser/OS architecture.
if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) {
if (os) {
os.architecture = 64;
os.family = os.family.replace(RegExp(' *' + data), '');
}
if (
name && (/\bWOW64\b/i.test(ua) ||
(useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua)))
) {
description.unshift('32-bit');
}
}
// Chrome 39 and above on OS X is always 64-bit.
else if (
os && /^OS X/.test(os.family) &&
name == 'Chrome' && parseFloat(version) >= 39
) {
os.architecture = 64;
}
ua || (ua = null);
/*------------------------------------------------------------------------*/
/**
* The platform object.
*
* @name platform
* @type Object
*/
var platform = {};
/**
* The platform description.
*
* @memberOf platform
* @type string|null
*/
platform.description = ua;
/**
* The name of the browser's layout engine.
*
* The list of common layout engines include:
* "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit"
*
* @memberOf platform
* @type string|null
*/
platform.layout = layout && layout[0];
/**
* The name of the product's manufacturer.
*
* The list of manufacturers include:
* "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry",
* "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo",
* "Nokia", "Samsung" and "Sony"
*
* @memberOf platform
* @type string|null
*/
platform.manufacturer = manufacturer;
/**
* The name of the browser/environment.
*
* The list of common browser names include:
* "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE",
* "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk",
* "Opera Mini" and "Opera"
*
* Mobile versions of some browsers have "Mobile" appended to their name:
* eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile"
*
* @memberOf platform
* @type string|null
*/
platform.name = name;
/**
* The alpha/beta release indicator.
*
* @memberOf platform
* @type string|null
*/
platform.prerelease = prerelease;
/**
* The name of the product hosting the browser.
*
* The list of common products include:
*
* "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle",
* "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer"
*
* @memberOf platform
* @type string|null
*/
platform.product = product;
/**
* The browser's user agent string.
*
* @memberOf platform
* @type string|null
*/
platform.ua = ua;
/**
* The browser/environment version.
*
* @memberOf platform
* @type string|null
*/
platform.version = name && version;
/**
* The name of the operating system.
*
* @memberOf platform
* @type Object
*/
platform.os = os || {
/**
* The CPU architecture the OS is built for.
*
* @memberOf platform.os
* @type number|null
*/
'architecture': null,
/**
* The family of the OS.
*
* Common values include:
* "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista",
* "Windows XP", "OS X", "Linux", "Ubuntu", "Debian", "Fedora", "Red Hat",
* "SuSE", "Android", "iOS" and "Windows Phone"
*
* @memberOf platform.os
* @type string|null
*/
'family': null,
/**
* The version of the OS.
*
* @memberOf platform.os
* @type string|null
*/
'version': null,
/**
* Returns the OS string.
*
* @memberOf platform.os
* @returns {string} The OS string.
*/
'toString': function() { return 'null'; }
};
platform.parse = parse;
platform.toString = toStringPlatform;
if (platform.version) {
description.unshift(version);
}
if (platform.name) {
description.unshift(name);
}
if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) {
description.push(product ? '(' + os + ')' : 'on ' + os);
}
if (description.length) {
platform.description = description.join(' ');
}
return platform;
}
/*--------------------------------------------------------------------------*/
// Export platform.
var platform = parse();
// Some AMD build optimizers, like r.js, check for condition patterns like the following:
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
// Expose platform on the global object to prevent errors when platform is
// loaded by a script tag in the presence of an AMD loader.
// See http://requirejs.org/docs/errors.html#mismatch for more details.
root.platform = platform;
// Define as an anonymous module so platform can be aliased through path mapping.
define(function() {
return platform;
});
}
// Check for `exports` after `define` in case a build optimizer adds an `exports` object.
else if (freeExports && freeModule) {
// Export for CommonJS support.
forOwn(platform, function(value, key) {
freeExports[key] = value;
});
}
else {
// Export to the global object.
root.platform = platform;
}
}.call(this));
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],13:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
} ())
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
}
// if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch(e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch(e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
}
// if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) { return [] }
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; };
},{}],14:[function(require,module,exports){
const debug = require('../internal/debug')
const { MAX_LENGTH, MAX_SAFE_INTEGER } = require('../internal/constants')
const { re, t } = require('../internal/re')
const parseOptions = require('../internal/parse-options')
const { compareIdentifiers } = require('../internal/identifiers')
class SemVer {
constructor (version, options) {
options = parseOptions(options)
if (version instanceof SemVer) {
if (version.loose === !!options.loose &&
version.includePrerelease === !!options.includePrerelease) {
return version
} else {
version = version.version
}
} else if (typeof version !== 'string') {
throw new TypeError(`Invalid Version: ${version}`)
}
if (version.length > MAX_LENGTH) {
throw new TypeError(
`version is longer than ${MAX_LENGTH} characters`
)
}
debug('SemVer', version, options)
this.options = options
this.loose = !!options.loose
// this isn't actually relevant for versions, but keep it so that we
// don't run into trouble passing this.options around.
this.includePrerelease = !!options.includePrerelease
const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL])
if (!m) {
throw new TypeError(`Invalid Version: ${version}`)
}
this.raw = version
// these are actually numbers
this.major = +m[1]
this.minor = +m[2]
this.patch = +m[3]
if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
throw new TypeError('Invalid major version')
}
if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
throw new TypeError('Invalid minor version')
}
if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
throw new TypeError('Invalid patch version')
}
// numberify any prerelease numeric ids
if (!m[4]) {
this.prerelease = []
} else {
this.prerelease = m[4].split('.').map((id) => {
if (/^[0-9]+$/.test(id)) {
const num = +id
if (num >= 0 && num < MAX_SAFE_INTEGER) {
return num
}
}
return id
})
}
this.build = m[5] ? m[5].split('.') : []
this.format()
}
format () {
this.version = `${this.major}.${this.minor}.${this.patch}`
if (this.prerelease.length) {
this.version += `-${this.prerelease.join('.')}`
}
return this.version
}
toString () {
return this.version
}
compare (other) {
debug('SemVer.compare', this.version, this.options, other)
if (!(other instanceof SemVer)) {
if (typeof other === 'string' && other === this.version) {
return 0
}
other = new SemVer(other, this.options)
}
if (other.version === this.version) {
return 0
}
return this.compareMain(other) || this.comparePre(other)
}
compareMain (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options)
}
return (
compareIdentifiers(this.major, other.major) ||
compareIdentifiers(this.minor, other.minor) ||
compareIdentifiers(this.patch, other.patch)
)
}
comparePre (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options)
}
// NOT having a prerelease is > having one
if (this.prerelease.length && !other.prerelease.length) {
return -1
} else if (!this.prerelease.length && other.prerelease.length) {
return 1
} else if (!this.prerelease.length && !other.prerelease.length) {
return 0
}
let i = 0
do {
const a = this.prerelease[i]
const b = other.prerelease[i]
debug('prerelease compare', i, a, b)
if (a === undefined && b === undefined) {
return 0
} else if (b === undefined) {
return 1
} else if (a === undefined) {
return -1
} else if (a === b) {
continue
} else {
return compareIdentifiers(a, b)
}
} while (++i)
}
compareBuild (other) {
if (!(other instanceof SemVer)) {
other = new SemVer(other, this.options)
}
let i = 0
do {
const a = this.build[i]
const b = other.build[i]
debug('prerelease compare', i, a, b)
if (a === undefined && b === undefined) {
return 0
} else if (b === undefined) {
return 1
} else if (a === undefined) {
return -1
} else if (a === b) {
continue
} else {
return compareIdentifiers(a, b)
}
} while (++i)
}
// preminor will bump the version up to the next minor release, and immediately
// down to pre-release. premajor and prepatch work the same way.
inc (release, identifier) {
switch (release) {
case 'premajor':
this.prerelease.length = 0
this.patch = 0
this.minor = 0
this.major++
this.inc('pre', identifier)
break
case 'preminor':
this.prerelease.length = 0
this.patch = 0
this.minor++
this.inc('pre', identifier)
break
case 'prepatch':
// If this is already a prerelease, it will bump to the next version
// drop any prereleases that might already exist, since they are not
// relevant at this point.
this.prerelease.length = 0
this.inc('patch', identifier)
this.inc('pre', identifier)
break
// If the input is a non-prerelease version, this acts the same as
// prepatch.
case 'prerelease':
if (this.prerelease.length === 0) {
this.inc('patch', identifier)
}
this.inc('pre', identifier)
break
case 'major':
// If this is a pre-major version, bump up to the same major version.
// Otherwise increment major.
// 1.0.0-5 bumps to 1.0.0
// 1.1.0 bumps to 2.0.0
if (
this.minor !== 0 ||
this.patch !== 0 ||
this.prerelease.length === 0
) {
this.major++
}
this.minor = 0
this.patch = 0
this.prerelease = []
break
case 'minor':
// If this is a pre-minor version, bump up to the same minor version.
// Otherwise increment minor.
// 1.2.0-5 bumps to 1.2.0
// 1.2.1 bumps to 1.3.0
if (this.patch !== 0 || this.prerelease.length === 0) {
this.minor++
}
this.patch = 0
this.prerelease = []
break
case 'patch':
// If this is not a pre-release version, it will increment the patch.
// If it is a pre-release it will bump up to the same patch version.
// 1.2.0-5 patches to 1.2.0
// 1.2.0 patches to 1.2.1
if (this.prerelease.length === 0) {
this.patch++
}
this.prerelease = []
break
// This probably shouldn't be used publicly.
// 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction.
case 'pre':
if (this.prerelease.length === 0) {
this.prerelease = [0]
} else {
let i = this.prerelease.length
while (--i >= 0) {
if (typeof this.prerelease[i] === 'number') {
this.prerelease[i]++
i = -2
}
}
if (i === -1) {
// didn't increment anything
this.prerelease.push(0)
}
}
if (identifier) {
// 1.2.0-beta.1 bumps to 1.2.0-beta.2,
// 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
if (isNaN(this.prerelease[1])) {
this.prerelease = [identifier, 0]
}
} else {
this.prerelease = [identifier, 0]
}
}
break
default:
throw new Error(`invalid increment argument: ${release}`)
}
this.format()
this.raw = this.version
return this
}
}
module.exports = SemVer
},{"../internal/constants":17,"../internal/debug":18,"../internal/identifiers":19,"../internal/parse-options":20,"../internal/re":21}],15:[function(require,module,exports){
const SemVer = require('../classes/semver')
const major = (a, loose) => new SemVer(a, loose).major
module.exports = major
},{"../classes/semver":14}],16:[function(require,module,exports){
const SemVer = require('../classes/semver')
const minor = (a, loose) => new SemVer(a, loose).minor
module.exports = minor
},{"../classes/semver":14}],17:[function(require,module,exports){
// Note: this is the semver.org version of the spec that it implements
// Not necessarily the package version of this code.
const SEMVER_SPEC_VERSION = '2.0.0'
const MAX_LENGTH = 256
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
/* istanbul ignore next */ 9007199254740991
// Max safe segment length for coercion.
const MAX_SAFE_COMPONENT_LENGTH = 16
module.exports = {
SEMVER_SPEC_VERSION,
MAX_LENGTH,
MAX_SAFE_INTEGER,
MAX_SAFE_COMPONENT_LENGTH,
}
},{}],18:[function(require,module,exports){
(function (process){(function (){
const debug = (
typeof process === 'object' &&
process.env &&
process.env.NODE_DEBUG &&
/\bsemver\b/i.test(process.env.NODE_DEBUG)
) ? (...args) => console.error('SEMVER', ...args)
: () => {}
module.exports = debug
}).call(this)}).call(this,require('_process'))
},{"_process":13}],19:[function(require,module,exports){
const numeric = /^[0-9]+$/
const compareIdentifiers = (a, b) => {
const anum = numeric.test(a)
const bnum = numeric.test(b)
if (anum && bnum) {
a = +a
b = +b
}
return a === b ? 0
: (anum && !bnum) ? -1
: (bnum && !anum) ? 1
: a < b ? -1
: 1
}
const rcompareIdentifiers = (a, b) => compareIdentifiers(b, a)
module.exports = {
compareIdentifiers,
rcompareIdentifiers,
}
},{}],20:[function(require,module,exports){
// parse out just the options we care about so we always get a consistent
// obj with keys in a consistent order.
const opts = ['includePrerelease', 'loose', 'rtl']
const parseOptions = options =>
!options ? {}
: typeof options !== 'object' ? { loose: true }
: opts.filter(k => options[k]).reduce((o, k) => {
o[k] = true
return o
}, {})
module.exports = parseOptions
},{}],21:[function(require,module,exports){
const { MAX_SAFE_COMPONENT_LENGTH } = require('./constants')
const debug = require('./debug')
exports = module.exports = {}
// The actual regexps go on exports.re
const re = exports.re = []
const src = exports.src = []
const t = exports.t = {}
let R = 0
const createToken = (name, value, isGlobal) => {
const index = R++
debug(name, index, value)
t[name] = index
src[index] = value
re[index] = new RegExp(value, isGlobal ? 'g' : undefined)
}
// The following Regular Expressions can be used for tokenizing,
// validating, and parsing SemVer version strings.
// ## Numeric Identifier
// A single `0`, or a non-zero digit followed by zero or more digits.
createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*')
createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+')
// ## Non-numeric Identifier
// Zero or more digits, followed by a letter or hyphen, and then zero or
// more letters, digits, or hyphens.
createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*')
// ## Main Version
// Three dot-separated numeric identifiers.
createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` +
`(${src[t.NUMERICIDENTIFIER]})\\.` +
`(${src[t.NUMERICIDENTIFIER]})`)
createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
`(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
`(${src[t.NUMERICIDENTIFIERLOOSE]})`)
// ## Pre-release Version Identifier
// A numeric identifier, or a non-numeric identifier.
createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER]
}|${src[t.NONNUMERICIDENTIFIER]})`)
createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE]
}|${src[t.NONNUMERICIDENTIFIER]})`)
// ## Pre-release Version
// Hyphen, followed by one or more dot-separated pre-release version
// identifiers.
createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER]
}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`)
createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`)
// ## Build Metadata Identifier
// Any combination of digits, letters, or hyphens.
createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+')
// ## Build Metadata
// Plus sign, followed by one or more period-separated build metadata
// identifiers.
createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER]
}(?:\\.${src[t.BUILDIDENTIFIER]})*))`)
// ## Full Version String
// A main version, followed optionally by a pre-release version and
// build metadata.
// Note that the only major, minor, patch, and pre-release sections of
// the version string are capturing groups. The build metadata is not a
// capturing group, because it should not ever be used in version
// comparison.
createToken('FULLPLAIN', `v?${src[t.MAINVERSION]
}${src[t.PRERELEASE]}?${
src[t.BUILD]}?`)
createToken('FULL', `^${src[t.FULLPLAIN]}$`)
// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
// common in the npm registry.
createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE]
}${src[t.PRERELEASELOOSE]}?${
src[t.BUILD]}?`)
createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`)
createToken('GTLT', '((?:<|>)?=?)')
// Something like "2.*" or "1.2.x".
// Note that "x.x" is a valid xRange identifer, meaning "any version"
// Only the first item is strictly required.
createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`)
createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`)
createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
`(?:${src[t.PRERELEASE]})?${
src[t.BUILD]}?` +
`)?)?`)
createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
`(?:${src[t.PRERELEASELOOSE]})?${
src[t.BUILD]}?` +
`)?)?`)
createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`)
createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`)
// Coercion.
// Extract anything that could conceivably be a part of a valid semver
createToken('COERCE', `${'(^|[^\\d])' +
'(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` +
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
`(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
`(?:$|[^\\d])`)
createToken('COERCERTL', src[t.COERCE], true)
// Tilde ranges.
// Meaning is "reasonably at or greater than"
createToken('LONETILDE', '(?:~>?)')
createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true)
exports.tildeTrimReplace = '$1~'
createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`)
createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`)
// Caret ranges.
// Meaning is "at least and backwards compatible with"
createToken('LONECARET', '(?:\\^)')
createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true)
exports.caretTrimReplace = '$1^'
createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`)
createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`)
// A simple gt/lt/eq thing, or just "" to indicate "any version"
createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`)
createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`)
// An expression to strip any whitespace between the gtlt and the thing
// it modifies, so that `> 1.2.3` ==> `>1.2.3`
createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT]
}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true)
exports.comparatorTrimReplace = '$1$2$3'
// Something like `1.2.3 - 1.2.4`
// Note that these all use the loose form, because they'll be
// checked against either the strict or loose comparator form
// later.
createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` +
`\\s+-\\s+` +
`(${src[t.XRANGEPLAIN]})` +
`\\s*$`)
createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
`\\s+-\\s+` +
`(${src[t.XRANGEPLAINLOOSE]})` +
`\\s*$`)
// Star ranges basically just allow anything at all.
createToken('STAR', '(<|>)?=?\\s*\\*')
// >=0.0.0 is like a star
createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$')
createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$')
},{"./constants":17,"./debug":18}],22:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "NIL", {
enumerable: true,
get: function () {
return _nil.default;
}
});
Object.defineProperty(exports, "parse", {
enumerable: true,
get: function () {
return _parse.default;
}
});
Object.defineProperty(exports, "stringify", {
enumerable: true,
get: function () {
return _stringify.default;
}
});
Object.defineProperty(exports, "v1", {
enumerable: true,
get: function () {
return _v.default;
}
});
Object.defineProperty(exports, "v3", {
enumerable: true,
get: function () {
return _v2.default;
}
});
Object.defineProperty(exports, "v4", {
enumerable: true,
get: function () {
return _v3.default;
}
});
Object.defineProperty(exports, "v5", {
enumerable: true,
get: function () {
return _v4.default;
}
});
Object.defineProperty(exports, "validate", {
enumerable: true,
get: function () {
return _validate.default;
}
});
Object.defineProperty(exports, "version", {
enumerable: true,
get: function () {
return _version.default;
}
});
var _v = _interopRequireDefault(require("./v1.js"));
var _v2 = _interopRequireDefault(require("./v3.js"));
var _v3 = _interopRequireDefault(require("./v4.js"));
var _v4 = _interopRequireDefault(require("./v5.js"));
var _nil = _interopRequireDefault(require("./nil.js"));
var _version = _interopRequireDefault(require("./version.js"));
var _validate = _interopRequireDefault(require("./validate.js"));
var _stringify = _interopRequireDefault(require("./stringify.js"));
var _parse = _interopRequireDefault(require("./parse.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
},{"./nil.js":25,"./parse.js":26,"./stringify.js":30,"./v1.js":31,"./v3.js":32,"./v4.js":34,"./v5.js":35,"./validate.js":36,"./version.js":37}],23:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
/*
* Browser-compatible JavaScript MD5
*
* Modification of JavaScript MD5
* https://github.com/blueimp/JavaScript-MD5
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*
* Based on
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
function md5(bytes) {
if (typeof bytes === 'string') {
const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape
bytes = new Uint8Array(msg.length);
for (let i = 0; i < msg.length; ++i) {
bytes[i] = msg.charCodeAt(i);
}
}
return md5ToHexEncodedArray(wordsToMd5(bytesToWords(bytes), bytes.length * 8));
}
/*
* Convert an array of little-endian words to an array of bytes
*/
function md5ToHexEncodedArray(input) {
const output = [];
const length32 = input.length * 32;
const hexTab = '0123456789abcdef';
for (let i = 0; i < length32; i += 8) {
const x = input[i >> 5] >>> i % 32 & 0xff;
const hex = parseInt(hexTab.charAt(x >>> 4 & 0x0f) + hexTab.charAt(x & 0x0f), 16);
output.push(hex);
}
return output;
}
/**
* Calculate output length with padding and bit length
*/
function getOutputLength(inputLength8) {
return (inputLength8 + 64 >>> 9 << 4) + 14 + 1;
}
/*
* Calculate the MD5 of an array of little-endian words, and a bit length.
*/
function wordsToMd5(x, len) {
/* append padding */
x[len >> 5] |= 0x80 << len % 32;
x[getOutputLength(len) - 1] = len;
let a = 1732584193;
let b = -271733879;
let c = -1732584194;
let d = 271733878;
for (let i = 0; i < x.length; i += 16) {
const olda = a;
const oldb = b;
const oldc = c;
const oldd = d;
a = md5ff(a, b, c, d, x[i], 7, -680876936);
d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);
c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);
b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);
d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);
a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
c = md5ff(c, d, a, b, x[i + 10], 17, -42063);
b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);
c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);
a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);
d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);
b = md5gg(b, c, d, a, x[i], 20, -373897302);
a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);
d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);
c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);
b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);
a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);
d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);
b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);
c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);
a = md5hh(a, b, c, d, x[i + 5], 4, -378558);
d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);
a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);
b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);
d = md5hh(d, a, b, c, x[i], 11, -358537222);
c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);
b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);
a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);
d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);
c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);
b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);
a = md5ii(a, b, c, d, x[i], 6, -198630844);
d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);
a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);
b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);
c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);
d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);
b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);
a = safeAdd(a, olda);
b = safeAdd(b, oldb);
c = safeAdd(c, oldc);
d = safeAdd(d, oldd);
}
return [a, b, c, d];
}
/*
* Convert an array bytes to an array of little-endian words
* Characters >255 have their high-byte silently ignored.
*/
function bytesToWords(input) {
if (input.length === 0) {
return [];
}
const length8 = input.length * 8;
const output = new Uint32Array(getOutputLength(length8));
for (let i = 0; i < length8; i += 8) {
output[i >> 5] |= (input[i / 8] & 0xff) << i % 32;
}
return output;
}
/*
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
* to work around bugs in some JS interpreters.
*/
function safeAdd(x, y) {
const lsw = (x & 0xffff) + (y & 0xffff);
const msw = (x >> 16) + (y >> 16) + (lsw >> 16);
return msw << 16 | lsw & 0xffff;
}
/*
* Bitwise rotate a 32-bit number to the left.
*/
function bitRotateLeft(num, cnt) {
return num << cnt | num >>> 32 - cnt;
}
/*
* These functions implement the four basic operations the algorithm uses.
*/
function md5cmn(q, a, b, x, s, t) {
return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);
}
function md5ff(a, b, c, d, x, s, t) {
return md5cmn(b & c | ~b & d, a, b, x, s, t);
}
function md5gg(a, b, c, d, x, s, t) {
return md5cmn(b & d | c & ~d, a, b, x, s, t);
}
function md5hh(a, b, c, d, x, s, t) {
return md5cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5ii(a, b, c, d, x, s, t) {
return md5cmn(c ^ (b | ~d), a, b, x, s, t);
}
var _default = md5;
exports.default = _default;
},{}],24:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
var _default = {
randomUUID
};
exports.default = _default;
},{}],25:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _default = '00000000-0000-0000-0000-000000000000';
exports.default = _default;
},{}],26:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _validate = _interopRequireDefault(require("./validate.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function parse(uuid) {
if (!(0, _validate.default)(uuid)) {
throw TypeError('Invalid UUID');
}
let v;
const arr = new Uint8Array(16); // Parse ########-....-....-....-............
arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;
arr[1] = v >>> 16 & 0xff;
arr[2] = v >>> 8 & 0xff;
arr[3] = v & 0xff; // Parse ........-####-....-....-............
arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;
arr[5] = v & 0xff; // Parse ........-....-####-....-............
arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;
arr[7] = v & 0xff; // Parse ........-....-....-####-............
arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;
arr[9] = v & 0xff; // Parse ........-....-....-....-############
// (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes)
arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff;
arr[11] = v / 0x100000000 & 0xff;
arr[12] = v >>> 24 & 0xff;
arr[13] = v >>> 16 & 0xff;
arr[14] = v >>> 8 & 0xff;
arr[15] = v & 0xff;
return arr;
}
var _default = parse;
exports.default = _default;
},{"./validate.js":36}],27:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
exports.default = _default;
},{}],28:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = rng;
// Unique ID creation requires a high quality random # generator. In the browser we therefore
// require the crypto API and do not support built-in fallback to lower quality random number
// generators (like Math.random()).
let getRandomValues;
const rnds8 = new Uint8Array(16);
function rng() {
// lazy load so that environments that need to polyfill have a chance to do so
if (!getRandomValues) {
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
if (!getRandomValues) {
throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
}
}
return getRandomValues(rnds8);
}
},{}],29:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
// Adapted from Chris Veness' SHA1 code at
// http://www.movable-type.co.uk/scripts/sha1.html
function f(s, x, y, z) {
switch (s) {
case 0:
return x & y ^ ~x & z;
case 1:
return x ^ y ^ z;
case 2:
return x & y ^ x & z ^ y & z;
case 3:
return x ^ y ^ z;
}
}
function ROTL(x, n) {
return x << n | x >>> 32 - n;
}
function sha1(bytes) {
const K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
const H = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];
if (typeof bytes === 'string') {
const msg = unescape(encodeURIComponent(bytes)); // UTF8 escape
bytes = [];
for (let i = 0; i < msg.length; ++i) {
bytes.push(msg.charCodeAt(i));
}
} else if (!Array.isArray(bytes)) {
// Convert Array-like to Array
bytes = Array.prototype.slice.call(bytes);
}
bytes.push(0x80);
const l = bytes.length / 4 + 2;
const N = Math.ceil(l / 16);
const M = new Array(N);
for (let i = 0; i < N; ++i) {
const arr = new Uint32Array(16);
for (let j = 0; j < 16; ++j) {
arr[j] = bytes[i * 64 + j * 4] << 24 | bytes[i * 64 + j * 4 + 1] << 16 | bytes[i * 64 + j * 4 + 2] << 8 | bytes[i * 64 + j * 4 + 3];
}
M[i] = arr;
}
M[N - 1][14] = (bytes.length - 1) * 8 / Math.pow(2, 32);
M[N - 1][14] = Math.floor(M[N - 1][14]);
M[N - 1][15] = (bytes.length - 1) * 8 & 0xffffffff;
for (let i = 0; i < N; ++i) {
const W = new Uint32Array(80);
for (let t = 0; t < 16; ++t) {
W[t] = M[i][t];
}
for (let t = 16; t < 80; ++t) {
W[t] = ROTL(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1);
}
let a = H[0];
let b = H[1];
let c = H[2];
let d = H[3];
let e = H[4];
for (let t = 0; t < 80; ++t) {
const s = Math.floor(t / 20);
const T = ROTL(a, 5) + f(s, b, c, d) + e + K[s] + W[t] >>> 0;
e = d;
d = c;
c = ROTL(b, 30) >>> 0;
b = a;
a = T;
}
H[0] = H[0] + a >>> 0;
H[1] = H[1] + b >>> 0;
H[2] = H[2] + c >>> 0;
H[3] = H[3] + d >>> 0;
H[4] = H[4] + e >>> 0;
}
return [H[0] >> 24 & 0xff, H[0] >> 16 & 0xff, H[0] >> 8 & 0xff, H[0] & 0xff, H[1] >> 24 & 0xff, H[1] >> 16 & 0xff, H[1] >> 8 & 0xff, H[1] & 0xff, H[2] >> 24 & 0xff, H[2] >> 16 & 0xff, H[2] >> 8 & 0xff, H[2] & 0xff, H[3] >> 24 & 0xff, H[3] >> 16 & 0xff, H[3] >> 8 & 0xff, H[3] & 0xff, H[4] >> 24 & 0xff, H[4] >> 16 & 0xff, H[4] >> 8 & 0xff, H[4] & 0xff];
}
var _default = sha1;
exports.default = _default;
},{}],30:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
exports.unsafeStringify = unsafeStringify;
var _validate = _interopRequireDefault(require("./validate.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
const byteToHex = [];
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 0x100).toString(16).slice(1));
}
function unsafeStringify(arr, offset = 0) {
// Note: Be careful editing this code! It's been tuned for performance
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
}
function stringify(arr, offset = 0) {
const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one
// of the following:
// - One or more input array values don't map to a hex octet (leading to
// "undefined" in the uuid)
// - Invalid input values for the RFC `version` or `variant` fields
if (!(0, _validate.default)(uuid)) {
throw TypeError('Stringified UUID is invalid');
}
return uuid;
}
var _default = stringify;
exports.default = _default;
},{"./validate.js":36}],31:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _rng = _interopRequireDefault(require("./rng.js"));
var _stringify = require("./stringify.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// **`v1()` - Generate time-based UUID**
//
// Inspired by https://github.com/LiosK/UUID.js
// and http://docs.python.org/library/uuid.html
let _nodeId;
let _clockseq; // Previous uuid creation time
let _lastMSecs = 0;
let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details
function v1(options, buf, offset) {
let i = buf && offset || 0;
const b = buf || new Array(16);
options = options || {};
let node = options.node || _nodeId;
let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not
// specified. We do this lazily to minimize issues related to insufficient
// system entropy. See #189
if (node == null || clockseq == null) {
const seedBytes = options.random || (options.rng || _rng.default)();
if (node == null) {
// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];
}
if (clockseq == null) {
// Per 4.2.2, randomize (14 bit) clockseq
clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
}
} // UUID timestamps are 100 nano-second units since the Gregorian epoch,
// (1582-10-15 00:00). JSNumbers aren't precise enough for this, so
// time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
// (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock
// cycle to simulate higher resolution clock
let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs)
const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression
if (dt < 0 && options.clockseq === undefined) {
clockseq = clockseq + 1 & 0x3fff;
} // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
// time interval
if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
nsecs = 0;
} // Per 4.2.1.2 Throw error if too many uuids are requested
if (nsecs >= 10000) {
throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
}
_lastMSecs = msecs;
_lastNSecs = nsecs;
_clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
msecs += 12219292800000; // `time_low`
const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
b[i++] = tl >>> 24 & 0xff;
b[i++] = tl >>> 16 & 0xff;
b[i++] = tl >>> 8 & 0xff;
b[i++] = tl & 0xff; // `time_mid`
const tmh = msecs / 0x100000000 * 10000 & 0xfffffff;
b[i++] = tmh >>> 8 & 0xff;
b[i++] = tmh & 0xff; // `time_high_and_version`
b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low`
b[i++] = clockseq & 0xff; // `node`
for (let n = 0; n < 6; ++n) {
b[i + n] = node[n];
}
return buf || (0, _stringify.unsafeStringify)(b);
}
var _default = v1;
exports.default = _default;
},{"./rng.js":28,"./stringify.js":30}],32:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _v = _interopRequireDefault(require("./v35.js"));
var _md = _interopRequireDefault(require("./md5.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const v3 = (0, _v.default)('v3', 0x30, _md.default);
var _default = v3;
exports.default = _default;
},{"./md5.js":23,"./v35.js":33}],33:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.URL = exports.DNS = void 0;
exports.default = v35;
var _stringify = require("./stringify.js");
var _parse = _interopRequireDefault(require("./parse.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function stringToBytes(str) {
str = unescape(encodeURIComponent(str)); // UTF8 escape
const bytes = [];
for (let i = 0; i < str.length; ++i) {
bytes.push(str.charCodeAt(i));
}
return bytes;
}
const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
exports.DNS = DNS;
const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
exports.URL = URL;
function v35(name, version, hashfunc) {
function generateUUID(value, namespace, buf, offset) {
var _namespace;
if (typeof value === 'string') {
value = stringToBytes(value);
}
if (typeof namespace === 'string') {
namespace = (0, _parse.default)(namespace);
}
if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) {
throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)');
} // Compute hash of namespace and value, Per 4.3
// Future: Use spread syntax when supported on all platforms, e.g. `bytes =
// hashfunc([...namespace, ... value])`
let bytes = new Uint8Array(16 + value.length);
bytes.set(namespace);
bytes.set(value, namespace.length);
bytes = hashfunc(bytes);
bytes[6] = bytes[6] & 0x0f | version;
bytes[8] = bytes[8] & 0x3f | 0x80;
if (buf) {
offset = offset || 0;
for (let i = 0; i < 16; ++i) {
buf[offset + i] = bytes[i];
}
return buf;
}
return (0, _stringify.unsafeStringify)(bytes);
} // Function#name is not settable on some platforms (#270)
try {
generateUUID.name = name; // eslint-disable-next-line no-empty
} catch (err) {} // For CommonJS default export support
generateUUID.DNS = DNS;
generateUUID.URL = URL;
return generateUUID;
}
},{"./parse.js":26,"./stringify.js":30}],34:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _native = _interopRequireDefault(require("./native.js"));
var _rng = _interopRequireDefault(require("./rng.js"));
var _stringify = require("./stringify.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function v4(options, buf, offset) {
if (_native.default.randomUUID && !buf && !options) {
return _native.default.randomUUID();
}
options = options || {};
const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = rnds[6] & 0x0f | 0x40;
rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
if (buf) {
offset = offset || 0;
for (let i = 0; i < 16; ++i) {
buf[offset + i] = rnds[i];
}
return buf;
}
return (0, _stringify.unsafeStringify)(rnds);
}
var _default = v4;
exports.default = _default;
},{"./native.js":24,"./rng.js":28,"./stringify.js":30}],35:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _v = _interopRequireDefault(require("./v35.js"));
var _sha = _interopRequireDefault(require("./sha1.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const v5 = (0, _v.default)('v5', 0x50, _sha.default);
var _default = v5;
exports.default = _default;
},{"./sha1.js":29,"./v35.js":33}],36:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _regex = _interopRequireDefault(require("./regex.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function validate(uuid) {
return typeof uuid === 'string' && _regex.default.test(uuid);
}
var _default = validate;
exports.default = _default;
},{"./regex.js":27}],37:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _validate = _interopRequireDefault(require("./validate.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function version(uuid) {
if (!(0, _validate.default)(uuid)) {
throw TypeError('Invalid UUID');
}
return parseInt(uuid.slice(14, 15), 16);
}
var _default = version;
exports.default = _default;
},{"./validate.js":36}],38:[function(require,module,exports){
/*
WildEmitter.js is a slim little event emitter by @henrikjoreteg largely based
on @visionmedia's Emitter from UI Kit.
Why? I wanted it standalone.
I also wanted support for wildcard emitters like this:
emitter.on('*', function (eventName, other, event, payloads) {
});
emitter.on('somenamespace*', function (eventName, payloads) {
});
Please note that callbacks triggered by wildcard registered events also get
the event name as the first argument.
*/
module.exports = WildEmitter;
function WildEmitter() { }
WildEmitter.mixin = function (constructor) {
var prototype = constructor.prototype || constructor;
prototype.isWildEmitter= true;
// Listen on the given `event` with `fn`. Store a group name if present.
prototype.on = function (event, groupName, fn) {
this.callbacks = this.callbacks || {};
var hasGroup = (arguments.length === 3),
group = hasGroup ? arguments[1] : undefined,
func = hasGroup ? arguments[2] : arguments[1];
func._groupName = group;
(this.callbacks[event] = this.callbacks[event] || []).push(func);
return this;
};
// Adds an `event` listener that will be invoked a single
// time then automatically removed.
prototype.once = function (event, groupName, fn) {
var self = this,
hasGroup = (arguments.length === 3),
group = hasGroup ? arguments[1] : undefined,
func = hasGroup ? arguments[2] : arguments[1];
function on() {
self.off(event, on);
func.apply(this, arguments);
}
this.on(event, group, on);
return this;
};
// Unbinds an entire group
prototype.releaseGroup = function (groupName) {
this.callbacks = this.callbacks || {};
var item, i, len, handlers;
for (item in this.callbacks) {
handlers = this.callbacks[item];
for (i = 0, len = handlers.length; i < len; i++) {
if (handlers[i]._groupName === groupName) {
//console.log('removing');
// remove it and shorten the array we're looping through
handlers.splice(i, 1);
i--;
len--;
}
}
}
return this;
};
// Remove the given callback for `event` or all
// registered callbacks.
prototype.off = function (event, fn) {
this.callbacks = this.callbacks || {};
var callbacks = this.callbacks[event],
i;
if (!callbacks) return this;
// remove all handlers
if (arguments.length === 1) {
delete this.callbacks[event];
return this;
}
// remove specific handler
i = callbacks.indexOf(fn);
if (i !== -1) {
callbacks.splice(i, 1);
if (callbacks.length === 0) {
delete this.callbacks[event];
}
}
return this;
};
/// Emit `event` with the given args.
// also calls any `*` handlers
prototype.emit = function (event) {
this.callbacks = this.callbacks || {};
var args = [].slice.call(arguments, 1),
callbacks = this.callbacks[event],
specialCallbacks = this.getWildcardCallbacks(event),
i,
len,
item,
listeners;
if (callbacks) {
listeners = callbacks.slice();
for (i = 0, len = listeners.length; i < len; ++i) {
if (!listeners[i]) {
break;
}
listeners[i].apply(this, args);
}
}
if (specialCallbacks) {
len = specialCallbacks.length;
listeners = specialCallbacks.slice();
for (i = 0, len = listeners.length; i < len; ++i) {
if (!listeners[i]) {
break;
}
listeners[i].apply(this, [event].concat(args));
}
}
return this;
};
// Helper for for finding special wildcard event handlers that match the event
prototype.getWildcardCallbacks = function (eventName) {
this.callbacks = this.callbacks || {};
var item,
split,
result = [];
for (item in this.callbacks) {
split = item.split('*');
if (item === '*' || (split.length === 2 && eventName.slice(0, split[0].length) === split[0])) {
result = result.concat(this.callbacks[item]);
}
}
return result;
};
};
WildEmitter.mixin(WildEmitter);
},{}],39:[function(require,module,exports){
/*!
* EventEmitter v5.2.9 - git.io/ee
* Unlicense - http://unlicense.org/
* Oliver Caldwell - https://oli.me.uk/
* @preserve
*/
;(function (exports) {
'use strict';
/**
* Class for managing events.
* Can be extended to provide event functionality in other classes.
*
* @class EventEmitter Manages event registering and emitting.
*/
function EventEmitter() {}
// Shortcuts to improve speed and size
var proto = EventEmitter.prototype;
var originalGlobalValue = exports.EventEmitter;
/**
* Finds the index of the listener for the event in its storage array.
*
* @param {Function[]} listeners Array of listeners to search through.
* @param {Function} listener Method to look for.
* @return {Number} Index of the specified listener, -1 if not found
* @api private
*/
function indexOfListener(listeners, listener) {
var i = listeners.length;
while (i--) {
if (listeners[i].listener === listener) {
return i;
}
}
return -1;
}
/**
* Alias a method while keeping the context correct, to allow for overwriting of target method.
*
* @param {String} name The name of the target method.
* @return {Function} The aliased method
* @api private
*/
function alias(name) {
return function aliasClosure() {
return this[name].apply(this, arguments);
};
}
/**
* Returns the listener array for the specified event.
* Will initialise the event object and listener arrays if required.
* Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
* Each property in the object response is an array of listener functions.
*
* @param {String|RegExp} evt Name of the event to return the listeners from.
* @return {Function[]|Object} All listener functions for the event.
*/
proto.getListeners = function getListeners(evt) {
var events = this._getEvents();
var response;
var key;
// Return a concatenated array of all matching events if
// the selector is a regular expression.
if (evt instanceof RegExp) {
response = {};
for (key in events) {
if (events.hasOwnProperty(key) && evt.test(key)) {
response[key] = events[key];
}
}
}
else {
response = events[evt] || (events[evt] = []);
}
return response;
};
/**
* Takes a list of listener objects and flattens it into a list of listener functions.
*
* @param {Object[]} listeners Raw listener objects.
* @return {Function[]} Just the listener functions.
*/
proto.flattenListeners = function flattenListeners(listeners) {
var flatListeners = [];
var i;
for (i = 0; i < listeners.length; i += 1) {
flatListeners.push(listeners[i].listener);
}
return flatListeners;
};
/**
* Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
*
* @param {String|RegExp} evt Name of the event to return the listeners from.
* @return {Object} All listener functions for an event in an object.
*/
proto.getListenersAsObject = function getListenersAsObject(evt) {
var listeners = this.getListeners(evt);
var response;
if (listeners instanceof Array) {
response = {};
response[evt] = listeners;
}
return response || listeners;
};
function isValidListener (listener) {
if (typeof listener === 'function' || listener instanceof RegExp) {
return true
} else if (listener && typeof listener === 'object') {
return isValidListener(listener.listener)
} else {
return false
}
}
/**
* Adds a listener function to the specified event.
* The listener will not be added if it is a duplicate.
* If the listener returns true then it will be removed after it is called.
* If you pass a regular expression as the event name then the listener will be added to all events that match it.
*
* @param {String|RegExp} evt Name of the event to attach the listener to.
* @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.addListener = function addListener(evt, listener) {
if (!isValidListener(listener)) {
throw new TypeError('listener must be a function');
}
var listeners = this.getListenersAsObject(evt);
var listenerIsWrapped = typeof listener === 'object';
var key;
for (key in listeners) {
if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
listeners[key].push(listenerIsWrapped ? listener : {
listener: listener,
once: false
});
}
}
return this;
};
/**
* Alias of addListener
*/
proto.on = alias('addListener');
/**
* Semi-alias of addListener. It will add a listener that will be
* automatically removed after its first execution.
*
* @param {String|RegExp} evt Name of the event to attach the listener to.
* @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.addOnceListener = function addOnceListener(evt, listener) {
return this.addListener(evt, {
listener: listener,
once: true
});
};
/**
* Alias of addOnceListener.
*/
proto.once = alias('addOnceListener');
/**
* Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
* You need to tell it what event names should be matched by a regex.
*
* @param {String} evt Name of the event to create.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.defineEvent = function defineEvent(evt) {
this.getListeners(evt);
return this;
};
/**
* Uses defineEvent to define multiple events.
*
* @param {String[]} evts An array of event names to define.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.defineEvents = function defineEvents(evts) {
for (var i = 0; i < evts.length; i += 1) {
this.defineEvent(evts[i]);
}
return this;
};
/**
* Removes a listener function from the specified event.
* When passed a regular expression as the event name, it will remove the listener from all events that match it.
*
* @param {String|RegExp} evt Name of the event to remove the listener from.
* @param {Function} listener Method to remove from the event.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.removeListener = function removeListener(evt, listener) {
var listeners = this.getListenersAsObject(evt);
var index;
var key;
for (key in listeners) {
if (listeners.hasOwnProperty(key)) {
index = indexOfListener(listeners[key], listener);
if (index !== -1) {
listeners[key].splice(index, 1);
}
}
}
return this;
};
/**
* Alias of removeListener
*/
proto.off = alias('removeListener');
/**
* Adds listeners in bulk using the manipulateListeners method.
* If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
* You can also pass it a regular expression to add the array of listeners to all events that match it.
* Yeah, this function does quite a bit. That's probably a bad thing.
*
* @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
* @param {Function[]} [listeners] An optional array of listener functions to add.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.addListeners = function addListeners(evt, listeners) {
// Pass through to manipulateListeners
return this.manipulateListeners(false, evt, listeners);
};
/**
* Removes listeners in bulk using the manipulateListeners method.
* If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
* You can also pass it an event name and an array of listeners to be removed.
* You can also pass it a regular expression to remove the listeners from all events that match it.
*
* @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
* @param {Function[]} [listeners] An optional array of listener functions to remove.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.removeListeners = function removeListeners(evt, listeners) {
// Pass through to manipulateListeners
return this.manipulateListeners(true, evt, listeners);
};
/**
* Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
* The first argument will determine if the listeners are removed (true) or added (false).
* If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
* You can also pass it an event name and an array of listeners to be added/removed.
* You can also pass it a regular expression to manipulate the listeners of all events that match it.
*
* @param {Boolean} remove True if you want to remove listeners, false if you want to add.
* @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
* @param {Function[]} [listeners] An optional array of listener functions to add/remove.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
var i;
var value;
var single = remove ? this.removeListener : this.addListener;
var multiple = remove ? this.removeListeners : this.addListeners;
// If evt is an object then pass each of its properties to this method
if (typeof evt === 'object' && !(evt instanceof RegExp)) {
for (i in evt) {
if (evt.hasOwnProperty(i) && (value = evt[i])) {
// Pass the single listener straight through to the singular method
if (typeof value === 'function') {
single.call(this, i, value);
}
else {
// Otherwise pass back to the multiple function
multiple.call(this, i, value);
}
}
}
}
else {
// So evt must be a string
// And listeners must be an array of listeners
// Loop over it and pass each one to the multiple method
i = listeners.length;
while (i--) {
single.call(this, evt, listeners[i]);
}
}
return this;
};
/**
* Removes all listeners from a specified event.
* If you do not specify an event then all listeners will be removed.
* That means every event will be emptied.
* You can also pass a regex to remove all events that match it.
*
* @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.removeEvent = function removeEvent(evt) {
var type = typeof evt;
var events = this._getEvents();
var key;
// Remove different things depending on the state of evt
if (type === 'string') {
// Remove all listeners for the specified event
delete events[evt];
}
else if (evt instanceof RegExp) {
// Remove all events matching the regex.
for (key in events) {
if (events.hasOwnProperty(key) && evt.test(key)) {
delete events[key];
}
}
}
else {
// Remove all listeners in all events
delete this._events;
}
return this;
};
/**
* Alias of removeEvent.
*
* Added to mirror the node API.
*/
proto.removeAllListeners = alias('removeEvent');
/**
* Emits an event of your choice.
* When emitted, every listener attached to that event will be executed.
* If you pass the optional argument array then those arguments will be passed to every listener upon execution.
* Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
* So they will not arrive within the array on the other side, they will be separate.
* You can also pass a regular expression to emit to all events that match it.
*
* @param {String|RegExp} evt Name of the event to emit and execute listeners for.
* @param {Array} [args] Optional array of arguments to be passed to each listener.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.emitEvent = function emitEvent(evt, args) {
var listenersMap = this.getListenersAsObject(evt);
var listeners;
var listener;
var i;
var key;
var response;
for (key in listenersMap) {
if (listenersMap.hasOwnProperty(key)) {
listeners = listenersMap[key].slice(0);
for (i = 0; i < listeners.length; i++) {
// If the listener returns true then it shall be removed from the event
// The function is executed either with a basic call or an apply if there is an args array
listener = listeners[i];
if (listener.once === true) {
this.removeListener(evt, listener.listener);
}
response = listener.listener.apply(this, args || []);
if (response === this._getOnceReturnValue()) {
this.removeListener(evt, listener.listener);
}
}
}
}
return this;
};
/**
* Alias of emitEvent
*/
proto.trigger = alias('emitEvent');
/**
* Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
* As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
*
* @param {String|RegExp} evt Name of the event to emit and execute listeners for.
* @param {...*} Optional additional arguments to be passed to each listener.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.emit = function emit(evt) {
var args = Array.prototype.slice.call(arguments, 1);
return this.emitEvent(evt, args);
};
/**
* Sets the current value to check against when executing listeners. If a
* listeners return value matches the one set here then it will be removed
* after execution. This value defaults to true.
*
* @param {*} value The new value to check for when executing listeners.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.setOnceReturnValue = function setOnceReturnValue(value) {
this._onceReturnValue = value;
return this;
};
/**
* Fetches the current value to check against when executing listeners. If
* the listeners return value matches this one then it should be removed
* automatically. It will return true by default.
*
* @return {*|Boolean} The current value to check for or the default, true.
* @api private
*/
proto._getOnceReturnValue = function _getOnceReturnValue() {
if (this.hasOwnProperty('_onceReturnValue')) {
return this._onceReturnValue;
}
else {
return true;
}
};
/**
* Fetches the events object and creates one if required.
*
* @return {Object} The events storage object.
* @api private
*/
proto._getEvents = function _getEvents() {
return this._events || (this._events = {});
};
/**
* Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
*
* @return {Function} Non conflicting EventEmitter class.
*/
EventEmitter.noConflict = function noConflict() {
exports.EventEmitter = originalGlobalValue;
return EventEmitter;
};
// Expose the class either via AMD, CommonJS or the global object
if (typeof define === 'function' && define.amd) {
define(function () {
return EventEmitter;
});
}
else if (typeof module === 'object' && module.exports){
module.exports = EventEmitter;
}
else {
exports.EventEmitter = EventEmitter;
}
}(typeof window !== 'undefined' ? window : this || {}));
},{}],40:[function(require,module,exports){
module.exports={
"author": "OpenVidu",
"dependencies": {
"freeice": "2.2.2",
"hark": "1.2.3",
"jsnlog": "2.30.0",
"mime": "3.0.0",
"platform": "1.3.6",
"semver": "7.3.8",
"uuid": "9.0.0",
"wolfy87-eventemitter": "5.2.9",
"events": "3.3.0",
"inherits": "2.0.4"
},
"description": "OpenVidu Browser",
"devDependencies": {
"@types/node": "18.11.9",
"@types/platform": "1.3.4",
"browserify": "17.0.0",
"grunt": "1.5.3",
"grunt-cli": "1.4.3",
"grunt-contrib-copy": "1.0.0",
"grunt-contrib-sass": "2.0.0",
"grunt-contrib-uglify": "5.2.2",
"grunt-contrib-watch": "1.1.0",
"grunt-postcss": "0.9.0",
"grunt-string-replace": "1.3.3",
"grunt-ts": "6.0.0-beta.22",
"terser": "5.15.1",
"tsify": "5.0.4",
"tslint": "6.1.3",
"typedoc": "0.23.21",
"typescript": "4.9.3"
},
"license": "Apache-2.0",
"main": "lib/index.js",
"name": "openvidu-browser",
"repository": {
"type": "git",
"url": "git://github.com/OpenVidu/openvidu"
},
"scripts": {
"browserify": "VERSION=${VERSION:-dev}; mkdir -p static/js/ && cd src && ../node_modules/browserify/bin/cmd.js Main.ts -p [ tsify ] --exclude kurento-browser-extensions --debug -o ../static/js/openvidu-browser-$VERSION.js -v",
"browserify-prod": "VERSION=${VERSION:-dev}; mkdir -p static/js/ && cd src && ../node_modules/browserify/bin/cmd.js --debug Main.ts -p [ tsify ] --exclude kurento-browser-extensions | ../node_modules/terser/bin/terser --source-map content=inline --output ../static/js/openvidu-browser-$VERSION.min.js",
"build": "cd src/OpenVidu && ./../../node_modules/typescript/bin/tsc && cd ../.. && ./node_modules/typescript/bin/tsc --declaration src/index.ts --outDir ./lib --sourceMap --target es5 --lib dom,es5,es2015.promise,scripthost && rm -rf ./ts4.4 && mkdir -p ./ts4.4/lib && cp -r ./lib ./ts4.4 && find ./ts4.4/lib -type f ! -iname '*.d.ts' -delete && ./config/replace_for_ts44.sh",
"docs": "./generate-docs.sh"
},
"types": "lib/index.d.ts",
"typesVersions": {
"<4.4": {
"*": [
"ts4.4/*"
]
}
},
"version": "2.25.0"
}
},{}],41:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var OpenVidu_1 = require("./OpenVidu/OpenVidu");
var jsnlog_1 = require("jsnlog");
if (typeof globalThis !== 'undefined') {
globalThis['OpenVidu'] = OpenVidu_1.OpenVidu;
}
jsnlog_1.JL.setOptions({ enabled: false });
},{"./OpenVidu/OpenVidu":46,"jsnlog":7}],42:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Connection = void 0;
var Stream_1 = require("./Stream");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var ExceptionEvent_1 = require("../OpenViduInternal/Events/ExceptionEvent");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var Connection = (function () {
function Connection(session, connectionOptions) {
this.session = session;
this.disposed = false;
var msg = "'Connection' created ";
if (!!connectionOptions.role) {
this.localOptions = connectionOptions;
this.connectionId = this.localOptions.id;
this.creationTime = this.localOptions.createdAt;
this.data = this.localOptions.metadata;
this.rpcSessionId = this.localOptions.sessionId;
this.role = this.localOptions.role;
this.record = this.localOptions.record;
msg += '(local)';
}
else {
this.remoteOptions = connectionOptions;
this.connectionId = this.remoteOptions.id;
this.creationTime = this.remoteOptions.createdAt;
if (this.remoteOptions.metadata) {
this.data = this.remoteOptions.metadata;
}
if (this.remoteOptions.streams) {
this.initRemoteStreams(this.remoteOptions.streams);
}
msg += "(remote) with 'connectionId' [" + this.remoteOptions.id + ']';
}
logger.info(msg);
}
Connection.prototype.sendIceCandidate = function (candidate) {
var _this = this;
if (!this.disposed) {
logger.debug((!!this.stream.outboundStreamOpts ? 'Local' : 'Remote') + 'candidate for' + this.connectionId, candidate);
this.session.openvidu.sendRequest('onIceCandidate', {
endpointName: this.connectionId,
candidate: candidate.candidate,
sdpMid: candidate.sdpMid,
sdpMLineIndex: candidate.sdpMLineIndex
}, function (error, response) {
if (error) {
logger.error('Error sending ICE candidate: ' + JSON.stringify(error));
_this.session.emitEvent('exception', [
new ExceptionEvent_1.ExceptionEvent(_this.session, ExceptionEvent_1.ExceptionEventName.ICE_CANDIDATE_ERROR, _this.session, 'There was an unexpected error on the server-side processing an ICE candidate generated and sent by the client-side', error)
]);
}
});
}
else {
logger.warn("Connection ".concat(this.connectionId, " disposed when trying to send an ICE candidate. ICE candidate not sent"));
}
};
Connection.prototype.initRemoteStreams = function (options) {
var _this = this;
options.forEach(function (opts) {
var streamOptions = {
id: opts.id,
createdAt: opts.createdAt,
connection: _this,
hasAudio: opts.hasAudio,
hasVideo: opts.hasVideo,
audioActive: opts.audioActive,
videoActive: opts.videoActive,
typeOfVideo: opts.typeOfVideo,
frameRate: opts.frameRate,
videoDimensions: !!opts.videoDimensions ? JSON.parse(opts.videoDimensions) : undefined,
filter: !!opts.filter ? opts.filter : undefined
};
var stream = new Stream_1.Stream(_this.session, streamOptions);
_this.addStream(stream);
});
logger.info("Remote 'Connection' with 'connectionId' [" + this.connectionId + '] is now configured for receiving Streams with options: ', this.stream.inboundStreamOpts);
};
Connection.prototype.addStream = function (stream) {
stream.connection = this;
this.stream = stream;
};
Connection.prototype.removeStream = function () {
delete this.stream;
};
Connection.prototype.dispose = function () {
this.disposed = true;
this.removeStream();
};
return Connection;
}());
exports.Connection = Connection;
},{"../OpenViduInternal/Events/ExceptionEvent":59,"../OpenViduInternal/Logger/OpenViduLogger":81,"./Stream":49}],43:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventDispatcher = void 0;
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var EventEmitter = require("wolfy87-eventemitter");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var EventDispatcher = (function () {
function EventDispatcher() {
this.userHandlerArrowHandler = new WeakMap();
this.ee = new EventEmitter();
}
EventDispatcher.prototype.onAux = function (type, message, handler) {
var arrowHandler = function (event) {
if (event) {
logger.debug(message, event);
}
else {
logger.debug(message);
}
handler(event);
};
this.userHandlerArrowHandler.set(handler, arrowHandler);
this.ee.on(type, arrowHandler);
return this;
};
EventDispatcher.prototype.onceAux = function (type, message, handler) {
var _this = this;
var arrowHandler = function (event) {
if (event) {
logger.debug(message, event);
}
else {
logger.debug(message);
}
handler(event);
_this.userHandlerArrowHandler.delete(handler);
};
this.userHandlerArrowHandler.set(handler, arrowHandler);
this.ee.once(type, arrowHandler);
return this;
};
EventDispatcher.prototype.offAux = function (type, handler) {
if (!handler) {
this.ee.removeAllListeners(type);
}
else {
var arrowHandler = this.userHandlerArrowHandler.get(handler);
if (!!arrowHandler) {
this.ee.off(type, arrowHandler);
}
this.userHandlerArrowHandler.delete(handler);
}
return this;
};
return EventDispatcher;
}());
exports.EventDispatcher = EventDispatcher;
},{"../OpenViduInternal/Logger/OpenViduLogger":81,"wolfy87-eventemitter":39}],44:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Filter = void 0;
var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var Filter = (function () {
function Filter(type, options) {
this.handlers = new Map();
this.type = type;
this.options = options;
}
Filter.prototype.execMethod = function (method, params) {
var _this = this;
return new Promise(function (resolve, reject) {
var _a;
logger.info('Executing filter method to stream ' + _this.stream.streamId);
var finalParams;
var successExecMethod = function (triggerEvent) {
logger.info('Filter method successfully executed on Stream ' + _this.stream.streamId);
var oldValue = Object.assign({}, _this.stream.filter);
_this.stream.filter.lastExecMethod = { method: method, params: finalParams };
if (triggerEvent) {
_this.stream.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.session, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')
]);
_this.stream.streamManager.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.stream.streamManager, _this.stream, 'filter', _this.stream.filter, oldValue, 'execFilterMethod')
]);
}
return resolve();
};
if (_this.type.startsWith('VB:')) {
if (typeof params === 'string') {
try {
params = JSON.parse(params);
}
catch (error) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'Wrong params syntax: ' + error));
}
}
finalParams = params;
if (method === 'update') {
if (!((_a = _this.stream.virtualBackgroundSinkElements) === null || _a === void 0 ? void 0 : _a.VB)) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'There is no Virtual Background filter applied'));
}
else {
_this.stream.virtualBackgroundSinkElements.VB.updateValues(params)
.then(function () { return successExecMethod(false); })
.catch(function (error) {
if (error.name === OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR) {
return reject(new OpenViduError_1.OpenViduError(error.name, error.message));
}
else {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'Error updating values on Virtual Background filter: ' + error));
}
});
}
}
else {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, "Unknown Virtual Background method \"".concat(method, "\"")));
}
}
else {
var stringParams = void 0;
if (typeof params !== 'string') {
try {
stringParams = JSON.stringify(params);
}
catch (error) {
var errorMsg = "'params' property must be a JSON formatted object";
logger.error(errorMsg);
return reject(errorMsg);
}
}
else {
stringParams = params;
}
finalParams = stringParams;
_this.stream.session.openvidu.sendRequest('execFilterMethod', { streamId: _this.stream.streamId, method: method, params: stringParams }, function (error, response) {
if (error) {
logger.error('Error executing filter method for Stream ' + _this.stream.streamId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to execute a filter method"));
}
else {
return reject(error);
}
}
else {
return successExecMethod(true);
}
});
}
});
};
Filter.prototype.addEventListener = function (eventType, handler) {
var _this = this;
return new Promise(function (resolve, reject) {
logger.info('Adding filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId);
_this.stream.session.openvidu.sendRequest('addFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) {
if (error) {
logger.error('Error adding filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener"));
}
else {
return reject(error);
}
}
else {
_this.handlers.set(eventType, handler);
logger.info('Filter event listener to event ' + eventType + ' successfully applied on Stream ' + _this.stream.streamId);
return resolve();
}
});
});
};
Filter.prototype.removeEventListener = function (eventType) {
var _this = this;
return new Promise(function (resolve, reject) {
logger.info('Removing filter event listener to event ' + eventType + ' to stream ' + _this.stream.streamId);
_this.stream.session.openvidu.sendRequest('removeFilterEventListener', { streamId: _this.stream.streamId, eventType: eventType }, function (error, response) {
if (error) {
logger.error('Error removing filter event listener to event ' + eventType + 'for Stream ' + _this.stream.streamId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to add a filter event listener"));
}
else {
return reject(error);
}
}
else {
_this.handlers.delete(eventType);
logger.info('Filter event listener to event ' + eventType + ' successfully removed on Stream ' + _this.stream.streamId);
return resolve();
}
});
});
};
return Filter;
}());
exports.Filter = Filter;
},{"../OpenViduInternal/Enums/OpenViduError":53,"../OpenViduInternal/Events/StreamPropertyChangedEvent":69,"../OpenViduInternal/Logger/OpenViduLogger":81}],45:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LocalRecorder = void 0;
var LocalRecorderState_1 = require("../OpenViduInternal/Enums/LocalRecorderState");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var Platform_1 = require("../OpenViduInternal/Utils/Platform");
var Mime = require("mime/lite");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var LocalRecorder = (function () {
function LocalRecorder(stream) {
this.stream = stream;
this.chunks = [];
platform = Platform_1.PlatformUtils.getInstance();
this.connectionId = !!this.stream.connection ? this.stream.connection.connectionId : 'default-connection';
this.id = this.stream.streamId + '_' + this.connectionId + '_localrecord';
this.state = LocalRecorderState_1.LocalRecorderState.READY;
}
LocalRecorder.prototype.record = function (options) {
var _this = this;
return new Promise(function (resolve, reject) {
try {
if (typeof options === 'string' || options instanceof String) {
return reject("When calling LocalRecorder.record(options) parameter 'options' cannot be a string. Must be an object like { mimeType: \"".concat(options, "\" }"));
}
if (typeof MediaRecorder === 'undefined') {
logger.error('MediaRecorder not supported on your device. See compatibility in https://caniuse.com/#search=MediaRecorder');
throw Error('MediaRecorder not supported on your device. See compatibility in https://caniuse.com/#search=MediaRecorder');
}
if (_this.state !== LocalRecorderState_1.LocalRecorderState.READY) {
throw Error("'LocalRecord.record()' needs 'LocalRecord.state' to be 'READY' (current value: '" +
_this.state +
"'). Call 'LocalRecorder.clean()' or init a new LocalRecorder before");
}
logger.log("Starting local recording of stream '" + _this.stream.streamId + "' of connection '" + _this.connectionId + "'");
if (!options) {
options = { mimeType: 'video/webm' };
}
else if (!options.mimeType) {
options.mimeType = 'video/webm';
}
_this.mediaRecorder = new MediaRecorder(_this.stream.getMediaStream(), options);
_this.mediaRecorder.start();
}
catch (err) {
return reject(err);
}
_this.mediaRecorder.ondataavailable = function (e) {
if (e.data.size > 0) {
_this.chunks.push(e.data);
}
};
_this.mediaRecorder.onerror = function (e) {
logger.error('MediaRecorder error: ', e);
};
_this.mediaRecorder.onstart = function () {
logger.log('MediaRecorder started (state=' + _this.mediaRecorder.state + ')');
};
_this.mediaRecorder.onstop = function () {
_this.onStopDefault();
};
_this.mediaRecorder.onpause = function () {
logger.log('MediaRecorder paused (state=' + _this.mediaRecorder.state + ')');
};
_this.mediaRecorder.onresume = function () {
logger.log('MediaRecorder resumed (state=' + _this.mediaRecorder.state + ')');
};
_this.state = LocalRecorderState_1.LocalRecorderState.RECORDING;
return resolve();
});
};
LocalRecorder.prototype.stop = function () {
var _this = this;
return new Promise(function (resolve, reject) {
try {
if (_this.state === LocalRecorderState_1.LocalRecorderState.READY || _this.state === LocalRecorderState_1.LocalRecorderState.FINISHED) {
throw Error("'LocalRecord.stop()' needs 'LocalRecord.state' to be 'RECORDING' or 'PAUSED' (current value: '" +
_this.state +
"'). Call 'LocalRecorder.start()' before");
}
_this.mediaRecorder.onstop = function () {
_this.onStopDefault();
return resolve();
};
_this.mediaRecorder.stop();
}
catch (e) {
return reject(e);
}
});
};
LocalRecorder.prototype.pause = function () {
var _this = this;
return new Promise(function (resolve, reject) {
try {
if (_this.state !== LocalRecorderState_1.LocalRecorderState.RECORDING) {
return reject(Error("'LocalRecord.pause()' needs 'LocalRecord.state' to be 'RECORDING' (current value: '" +
_this.state +
"'). Call 'LocalRecorder.start()' or 'LocalRecorder.resume()' before"));
}
_this.mediaRecorder.pause();
_this.state = LocalRecorderState_1.LocalRecorderState.PAUSED;
return resolve();
}
catch (error) {
return reject(error);
}
});
};
LocalRecorder.prototype.resume = function () {
var _this = this;
return new Promise(function (resolve, reject) {
try {
if (_this.state !== LocalRecorderState_1.LocalRecorderState.PAUSED) {
throw Error("'LocalRecord.resume()' needs 'LocalRecord.state' to be 'PAUSED' (current value: '" +
_this.state +
"'). Call 'LocalRecorder.pause()' before");
}
_this.mediaRecorder.resume();
_this.state = LocalRecorderState_1.LocalRecorderState.RECORDING;
return resolve();
}
catch (error) {
return reject(error);
}
});
};
LocalRecorder.prototype.preview = function (parentElement) {
if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) {
throw Error("'LocalRecord.preview()' needs 'LocalRecord.state' to be 'FINISHED' (current value: '" +
this.state +
"'). Call 'LocalRecorder.stop()' before");
}
this.videoPreview = document.createElement('video');
this.videoPreview.id = this.id;
this.videoPreview.autoplay = true;
if (platform.isSafariBrowser()) {
this.videoPreview.playsInline = true;
}
if (typeof parentElement === 'string') {
var parentElementDom = document.getElementById(parentElement);
if (parentElementDom) {
this.videoPreview = parentElementDom.appendChild(this.videoPreview);
}
}
else {
this.videoPreview = parentElement.appendChild(this.videoPreview);
}
this.videoPreview.src = this.videoPreviewSrc;
return this.videoPreview;
};
LocalRecorder.prototype.clean = function () {
var _this = this;
var f = function () {
delete _this.blob;
_this.chunks = [];
_this.state = LocalRecorderState_1.LocalRecorderState.READY;
};
if (this.state === LocalRecorderState_1.LocalRecorderState.RECORDING || this.state === LocalRecorderState_1.LocalRecorderState.PAUSED) {
this.stop()
.then(function () { return f(); })
.catch(function () { return f(); });
}
else {
f();
}
};
LocalRecorder.prototype.download = function () {
if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) {
throw Error("'LocalRecord.download()' needs 'LocalRecord.state' to be 'FINISHED' (current value: '" +
this.state +
"'). Call 'LocalRecorder.stop()' before");
}
else {
var a = document.createElement('a');
a.style.display = 'none';
document.body.appendChild(a);
var url = globalThis.URL.createObjectURL(this.blob);
a.href = url;
a.download = this.id + '.' + Mime.getExtension(this.blob.type);
a.click();
globalThis.URL.revokeObjectURL(url);
document.body.removeChild(a);
}
};
LocalRecorder.prototype.getBlob = function () {
if (this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) {
throw Error("Call 'LocalRecord.stop()' before getting Blob file");
}
else {
return this.blob;
}
};
LocalRecorder.prototype.uploadAsBinary = function (endpoint, headers) {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) {
return reject(Error("'LocalRecord.uploadAsBinary()' needs 'LocalRecord.state' to be 'FINISHED' (current value: '" +
_this.state +
"'). Call 'LocalRecorder.stop()' before"));
}
else {
var http_1 = new XMLHttpRequest();
http_1.open('POST', endpoint, true);
if (typeof headers === 'object') {
for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) {
var key = _a[_i];
http_1.setRequestHeader(key, headers[key]);
}
}
http_1.onreadystatechange = function () {
if (http_1.readyState === 4) {
if (http_1.status.toString().charAt(0) === '2') {
return resolve(http_1.responseText);
}
else {
return reject(http_1.status);
}
}
};
http_1.send(_this.blob);
}
});
};
LocalRecorder.prototype.uploadAsMultipartfile = function (endpoint, headers) {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this.state !== LocalRecorderState_1.LocalRecorderState.FINISHED) {
return reject(Error("'LocalRecord.uploadAsMultipartfile()' needs 'LocalRecord.state' to be 'FINISHED' (current value: '" +
_this.state +
"'). Call 'LocalRecorder.stop()' before"));
}
else {
var http_2 = new XMLHttpRequest();
http_2.open('POST', endpoint, true);
if (typeof headers === 'object') {
for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) {
var key = _a[_i];
http_2.setRequestHeader(key, headers[key]);
}
}
var sendable = new FormData();
sendable.append('file', _this.blob, _this.id + '.' + Mime.getExtension(_this.blob.type));
http_2.onreadystatechange = function () {
if (http_2.readyState === 4) {
if (http_2.status.toString().charAt(0) === '2') {
return resolve(http_2.responseText);
}
else {
return reject(http_2.status);
}
}
};
http_2.send(sendable);
}
});
};
LocalRecorder.prototype.onStopDefault = function () {
logger.log('MediaRecorder stopped (state=' + this.mediaRecorder.state + ')');
this.blob = new Blob(this.chunks, { type: this.mediaRecorder.mimeType });
this.chunks = [];
this.videoPreviewSrc = globalThis.URL.createObjectURL(this.blob);
this.state = LocalRecorderState_1.LocalRecorderState.FINISHED;
};
return LocalRecorder;
}());
exports.LocalRecorder = LocalRecorder;
},{"../OpenViduInternal/Enums/LocalRecorderState":52,"../OpenViduInternal/Logger/OpenViduLogger":81,"../OpenViduInternal/Utils/Platform":85,"mime/lite":9}],46:[function(require,module,exports){
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenVidu = void 0;
var LocalRecorder_1 = require("./LocalRecorder");
var Publisher_1 = require("./Publisher");
var Session_1 = require("./Session");
var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent");
var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var Platform_1 = require("../OpenViduInternal/Utils/Platform");
var screenSharingAuto = require("../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto");
var screenSharing = require("../OpenViduInternal/ScreenSharing/Screen-Capturing");
var OpenViduLoggerConfiguration_1 = require("../OpenViduInternal/Logger/OpenViduLoggerConfiguration");
var EventEmitter = require("wolfy87-eventemitter");
var RpcBuilder = require("../OpenViduInternal/KurentoUtils/kurento-jsonrpc");
var packageJson = require('../../package.json');
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var OpenVidu = (function () {
function OpenVidu() {
var _this = this;
this.masterNodeHasCrashed = false;
this.publishers = [];
this.secret = '';
this.recorder = false;
this.stt = false;
this.life = -1;
this.advancedConfiguration = {};
this.webrtcStatsInterval = -1;
this.sendBrowserLogs = OpenViduLoggerConfiguration_1.OpenViduLoggerConfiguration.disabled;
this.isAtLeastPro = false;
this.isEnterprise = false;
this.ee = new EventEmitter();
platform = Platform_1.PlatformUtils.getInstance();
this.libraryVersion = packageJson.version;
logger.info('OpenVidu initialized');
logger.info('Platform detected: ' + platform.getDescription());
logger.info('openvidu-browser version: ' + this.libraryVersion);
if (platform.isMobileDevice() || platform.isReactNative()) {
this.onOrientationChanged(function () {
_this.publishers.forEach(function (publisher) {
if (publisher.stream.isLocalStreamPublished && !!publisher.stream && !!publisher.stream.hasVideo) {
_this.sendNewVideoDimensionsIfRequired(publisher, 'deviceRotated', 75, 10);
}
});
});
}
}
OpenVidu.prototype.initSession = function () {
this.session = new Session_1.Session(this);
return this.session;
};
OpenVidu.prototype.initPublisher = function (targetElement, param2, param3) {
var properties;
if (!!param2 && typeof param2 !== 'function') {
properties = param2;
properties = {
audioSource: typeof properties.audioSource !== 'undefined' ? properties.audioSource : undefined,
frameRate: typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack
? undefined
: typeof properties.frameRate !== 'undefined'
? properties.frameRate
: undefined,
insertMode: typeof properties.insertMode !== 'undefined'
? typeof properties.insertMode === 'string'
? VideoInsertMode_1.VideoInsertMode[properties.insertMode]
: properties.insertMode
: VideoInsertMode_1.VideoInsertMode.APPEND,
mirror: typeof properties.mirror !== 'undefined' ? properties.mirror : true,
publishAudio: typeof properties.publishAudio !== 'undefined' ? properties.publishAudio : true,
publishVideo: typeof properties.publishVideo !== 'undefined' ? properties.publishVideo : true,
resolution: typeof MediaStreamTrack !== 'undefined' && properties.videoSource instanceof MediaStreamTrack
? undefined
: typeof properties.resolution !== 'undefined'
? properties.resolution
: '640x480',
videoSource: typeof properties.videoSource !== 'undefined' ? properties.videoSource : undefined,
videoSimulcast: properties.videoSimulcast,
filter: properties.filter
};
}
else {
properties = {
insertMode: VideoInsertMode_1.VideoInsertMode.APPEND,
mirror: true,
publishAudio: true,
publishVideo: true,
resolution: '640x480'
};
}
var publisher = new Publisher_1.Publisher(targetElement, properties, this);
var completionHandler;
if (!!param2 && typeof param2 === 'function') {
completionHandler = param2;
}
else if (!!param3) {
completionHandler = param3;
}
publisher
.initialize()
.then(function () {
if (completionHandler !== undefined) {
completionHandler(undefined);
}
publisher.emitEvent('accessAllowed', []);
})
.catch(function (error) {
if (completionHandler !== undefined) {
completionHandler(error);
}
publisher.emitEvent('accessDenied', [error]);
});
this.publishers.push(publisher);
return publisher;
};
OpenVidu.prototype.initPublisherAsync = function (targetElement, properties) {
var _this = this;
return new Promise(function (resolve, reject) {
var publisher;
var callback = function (error) {
if (!!error) {
return reject(error);
}
else {
return resolve(publisher);
}
};
if (!!properties) {
publisher = _this.initPublisher(targetElement, properties, callback);
}
else {
publisher = _this.initPublisher(targetElement, callback);
}
});
};
OpenVidu.prototype.initLocalRecorder = function (stream) {
return new LocalRecorder_1.LocalRecorder(stream);
};
OpenVidu.prototype.checkSystemRequirements = function () {
if (platform.isIPhoneOrIPad()) {
return (platform.isIOSWithSafari() ||
platform.isChromeMobileBrowser() ||
platform.isFirefoxMobileBrowser() ||
platform.isOperaMobileBrowser() ||
platform.isEdgeMobileBrowser() ||
platform.isIonicIos());
}
return (platform.isChromeBrowser() ||
platform.isChromeMobileBrowser() ||
platform.isFirefoxBrowser() ||
platform.isFirefoxMobileBrowser() ||
platform.isOperaBrowser() ||
platform.isOperaMobileBrowser() ||
platform.isEdgeBrowser() ||
platform.isEdgeMobileBrowser() ||
platform.isSamsungBrowser() ||
platform.isSafariBrowser() ||
platform.isAndroidBrowser() ||
platform.isElectron() ||
platform.isNodeJs());
};
OpenVidu.prototype.checkScreenSharingCapabilities = function () {
return platform.canScreenShare();
};
OpenVidu.prototype.getDevices = function () {
return new Promise(function (resolve, reject) {
navigator.mediaDevices
.enumerateDevices()
.then(function (deviceInfos) {
var _a;
var devices = [];
if (platform.isIonicAndroid() && typeof cordova != 'undefined' && ((_a = cordova === null || cordova === void 0 ? void 0 : cordova.plugins) === null || _a === void 0 ? void 0 : _a.EnumerateDevicesPlugin)) {
cordova.plugins.EnumerateDevicesPlugin.getEnumerateDevices().then(function (pluginDevices) {
var pluginAudioDevices = [];
var videoDevices = [];
var audioDevices = [];
pluginAudioDevices = pluginDevices.filter(function (device) { return device.kind === 'audioinput'; });
videoDevices = deviceInfos.filter(function (device) { return device.kind === 'videoinput'; });
audioDevices = deviceInfos.filter(function (device) { return device.kind === 'audioinput'; });
videoDevices.forEach(function (deviceInfo, index) {
if (!deviceInfo.label) {
var label = '';
if (index === 0) {
label = 'Front Camera';
}
else if (index === 1) {
label = 'Back Camera';
}
else {
label = 'Unknown Camera';
}
devices.push({
kind: deviceInfo.kind,
deviceId: deviceInfo.deviceId,
label: label
});
}
else {
devices.push({
kind: deviceInfo.kind,
deviceId: deviceInfo.deviceId,
label: deviceInfo.label
});
}
});
audioDevices.forEach(function (deviceInfo, index) {
if (!deviceInfo.label) {
var label = '';
switch (index) {
case 0:
label = 'Default';
break;
case 1:
var defaultMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Built'); })[0];
label = defaultMatch ? defaultMatch.label : 'Built-in Microphone';
break;
case 2:
var wiredMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Wired'); })[0];
if (wiredMatch) {
label = wiredMatch.label;
}
else {
label = 'Headset earpiece';
}
break;
case 3:
var wirelessMatch = pluginAudioDevices.filter(function (d) { return d.label.includes('Bluetooth'); })[0];
label = wirelessMatch ? wirelessMatch.label : 'Wireless';
break;
default:
label = 'Unknown Microphone';
break;
}
devices.push({
kind: deviceInfo.kind,
deviceId: deviceInfo.deviceId,
label: label
});
}
else {
devices.push({
kind: deviceInfo.kind,
deviceId: deviceInfo.deviceId,
label: deviceInfo.label
});
}
});
return resolve(devices);
});
}
else {
deviceInfos.forEach(function (deviceInfo) {
if (deviceInfo.kind === 'audioinput' || deviceInfo.kind === 'videoinput') {
devices.push({
kind: deviceInfo.kind,
deviceId: deviceInfo.deviceId,
label: deviceInfo.label
});
}
});
return resolve(devices);
}
})
.catch(function (error) {
logger.error('Error getting devices', error);
return reject(error);
});
});
};
OpenVidu.prototype.getUserMedia = function (options) {
var _this = this;
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var askForAudioStreamOnly, myConstraints, mustAskForAudioTrackLater, mediaStream, error_1, errorName, errorMessage, constraintsAux, mediaStream, error_2, errorName, errorMessage, error_3;
var _this = this;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
askForAudioStreamOnly = function (previousMediaStream, constraints) { return __awaiter(_this, void 0, void 0, function () {
var definedAudioConstraint, constraintsAux, audioOnlyStream, error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
definedAudioConstraint = constraints.audio === undefined ? true : constraints.audio;
constraintsAux = { audio: definedAudioConstraint, video: false };
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4, navigator.mediaDevices.getUserMedia(constraintsAux)];
case 2:
audioOnlyStream = _a.sent();
previousMediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]);
return [2, resolve(previousMediaStream)];
case 3:
error_4 = _a.sent();
previousMediaStream.getAudioTracks().forEach(function (track) {
track.stop();
});
previousMediaStream.getVideoTracks().forEach(function (track) {
track.stop();
});
return [2, reject(this.generateAudioDeviceError(error_4, constraintsAux))];
case 4: return [2];
}
});
}); };
_c.label = 1;
case 1:
_c.trys.push([1, 20, , 21]);
return [4, this.generateMediaConstraints(options)];
case 2:
myConstraints = _c.sent();
if (!((!!myConstraints.videoTrack && !!myConstraints.audioTrack) ||
(!!myConstraints.audioTrack && ((_a = myConstraints.constraints) === null || _a === void 0 ? void 0 : _a.video) === false) ||
(!!myConstraints.videoTrack && ((_b = myConstraints.constraints) === null || _b === void 0 ? void 0 : _b.audio) === false))) return [3, 3];
return [2, resolve(this.addAlreadyProvidedTracks(myConstraints, new MediaStream()))];
case 3:
if (!!myConstraints.videoTrack) {
delete myConstraints.constraints.video;
}
if (!!myConstraints.audioTrack) {
delete myConstraints.constraints.audio;
}
mustAskForAudioTrackLater = false;
if (!(typeof options.videoSource === 'string')) return [3, 12];
if (!(options.videoSource === 'screen' ||
options.videoSource === 'window' ||
(platform.isElectron() && options.videoSource.startsWith('screen:')))) return [3, 12];
mustAskForAudioTrackLater =
!myConstraints.audioTrack && options.audioSource !== null && options.audioSource !== false;
if (!(navigator.mediaDevices['getDisplayMedia'] && !platform.isElectron())) return [3, 11];
_c.label = 4;
case 4:
_c.trys.push([4, 9, , 10]);
return [4, navigator.mediaDevices['getDisplayMedia']({ video: true })];
case 5:
mediaStream = _c.sent();
this.addAlreadyProvidedTracks(myConstraints, mediaStream);
if (!mustAskForAudioTrackLater) return [3, 7];
return [4, askForAudioStreamOnly(mediaStream, myConstraints.constraints)];
case 6:
_c.sent();
return [2];
case 7: return [2, resolve(mediaStream)];
case 8: return [3, 10];
case 9:
error_1 = _c.sent();
errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED;
errorMessage = error_1.toString();
return [2, reject(new OpenViduError_1.OpenViduError(errorName, errorMessage))];
case 10: return [3, 11];
case 11: return [3, 12];
case 12:
constraintsAux = mustAskForAudioTrackLater
? { video: myConstraints.constraints.video }
: myConstraints.constraints;
_c.label = 13;
case 13:
_c.trys.push([13, 18, , 19]);
return [4, navigator.mediaDevices.getUserMedia(constraintsAux)];
case 14:
mediaStream = _c.sent();
this.addAlreadyProvidedTracks(myConstraints, mediaStream);
if (!mustAskForAudioTrackLater) return [3, 16];
return [4, askForAudioStreamOnly(mediaStream, myConstraints.constraints)];
case 15:
_c.sent();
return [3, 17];
case 16: return [2, resolve(mediaStream)];
case 17: return [3, 19];
case 18:
error_2 = _c.sent();
errorName = void 0;
errorMessage = error_2.toString();
if (!(options.videoSource === 'screen')) {
errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED;
}
else {
errorName = OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED;
}
return [2, reject(new OpenViduError_1.OpenViduError(errorName, errorMessage))];
case 19: return [3, 21];
case 20:
error_3 = _c.sent();
reject(error_3);
return [3, 21];
case 21: return [2];
}
});
}); });
};
OpenVidu.prototype.enableProdMode = function () {
logger.enableProdMode();
};
OpenVidu.prototype.setAdvancedConfiguration = function (configuration) {
this.advancedConfiguration = configuration;
};
OpenVidu.prototype.onOrientationChanged = function (handler) {
globalThis.addEventListener('orientationchange', handler);
};
OpenVidu.prototype.sendNewVideoDimensionsIfRequired = function (publisher, reason, WAIT_INTERVAL, MAX_ATTEMPTS) {
var _this = this;
var _a, _b, _c, _d;
var attempts = 0;
var oldWidth = ((_b = (_a = publisher === null || publisher === void 0 ? void 0 : publisher.stream) === null || _a === void 0 ? void 0 : _a.videoDimensions) === null || _b === void 0 ? void 0 : _b.width) || 0;
var oldHeight = ((_d = (_c = publisher === null || publisher === void 0 ? void 0 : publisher.stream) === null || _c === void 0 ? void 0 : _c.videoDimensions) === null || _d === void 0 ? void 0 : _d.height) || 0;
var repeatUntilChangeOrMaxAttempts = setInterval(function () {
attempts++;
if (attempts > MAX_ATTEMPTS) {
clearTimeout(repeatUntilChangeOrMaxAttempts);
}
publisher.getVideoDimensions().then(function (newDimensions) {
if (newDimensions.width !== oldWidth || newDimensions.height !== oldHeight) {
clearTimeout(repeatUntilChangeOrMaxAttempts);
_this.sendVideoDimensionsChangedEvent(publisher, reason, oldWidth, oldHeight, newDimensions.width, newDimensions.height);
}
});
}, WAIT_INTERVAL);
};
OpenVidu.prototype.sendVideoDimensionsChangedEvent = function (publisher, reason, oldWidth, oldHeight, newWidth, newHeight) {
var _this = this;
publisher.stream.videoDimensions = {
width: newWidth || 0,
height: newHeight || 0
};
this.sendRequest('streamPropertyChanged', {
streamId: publisher.stream.streamId,
property: 'videoDimensions',
newValue: JSON.stringify(publisher.stream.videoDimensions),
reason: reason
}, function (error, response) {
if (error) {
logger.error("Error sending 'streamPropertyChanged' event", error);
}
else {
_this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, reason)
]);
publisher.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, 'videoDimensions', publisher.stream.videoDimensions, { width: oldWidth, height: oldHeight }, reason)
]);
_this.session.sendVideoData(publisher);
}
});
};
OpenVidu.prototype.sendTrackChangedEvent = function (publisher, oldLabel, newLabel, propertyType) {
var _this = this;
var oldValue = { label: oldLabel };
var newValue = { label: newLabel };
var reason = 'trackReplaced';
if (publisher.stream.isLocalStreamPublished) {
this.sendRequest('streamPropertyChanged', {
streamId: publisher.stream.streamId,
property: propertyType,
newValue: newValue,
reason: reason
}, function (error, response) {
if (error) {
logger.error("Error sending 'streamPropertyChanged' event", error);
}
else {
_this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, publisher.stream, propertyType, newValue, oldValue, reason)
]);
publisher.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, propertyType, newValue, oldValue, reason)
]);
}
});
}
else {
this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(this.session, publisher.stream, propertyType, newValue, oldValue, reason)
]);
publisher.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(publisher, publisher.stream, propertyType, newValue, oldValue, reason)
]);
}
};
OpenVidu.prototype.generateMediaConstraints = function (publisherProperties) {
var _this = this;
return new Promise(function (resolve, reject) {
var myConstraints = {
audioTrack: undefined,
videoTrack: undefined,
constraints: {
audio: undefined,
video: undefined
}
};
var audioSource = publisherProperties.audioSource;
var videoSource = publisherProperties.videoSource;
if (audioSource === null || audioSource === false) {
myConstraints.constraints.audio = false;
}
if (videoSource === null || videoSource === false) {
myConstraints.constraints.video = false;
}
if (myConstraints.constraints.audio === false && myConstraints.constraints.video === false) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.NO_INPUT_SOURCE_SET, "Properties 'audioSource' and 'videoSource' cannot be set to false or null at the same time"));
}
if (typeof MediaStreamTrack !== 'undefined' && audioSource instanceof MediaStreamTrack) {
myConstraints.audioTrack = audioSource;
}
if (typeof MediaStreamTrack !== 'undefined' && videoSource instanceof MediaStreamTrack) {
myConstraints.videoTrack = videoSource;
}
if (audioSource === undefined) {
myConstraints.constraints.audio = true;
}
if (videoSource === undefined) {
myConstraints.constraints.video = {
width: {
ideal: 640
},
height: {
ideal: 480
}
};
}
if (videoSource !== null && videoSource !== false) {
if (!!publisherProperties.resolution) {
var widthAndHeight = publisherProperties.resolution.toLowerCase().split('x');
var idealWidth = Number(widthAndHeight[0]);
var idealHeight = Number(widthAndHeight[1]);
myConstraints.constraints.video = {
width: {
ideal: idealWidth
},
height: {
ideal: idealHeight
}
};
}
if (!!publisherProperties.frameRate) {
myConstraints.constraints.video.frameRate = { ideal: publisherProperties.frameRate };
}
}
_this.configureDeviceIdOrScreensharing(myConstraints, publisherProperties, resolve, reject);
return resolve(myConstraints);
});
};
OpenVidu.prototype.startWs = function (onConnectSucces) {
var config = {
heartbeat: 5000,
ws: {
uri: this.wsUri + '?sessionId=' + this.session.sessionId,
onconnected: onConnectSucces,
ondisconnect: this.disconnectCallback.bind(this),
onreconnecting: this.reconnectingCallback.bind(this),
onreconnected: this.reconnectedCallback.bind(this),
ismasternodecrashed: this.isMasterNodeCrashed.bind(this)
},
rpc: {
requestTimeout: 10000,
heartbeatRequestTimeout: 5000,
participantJoined: this.session.onParticipantJoined.bind(this.session),
participantPublished: this.session.onParticipantPublished.bind(this.session),
participantUnpublished: this.session.onParticipantUnpublished.bind(this.session),
participantLeft: this.session.onParticipantLeft.bind(this.session),
participantEvicted: this.session.onParticipantEvicted.bind(this.session),
recordingStarted: this.session.onRecordingStarted.bind(this.session),
recordingStopped: this.session.onRecordingStopped.bind(this.session),
sendMessage: this.session.onNewMessage.bind(this.session),
streamPropertyChanged: this.session.onStreamPropertyChanged.bind(this.session),
connectionPropertyChanged: this.session.onConnectionPropertyChanged.bind(this.session),
networkQualityLevelChanged: this.session.onNetworkQualityLevelChangedChanged.bind(this.session),
filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session),
iceCandidate: this.session.recvIceCandidate.bind(this.session),
mediaError: this.session.onMediaError.bind(this.session),
masterNodeCrashedNotification: this.onMasterNodeCrashedNotification.bind(this),
forciblyReconnectSubscriber: this.session.onForciblyReconnectSubscriber.bind(this.session),
speechToTextMessage: this.session.onSpeechToTextMessage.bind(this.session),
speechToTextDisconnected: this.session.onSpeechToTextDisconnected.bind(this.session)
}
};
this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config);
};
OpenVidu.prototype.onMasterNodeCrashedNotification = function (response) {
console.error('Master Node has crashed');
this.masterNodeHasCrashed = true;
this.session.onLostConnection('nodeCrashed');
this.jsonRpcClient.close(4103, 'Master Node has crashed');
};
OpenVidu.prototype.getWsReadyState = function () {
return this.jsonRpcClient.getReadyState();
};
OpenVidu.prototype.closeWs = function () {
this.jsonRpcClient.close(4102, 'Connection closed by client');
};
OpenVidu.prototype.sendRequest = function (method, params, callback) {
var _a;
if (params && params instanceof Function) {
callback = params;
params = {};
}
logger.debug('Sending request: {method:"' + method + '", params: ' + JSON.stringify(params) + '}');
(_a = this.jsonRpcClient) === null || _a === void 0 ? void 0 : _a.send(method, params, callback);
};
OpenVidu.prototype.getWsUri = function () {
return this.wsUri;
};
OpenVidu.prototype.getSecret = function () {
return this.secret;
};
OpenVidu.prototype.getRecorder = function () {
return this.recorder;
};
OpenVidu.prototype.getStt = function () {
return this.stt;
};
OpenVidu.prototype.generateAudioDeviceError = function (error, constraints) {
if (error.name === 'Error') {
error.name = error.constructor.name;
}
var errorName, errorMessage;
switch (error.name.toLowerCase()) {
case 'notfounderror':
errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND;
errorMessage = error.toString();
return new OpenViduError_1.OpenViduError(errorName, errorMessage);
case 'notallowederror':
errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED;
errorMessage = error.toString();
return new OpenViduError_1.OpenViduError(errorName, errorMessage);
case 'overconstrainederror':
if (error.constraint.toLowerCase() === 'deviceid') {
errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND;
errorMessage =
"Audio input device with deviceId '" +
constraints.audio.deviceId.exact +
"' not found";
}
else {
errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR;
errorMessage = "Audio input device doesn't support the value passed for constraint '" + error.constraint + "'";
}
return new OpenViduError_1.OpenViduError(errorName, errorMessage);
case 'notreadableerror':
errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE;
errorMessage = error.toString();
return new OpenViduError_1.OpenViduError(errorName, errorMessage);
default:
return new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_GENERIC_ERROR, error.toString());
}
};
OpenVidu.prototype.addAlreadyProvidedTracks = function (myConstraints, mediaStream, stream) {
if (!!myConstraints.videoTrack) {
mediaStream.addTrack(myConstraints.videoTrack);
if (!!stream) {
if (!!myConstraints.constraints.video) {
stream.lastVideoTrackConstraints = myConstraints.constraints.video;
}
else {
stream.lastVideoTrackConstraints = myConstraints.videoTrack.getConstraints();
}
}
}
if (!!myConstraints.audioTrack) {
mediaStream.addTrack(myConstraints.audioTrack);
}
return mediaStream;
};
OpenVidu.prototype.configureDeviceIdOrScreensharing = function (myConstraints, publisherProperties, resolve, reject) {
var _this = this;
var audioSource = publisherProperties.audioSource;
var videoSource = publisherProperties.videoSource;
if (typeof audioSource === 'string') {
myConstraints.constraints.audio = { deviceId: { exact: audioSource } };
}
if (typeof videoSource === 'string') {
if (!this.isScreenShare(videoSource)) {
this.setVideoSource(myConstraints, videoSource);
}
else {
if (!this.checkScreenSharingCapabilities()) {
var error = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_SHARING_NOT_SUPPORTED, 'You can only screen share in desktop Chrome, Firefox, Opera, Safari (>=13.0), Edge (>= 80) or Electron. Detected client: ' +
platform.getName() +
' ' +
platform.getVersion());
logger.error(error);
return reject(error);
}
else {
if (platform.isElectron()) {
var prefix = 'screen:';
var videoSourceString = videoSource;
var electronScreenId = videoSourceString.substr(videoSourceString.indexOf(prefix) + prefix.length);
myConstraints.constraints.video = {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: electronScreenId
}
};
return resolve(myConstraints);
}
else {
if (!!this.advancedConfiguration.screenShareChromeExtension &&
!(platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser()) &&
!navigator.mediaDevices['getDisplayMedia']) {
screenSharing.getScreenConstraints(function (error, screenConstraints) {
if (!!error ||
(!!screenConstraints.mandatory && screenConstraints.mandatory.chromeMediaSource === 'screen')) {
if (error === 'permission-denied' || error === 'PermissionDeniedError') {
var error_5 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop');
logger.error(error_5);
return reject(error_5);
}
else {
var extensionId = _this.advancedConfiguration
.screenShareChromeExtension.split('/')
.pop()
.trim();
screenSharing.getChromeExtensionStatus(extensionId, function (status) {
if (status === 'installed-disabled') {
var error_6 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension');
logger.error(error_6);
return reject(error_6);
}
if (status === 'not-installed') {
var error_7 = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, _this.advancedConfiguration.screenShareChromeExtension);
logger.error(error_7);
return reject(error_7);
}
});
return;
}
}
else {
myConstraints.constraints.video = screenConstraints;
return resolve(myConstraints);
}
});
return;
}
else {
if (navigator.mediaDevices['getDisplayMedia']) {
return resolve(myConstraints);
}
else {
var firefoxString = platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser()
? publisherProperties.videoSource
: undefined;
screenSharingAuto.getScreenId(firefoxString, function (error, sourceId, screenConstraints) {
if (!!error) {
if (error === 'not-installed') {
var extensionUrl = !!_this.advancedConfiguration.screenShareChromeExtension
? _this.advancedConfiguration.screenShareChromeExtension
: 'https://chrome.google.com/webstore/detail/openvidu-screensharing/lfcgfepafnobdloecchnfaclibenjold';
var err = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_NOT_INSTALLED, extensionUrl);
logger.error(err);
return reject(err);
}
else if (error === 'installed-disabled') {
var err = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_EXTENSION_DISABLED, 'You must enable the screen extension');
logger.error(err);
return reject(err);
}
else if (error === 'permission-denied') {
var err = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED, 'You must allow access to one window of your desktop');
logger.error(err);
return reject(err);
}
else {
var err = new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, 'Unknown error when accessing screen share');
logger.error(err);
logger.error(error);
return reject(err);
}
}
else {
myConstraints.constraints.video = screenConstraints.video;
return resolve(myConstraints);
}
});
return;
}
}
}
}
}
}
};
OpenVidu.prototype.setVideoSource = function (myConstraints, videoSource) {
if (!myConstraints.constraints.video) {
myConstraints.constraints.video = {};
}
myConstraints.constraints.video['deviceId'] = { exact: videoSource };
};
OpenVidu.prototype.disconnectCallback = function () {
logger.warn('Websocket connection lost');
if (this.isRoomAvailable()) {
this.session.onLostConnection('networkDisconnect');
}
else {
alert('Connection error. Please reload page.');
}
};
OpenVidu.prototype.reconnectingCallback = function () {
logger.warn('Websocket connection lost (reconnecting)');
if (!this.isRoomAvailable()) {
alert('Connection error. Please reload page.');
}
else {
this.session.emitEvent('reconnecting', []);
}
};
OpenVidu.prototype.reconnectWebsocketThroughRpcConnectMethod = function (rpcSessionId) {
var _this = this;
this.sendRequest('connect', { sessionId: rpcSessionId, reconnect: true }, function (error, response) {
if (!!error) {
if (_this.isMasterNodeCrashed()) {
logger.warn('Master Node has crashed!');
}
else {
logger.error(error);
var notifyLostConnection_1 = function (reason, errorMsg) {
logger.warn(errorMsg);
_this.session.onLostConnection(reason);
_this.jsonRpcClient.close(4101, 'Reconnection fault: ' + errorMsg);
};
var rpcSessionStatus = function () {
if (_this.life === -1) {
notifyLostConnection_1('networkDisconnect', 'WS successfully reconnected but the user was already evicted due to timeout');
}
else {
_this.sendRequest('sessionStatus', { sessionId: _this.session.sessionId }, function (error, response) {
if (error != null) {
console.error('Error checking session status', error);
}
else {
if (_this.life === response.life) {
notifyLostConnection_1('networkDisconnect', 'WS successfully reconnected but the user was already evicted due to timeout');
}
else {
notifyLostConnection_1('nodeCrashed', 'WS successfully reconnected to OpenVidu Server but your Master Node crashed');
}
}
});
}
};
if (error.code === 40007 && error.message === 'reconnection error') {
console.error('Invalid RPC sessionId. Client network disconnection or Master Node crash');
rpcSessionStatus();
}
else {
rpcSessionStatus();
}
}
}
else {
_this.jsonRpcClient.resetPing();
_this.session.onRecoveredConnection();
}
});
};
OpenVidu.prototype.reconnectedCallback = function () {
logger.warn('Websocket reconnected');
if (this.isRoomAvailable()) {
if (!!this.session.connection) {
this.reconnectWebsocketThroughRpcConnectMethod(this.session.connection.rpcSessionId);
}
else {
logger.warn('There was no previous connection when running reconnection callback');
var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this.session, 'networkDisconnect');
this.session.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]);
sessionDisconnectEvent.callDefaultBehavior();
}
}
else {
alert('Connection error. Please reload page.');
}
};
OpenVidu.prototype.isMasterNodeCrashed = function () {
return this.masterNodeHasCrashed;
};
OpenVidu.prototype.isRoomAvailable = function () {
if (this.session !== undefined && this.session instanceof Session_1.Session) {
return true;
}
else {
logger.warn('Session instance not found');
return false;
}
};
OpenVidu.prototype.isScreenShare = function (videoSource) {
return videoSource === 'screen' || videoSource === 'window' || (platform.isElectron() && videoSource.startsWith('screen:'));
};
return OpenVidu;
}());
exports.OpenVidu = OpenVidu;
},{"../../package.json":40,"../OpenViduInternal/Enums/OpenViduError":53,"../OpenViduInternal/Enums/VideoInsertMode":55,"../OpenViduInternal/Events/SessionDisconnectedEvent":64,"../OpenViduInternal/Events/StreamPropertyChangedEvent":69,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":76,"../OpenViduInternal/Logger/OpenViduLogger":81,"../OpenViduInternal/Logger/OpenViduLoggerConfiguration":82,"../OpenViduInternal/ScreenSharing/Screen-Capturing":84,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":83,"../OpenViduInternal/Utils/Platform":85,"./LocalRecorder":45,"./Publisher":47,"./Session":48,"wolfy87-eventemitter":39}],47:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Publisher = void 0;
var Session_1 = require("./Session");
var Stream_1 = require("./Stream");
var StreamManager_1 = require("./StreamManager");
var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent");
var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var Platform_1 = require("../OpenViduInternal/Utils/Platform");
var TypeOfVideo_1 = require("../OpenViduInternal/Enums/TypeOfVideo");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var Publisher = (function (_super) {
__extends(Publisher, _super);
function Publisher(targEl, properties, openvidu) {
var _this = _super.call(this, new Stream_1.Stream(!!openvidu.session ? openvidu.session : new Session_1.Session(openvidu), {
publisherProperties: properties,
mediaConstraints: {}
}), targEl) || this;
_this.accessAllowed = false;
_this.isSubscribedToRemote = false;
_this.accessDenied = false;
platform = Platform_1.PlatformUtils.getInstance();
_this.properties = properties;
_this.openvidu = openvidu;
_this.stream.ee.on('local-stream-destroyed', function (reason) {
_this.stream.isLocalStreamPublished = false;
var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', _this.stream, reason);
_this.emitEvent('streamDestroyed', [streamEvent]);
streamEvent.callDefaultBehavior();
});
return _this;
}
Publisher.prototype.publishAudio = function (enabled) {
var _this = this;
if (this.stream.audioActive !== enabled) {
var affectedMediaStream = this.stream.displayMyRemote()
? this.stream.localMediaStreamWhenSubscribedToRemote
: this.stream.getMediaStream();
affectedMediaStream.getAudioTracks().forEach(function (track) {
track.enabled = enabled;
});
if (!!this.session && !!this.stream.streamId) {
this.session.openvidu.sendRequest('streamPropertyChanged', {
streamId: this.stream.streamId,
property: 'audioActive',
newValue: enabled,
reason: 'publishAudio'
}, function (error, response) {
if (error) {
logger.error("Error sending 'streamPropertyChanged' event", error);
}
else {
_this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'audioActive', enabled, !enabled, 'publishAudio')
]);
_this.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'audioActive', enabled, !enabled, 'publishAudio')
]);
_this.session.sendVideoData(_this.stream.streamManager);
}
});
}
this.stream.audioActive = enabled;
logger.info("'Publisher' has " + (enabled ? 'published' : 'unpublished') + ' its audio stream');
}
};
Publisher.prototype.publishVideo = function (enabled, resource) {
var _this = this;
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var affectedMediaStream_1, mustRestartMediaStream_1, oldVideoTrack, replaceVideoTrack, mediaStream, error_1;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(this.stream.videoActive !== enabled)) return [3, 9];
affectedMediaStream_1 = this.stream.displayMyRemote()
? this.stream.localMediaStreamWhenSubscribedToRemote
: this.stream.getMediaStream();
mustRestartMediaStream_1 = false;
affectedMediaStream_1.getVideoTracks().forEach(function (track) {
track.enabled = enabled;
if (!enabled && resource === true) {
track.stop();
}
else if (enabled && track.readyState === 'ended') {
mustRestartMediaStream_1 = true;
}
});
if (!(!enabled && resource === true && !!this.stream.filter && this.stream.filter.type.startsWith('VB:'))) return [3, 2];
this.stream.lastVBFilter = this.stream.filter;
return [4, this.stream.removeFilterAux(true)];
case 1:
_a.sent();
_a.label = 2;
case 2:
if (!mustRestartMediaStream_1) return [3, 8];
oldVideoTrack = affectedMediaStream_1.getVideoTracks()[0];
affectedMediaStream_1.removeTrack(oldVideoTrack);
replaceVideoTrack = function (tr) { return __awaiter(_this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
affectedMediaStream_1.addTrack(tr);
if (!this.stream.isLocalStreamPublished) return [3, 2];
return [4, this.replaceTrackInRtcRtpSender(tr)];
case 1:
_a.sent();
_a.label = 2;
case 2:
if (!!this.stream.lastVBFilter) {
setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
var options, lastExecMethod;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
options = this.stream.lastVBFilter.options;
lastExecMethod = this.stream.lastVBFilter.lastExecMethod;
if (!!lastExecMethod && lastExecMethod.method === 'update') {
options = Object.assign({}, options, lastExecMethod.params);
}
return [4, this.stream.applyFilter(this.stream.lastVBFilter.type, options)];
case 1:
_a.sent();
delete this.stream.lastVBFilter;
return [2];
}
});
}); }, 1);
}
return [2];
}
});
}); };
if (!(!!resource && resource instanceof MediaStreamTrack)) return [3, 4];
return [4, replaceVideoTrack(resource)];
case 3:
_a.sent();
return [3, 8];
case 4:
_a.trys.push([4, 7, , 8]);
return [4, navigator.mediaDevices.getUserMedia({
audio: false,
video: this.stream.lastVideoTrackConstraints
})];
case 5:
mediaStream = _a.sent();
return [4, replaceVideoTrack(mediaStream.getVideoTracks()[0])];
case 6:
_a.sent();
return [3, 8];
case 7:
error_1 = _a.sent();
return [2, reject(error_1)];
case 8:
if (!!this.session && !!this.stream.streamId) {
this.session.openvidu.sendRequest('streamPropertyChanged', {
streamId: this.stream.streamId,
property: 'videoActive',
newValue: enabled,
reason: 'publishVideo'
}, function (error, response) {
if (error) {
logger.error("Error sending 'streamPropertyChanged' event", error);
}
else {
_this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this.stream, 'videoActive', enabled, !enabled, 'publishVideo')
]);
_this.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, _this.stream, 'videoActive', enabled, !enabled, 'publishVideo')
]);
_this.session.sendVideoData(_this.stream.streamManager);
}
});
}
this.stream.videoActive = enabled;
logger.info("'Publisher' has " + (enabled ? 'published' : 'unpublished') + ' its video stream');
return [2, resolve()];
case 9: return [2];
}
});
}); });
};
Publisher.prototype.subscribeToRemote = function (value) {
value = value !== undefined ? value : true;
this.isSubscribedToRemote = value;
this.stream.subscribeToMyRemote(value);
};
Publisher.prototype.on = function (type, handler) {
var _this = this;
_super.prototype.on.call(this, type, handler);
if (type === 'streamCreated') {
if (!!this.stream && this.stream.isLocalStreamPublished) {
this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]);
}
else {
this.stream.ee.on('stream-created-by-publisher', function () {
_this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]);
});
}
}
if (type === 'accessAllowed') {
if (this.accessAllowed) {
this.emitEvent('accessAllowed', []);
}
}
if (type === 'accessDenied') {
if (this.accessDenied) {
this.emitEvent('accessDenied', []);
}
}
return this;
};
Publisher.prototype.once = function (type, handler) {
var _this = this;
_super.prototype.once.call(this, type, handler);
if (type === 'streamCreated') {
if (!!this.stream && this.stream.isLocalStreamPublished) {
this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, this, 'streamCreated', this.stream, '')]);
}
else {
this.stream.ee.once('stream-created-by-publisher', function () {
_this.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', _this.stream, '')]);
});
}
}
if (type === 'accessAllowed') {
if (this.accessAllowed) {
this.emitEvent('accessAllowed', []);
}
}
if (type === 'accessDenied') {
if (this.accessDenied) {
this.emitEvent('accessDenied', []);
}
}
return this;
};
Publisher.prototype.off = function (type, handler) {
_super.prototype.off.call(this, type, handler);
return this;
};
Publisher.prototype.replaceTrack = function (track) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2, this.replaceTrackAux(track, true)];
});
});
};
Publisher.prototype.initialize = function () {
var _this = this;
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var constraints, constraintsAux, timeForDialogEvent, startTime, errorCallback, successCallback, getMediaSuccess, getMediaError, myConstraints, outboundStreamOptions, definedAudioConstraint, mediaStream, mediaStream, error_2, error_3;
var _this = this;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
constraints = {};
constraintsAux = {};
timeForDialogEvent = 2000;
errorCallback = function (openViduError) {
_this.accessDenied = true;
_this.accessAllowed = false;
logger.error("Publisher initialization failed. ".concat(openViduError.name, ": ").concat(openViduError.message));
return reject(openViduError);
};
successCallback = function (mediaStream) {
var _a, _b;
_this.accessAllowed = true;
_this.accessDenied = false;
if (typeof MediaStreamTrack !== 'undefined' && _this.properties.audioSource instanceof MediaStreamTrack) {
mediaStream.removeTrack(mediaStream.getAudioTracks()[0]);
mediaStream.addTrack(_this.properties.audioSource);
}
if (typeof MediaStreamTrack !== 'undefined' && _this.properties.videoSource instanceof MediaStreamTrack) {
mediaStream.removeTrack(mediaStream.getVideoTracks()[0]);
mediaStream.addTrack(_this.properties.videoSource);
}
if (!!mediaStream.getAudioTracks()[0]) {
var enabled = _this.stream.audioActive !== undefined && _this.stream.audioActive !== null
? _this.stream.audioActive
: !!_this.stream.outboundStreamOpts.publisherProperties.publishAudio;
mediaStream.getAudioTracks()[0].enabled = enabled;
}
if (!!mediaStream.getVideoTracks()[0]) {
var enabled = _this.stream.videoActive !== undefined && _this.stream.videoActive !== null
? _this.stream.videoActive
: !!_this.stream.outboundStreamOpts.publisherProperties.publishVideo;
mediaStream.getVideoTracks()[0].enabled = enabled;
}
for (var _i = 0, _c = mediaStream.getAudioTracks(); _i < _c.length; _i++) {
var track = _c[_i];
if (!((_a = track.contentHint) === null || _a === void 0 ? void 0 : _a.length)) {
track.contentHint = '';
logger.info("Audio track Content Hint set: '".concat(track.contentHint, "'"));
}
}
for (var _d = 0, _e = mediaStream.getVideoTracks(); _d < _e.length; _d++) {
var track = _e[_d];
if (!((_b = track.contentHint) === null || _b === void 0 ? void 0 : _b.length)) {
switch (_this.stream.typeOfVideo) {
case TypeOfVideo_1.TypeOfVideo.SCREEN:
track.contentHint = 'detail';
break;
case TypeOfVideo_1.TypeOfVideo.CUSTOM:
logger.warn('CUSTOM type video track was provided without Content Hint!');
track.contentHint = 'motion';
break;
case TypeOfVideo_1.TypeOfVideo.CAMERA:
case TypeOfVideo_1.TypeOfVideo.IPCAM:
default:
track.contentHint = 'motion';
break;
}
logger.info("Video track Content Hint set: '".concat(track.contentHint, "'"));
}
}
_this.initializeVideoReference(mediaStream);
if (!_this.stream.displayMyRemote()) {
_this.stream.updateMediaStreamInVideos();
}
delete _this.firstVideoElement;
if (_this.stream.isSendVideo()) {
_this.getVideoDimensions().then(function (dimensions) {
_this.stream.videoDimensions = {
width: dimensions.width,
height: dimensions.height
};
if (_this.stream.isSendScreen()) {
_this.screenShareResizeInterval = setInterval(function () {
var settings = mediaStream.getVideoTracks()[0].getSettings();
var newWidth = settings.width;
var newHeight = settings.height;
var widthChanged = newWidth != null && newWidth !== _this.stream.videoDimensions.width;
var heightChanged = newHeight != null && newHeight !== _this.stream.videoDimensions.height;
if (_this.stream.isLocalStreamPublished && (widthChanged || heightChanged)) {
_this.openvidu.sendVideoDimensionsChangedEvent(_this, 'screenResized', _this.stream.videoDimensions.width, _this.stream.videoDimensions.height, newWidth || 0, newHeight || 0);
}
}, 650);
}
_this.stream.isLocalStreamReadyToPublish = true;
_this.stream.ee.emitEvent('stream-ready-to-publish', []);
});
}
else {
_this.stream.isLocalStreamReadyToPublish = true;
_this.stream.ee.emitEvent('stream-ready-to-publish', []);
}
return resolve();
};
getMediaSuccess = function (mediaStream, definedAudioConstraint) { return __awaiter(_this, void 0, void 0, function () {
var audioOnlyStream, error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.clearPermissionDialogTimer(startTime, timeForDialogEvent);
if (!(this.stream.isSendScreen() && this.stream.isSendAudio())) return [3, 5];
constraintsAux.audio = definedAudioConstraint;
constraintsAux.video = false;
startTime = Date.now();
this.setPermissionDialogTimer(timeForDialogEvent);
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4, navigator.mediaDevices.getUserMedia(constraintsAux)];
case 2:
audioOnlyStream = _a.sent();
this.clearPermissionDialogTimer(startTime, timeForDialogEvent);
mediaStream.addTrack(audioOnlyStream.getAudioTracks()[0]);
successCallback(mediaStream);
return [3, 4];
case 3:
error_4 = _a.sent();
this.clearPermissionDialogTimer(startTime, timeForDialogEvent);
mediaStream.getAudioTracks().forEach(function (track) {
track.stop();
});
mediaStream.getVideoTracks().forEach(function (track) {
track.stop();
});
errorCallback(this.openvidu.generateAudioDeviceError(error_4, constraints));
return [2];
case 4: return [3, 6];
case 5:
successCallback(mediaStream);
_a.label = 6;
case 6: return [2];
}
});
}); };
getMediaError = function (error) { return __awaiter(_this, void 0, void 0, function () {
var errorName, errorMessage, _a, mediaStream, error_5, mediaStream, error_6;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
logger.error("getMediaError: ".concat(error.toString()));
this.clearPermissionDialogTimer(startTime, timeForDialogEvent);
if (error.name === 'Error') {
error.name = error.constructor.name;
}
_a = error.name.toLowerCase();
switch (_a) {
case 'notfounderror': return [3, 1];
case 'notallowederror': return [3, 5];
case 'overconstrainederror': return [3, 6];
case 'aborterror': return [3, 10];
case 'notreadableerror': return [3, 10];
}
return [3, 11];
case 1:
_b.trys.push([1, 3, , 4]);
return [4, navigator.mediaDevices.getUserMedia({
audio: false,
video: constraints.video
})];
case 2:
mediaStream = _b.sent();
mediaStream.getVideoTracks().forEach(function (track) {
track.stop();
});
errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND;
errorMessage = error.toString();
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 4];
case 3:
error_5 = _b.sent();
errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND;
errorMessage = error_5.toString();
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 4];
case 4: return [3, 12];
case 5:
errorName = this.stream.isSendScreen()
? OpenViduError_1.OpenViduErrorName.SCREEN_CAPTURE_DENIED
: OpenViduError_1.OpenViduErrorName.DEVICE_ACCESS_DENIED;
errorMessage = error.toString();
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 12];
case 6:
_b.trys.push([6, 8, , 9]);
return [4, navigator.mediaDevices.getUserMedia({
audio: false,
video: constraints.video
})];
case 7:
mediaStream = _b.sent();
mediaStream.getVideoTracks().forEach(function (track) {
track.stop();
});
if (error.constraint.toLowerCase() === 'deviceid') {
errorName = OpenViduError_1.OpenViduErrorName.INPUT_AUDIO_DEVICE_NOT_FOUND;
errorMessage =
"Audio input device with deviceId '" +
constraints.audio.deviceId.exact +
"' not found";
}
else {
errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR;
errorMessage =
"Audio input device doesn't support the value passed for constraint '" + error.constraint + "'";
}
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 9];
case 8:
error_6 = _b.sent();
if (error_6.constraint.toLowerCase() === 'deviceid') {
errorName = OpenViduError_1.OpenViduErrorName.INPUT_VIDEO_DEVICE_NOT_FOUND;
errorMessage =
"Video input device with deviceId '" +
constraints.video.deviceId.exact +
"' not found";
}
else {
errorName = OpenViduError_1.OpenViduErrorName.PUBLISHER_PROPERTIES_ERROR;
errorMessage =
"Video input device doesn't support the value passed for constraint '" + error_6.constraint + "'";
}
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 9];
case 9: return [3, 12];
case 10:
errorName = OpenViduError_1.OpenViduErrorName.DEVICE_ALREADY_IN_USE;
errorMessage = error.toString();
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 12];
case 11:
errorName = OpenViduError_1.OpenViduErrorName.GENERIC_ERROR;
errorMessage = error.toString();
errorCallback(new OpenViduError_1.OpenViduError(errorName, errorMessage));
return [3, 12];
case 12: return [2];
}
});
}); };
_c.label = 1;
case 1:
_c.trys.push([1, 14, , 15]);
return [4, this.openvidu.generateMediaConstraints(this.properties)];
case 2:
myConstraints = _c.sent();
if (!((!!myConstraints.videoTrack && !!myConstraints.audioTrack) ||
(!!myConstraints.audioTrack && ((_a = myConstraints.constraints) === null || _a === void 0 ? void 0 : _a.video) === false) ||
(!!myConstraints.videoTrack && ((_b = myConstraints.constraints) === null || _b === void 0 ? void 0 : _b.audio) === false))) return [3, 3];
successCallback(this.openvidu.addAlreadyProvidedTracks(myConstraints, new MediaStream(), this.stream));
return [3, 13];
case 3:
constraints = myConstraints.constraints;
outboundStreamOptions = {
mediaConstraints: constraints,
publisherProperties: this.properties
};
this.stream.setOutboundStreamOptions(outboundStreamOptions);
definedAudioConstraint = constraints.audio === undefined ? true : constraints.audio;
constraintsAux.audio = this.stream.isSendScreen() ? false : definedAudioConstraint;
constraintsAux.video = constraints.video;
startTime = Date.now();
this.setPermissionDialogTimer(timeForDialogEvent);
_c.label = 4;
case 4:
_c.trys.push([4, 11, , 13]);
if (!(this.stream.isSendScreen() && navigator.mediaDevices['getDisplayMedia'] && !platform.isElectron())) return [3, 7];
return [4, navigator.mediaDevices['getDisplayMedia']({ video: true })];
case 5:
mediaStream = _c.sent();
this.openvidu.addAlreadyProvidedTracks(myConstraints, mediaStream);
return [4, getMediaSuccess(mediaStream, definedAudioConstraint)];
case 6:
_c.sent();
return [3, 10];
case 7:
this.stream.lastVideoTrackConstraints = constraintsAux.video;
return [4, navigator.mediaDevices.getUserMedia(constraintsAux)];
case 8:
mediaStream = _c.sent();
this.openvidu.addAlreadyProvidedTracks(myConstraints, mediaStream, this.stream);
return [4, getMediaSuccess(mediaStream, definedAudioConstraint)];
case 9:
_c.sent();
_c.label = 10;
case 10: return [3, 13];
case 11:
error_2 = _c.sent();
return [4, getMediaError(error_2)];
case 12:
_c.sent();
return [3, 13];
case 13: return [3, 15];
case 14:
error_3 = _c.sent();
errorCallback(error_3);
return [3, 15];
case 15: return [2];
}
});
}); });
};
Publisher.prototype.replaceTrackAux = function (track, updateLastConstraints) {
return __awaiter(this, void 0, void 0, function () {
var trackOriginalEnabledValue, error_7;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
trackOriginalEnabledValue = track.enabled;
if (track.kind === 'video') {
track.enabled = this.stream.videoActive;
}
else if (track.kind === 'audio') {
track.enabled = this.stream.audioActive;
}
_a.label = 1;
case 1:
_a.trys.push([1, 5, , 6]);
if (!this.stream.isLocalStreamPublished) return [3, 3];
this.replaceTrackInMediaStream(track, updateLastConstraints);
return [4, this.replaceTrackInRtcRtpSender(track)];
case 2: return [2, _a.sent()];
case 3: return [2, this.replaceTrackInMediaStream(track, updateLastConstraints)];
case 4: return [3, 6];
case 5:
error_7 = _a.sent();
track.enabled = trackOriginalEnabledValue;
throw error_7;
case 6: return [2];
}
});
});
};
Publisher.prototype.getVideoDimensions = function () {
var _this = this;
return new Promise(function (resolve, reject) {
var requiresDomInsertion = platform.isIonicIos() || platform.isIOSWithSafari();
var loadedmetadataListener;
var resolveDimensions = function () {
var width;
var height;
if (typeof _this.stream.getMediaStream().getVideoTracks()[0].getSettings === 'function') {
var settings = _this.stream.getMediaStream().getVideoTracks()[0].getSettings();
width = settings.width || _this.videoReference.videoWidth;
height = settings.height || _this.videoReference.videoHeight;
}
else {
logger.warn('MediaStreamTrack does not have getSettings method on ' + platform.getDescription());
width = _this.videoReference.videoWidth;
height = _this.videoReference.videoHeight;
}
if (loadedmetadataListener != null) {
_this.videoReference.removeEventListener('loadedmetadata', loadedmetadataListener);
}
if (requiresDomInsertion) {
document.body.removeChild(_this.videoReference);
}
return resolve({ width: width, height: height });
};
if (_this.videoReference.readyState >= 1) {
resolveDimensions();
}
else {
loadedmetadataListener = function () {
if (!_this.videoReference.videoWidth) {
var interval_1 = setInterval(function () {
if (!!_this.videoReference.videoWidth) {
clearInterval(interval_1);
resolveDimensions();
}
}, 40);
}
else {
resolveDimensions();
}
};
_this.videoReference.addEventListener('loadedmetadata', loadedmetadataListener);
if (requiresDomInsertion) {
document.body.appendChild(_this.videoReference);
}
}
});
};
Publisher.prototype.reestablishStreamPlayingEvent = function () {
if (this.ee.getListeners('streamPlaying').length > 0) {
this.addPlayEventToFirstVideo();
}
};
Publisher.prototype.initializeVideoReference = function (mediaStream) {
this.videoReference = document.createElement('video');
this.videoReference.style.display = 'none';
this.videoReference.muted = true;
this.videoReference.autoplay = true;
this.videoReference.controls = false;
if (platform.isSafariBrowser() ||
(platform.isIPhoneOrIPad() &&
(platform.isChromeMobileBrowser() ||
platform.isEdgeMobileBrowser() ||
platform.isOperaMobileBrowser() ||
platform.isFirefoxMobileBrowser()))) {
this.videoReference.playsInline = true;
}
this.stream.setMediaStream(mediaStream);
if (!!this.firstVideoElement) {
this.createVideoElement(this.firstVideoElement.targetElement, this.properties.insertMode);
}
this.videoReference.srcObject = this.stream.getMediaStream();
};
Publisher.prototype.replaceTrackInMediaStream = function (track, updateLastConstraints) {
var mediaStream = this.stream.displayMyRemote()
? this.stream.localMediaStreamWhenSubscribedToRemote
: this.stream.getMediaStream();
var removedTrack;
if (track.kind === 'video') {
removedTrack = mediaStream.getVideoTracks()[0];
if (updateLastConstraints) {
this.stream.lastVideoTrackConstraints = track.getConstraints();
}
}
else {
removedTrack = mediaStream.getAudioTracks()[0];
}
removedTrack.enabled = false;
removedTrack.stop();
mediaStream.removeTrack(removedTrack);
mediaStream.addTrack(track);
var trackInfo = {
oldLabel: (removedTrack === null || removedTrack === void 0 ? void 0 : removedTrack.label) || '',
newLabel: (track === null || track === void 0 ? void 0 : track.label) || ''
};
if (track.kind === 'video' && updateLastConstraints) {
this.openvidu.sendNewVideoDimensionsIfRequired(this, 'trackReplaced', 50, 30);
this.openvidu.sendTrackChangedEvent(this, trackInfo.oldLabel, trackInfo.newLabel, 'videoTrack');
if (this.stream.isLocalStreamPublished) {
this.session.sendVideoData(this.stream.streamManager, 5, true, 5);
}
}
else if (track.kind === 'audio' && updateLastConstraints) {
this.openvidu.sendTrackChangedEvent(this, trackInfo.oldLabel, trackInfo.newLabel, 'audioTrack');
}
if (track.kind === 'audio') {
this.stream.disableHarkSpeakingEvent(false);
this.stream.disableHarkStoppedSpeakingEvent(false);
this.stream.disableHarkVolumeChangeEvent(false);
this.stream.initHarkEvents();
}
};
Publisher.prototype.setPermissionDialogTimer = function (waitTime) {
var _this = this;
this.permissionDialogTimeout = setTimeout(function () {
_this.emitEvent('accessDialogOpened', []);
}, waitTime);
};
Publisher.prototype.clearPermissionDialogTimer = function (startTime, waitTime) {
clearTimeout(this.permissionDialogTimeout);
if (Date.now() - startTime > waitTime) {
this.emitEvent('accessDialogClosed', []);
}
};
Publisher.prototype.replaceTrackInRtcRtpSender = function (track) {
return __awaiter(this, void 0, void 0, function () {
var senders, sender;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
senders = this.stream.getRTCPeerConnection().getSenders();
if (track.kind === 'video') {
sender = senders.find(function (s) { return !!s.track && s.track.kind === 'video'; });
if (!sender) {
throw new Error("There's no replaceable track for that kind of MediaStreamTrack in this Publisher object");
}
}
else if (track.kind === 'audio') {
sender = senders.find(function (s) { return !!s.track && s.track.kind === 'audio'; });
if (!sender) {
throw new Error("There's no replaceable track for that kind of MediaStreamTrack in this Publisher object");
}
}
else {
throw new Error('Unknown track kind ' + track.kind);
}
return [4, sender.replaceTrack(track)];
case 1:
_a.sent();
return [2];
}
});
});
};
return Publisher;
}(StreamManager_1.StreamManager));
exports.Publisher = Publisher;
},{"../OpenViduInternal/Enums/OpenViduError":53,"../OpenViduInternal/Enums/TypeOfVideo":54,"../OpenViduInternal/Events/StreamEvent":67,"../OpenViduInternal/Events/StreamPropertyChangedEvent":69,"../OpenViduInternal/Logger/OpenViduLogger":81,"../OpenViduInternal/Utils/Platform":85,"./Session":48,"./Stream":49,"./StreamManager":50}],48:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Session = void 0;
var Connection_1 = require("./Connection");
var Filter_1 = require("./Filter");
var Subscriber_1 = require("./Subscriber");
var EventDispatcher_1 = require("./EventDispatcher");
var ConnectionEvent_1 = require("../OpenViduInternal/Events/ConnectionEvent");
var FilterEvent_1 = require("../OpenViduInternal/Events/FilterEvent");
var RecordingEvent_1 = require("../OpenViduInternal/Events/RecordingEvent");
var SessionDisconnectedEvent_1 = require("../OpenViduInternal/Events/SessionDisconnectedEvent");
var SignalEvent_1 = require("../OpenViduInternal/Events/SignalEvent");
var SpeechToTextEvent_1 = require("../OpenViduInternal/Events/SpeechToTextEvent");
var StreamEvent_1 = require("../OpenViduInternal/Events/StreamEvent");
var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent");
var ConnectionPropertyChangedEvent_1 = require("../OpenViduInternal/Events/ConnectionPropertyChangedEvent");
var NetworkQualityLevelChangedEvent_1 = require("../OpenViduInternal/Events/NetworkQualityLevelChangedEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var Platform_1 = require("../OpenViduInternal/Utils/Platform");
var semverMajor = require("semver/functions/major");
var semverMinor = require("semver/functions/minor");
var ExceptionEvent_1 = require("../OpenViduInternal/Events/ExceptionEvent");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var Session = (function (_super) {
__extends(Session, _super);
function Session(openvidu) {
var _this = _super.call(this) || this;
_this.streamManagers = [];
_this.remoteStreamsCreated = new Map();
_this.remoteConnections = new Map();
platform = Platform_1.PlatformUtils.getInstance();
_this.openvidu = openvidu;
return _this;
}
Session.prototype.connect = function (token, metadata) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.processToken(token);
if (_this.openvidu.checkSystemRequirements()) {
_this.options = {
sessionId: _this.sessionId,
participantId: token,
metadata: !!metadata ? _this.stringClientMetadata(metadata) : ''
};
_this.connectAux(token)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
}
else {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.BROWSER_NOT_SUPPORTED, 'Browser ' +
platform.getName() +
' (version ' +
platform.getVersion() +
') for ' +
platform.getFamily() +
' is not supported in OpenVidu'));
}
});
};
Session.prototype.disconnect = function () {
this.leave(false, 'disconnect');
};
Session.prototype.subscribe = function (stream, targetElement, param3, param4) {
var properties = {};
if (!!param3 && typeof param3 !== 'function') {
properties = {
insertMode: typeof param3.insertMode !== 'undefined'
? typeof param3.insertMode === 'string'
? VideoInsertMode_1.VideoInsertMode[param3.insertMode]
: properties.insertMode
: VideoInsertMode_1.VideoInsertMode.APPEND,
subscribeToAudio: typeof param3.subscribeToAudio !== 'undefined' ? param3.subscribeToAudio : true,
subscribeToVideo: typeof param3.subscribeToVideo !== 'undefined' ? param3.subscribeToVideo : true
};
}
else {
properties = {
insertMode: VideoInsertMode_1.VideoInsertMode.APPEND,
subscribeToAudio: true,
subscribeToVideo: true
};
}
var completionHandler = undefined;
if (!!param3 && typeof param3 === 'function') {
completionHandler = param3;
}
else if (!!param4) {
completionHandler = param4;
}
if (!this.sessionConnected()) {
if (completionHandler !== undefined) {
completionHandler(this.notConnectedError());
}
throw this.notConnectedError();
}
logger.info('Subscribing to ' + stream.connection.connectionId);
stream
.subscribe()
.then(function () {
logger.info('Subscribed correctly to ' + stream.connection.connectionId);
if (completionHandler !== undefined) {
completionHandler(undefined);
}
})
.catch(function (error) {
if (completionHandler !== undefined) {
completionHandler(error);
}
});
var subscriber = new Subscriber_1.Subscriber(stream, targetElement, properties);
if (!!subscriber.targetElement) {
stream.streamManager.createVideoElement(subscriber.targetElement, properties.insertMode);
}
return subscriber;
};
Session.prototype.subscribeAsync = function (stream, targetElement, properties) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
return reject(_this.notConnectedError());
}
var subscriber;
var callback = function (error) {
if (!!error) {
return reject(error);
}
else {
return resolve(subscriber);
}
};
if (!!properties) {
subscriber = _this.subscribe(stream, targetElement, properties, callback);
}
else {
subscriber = _this.subscribe(stream, targetElement, callback);
}
});
};
Session.prototype.unsubscribe = function (subscriber) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
return reject(_this.notConnectedError());
}
else {
var connectionId_1 = subscriber.stream.connection.connectionId;
logger.info('Unsubscribing from ' + connectionId_1);
_this.openvidu.sendRequest('unsubscribeFromVideo', { sender: subscriber.stream.connection.connectionId }, function (error, response) {
if (error) {
logger.error('Error unsubscribing from ' + connectionId_1);
return reject(error);
}
else {
logger.info('Unsubscribed correctly from ' + connectionId_1);
subscriber.stream.streamManager.removeAllVideos();
subscriber.stream.disposeWebRtcPeer();
subscriber.stream.disposeMediaStream();
return resolve();
}
});
}
});
};
Session.prototype.publish = function (publisher) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
return reject(_this.notConnectedError());
}
publisher.session = _this;
publisher.stream.session = _this;
if (!publisher.stream.publishedOnce) {
_this.connection.addStream(publisher.stream);
publisher.stream
.publish()
.then(function () {
_this.sendVideoData(publisher, 8, true, 5);
return resolve();
})
.catch(function (error) { return reject(error); });
}
else {
publisher
.initialize()
.then(function () {
_this.connection.addStream(publisher.stream);
publisher.reestablishStreamPlayingEvent();
publisher.stream
.publish()
.then(function () {
_this.sendVideoData(publisher, 8, true, 5);
return resolve();
})
.catch(function (error) { return reject(error); });
})
.catch(function (error) { return reject(error); });
}
});
};
Session.prototype.unpublish = function (publisher) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
throw _this.notConnectedError();
}
var stream = publisher.stream;
if (!stream.connection) {
return reject(new Error('The associated Connection object of this Publisher is null'));
}
else if (stream.connection !== _this.connection) {
return reject(new Error('The associated Connection object of this Publisher is not your local Connection. ' +
"Only moderators can force unpublish on remote Streams via 'forceUnpublish' method"));
}
else {
logger.info('Unpublishing local media (' + stream.connection.connectionId + ')');
_this.openvidu.sendRequest('unpublishVideo', function (error, response) {
if (error) {
return reject(error);
}
else {
logger.info('Media unpublished correctly');
stream.disposeWebRtcPeer();
if (stream.connection.stream == stream) {
delete stream.connection.stream;
}
var streamEvent = new StreamEvent_1.StreamEvent(true, publisher, 'streamDestroyed', publisher.stream, 'unpublish');
publisher.emitEvent('streamDestroyed', [streamEvent]);
streamEvent.callDefaultBehavior();
return resolve();
}
});
}
});
};
Session.prototype.forceDisconnect = function (connection) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
return reject(_this.notConnectedError());
}
logger.info('Forcing disconnect for connection ' + connection.connectionId);
_this.openvidu.sendRequest('forceDisconnect', { connectionId: connection.connectionId }, function (error, response) {
if (error) {
logger.error('Error forcing disconnect for Connection ' + connection.connectionId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force a disconnection"));
}
else {
return reject(error);
}
}
else {
logger.info('Forcing disconnect correctly for Connection ' + connection.connectionId);
return resolve();
}
});
});
};
Session.prototype.forceUnpublish = function (stream) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
return reject(_this.notConnectedError());
}
logger.info('Forcing unpublish for stream ' + stream.streamId);
_this.openvidu.sendRequest('forceUnpublish', { streamId: stream.streamId }, function (error, response) {
if (error) {
logger.error('Error forcing unpublish for Stream ' + stream.streamId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to force an unpublishing"));
}
else {
return reject(error);
}
}
else {
logger.info('Forcing unpublish correctly for Stream ' + stream.streamId);
return resolve();
}
});
});
};
Session.prototype.signal = function (signal) {
var _this = this;
return new Promise(function (resolve, reject) {
if (!_this.sessionConnected()) {
return reject(_this.notConnectedError());
}
var signalMessage = {};
if (signal.to && signal.to.length > 0) {
var connectionIds_1 = [];
signal.to.forEach(function (connection) {
if (!!connection.connectionId) {
connectionIds_1.push(connection.connectionId);
}
});
signalMessage['to'] = connectionIds_1;
}
else {
signalMessage['to'] = [];
}
signalMessage['data'] = signal.data ? signal.data : '';
var typeAux = signal.type ? signal.type : 'signal';
if (!!typeAux) {
if (typeAux.substring(0, 7) !== 'signal:') {
typeAux = 'signal:' + typeAux;
}
}
signalMessage['type'] = typeAux;
_this.openvidu.sendRequest('sendMessage', {
message: JSON.stringify(signalMessage)
}, function (error, response) {
if (!!error) {
return reject(error);
}
else {
return resolve();
}
});
});
};
Session.prototype.subscribeToSpeechToText = function (stream, lang) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.openvidu.sendRequest('subscribeToSpeechToText', {
connectionId: stream.connection.connectionId,
lang: lang
}, function (error, response) {
if (!!error) {
return reject(error);
}
else {
return resolve();
}
});
});
};
Session.prototype.unsubscribeFromSpeechToText = function (stream) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.openvidu.sendRequest('unsubscribeFromSpeechToText', {
connectionId: stream.connection.connectionId
}, function (error, response) {
if (!!error) {
return reject(error);
}
else {
return resolve();
}
});
});
};
Session.prototype.on = function (type, handler) {
var _a, _b, _c, _d;
_super.prototype.onAux.call(this, type, "Event '" + type + "' triggered by 'Session'", handler);
if (type === 'publisherStartSpeaking') {
this.remoteConnections.forEach(function (remoteConnection) {
var _a;
if (!!((_a = remoteConnection.stream) === null || _a === void 0 ? void 0 : _a.hasAudio)) {
remoteConnection.stream.enableHarkSpeakingEvent();
}
});
if (!!((_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.stream) === null || _b === void 0 ? void 0 : _b.hasAudio)) {
this.connection.stream.enableHarkSpeakingEvent();
}
}
if (type === 'publisherStopSpeaking') {
this.remoteConnections.forEach(function (remoteConnection) {
var _a;
if (!!((_a = remoteConnection.stream) === null || _a === void 0 ? void 0 : _a.hasAudio)) {
remoteConnection.stream.enableHarkStoppedSpeakingEvent();
}
});
if (!!((_d = (_c = this.connection) === null || _c === void 0 ? void 0 : _c.stream) === null || _d === void 0 ? void 0 : _d.hasAudio)) {
this.connection.stream.enableHarkStoppedSpeakingEvent();
}
}
return this;
};
Session.prototype.once = function (type, handler) {
var _a, _b, _c, _d;
_super.prototype.onceAux.call(this, type, "Event '" + type + "' triggered once by 'Session'", handler);
if (type === 'publisherStartSpeaking') {
this.remoteConnections.forEach(function (remoteConnection) {
var _a;
if (!!((_a = remoteConnection.stream) === null || _a === void 0 ? void 0 : _a.hasAudio)) {
remoteConnection.stream.enableOnceHarkSpeakingEvent();
}
});
if (!!((_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.stream) === null || _b === void 0 ? void 0 : _b.hasAudio)) {
this.connection.stream.enableOnceHarkSpeakingEvent();
}
}
if (type === 'publisherStopSpeaking') {
this.remoteConnections.forEach(function (remoteConnection) {
var _a;
if (!!((_a = remoteConnection.stream) === null || _a === void 0 ? void 0 : _a.hasAudio)) {
remoteConnection.stream.enableOnceHarkStoppedSpeakingEvent();
}
});
if (!!((_d = (_c = this.connection) === null || _c === void 0 ? void 0 : _c.stream) === null || _d === void 0 ? void 0 : _d.hasAudio)) {
this.connection.stream.enableOnceHarkStoppedSpeakingEvent();
}
}
return this;
};
Session.prototype.off = function (type, handler) {
var _this = this;
var _a, _b, _c, _d;
_super.prototype.offAux.call(this, type, handler);
if (type === 'publisherStartSpeaking') {
if (!this.anySpeechEventListenerEnabled('publisherStartSpeaking', false)) {
this.remoteConnections.forEach(function (remoteConnection) {
var _a;
if (!!((_a = remoteConnection.stream) === null || _a === void 0 ? void 0 : _a.streamManager)) {
if (!_this.anySpeechEventListenerEnabled('publisherStartSpeaking', false, remoteConnection.stream.streamManager)) {
remoteConnection.stream.disableHarkSpeakingEvent(false);
}
}
});
if (!!((_b = (_a = this.connection) === null || _a === void 0 ? void 0 : _a.stream) === null || _b === void 0 ? void 0 : _b.streamManager)) {
if (!this.anySpeechEventListenerEnabled('publisherStartSpeaking', false, this.connection.stream.streamManager)) {
this.connection.stream.disableHarkSpeakingEvent(false);
}
}
}
}
if (type === 'publisherStopSpeaking') {
if (!this.anySpeechEventListenerEnabled('publisherStopSpeaking', false)) {
this.remoteConnections.forEach(function (remoteConnection) {
var _a;
if (!!((_a = remoteConnection.stream) === null || _a === void 0 ? void 0 : _a.streamManager)) {
if (!_this.anySpeechEventListenerEnabled('publisherStopSpeaking', false, remoteConnection.stream.streamManager)) {
remoteConnection.stream.disableHarkStoppedSpeakingEvent(false);
}
}
});
if (!!((_d = (_c = this.connection) === null || _c === void 0 ? void 0 : _c.stream) === null || _d === void 0 ? void 0 : _d.streamManager)) {
if (!this.anySpeechEventListenerEnabled('publisherStopSpeaking', false, this.connection.stream.streamManager)) {
this.connection.stream.disableHarkStoppedSpeakingEvent(false);
}
}
}
}
return this;
};
Session.prototype.onParticipantJoined = function (event) {
var _this = this;
this.getConnection(event.id, '')
.then(function (connection) {
logger.warn('Connection ' + connection.connectionId + ' already exists in connections list');
})
.catch(function (openViduError) {
var connection = new Connection_1.Connection(_this, event);
_this.remoteConnections.set(event.id, connection);
_this.ee.emitEvent('connectionCreated', [new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')]);
});
};
Session.prototype.onParticipantLeft = function (event) {
var _this = this;
this.getRemoteConnection(event.connectionId, 'onParticipantLeft')
.then(function (connection) {
if (!!connection.stream) {
var stream = connection.stream;
var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', stream, event.reason);
_this.ee.emitEvent('streamDestroyed', [streamEvent]);
streamEvent.callDefaultBehavior();
_this.remoteStreamsCreated.delete(stream.streamId);
}
connection.dispose();
_this.remoteConnections.delete(connection.connectionId);
_this.ee.emitEvent('connectionDestroyed', [
new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionDestroyed', connection, event.reason)
]);
})
.catch(function (openViduError) {
logger.error(openViduError);
});
};
Session.prototype.onParticipantPublished = function (event) {
var _this = this;
var afterConnectionFound = function (connection) {
_this.remoteConnections.set(connection.connectionId, connection);
if (!_this.remoteStreamsCreated.get(connection.stream.streamId)) {
_this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', connection.stream, '')]);
}
_this.remoteStreamsCreated.set(connection.stream.streamId, true);
};
var connection;
this.getRemoteConnection(event.id, 'onParticipantPublished')
.then(function (con) {
connection = con;
event.metadata = con.data;
connection.remoteOptions = event;
connection.initRemoteStreams(event.streams);
afterConnectionFound(connection);
})
.catch(function (openViduError) {
connection = new Connection_1.Connection(_this, event);
afterConnectionFound(connection);
});
};
Session.prototype.onParticipantUnpublished = function (event) {
var _this = this;
if (event.connectionId === this.connection.connectionId) {
this.stopPublisherStream(event.reason);
}
else {
this.getRemoteConnection(event.connectionId, 'onParticipantUnpublished')
.then(function (connection) {
var streamEvent = new StreamEvent_1.StreamEvent(true, _this, 'streamDestroyed', connection.stream, event.reason);
_this.ee.emitEvent('streamDestroyed', [streamEvent]);
streamEvent.callDefaultBehavior();
if (connection.stream != null) {
var streamId = connection.stream.streamId;
_this.remoteStreamsCreated.delete(streamId);
connection.removeStream();
}
})
.catch(function (openViduError) {
logger.error(openViduError);
});
}
};
Session.prototype.onParticipantEvicted = function (event) {
if (event.connectionId === this.connection.connectionId) {
if (!!this.sessionId && !this.connection.disposed) {
this.leave(true, event.reason);
}
}
};
Session.prototype.onNewMessage = function (event) {
var _this = this;
logger.info('New signal: ' + JSON.stringify(event));
var strippedType = !!event.type ? event.type.replace(/^(signal:)/, '') : undefined;
if (!!event.from) {
this.getConnection(event.from, "Connection '" +
event.from +
"' unknown when 'onNewMessage'. Existing remote connections: " +
JSON.stringify(this.remoteConnections.keys()) +
'. Existing local connection: ' +
this.connection.connectionId)
.then(function (connection) {
_this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(_this, strippedType, event.data, connection)]);
if (!!event.type && event.type !== 'signal') {
_this.ee.emitEvent(event.type, [new SignalEvent_1.SignalEvent(_this, strippedType, event.data, connection)]);
}
})
.catch(function (openViduError) {
logger.error(openViduError);
});
}
else {
this.ee.emitEvent('signal', [new SignalEvent_1.SignalEvent(this, strippedType, event.data, undefined)]);
if (!!event.type && event.type !== 'signal') {
this.ee.emitEvent(event.type, [new SignalEvent_1.SignalEvent(this, strippedType, event.data, undefined)]);
}
}
};
Session.prototype.onStreamPropertyChanged = function (event) {
var _this = this;
var callback = function (connection) {
if (!!connection.stream && connection.stream.streamId === event.streamId) {
var stream = connection.stream;
var oldValue = void 0;
switch (event.property) {
case 'audioActive':
oldValue = stream.audioActive;
event.newValue = event.newValue === 'true';
stream.audioActive = event.newValue;
break;
case 'videoActive':
oldValue = stream.videoActive;
event.newValue = event.newValue === 'true';
stream.videoActive = event.newValue;
break;
case 'videoTrack':
event.newValue = JSON.parse(event.newValue);
break;
case 'audioTrack':
event.newValue = JSON.parse(event.newValue);
break;
case 'videoDimensions':
oldValue = stream.videoDimensions;
event.newValue = JSON.parse(JSON.parse(event.newValue));
stream.videoDimensions = event.newValue;
break;
case 'filter':
oldValue = stream.filter;
event.newValue = Object.keys(event.newValue).length > 0 ? event.newValue : undefined;
if (event.newValue !== undefined) {
stream.filter = new Filter_1.Filter(event.newValue.type, event.newValue.options);
stream.filter.stream = stream;
if (event.newValue.lastExecMethod) {
stream.filter.lastExecMethod = event.newValue.lastExecMethod;
}
}
else {
delete stream.filter;
}
event.newValue = stream.filter;
break;
}
_this.ee.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this, stream, event.property, event.newValue, oldValue, event.reason)
]);
if (!!stream.streamManager) {
stream.streamManager.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(stream.streamManager, stream, event.property, event.newValue, oldValue, event.reason)
]);
}
}
else {
logger.error("No stream with streamId '" +
event.streamId +
"' found for connection '" +
event.connectionId +
"' on 'streamPropertyChanged' event");
}
};
if (event.connectionId === this.connection.connectionId) {
callback(this.connection);
}
else {
this.getRemoteConnection(event.connectionId, 'onStreamPropertyChanged')
.then(function (connection) {
callback(connection);
})
.catch(function (openViduError) {
logger.error(openViduError);
});
}
};
Session.prototype.onConnectionPropertyChanged = function (event) {
var oldValue;
switch (event.property) {
case 'role':
oldValue = this.connection.role.slice();
this.connection.role = event.newValue;
this.connection.localOptions.role = event.newValue;
break;
case 'record':
oldValue = this.connection.record;
event.newValue = event.newValue === 'true';
this.connection.record = event.newValue;
this.connection.localOptions.record = event.newValue;
break;
}
this.ee.emitEvent('connectionPropertyChanged', [
new ConnectionPropertyChangedEvent_1.ConnectionPropertyChangedEvent(this, this.connection, event.property, event.newValue, oldValue)
]);
};
Session.prototype.onNetworkQualityLevelChangedChanged = function (event) {
var _this = this;
if (event.connectionId === this.connection.connectionId) {
this.ee.emitEvent('networkQualityLevelChanged', [
new NetworkQualityLevelChangedEvent_1.NetworkQualityLevelChangedEvent(this, event.newValue, event.oldValue, this.connection)
]);
}
else {
this.getConnection(event.connectionId, 'Connection not found for connectionId ' + event.connectionId)
.then(function (connection) {
_this.ee.emitEvent('networkQualityLevelChanged', [
new NetworkQualityLevelChangedEvent_1.NetworkQualityLevelChangedEvent(_this, event.newValue, event.oldValue, connection)
]);
})
.catch(function (openViduError) {
logger.error(openViduError);
});
}
};
Session.prototype.recvIceCandidate = function (event) {
var candidateInit = {
candidate: event.candidate,
sdpMLineIndex: event.sdpMLineIndex,
sdpMid: event.sdpMid
};
var iceCandidate = new RTCIceCandidate(candidateInit);
this.getConnection(event.senderConnectionId, 'Connection not found for connectionId ' +
event.senderConnectionId +
' owning endpoint ' +
event.endpointName +
'. Ice candidate will be ignored: ' +
iceCandidate)
.then(function (connection) {
var stream = connection.stream;
stream
.getWebRtcPeer()
.addIceCandidate(iceCandidate)
.catch(function (error) {
logger.error('Error adding candidate for ' + stream.streamId + ' stream of endpoint ' + event.endpointName + ': ' + error);
});
})
.catch(function (openViduError) {
logger.error(openViduError);
});
};
Session.prototype.onSessionClosed = function (msg) {
logger.info('Session closed: ' + JSON.stringify(msg));
var s = msg.sessionId;
if (s !== undefined) {
this.ee.emitEvent('session-closed', [
{
session: s
}
]);
}
else {
logger.warn('Session undefined on session closed', msg);
}
};
Session.prototype.onLostConnection = function (reason) {
logger.warn('Lost connection in Session ' + this.sessionId);
if (!!this.sessionId && !!this.connection && !this.connection.disposed) {
this.leave(true, reason);
}
};
Session.prototype.onRecoveredConnection = function () {
logger.info('Recovered connection in Session ' + this.sessionId);
this.reconnectBrokenStreams();
this.ee.emitEvent('reconnected', []);
};
Session.prototype.onMediaError = function (event) {
logger.error('Media error: ' + JSON.stringify(event));
var err = event.error;
if (err) {
this.ee.emitEvent('error-media', [
{
error: err
}
]);
}
else {
logger.warn('Received undefined media error:', event);
}
};
Session.prototype.onRecordingStarted = function (event) {
this.ee.emitEvent('recordingStarted', [new RecordingEvent_1.RecordingEvent(this, 'recordingStarted', event.id, event.name)]);
};
Session.prototype.onRecordingStopped = function (event) {
this.ee.emitEvent('recordingStopped', [new RecordingEvent_1.RecordingEvent(this, 'recordingStopped', event.id, event.name, event.reason)]);
};
Session.prototype.onFilterEventDispatched = function (event) {
var _this = this;
var connectionId = event.connectionId;
this.getConnection(connectionId, 'No connection found for connectionId ' + connectionId).then(function (connection) {
logger.info("Filter event of type \"".concat(event.eventType, "\" dispatched"));
var stream = connection.stream;
if (!stream || !stream.filter) {
return logger.error("Filter event of type \"".concat(event.eventType, "\" dispatched for stream ").concat(stream.streamId, " but there is no ").concat(!stream ? 'stream' : 'filter', " defined"));
}
var eventHandler = stream.filter.handlers.get(event.eventType);
if (!eventHandler || typeof eventHandler !== 'function') {
var actualHandlers = Array.from(stream.filter.handlers.keys());
return logger.error("Filter event of type \"".concat(event.eventType, "\" not handled or not a function! Active filter events: ").concat(actualHandlers.join(',')));
}
else {
eventHandler.call(_this, new FilterEvent_1.FilterEvent(stream.filter, event.eventType, event.data));
}
});
};
Session.prototype.onForciblyReconnectSubscriber = function (event) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.getRemoteConnection(event.connectionId, 'onForciblyReconnectSubscriber')
.then(function (connection) {
if (!!connection.stream && connection.stream.streamId === event.streamId) {
var stream_1 = connection.stream;
if (stream_1.setupReconnectionEventEmitter(resolve, reject)) {
if (stream_1.reconnectionEventEmitter['onForciblyReconnectSubscriberLastEvent'] != null) {
stream_1.reconnectionEventEmitter['onForciblyReconnectSubscriberLastEvent'] = event;
return reject('Ongoing forced subscriber reconnection');
}
else {
stream_1.reconnectionEventEmitter['onForciblyReconnectSubscriberLastEvent'] = event;
var callback_1 = function () {
var eventAux = stream_1.reconnectionEventEmitter['onForciblyReconnectSubscriberLastEvent'];
delete stream_1.reconnectionEventEmitter['onForciblyReconnectSubscriberLastEvent'];
_this.onForciblyReconnectSubscriber(eventAux);
};
stream_1.reconnectionEventEmitter.once('success', function () {
callback_1();
});
stream_1.reconnectionEventEmitter.once('error', function () {
callback_1();
});
}
return;
}
stream_1
.completeWebRtcPeerReceive(true, true, event.sdpOffer)
.then(function () { return stream_1.finalResolveForSubscription(true, resolve); })
.catch(function (error) {
return stream_1.finalRejectForSubscription(true, "Error while forcibly reconnecting remote stream ".concat(event.streamId, ": ").concat(error.toString()), reject);
});
}
else {
var errMsg = "No stream with streamId '" +
event.streamId +
"' found for connection '" +
event.connectionId +
"' on 'streamPropertyChanged' event";
logger.error(errMsg);
return reject(errMsg);
}
})
.catch(function (openViduError) {
logger.error(openViduError);
return reject(openViduError);
});
});
};
Session.prototype.reconnectBrokenStreams = function () {
logger.info('Re-establishing media connections...');
var someReconnection = false;
if (!!this.connection.stream && this.connection.stream.streamIceConnectionStateBroken()) {
logger.warn('Re-establishing Publisher ' + this.connection.stream.streamId);
this.connection.stream.initWebRtcPeerSend(true);
someReconnection = true;
}
this.remoteConnections.forEach(function (remoteConnection) {
if (!!remoteConnection.stream && remoteConnection.stream.streamIceConnectionStateBroken()) {
logger.warn('Re-establishing Subscriber ' + remoteConnection.stream.streamId);
remoteConnection.stream.initWebRtcPeerReceive(true);
someReconnection = true;
}
});
if (!someReconnection) {
logger.info('There were no media streams in need of a reconnection');
}
};
Session.prototype.onSpeechToTextMessage = function (event) {
return __awaiter(this, void 0, void 0, function () {
var connection, ev;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.getConnection(event.connectionId, 'No connection found for connectionId ' + event.connectionId)];
case 1:
connection = _a.sent();
ev = new SpeechToTextEvent_1.SpeechToTextEvent(this, connection, event.text, (event.reason).toLowerCase(), event.raw, event.lang);
this.ee.emitEvent('speechToTextMessage', [ev]);
return [2];
}
});
});
};
Session.prototype.onSpeechToTextDisconnected = function (event) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
this.emitEvent('exception', [new ExceptionEvent_1.ExceptionEvent(this, ExceptionEvent_1.ExceptionEventName.SPEECH_TO_TEXT_DISCONNECTED, this, event.message)]);
return [2];
});
});
};
Session.prototype.emitEvent = function (type, eventArray) {
this.ee.emitEvent(type, eventArray);
};
Session.prototype.leave = function (forced, reason) {
var _this = this;
forced = !!forced;
logger.info('Leaving Session (forced=' + forced + ')');
this.stopVideoDataIntervals();
if (!!this.connection) {
if (!this.connection.disposed && !forced) {
this.openvidu.sendRequest('leaveRoom', function (error, response) {
if (error) {
logger.error("leaveRoom error: ".concat(JSON.stringify(error)));
}
_this.openvidu.closeWs();
});
}
else {
this.openvidu.closeWs();
}
this.stopPublisherStream(reason);
if (!this.connection.disposed) {
var sessionDisconnectEvent = new SessionDisconnectedEvent_1.SessionDisconnectedEvent(this, reason);
this.ee.emitEvent('sessionDisconnected', [sessionDisconnectEvent]);
sessionDisconnectEvent.callDefaultBehavior();
}
}
else {
logger.warn('You were not connected to the session ' + this.sessionId);
}
logger.flush();
};
Session.prototype.initializeParams = function (token) {
var joinParams = {
token: !!token ? token : '',
session: this.sessionId,
platform: !!platform.getDescription() ? platform.getDescription() : 'unknown',
sdkVersion: this.openvidu.libraryVersion,
metadata: !!this.options.metadata ? this.options.metadata : '',
secret: this.openvidu.getSecret(),
recorder: this.openvidu.getRecorder(),
stt: this.openvidu.getStt()
};
return joinParams;
};
Session.prototype.sendVideoData = function (streamManager, intervalSeconds, doInterval, maxLoops) {
var _this = this;
var _a, _b;
if (intervalSeconds === void 0) { intervalSeconds = 1; }
if (doInterval === void 0) { doInterval = false; }
if (maxLoops === void 0) { maxLoops = 1; }
if (platform.isChromeBrowser() ||
platform.isChromeMobileBrowser() ||
platform.isOperaBrowser() ||
platform.isOperaMobileBrowser() ||
platform.isEdgeBrowser() ||
platform.isEdgeMobileBrowser() ||
platform.isElectron() ||
(platform.isSafariBrowser() && !platform.isIonicIos()) ||
platform.isAndroidBrowser() ||
platform.isSamsungBrowser() ||
platform.isIonicAndroid() ||
platform.isIOSWithSafari()) {
var obtainAndSendVideo_1 = function () { return __awaiter(_this, void 0, void 0, function () {
var pc, statsMap, arr_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
pc = streamManager.stream.getRTCPeerConnection();
if (!(pc.connectionState === 'connected')) return [3, 2];
return [4, pc.getStats()];
case 1:
statsMap = _a.sent();
arr_1 = [];
statsMap.forEach(function (stats) {
if ('frameWidth' in stats && 'frameHeight' in stats && arr_1.length === 0) {
arr_1.push(stats);
}
});
if (arr_1.length > 0) {
this.openvidu.sendRequest('videoData', {
height: arr_1[0].frameHeight,
width: arr_1[0].frameWidth,
videoActive: streamManager.stream.videoActive != null ? streamManager.stream.videoActive : false,
audioActive: streamManager.stream.audioActive != null ? streamManager.stream.audioActive : false
}, function (error, response) {
if (error) {
logger.error("Error sending 'videoData' event", error);
}
});
}
_a.label = 2;
case 2: return [2];
}
});
}); };
if (doInterval) {
var loops_1 = 1;
this.videoDataInterval = setInterval(function () {
if (loops_1 < maxLoops) {
loops_1++;
obtainAndSendVideo_1();
}
else {
clearInterval(_this.videoDataInterval);
}
}, intervalSeconds * 1000);
}
else {
this.videoDataTimeout = setTimeout(obtainAndSendVideo_1, intervalSeconds * 1000);
}
}
else if (platform.isFirefoxBrowser() || platform.isFirefoxMobileBrowser() || platform.isIonicIos() || platform.isReactNative()) {
this.openvidu.sendRequest('videoData', {
height: ((_a = streamManager.stream.videoDimensions) === null || _a === void 0 ? void 0 : _a.height) || 0,
width: ((_b = streamManager.stream.videoDimensions) === null || _b === void 0 ? void 0 : _b.width) || 0,
videoActive: streamManager.stream.videoActive != null ? streamManager.stream.videoActive : false,
audioActive: streamManager.stream.audioActive != null ? streamManager.stream.audioActive : false
}, function (error, response) {
if (error) {
logger.error("Error sending 'videoData' event", error);
}
});
}
else {
logger.error('Browser ' +
platform.getName() +
' (version ' +
platform.getVersion() +
') for ' +
platform.getFamily() +
' is not supported in OpenVidu for Network Quality');
}
};
Session.prototype.sessionConnected = function () {
return this.connection != null;
};
Session.prototype.notConnectedError = function () {
return new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_NOT_CONNECTED, "There is no connection to the session. Method 'Session.connect' must be successfully completed first");
};
Session.prototype.anySpeechEventListenerEnabled = function (event, onlyOnce, streamManager) {
var handlersInSession = this.ee.getListeners(event);
if (onlyOnce) {
handlersInSession = handlersInSession.filter(function (h) { return h.once; });
}
var listenersInSession = handlersInSession.length;
if (listenersInSession > 0)
return true;
var listenersInStreamManager = 0;
if (!!streamManager) {
var handlersInStreamManager = streamManager.ee.getListeners(event);
if (onlyOnce) {
handlersInStreamManager = handlersInStreamManager.filter(function (h) { return h.once; });
}
listenersInStreamManager = handlersInStreamManager.length;
}
return listenersInStreamManager > 0;
};
Session.prototype.getTokenParams = function (token) {
var match = token.match(/^(wss?)\:\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/);
if (!!match) {
var url = {
protocol: match[1],
host: match[2],
hostname: match[3],
port: match[4],
pathname: match[5],
search: match[6],
hash: match[7]
};
var params = token.split('?');
var queryParams = decodeURI(params[1])
.split('&')
.map(function (param) { return param.split('='); })
.reduce(function (values, _a) {
var key = _a[0], value = _a[1];
values[key] = value;
return values;
}, {});
return {
sessionId: queryParams['sessionId'],
secret: queryParams['secret'],
recorder: queryParams['recorder'],
stt: queryParams['stt'],
webrtcStatsInterval: queryParams['webrtcStatsInterval'],
sendBrowserLogs: queryParams['sendBrowserLogs'],
edition: queryParams['edition'],
wsUri: url.protocol + '://' + url.host + '/openvidu',
httpUri: 'https://' + url.host
};
}
else {
throw new Error("Token not valid: \"".concat(token, "\""));
}
};
Session.prototype.connectAux = function (token) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.openvidu.startWs(function (error) {
if (!!error) {
return reject(error);
}
else {
var joinParams = _this.initializeParams(token);
_this.openvidu.sendRequest('joinRoom', joinParams, function (error, response) {
if (!!error) {
return reject(error);
}
else {
_this.processJoinRoomResponse(response, token);
_this.connection = new Connection_1.Connection(_this, response);
var events_1 = {
connections: new Array(),
streams: new Array()
};
var existingParticipants = response.value;
existingParticipants.forEach(function (remoteConnectionOptions) {
var connection = new Connection_1.Connection(_this, remoteConnectionOptions);
_this.remoteConnections.set(connection.connectionId, connection);
events_1.connections.push(connection);
if (!!connection.stream) {
_this.remoteStreamsCreated.set(connection.stream.streamId, true);
events_1.streams.push(connection.stream);
}
});
_this.ee.emitEvent('connectionCreated', [
new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', _this.connection, '')
]);
events_1.connections.forEach(function (connection) {
_this.ee.emitEvent('connectionCreated', [
new ConnectionEvent_1.ConnectionEvent(false, _this, 'connectionCreated', connection, '')
]);
});
events_1.streams.forEach(function (stream) {
_this.ee.emitEvent('streamCreated', [new StreamEvent_1.StreamEvent(false, _this, 'streamCreated', stream, '')]);
});
if (!!response.recordingId && !!response.recordingName) {
_this.ee.emitEvent('recordingStarted', [
new RecordingEvent_1.RecordingEvent(_this, 'recordingStarted', response.recordingId, response.recordingName)
]);
}
return resolve();
}
});
}
});
});
};
Session.prototype.stopPublisherStream = function (reason) {
if (!!this.connection.stream) {
this.connection.stream.disposeWebRtcPeer();
if (this.connection.stream.isLocalStreamPublished) {
this.connection.stream.ee.emitEvent('local-stream-destroyed', [reason]);
}
}
};
Session.prototype.stopVideoDataIntervals = function () {
clearInterval(this.videoDataInterval);
clearTimeout(this.videoDataTimeout);
};
Session.prototype.stringClientMetadata = function (metadata) {
if (typeof metadata !== 'string') {
return JSON.stringify(metadata);
}
else {
return metadata;
}
};
Session.prototype.getConnection = function (connectionId, errorMessage) {
var _this = this;
return new Promise(function (resolve, reject) {
var connection = _this.remoteConnections.get(connectionId);
if (!!connection) {
return resolve(connection);
}
else {
if (_this.connection.connectionId === connectionId) {
return resolve(_this.connection);
}
else {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage));
}
}
});
};
Session.prototype.getRemoteConnection = function (connectionId, operation) {
var _this = this;
return new Promise(function (resolve, reject) {
var connection = _this.remoteConnections.get(connectionId);
if (!!connection) {
return resolve(connection);
}
else {
var errorMessage = 'Remote connection ' +
connectionId +
" unknown when '" +
operation +
"'. " +
'Existing remote connections: ' +
JSON.stringify(_this.remoteConnections.keys());
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, errorMessage));
}
});
};
Session.prototype.processToken = function (token) {
var tokenParams = this.getTokenParams(token);
this.sessionId = tokenParams.sessionId;
if (!!tokenParams.secret) {
this.openvidu.secret = tokenParams.secret;
}
if (!!tokenParams.recorder) {
this.openvidu.recorder = true;
}
if (!!tokenParams.stt) {
this.openvidu.stt = true;
}
if (!!tokenParams.webrtcStatsInterval) {
this.openvidu.webrtcStatsInterval = tokenParams.webrtcStatsInterval;
}
if (!!tokenParams.sendBrowserLogs) {
this.openvidu.sendBrowserLogs = tokenParams.sendBrowserLogs;
}
this.openvidu.isAtLeastPro = tokenParams.edition === 'pro' || tokenParams.edition === 'enterprise';
this.openvidu.isEnterprise = tokenParams.edition === 'enterprise';
this.openvidu.wsUri = tokenParams.wsUri;
this.openvidu.httpUri = tokenParams.httpUri;
};
Session.prototype.processJoinRoomResponse = function (opts, token) {
this.sessionId = opts.session;
if (opts.customIceServers != null && opts.customIceServers.length > 0) {
this.openvidu.iceServers = [];
for (var _i = 0, _a = opts.customIceServers; _i < _a.length; _i++) {
var iceServer = _a[_i];
var rtcIceServer = {
urls: [iceServer.url]
};
logger.log('STUN/TURN server IP: ' + iceServer.url);
if (iceServer.username != null && iceServer.credential != null) {
rtcIceServer.username = iceServer.username;
rtcIceServer.credential = iceServer.credential;
logger.log('TURN credentials [' + iceServer.username + ':' + iceServer.credential + ']');
}
this.openvidu.iceServers.push(rtcIceServer);
}
}
this.openvidu.role = opts.role;
this.openvidu.finalUserId = opts.finalUserId;
this.openvidu.mediaServer = opts.mediaServer;
this.openvidu.videoSimulcast = opts.videoSimulcast;
this.capabilities = {
subscribe: true,
publish: this.openvidu.role !== 'SUBSCRIBER',
forceUnpublish: this.openvidu.role === 'MODERATOR',
forceDisconnect: this.openvidu.role === 'MODERATOR'
};
logger.info('openvidu-server version: ' + opts.version);
if (opts.life != null) {
this.openvidu.life = opts.life;
}
var minorDifference = semverMinor(opts.version) - semverMinor(this.openvidu.libraryVersion);
if (semverMajor(opts.version) !== semverMajor(this.openvidu.libraryVersion) || !(minorDifference == 0 || minorDifference == 1)) {
logger.error("openvidu-browser (".concat(this.openvidu.libraryVersion, ") and openvidu-server (").concat(opts.version, ") versions are incompatible. ") +
'Errors are likely to occur. openvidu-browser SDK is only compatible with the same version or the immediately following minor version of an OpenVidu deployment');
}
else if (minorDifference == 1) {
logger.warn("openvidu-browser version ".concat(this.openvidu.libraryVersion, " does not match openvidu-server version ").concat(opts.version, ". ") +
"These versions are still compatible with each other, but openvidu-browser version must be updated as soon as possible to ".concat(semverMajor(opts.version), ".").concat(semverMinor(opts.version), ".x. ") +
"This client using openvidu-browser ".concat(this.openvidu.libraryVersion, " will become incompatible with the next release of openvidu-server"));
}
OpenViduLogger_1.OpenViduLogger.configureJSNLog(this.openvidu, token);
this.token = token;
};
return Session;
}(EventDispatcher_1.EventDispatcher));
exports.Session = Session;
},{"../OpenViduInternal/Enums/OpenViduError":53,"../OpenViduInternal/Enums/VideoInsertMode":55,"../OpenViduInternal/Events/ConnectionEvent":56,"../OpenViduInternal/Events/ConnectionPropertyChangedEvent":57,"../OpenViduInternal/Events/ExceptionEvent":59,"../OpenViduInternal/Events/FilterEvent":60,"../OpenViduInternal/Events/NetworkQualityLevelChangedEvent":61,"../OpenViduInternal/Events/RecordingEvent":63,"../OpenViduInternal/Events/SessionDisconnectedEvent":64,"../OpenViduInternal/Events/SignalEvent":65,"../OpenViduInternal/Events/SpeechToTextEvent":66,"../OpenViduInternal/Events/StreamEvent":67,"../OpenViduInternal/Events/StreamPropertyChangedEvent":69,"../OpenViduInternal/Logger/OpenViduLogger":81,"../OpenViduInternal/Utils/Platform":85,"./Connection":42,"./EventDispatcher":43,"./Filter":44,"./Subscriber":51,"semver/functions/major":15,"semver/functions/minor":16}],49:[function(require,module,exports){
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Stream = void 0;
var Filter_1 = require("./Filter");
var Subscriber_1 = require("./Subscriber");
var WebRtcPeer_1 = require("../OpenViduInternal/WebRtcPeer/WebRtcPeer");
var WebRtcStats_1 = require("../OpenViduInternal/WebRtcStats/WebRtcStats");
var ExceptionEvent_1 = require("../OpenViduInternal/Events/ExceptionEvent");
var PublisherSpeakingEvent_1 = require("../OpenViduInternal/Events/PublisherSpeakingEvent");
var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent");
var StreamPropertyChangedEvent_1 = require("../OpenViduInternal/Events/StreamPropertyChangedEvent");
var OpenViduError_1 = require("../OpenViduInternal/Enums/OpenViduError");
var TypeOfVideo_1 = require("../OpenViduInternal/Enums/TypeOfVideo");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var Platform_1 = require("../OpenViduInternal/Utils/Platform");
var uuid_1 = require("uuid");
var hark = require("hark");
var EventEmitter = require("wolfy87-eventemitter");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var Stream = (function () {
function Stream(session, options) {
var _this = this;
this.isSubscribeToRemote = false;
this.isLocalStreamReadyToPublish = false;
this.isLocalStreamPublished = false;
this.publishedOnce = false;
this.harkSpeakingEnabled = false;
this.harkSpeakingEnabledOnce = false;
this.harkStoppedSpeakingEnabled = false;
this.harkStoppedSpeakingEnabledOnce = false;
this.harkVolumeChangeEnabled = false;
this.harkVolumeChangeEnabledOnce = false;
this.ee = new EventEmitter();
platform = Platform_1.PlatformUtils.getInstance();
this.session = session;
if (options.hasOwnProperty('id')) {
this.inboundStreamOpts = options;
this.streamId = this.inboundStreamOpts.id;
this.creationTime = this.inboundStreamOpts.createdAt;
this.hasAudio = this.inboundStreamOpts.hasAudio;
this.hasVideo = this.inboundStreamOpts.hasVideo;
if (this.hasAudio) {
this.audioActive = this.inboundStreamOpts.audioActive;
}
if (this.hasVideo) {
this.videoActive = this.inboundStreamOpts.videoActive;
this.typeOfVideo = !this.inboundStreamOpts.typeOfVideo ? undefined : this.inboundStreamOpts.typeOfVideo;
this.frameRate = this.inboundStreamOpts.frameRate === -1 ? undefined : this.inboundStreamOpts.frameRate;
this.videoDimensions = this.inboundStreamOpts.videoDimensions;
}
if (!!this.inboundStreamOpts.filter && Object.keys(this.inboundStreamOpts.filter).length > 0) {
if (!!this.inboundStreamOpts.filter.lastExecMethod &&
Object.keys(this.inboundStreamOpts.filter.lastExecMethod).length === 0) {
delete this.inboundStreamOpts.filter.lastExecMethod;
}
this.filter = this.inboundStreamOpts.filter;
}
}
else {
this.outboundStreamOpts = options;
this.hasAudio = this.isSendAudio();
this.hasVideo = this.isSendVideo();
if (this.hasAudio) {
this.audioActive = !!this.outboundStreamOpts.publisherProperties.publishAudio;
}
if (this.hasVideo) {
this.videoActive = !!this.outboundStreamOpts.publisherProperties.publishVideo;
this.frameRate = this.outboundStreamOpts.publisherProperties.frameRate;
if (typeof MediaStreamTrack !== 'undefined' &&
this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack) {
this.typeOfVideo = TypeOfVideo_1.TypeOfVideo.CUSTOM;
}
else {
this.typeOfVideo = this.isSendScreen() ? TypeOfVideo_1.TypeOfVideo.SCREEN : TypeOfVideo_1.TypeOfVideo.CAMERA;
}
}
if (!!this.outboundStreamOpts.publisherProperties.filter) {
this.filter = this.outboundStreamOpts.publisherProperties.filter;
}
}
this.ee.on('mediastream-updated', function () {
var _a;
_this.streamManager.updateMediaStream(_this.mediaStream);
logger.debug('Video srcObject [' + ((_a = _this.mediaStream) === null || _a === void 0 ? void 0 : _a.id) + '] updated in stream [' + _this.streamId + ']');
});
}
Stream.prototype.reconnect = function () {
return this.reconnectStream('API');
};
Stream.prototype.applyFilter = function (type, options) {
var _this = this;
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var resolveApplyFilter, openviduToken_1, tokenParams_1, afterScriptLoaded_1, script, optionsString;
var _this = this;
return __generator(this, function (_a) {
if (!!this.filter) {
return [2, reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, 'There is already a filter applied to Stream ' + this.streamId))];
}
resolveApplyFilter = function (error, triggerEvent) {
if (error) {
logger.error('Error applying filter for Stream ' + _this.streamId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to apply a filter"));
}
else {
return reject(error);
}
}
else {
logger.info('Filter successfully applied on Stream ' + _this.streamId);
var oldValue = _this.filter;
_this.filter = new Filter_1.Filter(type, options);
_this.filter.stream = _this;
if (triggerEvent) {
_this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')
]);
_this.streamManager.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')
]);
}
return resolve(_this.filter);
}
};
if (type.startsWith('VB:')) {
if (!this.hasVideo) {
return [2, reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'The Virtual Background filter requires a video track to be applied'))];
}
if (!this.mediaStream || this.streamManager.videos.length === 0) {
return [2, reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'The StreamManager requires some video element to be attached to it in order to apply a Virtual Background filter'))];
}
if (!!this.session.token) {
openviduToken_1 = this.session.token;
}
else {
openviduToken_1 = options['token'];
}
if (!openviduToken_1) {
return [2, reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'Virtual Background requires the client to be connected to a Session or to have a "token" property available in "options" parameter with a valid OpenVidu token'))];
}
tokenParams_1 = this.session.getTokenParams(openviduToken_1);
if (tokenParams_1.edition !== 'pro' && tokenParams_1.edition !== 'enterprise') {
return [2, reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, 'OpenVidu Virtual Background API is available from OpenVidu Pro edition onwards'))];
}
openviduToken_1 = encodeURIComponent(btoa(openviduToken_1));
logger.info('Applying Virtual Background to stream ' + this.streamId);
afterScriptLoaded_1 = function () { return __awaiter(_this, void 0, void 0, function () {
var id, mediaStreamClone, videoClone, VB, filteredVideo, _a, error_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 8, , 9]);
id = this.streamId + '_' + (0, uuid_1.v4)();
mediaStreamClone = this.mediaStream.clone();
videoClone = this.streamManager.videos[0].video.cloneNode(false);
videoClone.id = VirtualBackground.VirtualBackground.SOURCE_VIDEO_PREFIX + id;
videoClone.srcObject = mediaStreamClone;
videoClone.muted = true;
this.virtualBackgroundSourceElements = { videoClone: videoClone, mediaStreamClone: mediaStreamClone };
VirtualBackground.VirtualBackground.hideHtmlElement(videoClone, false);
VirtualBackground.VirtualBackground.appendHtmlElementToHiddenContainer(videoClone, id);
return [4, videoClone.play()];
case 1:
_b.sent();
VB = new VirtualBackground.VirtualBackground({
id: id,
openviduServerUrl: new URL(tokenParams_1.httpUri),
openviduToken: openviduToken_1,
inputVideo: videoClone,
inputResolution: '160x96',
outputFramerate: 24
});
filteredVideo = void 0;
_a = type;
switch (_a) {
case 'VB:blur': return [3, 2];
case 'VB:image': return [3, 4];
}
return [3, 6];
case 2: return [4, VB.backgroundBlur(options)];
case 3:
filteredVideo = _b.sent();
return [3, 7];
case 4: return [4, VB.backgroundImage(options)];
case 5:
filteredVideo = _b.sent();
return [3, 7];
case 6: throw new Error('Unknown Virtual Background filter: ' + type);
case 7:
this.virtualBackgroundSinkElements = { VB: VB, video: filteredVideo };
videoClone.style.display = 'none';
if (this.streamManager.remote) {
this.streamManager.replaceTrackInMediaStream(this.virtualBackgroundSinkElements.video.srcObject.getVideoTracks()[0], false);
}
else {
this.streamManager.replaceTrackAux(this.virtualBackgroundSinkElements.video.srcObject.getVideoTracks()[0], false);
}
resolveApplyFilter(undefined, false);
return [3, 9];
case 8:
error_1 = _b.sent();
if (error_1.name === OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR) {
resolveApplyFilter(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.VIRTUAL_BACKGROUND_ERROR, error_1.message), false);
}
else {
resolveApplyFilter(error_1, false);
}
return [3, 9];
case 9: return [2];
}
});
}); };
if (typeof VirtualBackground === 'undefined') {
script = document.createElement('script');
script.type = 'text/javascript';
script.src = tokenParams_1.httpUri + '/openvidu/virtual-background/openvidu-virtual-background.js?token=' + openviduToken_1;
script.onload = function () { return __awaiter(_this, void 0, void 0, function () {
var error_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, afterScriptLoaded_1()];
case 1:
_a.sent();
resolve(new Filter_1.Filter(type, options));
return [3, 3];
case 2:
error_2 = _a.sent();
reject(error_2);
return [3, 3];
case 3: return [2];
}
});
}); };
document.body.appendChild(script);
}
else {
afterScriptLoaded_1()
.then(function () { return resolve(new Filter_1.Filter(type, options)); })
.catch(function (error) { return reject(error); });
}
}
else {
if (!this.session.sessionConnected()) {
return [2, reject(this.session.notConnectedError())];
}
logger.info('Applying server filter to stream ' + this.streamId);
options = options != null ? options : {};
optionsString = options;
if (typeof optionsString !== 'string') {
optionsString = JSON.stringify(optionsString);
}
this.session.openvidu.sendRequest('applyFilter', { streamId: this.streamId, type: type, options: optionsString }, function (error, response) {
resolveApplyFilter(error, true);
});
}
return [2];
});
}); });
};
Stream.prototype.removeFilter = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.removeFilterAux(false)];
case 1: return [2, _a.sent()];
}
});
});
};
Stream.prototype.getRTCPeerConnection = function () {
return this.webRtcPeer.pc;
};
Stream.prototype.getMediaStream = function () {
return this.mediaStream;
};
Stream.prototype.removeFilterAux = function (isDisposing) {
var _this = this;
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var resolveRemoveFilter, mediaStreamClone, error_3;
var _this = this;
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
resolveRemoveFilter = function (error, triggerEvent) {
if (error) {
delete _this.filter;
logger.error('Error removing filter for Stream ' + _this.streamId, error);
if (error.code === 401) {
return reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to remove a filter"));
}
else {
return reject(error);
}
}
else {
logger.info('Filter successfully removed from Stream ' + _this.streamId);
var oldValue = _this.filter;
delete _this.filter;
if (triggerEvent) {
_this.session.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.session, _this, 'filter', _this.filter, oldValue, 'applyFilter')
]);
_this.streamManager.emitEvent('streamPropertyChanged', [
new StreamPropertyChangedEvent_1.StreamPropertyChangedEvent(_this.streamManager, _this, 'filter', _this.filter, oldValue, 'applyFilter')
]);
}
return resolve();
}
};
if (!!!this.filter) return [3, 11];
if (!((_a = this.filter) === null || _a === void 0 ? void 0 : _a.type.startsWith('VB:'))) return [3, 9];
_b.label = 1;
case 1:
_b.trys.push([1, 7, , 8]);
mediaStreamClone = this.virtualBackgroundSourceElements.mediaStreamClone;
if (!!isDisposing) return [3, 5];
if (!this.streamManager.remote) return [3, 2];
this.streamManager.replaceTrackInMediaStream(mediaStreamClone.getVideoTracks()[0], false);
return [3, 4];
case 2: return [4, this.streamManager.replaceTrackAux(mediaStreamClone.getVideoTracks()[0], false)];
case 3:
_b.sent();
_b.label = 4;
case 4: return [3, 6];
case 5:
mediaStreamClone.getTracks().forEach(function (track) { return track.stop(); });
_b.label = 6;
case 6:
this.virtualBackgroundSinkElements.VB.cleanUp();
delete this.virtualBackgroundSinkElements;
delete this.virtualBackgroundSourceElements;
return [2, resolveRemoveFilter(undefined, false)];
case 7:
error_3 = _b.sent();
return [2, resolveRemoveFilter(error_3, false)];
case 8: return [3, 10];
case 9:
if (!this.session.sessionConnected()) {
return [2, reject(this.session.notConnectedError())];
}
logger.info('Removing filter of stream ' + this.streamId);
this.session.openvidu.sendRequest('removeFilter', { streamId: this.streamId }, function (error, response) {
return resolveRemoveFilter(error, true);
});
_b.label = 10;
case 10: return [3, 12];
case 11: return [2, reject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.GENERIC_ERROR, 'Stream ' + this.streamId + ' has no filter applied'))];
case 12: return [2];
}
});
}); });
};
Stream.prototype.setMediaStream = function (mediaStream) {
this.mediaStream = mediaStream;
};
Stream.prototype.updateMediaStreamInVideos = function () {
this.ee.emitEvent('mediastream-updated', []);
};
Stream.prototype.getWebRtcPeer = function () {
return this.webRtcPeer;
};
Stream.prototype.subscribeToMyRemote = function (value) {
this.isSubscribeToRemote = value;
};
Stream.prototype.setOutboundStreamOptions = function (outboundStreamOpts) {
this.outboundStreamOpts = outboundStreamOpts;
};
Stream.prototype.subscribe = function () {
var _this = this;
return new Promise(function (resolve, reject) {
_this.initWebRtcPeerReceive(false)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
});
};
Stream.prototype.publish = function () {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this.isLocalStreamReadyToPublish) {
_this.initWebRtcPeerSend(false)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
}
else {
_this.ee.once('stream-ready-to-publish', function () {
_this.publish()
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
});
}
});
};
Stream.prototype.disposeWebRtcPeer = function () {
var webrtcId;
if (!!this.webRtcPeer) {
this.webRtcPeer.dispose();
webrtcId = this.webRtcPeer.getId();
}
this.stopWebRtcStats();
logger.info((!!this.outboundStreamOpts ? 'Outbound ' : 'Inbound ') +
'RTCPeerConnection with id [' +
webrtcId +
"] from 'Stream' with id [" +
this.streamId +
'] is now closed');
};
Stream.prototype.disposeMediaStream = function () {
return __awaiter(this, void 0, void 0, function () {
var error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(!!this.filter && this.filter.type.startsWith('VB:'))) return [3, 4];
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4, this.removeFilterAux(true)];
case 2:
_a.sent();
console.debug("Success removing Virtual Background filter for stream ".concat(this.streamId));
return [3, 4];
case 3:
error_4 = _a.sent();
console.error("Error removing Virtual Background filter for stream ".concat(this.streamId), error_4);
return [3, 4];
case 4:
if (this.mediaStream) {
this.mediaStream.getAudioTracks().forEach(function (track) {
track.stop();
});
this.mediaStream.getVideoTracks().forEach(function (track) {
track.stop();
});
delete this.mediaStream;
}
if (this.localMediaStreamWhenSubscribedToRemote) {
this.localMediaStreamWhenSubscribedToRemote.getAudioTracks().forEach(function (track) {
track.stop();
});
this.localMediaStreamWhenSubscribedToRemote.getVideoTracks().forEach(function (track) {
track.stop();
});
delete this.localMediaStreamWhenSubscribedToRemote;
}
if (!!this.speechEvent) {
if (!!this.speechEvent.stop) {
this.speechEvent.stop();
}
delete this.speechEvent;
}
logger.info((!!this.outboundStreamOpts ? 'Local ' : 'Remote ') + "MediaStream from 'Stream' with id [" + this.streamId + '] is now disposed');
return [2];
}
});
});
};
Stream.prototype.displayMyRemote = function () {
return this.isSubscribeToRemote;
};
Stream.prototype.isSendAudio = function () {
return (!!this.outboundStreamOpts &&
this.outboundStreamOpts.publisherProperties.audioSource !== null &&
this.outboundStreamOpts.publisherProperties.audioSource !== false);
};
Stream.prototype.isSendVideo = function () {
return (!!this.outboundStreamOpts &&
this.outboundStreamOpts.publisherProperties.videoSource !== null &&
this.outboundStreamOpts.publisherProperties.videoSource !== false);
};
Stream.prototype.isSendScreen = function () {
var screen = this.outboundStreamOpts.publisherProperties.videoSource === 'screen';
if (platform.isElectron()) {
screen =
typeof this.outboundStreamOpts.publisherProperties.videoSource === 'string' &&
this.outboundStreamOpts.publisherProperties.videoSource.startsWith('screen:');
}
return !!this.outboundStreamOpts && screen;
};
Stream.prototype.enableHarkSpeakingEvent = function () {
var _this = this;
this.setHarkListenerIfNotExists();
if (!this.harkSpeakingEnabled && !!this.speechEvent) {
this.harkSpeakingEnabled = true;
this.speechEvent.on('speaking', function () {
_this.session.emitEvent('publisherStartSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)
]);
_this.streamManager.emitEvent('publisherStartSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.streamManager, 'publisherStartSpeaking', _this.connection, _this.streamId)
]);
_this.harkSpeakingEnabledOnce = false;
});
}
};
Stream.prototype.enableOnceHarkSpeakingEvent = function () {
var _this = this;
this.setHarkListenerIfNotExists();
if (!this.harkSpeakingEnabledOnce && !!this.speechEvent) {
this.harkSpeakingEnabledOnce = true;
this.speechEvent.once('speaking', function () {
if (_this.harkSpeakingEnabledOnce) {
_this.session.emitEvent('publisherStartSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStartSpeaking', _this.connection, _this.streamId)
]);
_this.streamManager.emitEvent('publisherStartSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.streamManager, 'publisherStartSpeaking', _this.connection, _this.streamId)
]);
}
_this.disableHarkSpeakingEvent(true);
});
}
};
Stream.prototype.disableHarkSpeakingEvent = function (disabledByOnce) {
if (!!this.speechEvent) {
this.harkSpeakingEnabledOnce = false;
if (disabledByOnce) {
if (this.harkSpeakingEnabled) {
return;
}
}
else {
this.harkSpeakingEnabled = false;
}
if (this.harkVolumeChangeEnabled ||
this.harkVolumeChangeEnabledOnce ||
this.harkStoppedSpeakingEnabled ||
this.harkStoppedSpeakingEnabledOnce) {
this.speechEvent.off('speaking');
}
else {
this.speechEvent.stop();
delete this.speechEvent;
}
}
};
Stream.prototype.enableHarkStoppedSpeakingEvent = function () {
var _this = this;
this.setHarkListenerIfNotExists();
if (!this.harkStoppedSpeakingEnabled && !!this.speechEvent) {
this.harkStoppedSpeakingEnabled = true;
this.speechEvent.on('stopped_speaking', function () {
_this.session.emitEvent('publisherStopSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)
]);
_this.streamManager.emitEvent('publisherStopSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.streamManager, 'publisherStopSpeaking', _this.connection, _this.streamId)
]);
_this.harkStoppedSpeakingEnabledOnce = false;
});
}
};
Stream.prototype.enableOnceHarkStoppedSpeakingEvent = function () {
var _this = this;
this.setHarkListenerIfNotExists();
if (!this.harkStoppedSpeakingEnabledOnce && !!this.speechEvent) {
this.harkStoppedSpeakingEnabledOnce = true;
this.speechEvent.once('stopped_speaking', function () {
if (_this.harkStoppedSpeakingEnabledOnce) {
_this.session.emitEvent('publisherStopSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.session, 'publisherStopSpeaking', _this.connection, _this.streamId)
]);
_this.streamManager.emitEvent('publisherStopSpeaking', [
new PublisherSpeakingEvent_1.PublisherSpeakingEvent(_this.streamManager, 'publisherStopSpeaking', _this.connection, _this.streamId)
]);
}
_this.disableHarkStoppedSpeakingEvent(true);
});
}
};
Stream.prototype.disableHarkStoppedSpeakingEvent = function (disabledByOnce) {
if (!!this.speechEvent) {
this.harkStoppedSpeakingEnabledOnce = false;
if (disabledByOnce) {
if (this.harkStoppedSpeakingEnabled) {
return;
}
}
else {
this.harkStoppedSpeakingEnabled = false;
}
if (this.harkVolumeChangeEnabled ||
this.harkVolumeChangeEnabledOnce ||
this.harkSpeakingEnabled ||
this.harkSpeakingEnabledOnce) {
this.speechEvent.off('stopped_speaking');
}
else {
this.speechEvent.stop();
delete this.speechEvent;
}
}
};
Stream.prototype.enableHarkVolumeChangeEvent = function (force) {
var _this = this;
if (this.setHarkListenerIfNotExists()) {
if (!this.harkVolumeChangeEnabled || force) {
this.harkVolumeChangeEnabled = true;
this.speechEvent.on('volume_change', function (harkEvent) {
var oldValue = _this.speechEvent.oldVolumeValue;
var value = { newValue: harkEvent, oldValue: oldValue };
_this.speechEvent.oldVolumeValue = harkEvent;
_this.streamManager.emitEvent('streamAudioVolumeChange', [
new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)
]);
});
}
}
else {
this.harkVolumeChangeEnabled = true;
}
};
Stream.prototype.enableOnceHarkVolumeChangeEvent = function (force) {
var _this = this;
if (this.setHarkListenerIfNotExists()) {
if (!this.harkVolumeChangeEnabledOnce || force) {
this.harkVolumeChangeEnabledOnce = true;
this.speechEvent.once('volume_change', function (harkEvent) {
var oldValue = _this.speechEvent.oldVolumeValue;
var value = { newValue: harkEvent, oldValue: oldValue };
_this.speechEvent.oldVolumeValue = harkEvent;
_this.disableHarkVolumeChangeEvent(true);
_this.streamManager.emitEvent('streamAudioVolumeChange', [
new StreamManagerEvent_1.StreamManagerEvent(_this.streamManager, 'streamAudioVolumeChange', value)
]);
});
}
}
else {
this.harkVolumeChangeEnabledOnce = true;
}
};
Stream.prototype.disableHarkVolumeChangeEvent = function (disabledByOnce) {
if (!!this.speechEvent) {
this.harkVolumeChangeEnabledOnce = false;
if (disabledByOnce) {
if (this.harkVolumeChangeEnabled) {
return;
}
}
else {
this.harkVolumeChangeEnabled = false;
}
if (this.harkSpeakingEnabled ||
this.harkSpeakingEnabledOnce ||
this.harkStoppedSpeakingEnabled ||
this.harkStoppedSpeakingEnabledOnce) {
this.speechEvent.off('volume_change');
}
else {
this.speechEvent.stop();
delete this.speechEvent;
}
}
};
Stream.prototype.isLocal = function () {
return !this.inboundStreamOpts && !!this.outboundStreamOpts;
};
Stream.prototype.getSelectedIceCandidate = function () {
var _this = this;
return new Promise(function (resolve, reject) {
_this.webRtcStats
.getSelectedIceCandidateInfo()
.then(function (report) { return resolve(report); })
.catch(function (error) { return reject(error); });
});
};
Stream.prototype.getRemoteIceCandidateList = function () {
return this.webRtcPeer.remoteCandidatesQueue;
};
Stream.prototype.getLocalIceCandidateList = function () {
return this.webRtcPeer.localCandidatesQueue;
};
Stream.prototype.streamIceConnectionStateBroken = function () {
if (!this.getWebRtcPeer() || !this.getRTCPeerConnection()) {
return false;
}
if (this.isLocal() && !!this.session.openvidu.advancedConfiguration.forceMediaReconnectionAfterNetworkDrop) {
logger.warn("OpenVidu Browser advanced configuration option \"forceMediaReconnectionAfterNetworkDrop\" is enabled. Stream ".concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") will force a reconnection"));
return true;
}
var iceConnectionState = this.getRTCPeerConnection().iceConnectionState;
return iceConnectionState !== 'connected' && iceConnectionState !== 'completed';
};
Stream.prototype.setHarkListenerIfNotExists = function () {
if (!!this.mediaStream) {
if (!this.speechEvent) {
var harkOptions = !!this.harkOptions
? this.harkOptions
: this.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {};
harkOptions.interval = typeof harkOptions.interval === 'number' ? harkOptions.interval : 100;
harkOptions.threshold = typeof harkOptions.threshold === 'number' ? harkOptions.threshold : -50;
this.speechEvent = hark(this.mediaStream, harkOptions);
}
return true;
}
return false;
};
Stream.prototype.setupReconnectionEventEmitter = function (resolve, reject) {
if (this.reconnectionEventEmitter == undefined) {
this.reconnectionEventEmitter = new EventEmitter();
return false;
}
else {
console.warn("Trying to reconnect stream ".concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") but an ongoing reconnection process is active. Waiting for response..."));
this.reconnectionEventEmitter.once('success', function () { return resolve(); });
this.reconnectionEventEmitter.once('error', function (error) { return reject(error); });
return true;
}
};
Stream.prototype.initWebRtcPeerSend = function (reconnect) {
var _this = this;
return new Promise(function (resolve, reject) {
var _a;
if (reconnect) {
if (_this.setupReconnectionEventEmitter(resolve, reject)) {
return;
}
}
else {
_this.initHarkEvents();
}
var finalResolve = function () {
var _a;
if (reconnect) {
(_a = _this.reconnectionEventEmitter) === null || _a === void 0 ? void 0 : _a.emitEvent('success');
delete _this.reconnectionEventEmitter;
}
return resolve();
};
var finalReject = function (error) {
var _a;
if (reconnect) {
(_a = _this.reconnectionEventEmitter) === null || _a === void 0 ? void 0 : _a.emitEvent('error', [error]);
delete _this.reconnectionEventEmitter;
}
return reject(error);
};
var successOfferCallback = function (sdpOfferParam) {
logger.debug('Sending SDP offer to publish as ' + _this.streamId, sdpOfferParam);
var method = reconnect ? 'reconnectStream' : 'publishVideo';
var params;
if (reconnect) {
params = {
stream: _this.streamId,
sdpString: sdpOfferParam
};
}
else {
var typeOfVideo = void 0;
if (_this.isSendVideo()) {
typeOfVideo =
typeof MediaStreamTrack !== 'undefined' &&
_this.outboundStreamOpts.publisherProperties.videoSource instanceof MediaStreamTrack
? TypeOfVideo_1.TypeOfVideo.CUSTOM
: _this.isSendScreen()
? TypeOfVideo_1.TypeOfVideo.SCREEN
: TypeOfVideo_1.TypeOfVideo.CAMERA;
}
params = {
doLoopback: _this.displayMyRemote() || false,
hasAudio: _this.isSendAudio(),
hasVideo: _this.isSendVideo(),
audioActive: _this.audioActive,
videoActive: _this.videoActive,
typeOfVideo: typeOfVideo,
frameRate: !!_this.frameRate ? _this.frameRate : -1,
videoDimensions: JSON.stringify(_this.videoDimensions),
filter: _this.outboundStreamOpts.publisherProperties.filter,
sdpOffer: sdpOfferParam
};
}
_this.session.openvidu.sendRequest(method, params, function (error, response) {
if (error) {
if (error.code === 401) {
finalReject(new OpenViduError_1.OpenViduError(OpenViduError_1.OpenViduErrorName.OPENVIDU_PERMISSION_DENIED, "You don't have permissions to publish"));
}
else {
finalReject('Error on publishVideo: ' + JSON.stringify(error));
}
}
else {
_this.webRtcPeer
.processRemoteAnswer(response.sdpAnswer)
.then(function () {
_this.streamId = response.id;
_this.creationTime = response.createdAt;
_this.isLocalStreamPublished = true;
_this.publishedOnce = true;
if (_this.displayMyRemote()) {
_this.localMediaStreamWhenSubscribedToRemote = _this.mediaStream;
_this.remotePeerSuccessfullyEstablished(reconnect);
}
if (reconnect) {
_this.ee.emitEvent('stream-reconnected-by-publisher', []);
}
else {
_this.ee.emitEvent('stream-created-by-publisher', []);
}
_this.initWebRtcStats();
logger.info("'Publisher' (" +
_this.streamId +
') successfully ' +
(reconnect ? 'reconnected' : 'published') +
' to session');
finalResolve();
})
.catch(function (error) {
finalReject(error);
});
}
});
};
var config = {
mediaConstraints: {
audio: _this.hasAudio,
video: _this.hasVideo
},
simulcast: (_a = _this.outboundStreamOpts.publisherProperties.videoSimulcast) !== null && _a !== void 0 ? _a : _this.session.openvidu.videoSimulcast,
onIceCandidate: _this.connection.sendIceCandidate.bind(_this.connection),
onIceConnectionStateException: _this.onIceConnectionStateExceptionHandler.bind(_this),
iceServers: _this.getIceServersConf(),
mediaStream: _this.mediaStream,
mediaServer: _this.session.openvidu.mediaServer,
typeOfVideo: _this.typeOfVideo ? TypeOfVideo_1.TypeOfVideo[_this.typeOfVideo] : undefined
};
if (_this.session.openvidu.mediaServer !== 'mediasoup') {
config.simulcast = false;
}
if (reconnect) {
_this.disposeWebRtcPeer();
}
if (_this.displayMyRemote()) {
_this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendrecv(config);
}
else {
_this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerSendonly(config);
}
_this.webRtcPeer.addIceConnectionStateChangeListener('publisher of ' + _this.connection.connectionId);
_this.webRtcPeer
.createOffer()
.then(function (sdpOffer) {
_this.webRtcPeer
.processLocalOffer(sdpOffer)
.then(function () {
successOfferCallback(sdpOffer.sdp);
})
.catch(function (error) {
finalReject(new Error('(publish) SDP process local offer error: ' + JSON.stringify(error)));
});
})
.catch(function (error) {
finalReject(new Error('(publish) SDP create offer error: ' + JSON.stringify(error)));
});
});
};
Stream.prototype.finalResolveForSubscription = function (reconnect, resolve) {
var _a;
logger.info("'Subscriber' (" + this.streamId + ') successfully ' + (reconnect ? 'reconnected' : 'subscribed'));
this.remotePeerSuccessfullyEstablished(reconnect);
this.initWebRtcStats();
if (reconnect) {
(_a = this.reconnectionEventEmitter) === null || _a === void 0 ? void 0 : _a.emitEvent('success');
delete this.reconnectionEventEmitter;
}
return resolve();
};
Stream.prototype.finalRejectForSubscription = function (reconnect, error, reject) {
var _a;
logger.error("Error for 'Subscriber' (" +
this.streamId +
') while trying to ' +
(reconnect ? 'reconnect' : 'subscribe') +
': ' +
error.toString());
if (reconnect) {
(_a = this.reconnectionEventEmitter) === null || _a === void 0 ? void 0 : _a.emitEvent('error', [error]);
delete this.reconnectionEventEmitter;
}
return reject(error);
};
Stream.prototype.initWebRtcPeerReceive = function (reconnect) {
var _this = this;
return new Promise(function (resolve, reject) {
if (reconnect) {
if (_this.setupReconnectionEventEmitter(resolve, reject)) {
return;
}
}
if (_this.session.openvidu.mediaServer === 'mediasoup') {
_this.initWebRtcPeerReceiveFromServer(reconnect)
.then(function () { return _this.finalResolveForSubscription(reconnect, resolve); })
.catch(function (error) { return _this.finalRejectForSubscription(reconnect, error, reject); });
}
else {
_this.initWebRtcPeerReceiveFromClient(reconnect)
.then(function () { return _this.finalResolveForSubscription(reconnect, resolve); })
.catch(function (error) { return _this.finalRejectForSubscription(reconnect, error, reject); });
}
});
};
Stream.prototype.initWebRtcPeerReceiveFromClient = function (reconnect) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.completeWebRtcPeerReceive(reconnect, false)
.then(function (response) {
_this.webRtcPeer
.processRemoteAnswer(response.sdpAnswer)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
})
.catch(function (error) { return reject(error); });
});
};
Stream.prototype.initWebRtcPeerReceiveFromServer = function (reconnect) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.session.openvidu.sendRequest('prepareReceiveVideoFrom', { sender: _this.streamId, reconnect: reconnect }, function (error, response) {
if (error) {
return reject(new Error('Error on prepareReceiveVideoFrom: ' + JSON.stringify(error)));
}
else {
_this.completeWebRtcPeerReceive(reconnect, false, response.sdpOffer)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
}
});
});
};
Stream.prototype.completeWebRtcPeerReceive = function (reconnect, forciblyReconnect, sdpOfferByServer) {
var _this = this;
return new Promise(function (resolve, reject) {
logger.debug("'Session.subscribe(Stream)' called");
var sendSdpToServer = function (sdpString) {
logger.debug("Sending local SDP ".concat(!!sdpOfferByServer ? 'answer' : 'offer', " to subscribe to ").concat(_this.streamId), sdpString);
var method = reconnect ? 'reconnectStream' : 'receiveVideoFrom';
var params = {};
params[reconnect ? 'stream' : 'sender'] = _this.streamId;
if (!!sdpOfferByServer) {
params[reconnect ? 'sdpString' : 'sdpAnswer'] = sdpString;
}
else {
params['sdpOffer'] = sdpString;
}
if (reconnect) {
params['forciblyReconnect'] = forciblyReconnect;
}
_this.session.openvidu.sendRequest(method, params, function (error, response) {
if (error) {
return reject(new Error('Error on ' + method + ' : ' + JSON.stringify(error)));
}
else {
return resolve(response);
}
});
};
var config = {
mediaConstraints: {
audio: _this.hasAudio,
video: _this.hasVideo
},
simulcast: false,
onIceCandidate: _this.connection.sendIceCandidate.bind(_this.connection),
onIceConnectionStateException: _this.onIceConnectionStateExceptionHandler.bind(_this),
iceServers: _this.getIceServersConf(),
mediaServer: _this.session.openvidu.mediaServer,
typeOfVideo: _this.typeOfVideo ? TypeOfVideo_1.TypeOfVideo[_this.typeOfVideo] : undefined
};
if (reconnect) {
_this.disposeWebRtcPeer();
}
_this.webRtcPeer = new WebRtcPeer_1.WebRtcPeerRecvonly(config);
_this.webRtcPeer.addIceConnectionStateChangeListener(_this.streamId);
if (!!sdpOfferByServer) {
_this.webRtcPeer
.processRemoteOffer(sdpOfferByServer)
.then(function () {
_this.webRtcPeer
.createAnswer()
.then(function (sdpAnswer) {
_this.webRtcPeer
.processLocalAnswer(sdpAnswer)
.then(function () {
sendSdpToServer(sdpAnswer.sdp);
})
.catch(function (error) {
return reject(new Error('(subscribe) SDP process local answer error: ' + JSON.stringify(error)));
});
})
.catch(function (error) {
return reject(new Error('(subscribe) SDP create answer error: ' + JSON.stringify(error)));
});
})
.catch(function (error) {
return reject(new Error('(subscribe) SDP process remote offer error: ' + JSON.stringify(error)));
});
}
else {
_this.webRtcPeer
.createOffer()
.then(function (sdpOffer) {
_this.webRtcPeer
.processLocalOffer(sdpOffer)
.then(function () {
sendSdpToServer(sdpOffer.sdp);
})
.catch(function (error) {
return reject(new Error('(subscribe) SDP process local offer error: ' + JSON.stringify(error)));
});
})
.catch(function (error) {
return reject(new Error('(subscribe) SDP create offer error: ' + JSON.stringify(error)));
});
}
});
};
Stream.prototype.remotePeerSuccessfullyEstablished = function (reconnect) {
if (reconnect && this.mediaStream != null) {
this.disposeMediaStream();
}
this.mediaStream = new MediaStream();
var receiver;
for (var _i = 0, _a = this.webRtcPeer.pc.getReceivers(); _i < _a.length; _i++) {
receiver = _a[_i];
if (!!receiver.track) {
this.mediaStream.addTrack(receiver.track);
}
}
logger.debug('Peer remote stream', this.mediaStream);
if (!!this.mediaStream) {
if (this.streamManager instanceof Subscriber_1.Subscriber) {
if (!!this.mediaStream.getAudioTracks()[0]) {
var enabled = reconnect ? this.audioActive : !!this.streamManager.properties.subscribeToAudio;
this.mediaStream.getAudioTracks()[0].enabled = enabled;
}
if (!!this.mediaStream.getVideoTracks()[0]) {
var enabled = reconnect ? this.videoActive : !!this.streamManager.properties.subscribeToVideo;
this.mediaStream.getVideoTracks()[0].enabled = enabled;
}
}
this.updateMediaStreamInVideos();
this.initHarkEvents();
}
};
Stream.prototype.initHarkEvents = function () {
if (!!this.mediaStream.getAudioTracks()[0]) {
if (this.session.anySpeechEventListenerEnabled('publisherStartSpeaking', true, this.streamManager)) {
this.enableOnceHarkSpeakingEvent();
}
if (this.session.anySpeechEventListenerEnabled('publisherStartSpeaking', false, this.streamManager)) {
this.enableHarkSpeakingEvent();
}
if (this.session.anySpeechEventListenerEnabled('publisherStopSpeaking', true, this.streamManager)) {
this.enableOnceHarkStoppedSpeakingEvent();
}
if (this.session.anySpeechEventListenerEnabled('publisherStopSpeaking', false, this.streamManager)) {
this.enableHarkStoppedSpeakingEvent();
}
if (this.harkVolumeChangeEnabledOnce) {
this.enableOnceHarkVolumeChangeEvent(true);
}
if (this.harkVolumeChangeEnabled) {
this.enableHarkVolumeChangeEvent(true);
}
}
};
Stream.prototype.onIceConnectionStateExceptionHandler = function (exceptionName, message, data) {
switch (exceptionName) {
case ExceptionEvent_1.ExceptionEventName.ICE_CONNECTION_FAILED:
this.onIceConnectionFailed();
break;
case ExceptionEvent_1.ExceptionEventName.ICE_CONNECTION_DISCONNECTED:
this.onIceConnectionDisconnected();
break;
}
this.session.emitEvent('exception', [new ExceptionEvent_1.ExceptionEvent(this.session, exceptionName, this, message, data)]);
};
Stream.prototype.onIceConnectionFailed = function () {
logger.log("[ICE_CONNECTION_FAILED] Handling ICE_CONNECTION_FAILED event. Reconnecting stream ".concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ")"));
this.reconnectStreamAndLogResultingIceConnectionState(ExceptionEvent_1.ExceptionEventName.ICE_CONNECTION_FAILED);
};
Stream.prototype.onIceConnectionDisconnected = function () {
var _this = this;
logger.log("[ICE_CONNECTION_DISCONNECTED] Handling ICE_CONNECTION_DISCONNECTED event. Waiting for ICE to be restored and reconnect stream ".concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") if not possible"));
var timeout = this.session.openvidu.advancedConfiguration.iceConnectionDisconnectedExceptionTimeout || 4000;
this.awaitWebRtcPeerConnectionState(timeout).then(function (state) {
switch (state) {
case 'failed':
logger.warn("[ICE_CONNECTION_DISCONNECTED] ICE connection of stream ".concat(_this.streamId, " (").concat(_this.isLocal() ? 'Publisher' : 'Subscriber', ") is now failed after ICE_CONNECTION_DISCONNECTED"));
break;
case 'connected':
case 'completed':
logger.log("[ICE_CONNECTION_DISCONNECTED] ICE connection of stream ".concat(_this.streamId, " (").concat(_this.isLocal() ? 'Publisher' : 'Subscriber', ") automatically restored after ICE_CONNECTION_DISCONNECTED. Current ICE connection state: ").concat(state));
break;
case 'closed':
case 'checking':
case 'new':
case 'disconnected':
logger.warn("[ICE_CONNECTION_DISCONNECTED] ICE connection of stream ".concat(_this.streamId, " (").concat(_this.isLocal() ? 'Publisher' : 'Subscriber', ") couldn't be restored after ICE_CONNECTION_DISCONNECTED event. Current ICE connection state after ").concat(timeout, " ms: ").concat(state));
_this.reconnectStreamAndLogResultingIceConnectionState(ExceptionEvent_1.ExceptionEventName.ICE_CONNECTION_DISCONNECTED);
break;
}
});
};
Stream.prototype.reconnectStreamAndLogResultingIceConnectionState = function (event) {
return __awaiter(this, void 0, void 0, function () {
var finalIceStateAfterReconnection, error_5;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, this.reconnectStreamAndReturnIceConnectionState(event)];
case 1:
finalIceStateAfterReconnection = _a.sent();
switch (finalIceStateAfterReconnection) {
case 'connected':
case 'completed':
logger.log("[".concat(event, "] Stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") successfully reconnected after ").concat(event, ". Current ICE connection state: ").concat(finalIceStateAfterReconnection));
break;
default:
logger.error("[".concat(event, "] Stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") failed to reconnect after ").concat(event, ". Current ICE connection state: ").concat(finalIceStateAfterReconnection));
break;
}
return [3, 3];
case 2:
error_5 = _a.sent();
logger.error("[".concat(event, "] Error reconnecting stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") after ").concat(event, ": ").concat(error_5));
return [3, 3];
case 3: return [2];
}
});
});
};
Stream.prototype.reconnectStreamAndReturnIceConnectionState = function (event) {
return __awaiter(this, void 0, void 0, function () {
var timeout, error_6;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
logger.log("[".concat(event, "] Reconnecting stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") after event ").concat(event));
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4, this.reconnectStream(event)];
case 2:
_a.sent();
timeout = this.session.openvidu.advancedConfiguration.iceConnectionDisconnectedExceptionTimeout || 4000;
return [2, this.awaitWebRtcPeerConnectionState(timeout)];
case 3:
error_6 = _a.sent();
logger.warn("[".concat(event, "] Error reconnecting stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', "). Reason: ").concat(error_6));
return [2, this.awaitWebRtcPeerConnectionState(1)];
case 4: return [2];
}
});
});
};
Stream.prototype.awaitWebRtcPeerConnectionState = function (timeout) {
return __awaiter(this, void 0, void 0, function () {
var state, interval, intervals, i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
state = this.getRTCPeerConnection().iceConnectionState;
interval = 150;
intervals = Math.ceil(timeout / interval);
i = 0;
_a.label = 1;
case 1:
if (!(i < intervals)) return [3, 4];
state = this.getRTCPeerConnection().iceConnectionState;
if (state === 'connected' || state === 'completed') {
return [3, 4];
}
return [4, new Promise(function (resolve) { return setTimeout(resolve, interval); })];
case 2:
_a.sent();
_a.label = 3;
case 3:
i++;
return [3, 1];
case 4: return [2, state];
}
});
});
};
Stream.prototype.reconnectStream = function (event) {
return __awaiter(this, void 0, void 0, function () {
var isWsConnected, errorMsg;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.isWebsocketConnected(event, 3000)];
case 1:
isWsConnected = _a.sent();
if (isWsConnected) {
logger.log("[".concat(event, "] Trying to reconnect stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") and the websocket is opened"));
if (this.isLocal()) {
return [2, this.initWebRtcPeerSend(true)];
}
else {
return [2, this.initWebRtcPeerReceive(true)];
}
}
else {
errorMsg = "[".concat(event, "] Trying to reconnect stream ").concat(this.streamId, " (").concat(this.isLocal() ? 'Publisher' : 'Subscriber', ") but the websocket wasn't opened");
logger.error(errorMsg);
throw Error(errorMsg);
}
return [2];
}
});
});
};
Stream.prototype.isWebsocketConnected = function (event, msResponseTimeout) {
var _this = this;
return new Promise(function (resolve, reject) {
var wsReadyState = _this.session.openvidu.getWsReadyState();
if (wsReadyState === 1) {
var responseTimeout_1 = setTimeout(function () {
console.warn("[".concat(event, "] Websocket timeout of ").concat(msResponseTimeout, "ms"));
return resolve(false);
}, msResponseTimeout);
_this.session.openvidu.sendRequest('echo', {}, function (error, response) {
clearTimeout(responseTimeout_1);
if (!!error) {
console.warn("[".concat(event, "] Websocket 'echo' returned error: ").concat(error));
return resolve(false);
}
else {
return resolve(true);
}
});
}
else {
console.warn("[".concat(event, "] Websocket readyState is ").concat(wsReadyState));
return resolve(false);
}
});
};
Stream.prototype.initWebRtcStats = function () {
this.webRtcStats = new WebRtcStats_1.WebRtcStats(this);
this.webRtcStats.initWebRtcStats();
};
Stream.prototype.stopWebRtcStats = function () {
if (!!this.webRtcStats && this.webRtcStats.isEnabled()) {
this.webRtcStats.stopWebRtcStats();
}
};
Stream.prototype.getIceServersConf = function () {
var returnValue;
if (!!this.session.openvidu.advancedConfiguration.iceServers) {
returnValue =
this.session.openvidu.advancedConfiguration.iceServers === 'freeice'
? undefined
: this.session.openvidu.advancedConfiguration.iceServers;
}
else if (this.session.openvidu.iceServers) {
returnValue = this.session.openvidu.iceServers;
}
else {
returnValue = undefined;
}
return returnValue;
};
Stream.prototype.gatherStatsForPeer = function () {
var _this = this;
return new Promise(function (resolve, reject) {
if (_this.isLocal()) {
_this.getRTCPeerConnection()
.getSenders()
.forEach(function (sender) {
return sender.getStats().then(function (response) {
response.forEach(function (report) {
if (_this.isReportWanted(report)) {
var finalReport = {};
finalReport['type'] = report.type;
finalReport['timestamp'] = report.timestamp;
finalReport['id'] = report.id;
if (report.type === 'outbound-rtp') {
finalReport['ssrc'] = report.ssrc;
finalReport['firCount'] = report.firCount;
finalReport['pliCount'] = report.pliCount;
finalReport['nackCount'] = report.nackCount;
finalReport['qpSum'] = report.qpSum;
if (!!report.kind) {
finalReport['mediaType'] = report.kind;
}
else if (!!report.mediaType) {
finalReport['mediaType'] = report.mediaType;
}
else {
finalReport['mediaType'] = report.id.indexOf('VideoStream') !== -1 ? 'video' : 'audio';
}
if (finalReport['mediaType'] === 'video') {
finalReport['framesEncoded'] = report.framesEncoded;
}
finalReport['packetsSent'] = report.packetsSent;
finalReport['bytesSent'] = report.bytesSent;
}
if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) {
finalReport['availableOutgoingBitrate'] = report.availableOutgoingBitrate;
finalReport['rtt'] = report.currentRoundTripTime;
finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived;
}
if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') {
}
logger.log(finalReport);
}
});
});
});
}
else {
_this.getRTCPeerConnection()
.getReceivers()
.forEach(function (receiver) {
return receiver.getStats().then(function (response) {
response.forEach(function (report) {
if (_this.isReportWanted(report)) {
var finalReport = {};
finalReport['type'] = report.type;
finalReport['timestamp'] = report.timestamp;
finalReport['id'] = report.id;
if (report.type === 'inbound-rtp') {
finalReport['ssrc'] = report.ssrc;
finalReport['firCount'] = report.firCount;
finalReport['pliCount'] = report.pliCount;
finalReport['nackCount'] = report.nackCount;
finalReport['qpSum'] = report.qpSum;
if (!!report.kind) {
finalReport['mediaType'] = report.kind;
}
else if (!!report.mediaType) {
finalReport['mediaType'] = report.mediaType;
}
else {
finalReport['mediaType'] = report.id.indexOf('VideoStream') !== -1 ? 'video' : 'audio';
}
if (finalReport['mediaType'] === 'video') {
finalReport['framesDecoded'] = report.framesDecoded;
}
finalReport['packetsReceived'] = report.packetsReceived;
finalReport['packetsLost'] = report.packetsLost;
finalReport['jitter'] = report.jitter;
finalReport['bytesReceived'] = report.bytesReceived;
}
if (report.type === 'candidate-pair' && report.totalRoundTripTime !== undefined) {
finalReport['availableIncomingBitrate'] = report.availableIncomingBitrate;
finalReport['rtt'] = report.currentRoundTripTime;
finalReport['averageRtt'] = report.totalRoundTripTime / report.responsesReceived;
}
if (report.type === 'remote-inbound-rtp' || report.type === 'remote-outbound-rtp') {
}
logger.log(finalReport);
}
});
});
});
}
});
};
Stream.prototype.isReportWanted = function (report) {
return ((report.type === 'inbound-rtp' && !this.isLocal()) ||
(report.type === 'outbound-rtp' && this.isLocal()) ||
(report.type === 'candidate-pair' && report.nominated && report.bytesSent > 0));
};
return Stream;
}());
exports.Stream = Stream;
},{"../OpenViduInternal/Enums/OpenViduError":53,"../OpenViduInternal/Enums/TypeOfVideo":54,"../OpenViduInternal/Events/ExceptionEvent":59,"../OpenViduInternal/Events/PublisherSpeakingEvent":62,"../OpenViduInternal/Events/StreamManagerEvent":68,"../OpenViduInternal/Events/StreamPropertyChangedEvent":69,"../OpenViduInternal/Logger/OpenViduLogger":81,"../OpenViduInternal/Utils/Platform":85,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":86,"../OpenViduInternal/WebRtcStats/WebRtcStats":87,"./Filter":44,"./Subscriber":51,"hark":5,"uuid":22,"wolfy87-eventemitter":39}],50:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.StreamManager = void 0;
var EventDispatcher_1 = require("./EventDispatcher");
var StreamManagerEvent_1 = require("../OpenViduInternal/Events/StreamManagerEvent");
var VideoElementEvent_1 = require("../OpenViduInternal/Events/VideoElementEvent");
var ExceptionEvent_1 = require("../OpenViduInternal/Events/ExceptionEvent");
var VideoInsertMode_1 = require("../OpenViduInternal/Enums/VideoInsertMode");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var Platform_1 = require("../OpenViduInternal/Utils/Platform");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var StreamManager = (function (_super) {
__extends(StreamManager, _super);
function StreamManager(stream, targetElement) {
var _this = _super.call(this) || this;
_this.videos = [];
_this.lazyLaunchVideoElementCreatedEvent = false;
platform = Platform_1.PlatformUtils.getInstance();
_this.stream = stream;
_this.stream.streamManager = _this;
_this.remote = !_this.stream.isLocal();
if (!!targetElement) {
var targEl = void 0;
if (typeof targetElement === 'string') {
targEl = document.getElementById(targetElement);
}
else if (targetElement instanceof HTMLElement) {
targEl = targetElement;
}
if (!!targEl) {
_this.firstVideoElement = {
targetElement: targEl,
video: document.createElement('video'),
id: '',
canplayListenerAdded: false
};
if (platform.isSafariBrowser() ||
(platform.isIPhoneOrIPad() &&
(platform.isChromeMobileBrowser() ||
platform.isEdgeMobileBrowser() ||
platform.isOperaMobileBrowser() ||
platform.isFirefoxMobileBrowser()))) {
_this.firstVideoElement.video.playsInline = true;
}
_this.targetElement = targEl;
_this.element = targEl;
}
}
_this.canPlayListener = function () {
_this.deactivateStreamPlayingEventExceptionTimeout();
_this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(_this, 'streamPlaying', undefined)]);
};
return _this;
}
StreamManager.prototype.on = function (type, handler) {
_super.prototype.onAux.call(this, type, "Event '" + type + "' triggered by '" + (this.remote ? 'Subscriber' : 'Publisher') + "'", handler);
if (type === 'videoElementCreated') {
if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) {
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]);
this.lazyLaunchVideoElementCreatedEvent = false;
}
}
if (type === 'streamPlaying') {
if (this.videos[0] &&
this.videos[0].video &&
this.videos[0].video.currentTime > 0 &&
this.videos[0].video.paused === false &&
this.videos[0].video.ended === false &&
this.videos[0].video.readyState === 4) {
this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]);
}
}
if (this.stream.hasAudio) {
if (type === 'publisherStartSpeaking') {
this.stream.enableHarkSpeakingEvent();
}
if (type === 'publisherStopSpeaking') {
this.stream.enableHarkStoppedSpeakingEvent();
}
if (type === 'streamAudioVolumeChange') {
this.stream.enableHarkVolumeChangeEvent(false);
}
}
return this;
};
StreamManager.prototype.once = function (type, handler) {
_super.prototype.onceAux.call(this, type, "Event '" + type + "' triggered once by '" + (this.remote ? 'Subscriber' : 'Publisher') + "'", handler);
if (type === 'videoElementCreated') {
if (!!this.stream && this.lazyLaunchVideoElementCreatedEvent) {
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(this.videos[0].video, this, 'videoElementCreated')]);
}
}
if (type === 'streamPlaying') {
if (this.videos[0] &&
this.videos[0].video &&
this.videos[0].video.currentTime > 0 &&
this.videos[0].video.paused === false &&
this.videos[0].video.ended === false &&
this.videos[0].video.readyState === 4) {
this.ee.emitEvent('streamPlaying', [new StreamManagerEvent_1.StreamManagerEvent(this, 'streamPlaying', undefined)]);
}
}
if (this.stream.hasAudio) {
if (type === 'publisherStartSpeaking') {
this.stream.enableOnceHarkSpeakingEvent();
}
if (type === 'publisherStopSpeaking') {
this.stream.enableOnceHarkStoppedSpeakingEvent();
}
if (type === 'streamAudioVolumeChange') {
this.stream.enableOnceHarkVolumeChangeEvent(false);
}
}
return this;
};
StreamManager.prototype.off = function (type, handler) {
_super.prototype.offAux.call(this, type, handler);
if (type === 'publisherStartSpeaking') {
var remainingStartSpeakingEventListeners = this.ee.getListeners(type).length + this.stream.session.ee.getListeners(type).length;
if (remainingStartSpeakingEventListeners === 0) {
this.stream.disableHarkSpeakingEvent(false);
}
}
if (type === 'publisherStopSpeaking') {
var remainingStopSpeakingEventListeners = this.ee.getListeners(type).length + this.stream.session.ee.getListeners(type).length;
if (remainingStopSpeakingEventListeners === 0) {
this.stream.disableHarkStoppedSpeakingEvent(false);
}
}
if (type === 'streamAudioVolumeChange') {
var remainingVolumeEventListeners = this.ee.getListeners(type).length;
if (remainingVolumeEventListeners === 0) {
this.stream.disableHarkVolumeChangeEvent(false);
}
}
return this;
};
StreamManager.prototype.addVideoElement = function (video) {
this.initializeVideoProperties(video);
if (!this.remote && this.stream.displayMyRemote()) {
if (video.srcObject !== this.stream.getMediaStream()) {
video.srcObject = this.stream.getMediaStream();
}
}
for (var _i = 0, _a = this.videos; _i < _a.length; _i++) {
var v = _a[_i];
if (v.video === video) {
return 0;
}
}
var returnNumber = 1;
for (var _b = 0, _c = this.stream.session.streamManagers; _b < _c.length; _b++) {
var streamManager = _c[_b];
if (streamManager.disassociateVideo(video)) {
returnNumber = -1;
break;
}
}
this.stream.session.streamManagers.forEach(function (streamManager) {
streamManager.disassociateVideo(video);
});
this.pushNewStreamManagerVideo({
video: video,
id: video.id,
canplayListenerAdded: false
});
logger.info('New video element associated to ', this);
return returnNumber;
};
StreamManager.prototype.createVideoElement = function (targetElement, insertMode) {
var targEl;
if (typeof targetElement === 'string') {
targEl = document.getElementById(targetElement);
if (!targEl) {
throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement);
}
}
else if (targetElement instanceof HTMLElement) {
targEl = targetElement;
}
else {
throw new Error("The provided 'targetElement' couldn't be resolved to any HTML element: " + targetElement);
}
var video = this.createVideo();
this.initializeVideoProperties(video);
var insMode = !!insertMode ? insertMode : VideoInsertMode_1.VideoInsertMode.APPEND;
switch (insMode) {
case VideoInsertMode_1.VideoInsertMode.AFTER:
targEl.parentNode.insertBefore(video, targEl.nextSibling);
break;
case VideoInsertMode_1.VideoInsertMode.APPEND:
targEl.appendChild(video);
break;
case VideoInsertMode_1.VideoInsertMode.BEFORE:
targEl.parentNode.insertBefore(video, targEl);
break;
case VideoInsertMode_1.VideoInsertMode.PREPEND:
targEl.insertBefore(video, targEl.childNodes[0]);
break;
case VideoInsertMode_1.VideoInsertMode.REPLACE:
targEl.parentNode.replaceChild(video, targEl);
break;
default:
insMode = VideoInsertMode_1.VideoInsertMode.APPEND;
targEl.appendChild(video);
break;
}
var v = {
targetElement: targEl,
video: video,
insertMode: insMode,
id: video.id,
canplayListenerAdded: false
};
this.pushNewStreamManagerVideo(v);
this.ee.emitEvent('videoElementCreated', [new VideoElementEvent_1.VideoElementEvent(v.video, this, 'videoElementCreated')]);
this.lazyLaunchVideoElementCreatedEvent = !!this.firstVideoElement;
return video;
};
StreamManager.prototype.updatePublisherSpeakingEventsOptions = function (publisherSpeakingEventsOptions) {
var currentHarkOptions = !!this.stream.harkOptions
? this.stream.harkOptions
: this.stream.session.openvidu.advancedConfiguration.publisherSpeakingEventsOptions || {};
var newInterval = typeof publisherSpeakingEventsOptions.interval === 'number'
? publisherSpeakingEventsOptions.interval
: typeof currentHarkOptions.interval === 'number'
? currentHarkOptions.interval
: 100;
var newThreshold = typeof publisherSpeakingEventsOptions.threshold === 'number'
? publisherSpeakingEventsOptions.threshold
: typeof currentHarkOptions.threshold === 'number'
? currentHarkOptions.threshold
: -50;
this.stream.harkOptions = {
interval: newInterval,
threshold: newThreshold
};
if (!!this.stream.speechEvent) {
this.stream.speechEvent.setInterval(newInterval);
this.stream.speechEvent.setThreshold(newThreshold);
}
};
StreamManager.prototype.initializeVideoProperties = function (video) {
if (!(!this.remote && this.stream.displayMyRemote())) {
if (video.srcObject !== this.stream.getMediaStream()) {
video.srcObject = this.stream.getMediaStream();
}
}
video.autoplay = true;
video.controls = false;
if (platform.isSafariBrowser() ||
(platform.isIPhoneOrIPad() &&
(platform.isChromeMobileBrowser() ||
platform.isEdgeMobileBrowser() ||
platform.isOperaMobileBrowser() ||
platform.isFirefoxMobileBrowser()))) {
video.playsInline = true;
}
if (!video.id) {
video.id = (this.remote ? 'remote-' : 'local-') + 'video-' + this.stream.streamId;
if (!this.id && !!this.targetElement) {
this.id = video.id;
}
}
if (this.remote && this.isMirroredVideo(video)) {
this.removeMirrorVideo(video);
}
else if (!this.remote && !this.stream.displayMyRemote()) {
video.muted = true;
if (this.isMirroredVideo(video) && !this.stream.outboundStreamOpts.publisherProperties.mirror) {
this.removeMirrorVideo(video);
}
else if (this.stream.outboundStreamOpts.publisherProperties.mirror && !this.stream.isSendScreen()) {
this.mirrorVideo(video);
}
}
};
StreamManager.prototype.removeAllVideos = function () {
var _this = this;
for (var i = this.stream.session.streamManagers.length - 1; i >= 0; --i) {
if (this.stream.session.streamManagers[i] === this) {
this.stream.session.streamManagers.splice(i, 1);
}
}
this.videos.forEach(function (streamManagerVideo) {
if (!!streamManagerVideo.video && !!streamManagerVideo.video.removeEventListener) {
streamManagerVideo.video.removeEventListener('canplay', _this.canPlayListener);
}
streamManagerVideo.canplayListenerAdded = false;
if (!!streamManagerVideo.targetElement) {
streamManagerVideo.video.parentNode.removeChild(streamManagerVideo.video);
_this.ee.emitEvent('videoElementDestroyed', [
new VideoElementEvent_1.VideoElementEvent(streamManagerVideo.video, _this, 'videoElementDestroyed')
]);
}
_this.removeSrcObject(streamManagerVideo);
_this.videos.filter(function (v) { return !v.targetElement; });
});
};
StreamManager.prototype.disassociateVideo = function (video) {
var disassociated = false;
for (var i = 0; i < this.videos.length; i++) {
if (this.videos[i].video === video) {
this.videos[i].video.removeEventListener('canplay', this.canPlayListener);
this.videos.splice(i, 1);
disassociated = true;
logger.info('Video element disassociated from ', this);
break;
}
}
return disassociated;
};
StreamManager.prototype.addPlayEventToFirstVideo = function () {
if (!!this.videos[0] && !!this.videos[0].video && !this.videos[0].canplayListenerAdded) {
this.activateStreamPlayingEventExceptionTimeout();
this.videos[0].video.addEventListener('canplay', this.canPlayListener);
this.videos[0].canplayListenerAdded = true;
}
};
StreamManager.prototype.updateMediaStream = function (mediaStream) {
this.videos.forEach(function (streamManagerVideo) {
streamManagerVideo.video.srcObject = mediaStream;
if (platform.isIonicIos()) {
var vParent = streamManagerVideo.video.parentElement;
var newVideo = streamManagerVideo.video;
vParent.replaceChild(newVideo, streamManagerVideo.video);
streamManagerVideo.video = newVideo;
}
});
};
StreamManager.prototype.emitEvent = function (type, eventArray) {
this.ee.emitEvent(type, eventArray);
};
StreamManager.prototype.createVideo = function () {
return document.createElement('video');
};
StreamManager.prototype.removeSrcObject = function (streamManagerVideo) {
streamManagerVideo.video.srcObject = null;
this.deactivateStreamPlayingEventExceptionTimeout();
};
StreamManager.prototype.pushNewStreamManagerVideo = function (streamManagerVideo) {
this.videos.push(streamManagerVideo);
this.addPlayEventToFirstVideo();
if (this.stream.session.streamManagers.indexOf(this) === -1) {
this.stream.session.streamManagers.push(this);
}
};
StreamManager.prototype.mirrorVideo = function (video) {
if (!platform.isIonicIos()) {
video.style.transform = 'rotateY(180deg)';
video.style.webkitTransform = 'rotateY(180deg)';
}
};
StreamManager.prototype.removeMirrorVideo = function (video) {
video.style.transform = 'unset';
video.style.webkitTransform = 'unset';
};
StreamManager.prototype.isMirroredVideo = function (video) {
return video.style.transform === 'rotateY(180deg)' || video.style.webkitTransform === 'rotateY(180deg)';
};
StreamManager.prototype.activateStreamPlayingEventExceptionTimeout = function () {
var _this = this;
if (!this.remote) {
return;
}
if (this.streamPlayingEventExceptionTimeout != null) {
return;
}
var msTimeout = this.stream.session.openvidu.advancedConfiguration.noStreamPlayingEventExceptionTimeout || 4000;
this.streamPlayingEventExceptionTimeout = setTimeout(function () {
var msg = 'StreamManager of Stream ' +
_this.stream.streamId +
' (' +
(_this.remote ? 'Subscriber' : 'Publisher') +
') did not trigger "streamPlaying" event in ' +
msTimeout +
' ms';
logger.warn(msg);
_this.stream.session.emitEvent('exception', [
new ExceptionEvent_1.ExceptionEvent(_this.stream.session, ExceptionEvent_1.ExceptionEventName.NO_STREAM_PLAYING_EVENT, _this, msg)
]);
delete _this.streamPlayingEventExceptionTimeout;
}, msTimeout);
};
StreamManager.prototype.deactivateStreamPlayingEventExceptionTimeout = function () {
clearTimeout(this.streamPlayingEventExceptionTimeout);
delete this.streamPlayingEventExceptionTimeout;
};
return StreamManager;
}(EventDispatcher_1.EventDispatcher));
exports.StreamManager = StreamManager;
},{"../OpenViduInternal/Enums/VideoInsertMode":55,"../OpenViduInternal/Events/ExceptionEvent":59,"../OpenViduInternal/Events/StreamManagerEvent":68,"../OpenViduInternal/Events/VideoElementEvent":70,"../OpenViduInternal/Logger/OpenViduLogger":81,"../OpenViduInternal/Utils/Platform":85,"./EventDispatcher":43}],51:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Subscriber = void 0;
var StreamManager_1 = require("./StreamManager");
var OpenViduLogger_1 = require("../OpenViduInternal/Logger/OpenViduLogger");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var Subscriber = (function (_super) {
__extends(Subscriber, _super);
function Subscriber(stream, targEl, properties) {
var _this = _super.call(this, stream, targEl) || this;
_this.element = _this.targetElement;
_this.stream = stream;
_this.properties = properties;
return _this;
}
Subscriber.prototype.subscribeToAudio = function (value) {
this.stream
.getMediaStream()
.getAudioTracks()
.forEach(function (track) {
track.enabled = value;
});
this.stream.audioActive = value;
logger.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its audio stream');
return this;
};
Subscriber.prototype.subscribeToVideo = function (value) {
this.stream
.getMediaStream()
.getVideoTracks()
.forEach(function (track) {
track.enabled = value;
});
this.stream.videoActive = value;
logger.info("'Subscriber' has " + (value ? 'subscribed to' : 'unsubscribed from') + ' its video stream');
return this;
};
Subscriber.prototype.replaceTrackInMediaStream = function (track, updateLastConstraints) {
var mediaStream = this.stream.getMediaStream();
var removedTrack;
if (track.kind === 'video') {
removedTrack = mediaStream.getVideoTracks()[0];
if (updateLastConstraints) {
this.stream.lastVideoTrackConstraints = track.getConstraints();
}
}
else {
removedTrack = mediaStream.getAudioTracks()[0];
}
mediaStream.removeTrack(removedTrack);
removedTrack.stop();
mediaStream.addTrack(track);
};
return Subscriber;
}(StreamManager_1.StreamManager));
exports.Subscriber = Subscriber;
},{"../OpenViduInternal/Logger/OpenViduLogger":81,"./StreamManager":50}],52:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LocalRecorderState = void 0;
var LocalRecorderState;
(function (LocalRecorderState) {
LocalRecorderState["READY"] = "READY";
LocalRecorderState["RECORDING"] = "RECORDING";
LocalRecorderState["PAUSED"] = "PAUSED";
LocalRecorderState["FINISHED"] = "FINISHED";
})(LocalRecorderState = exports.LocalRecorderState || (exports.LocalRecorderState = {}));
},{}],53:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenViduError = exports.OpenViduErrorName = void 0;
var OpenViduErrorName;
(function (OpenViduErrorName) {
OpenViduErrorName["BROWSER_NOT_SUPPORTED"] = "BROWSER_NOT_SUPPORTED";
OpenViduErrorName["DEVICE_ACCESS_DENIED"] = "DEVICE_ACCESS_DENIED";
OpenViduErrorName["DEVICE_ALREADY_IN_USE"] = "DEVICE_ALREADY_IN_USE";
OpenViduErrorName["SCREEN_CAPTURE_DENIED"] = "SCREEN_CAPTURE_DENIED";
OpenViduErrorName["SCREEN_SHARING_NOT_SUPPORTED"] = "SCREEN_SHARING_NOT_SUPPORTED";
OpenViduErrorName["SCREEN_EXTENSION_NOT_INSTALLED"] = "SCREEN_EXTENSION_NOT_INSTALLED";
OpenViduErrorName["SCREEN_EXTENSION_DISABLED"] = "SCREEN_EXTENSION_DISABLED";
OpenViduErrorName["INPUT_VIDEO_DEVICE_NOT_FOUND"] = "INPUT_VIDEO_DEVICE_NOT_FOUND";
OpenViduErrorName["INPUT_AUDIO_DEVICE_NOT_FOUND"] = "INPUT_AUDIO_DEVICE_NOT_FOUND";
OpenViduErrorName["INPUT_AUDIO_DEVICE_GENERIC_ERROR"] = "INPUT_AUDIO_DEVICE_GENERIC_ERROR";
OpenViduErrorName["NO_INPUT_SOURCE_SET"] = "NO_INPUT_SOURCE_SET";
OpenViduErrorName["PUBLISHER_PROPERTIES_ERROR"] = "PUBLISHER_PROPERTIES_ERROR";
OpenViduErrorName["OPENVIDU_PERMISSION_DENIED"] = "OPENVIDU_PERMISSION_DENIED";
OpenViduErrorName["OPENVIDU_NOT_CONNECTED"] = "OPENVIDU_NOT_CONNECTED";
OpenViduErrorName["VIRTUAL_BACKGROUND_ERROR"] = "VIRTUAL_BACKGROUND_ERROR";
OpenViduErrorName["GENERIC_ERROR"] = "GENERIC_ERROR";
})(OpenViduErrorName = exports.OpenViduErrorName || (exports.OpenViduErrorName = {}));
var OpenViduError = (function () {
function OpenViduError(name, message) {
this.name = name;
this.message = message;
}
return OpenViduError;
}());
exports.OpenViduError = OpenViduError;
},{}],54:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypeOfVideo = void 0;
var TypeOfVideo;
(function (TypeOfVideo) {
TypeOfVideo["CAMERA"] = "CAMERA";
TypeOfVideo["SCREEN"] = "SCREEN";
TypeOfVideo["CUSTOM"] = "CUSTOM";
TypeOfVideo["IPCAM"] = "IPCAM";
})(TypeOfVideo = exports.TypeOfVideo || (exports.TypeOfVideo = {}));
},{}],55:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VideoInsertMode = void 0;
var VideoInsertMode;
(function (VideoInsertMode) {
VideoInsertMode["AFTER"] = "AFTER";
VideoInsertMode["APPEND"] = "APPEND";
VideoInsertMode["BEFORE"] = "BEFORE";
VideoInsertMode["PREPEND"] = "PREPEND";
VideoInsertMode["REPLACE"] = "REPLACE";
})(VideoInsertMode = exports.VideoInsertMode || (exports.VideoInsertMode = {}));
},{}],56:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConnectionEvent = void 0;
var Event_1 = require("./Event");
var ConnectionEvent = (function (_super) {
__extends(ConnectionEvent, _super);
function ConnectionEvent(cancelable, target, type, connection, reason) {
var _this = _super.call(this, cancelable, target, type) || this;
_this.connection = connection;
_this.reason = reason;
return _this;
}
ConnectionEvent.prototype.callDefaultBehavior = function () { };
return ConnectionEvent;
}(Event_1.Event));
exports.ConnectionEvent = ConnectionEvent;
},{"./Event":58}],57:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConnectionPropertyChangedEvent = void 0;
var Event_1 = require("./Event");
var ConnectionPropertyChangedEvent = (function (_super) {
__extends(ConnectionPropertyChangedEvent, _super);
function ConnectionPropertyChangedEvent(target, connection, changedProperty, newValue, oldValue) {
var _this = _super.call(this, false, target, 'connectionPropertyChanged') || this;
_this.connection = connection;
_this.changedProperty = changedProperty;
_this.newValue = newValue;
_this.oldValue = oldValue;
return _this;
}
ConnectionPropertyChangedEvent.prototype.callDefaultBehavior = function () { };
return ConnectionPropertyChangedEvent;
}(Event_1.Event));
exports.ConnectionPropertyChangedEvent = ConnectionPropertyChangedEvent;
},{"./Event":58}],58:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Event = void 0;
var Event = (function () {
function Event(cancelable, target, type) {
this.hasBeenPrevented = false;
this.cancelable = cancelable;
this.target = target;
this.type = type;
}
Event.prototype.isDefaultPrevented = function () {
return this.hasBeenPrevented;
};
Event.prototype.preventDefault = function () {
this.callDefaultBehavior = function () { };
this.hasBeenPrevented = true;
};
return Event;
}());
exports.Event = Event;
},{}],59:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExceptionEvent = exports.ExceptionEventName = void 0;
var Event_1 = require("./Event");
var ExceptionEventName;
(function (ExceptionEventName) {
ExceptionEventName["ICE_CANDIDATE_ERROR"] = "ICE_CANDIDATE_ERROR";
ExceptionEventName["ICE_CONNECTION_FAILED"] = "ICE_CONNECTION_FAILED";
ExceptionEventName["ICE_CONNECTION_DISCONNECTED"] = "ICE_CONNECTION_DISCONNECTED";
ExceptionEventName["NO_STREAM_PLAYING_EVENT"] = "NO_STREAM_PLAYING_EVENT";
ExceptionEventName["SPEECH_TO_TEXT_DISCONNECTED"] = "SPEECH_TO_TEXT_DISCONNECTED";
})(ExceptionEventName = exports.ExceptionEventName || (exports.ExceptionEventName = {}));
var ExceptionEvent = (function (_super) {
__extends(ExceptionEvent, _super);
function ExceptionEvent(session, name, origin, message, data) {
var _this = _super.call(this, false, session, 'exception') || this;
_this.name = name;
_this.origin = origin;
_this.message = message;
_this.data = data;
return _this;
}
ExceptionEvent.prototype.callDefaultBehavior = function () { };
return ExceptionEvent;
}(Event_1.Event));
exports.ExceptionEvent = ExceptionEvent;
},{"./Event":58}],60:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.FilterEvent = void 0;
var Event_1 = require("./Event");
var FilterEvent = (function (_super) {
__extends(FilterEvent, _super);
function FilterEvent(target, eventType, data) {
var _this = _super.call(this, false, target, eventType) || this;
_this.data = data;
return _this;
}
FilterEvent.prototype.callDefaultBehavior = function () { };
return FilterEvent;
}(Event_1.Event));
exports.FilterEvent = FilterEvent;
},{"./Event":58}],61:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.NetworkQualityLevelChangedEvent = void 0;
var Event_1 = require("./Event");
var NetworkQualityLevelChangedEvent = (function (_super) {
__extends(NetworkQualityLevelChangedEvent, _super);
function NetworkQualityLevelChangedEvent(target, newValue, oldValue, connection) {
var _this = _super.call(this, false, target, 'networkQualityLevelChanged') || this;
_this.newValue = newValue;
_this.oldValue = oldValue;
_this.connection = connection;
return _this;
}
NetworkQualityLevelChangedEvent.prototype.callDefaultBehavior = function () { };
return NetworkQualityLevelChangedEvent;
}(Event_1.Event));
exports.NetworkQualityLevelChangedEvent = NetworkQualityLevelChangedEvent;
},{"./Event":58}],62:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.PublisherSpeakingEvent = void 0;
var Event_1 = require("./Event");
var PublisherSpeakingEvent = (function (_super) {
__extends(PublisherSpeakingEvent, _super);
function PublisherSpeakingEvent(target, type, connection, streamId) {
var _this = _super.call(this, false, target, type) || this;
_this.type = type;
_this.connection = connection;
_this.streamId = streamId;
return _this;
}
PublisherSpeakingEvent.prototype.callDefaultBehavior = function () { };
return PublisherSpeakingEvent;
}(Event_1.Event));
exports.PublisherSpeakingEvent = PublisherSpeakingEvent;
},{"./Event":58}],63:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.RecordingEvent = void 0;
var Event_1 = require("./Event");
var RecordingEvent = (function (_super) {
__extends(RecordingEvent, _super);
function RecordingEvent(target, type, id, name, reason) {
var _this = _super.call(this, false, target, type) || this;
_this.id = id;
if (name !== id) {
_this.name = name;
}
_this.reason = reason;
return _this;
}
RecordingEvent.prototype.callDefaultBehavior = function () { };
return RecordingEvent;
}(Event_1.Event));
exports.RecordingEvent = RecordingEvent;
},{"./Event":58}],64:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.SessionDisconnectedEvent = void 0;
var Event_1 = require("./Event");
var OpenViduLogger_1 = require("../Logger/OpenViduLogger");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var SessionDisconnectedEvent = (function (_super) {
__extends(SessionDisconnectedEvent, _super);
function SessionDisconnectedEvent(target, reason) {
var _this = _super.call(this, true, target, 'sessionDisconnected') || this;
_this.reason = reason;
return _this;
}
SessionDisconnectedEvent.prototype.callDefaultBehavior = function () {
logger.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'");
var session = this.target;
session.remoteConnections.forEach(function (remoteConnection) {
var _a, _b, _c, _d, _e, _f, _g, _h;
var connectionId = remoteConnection.connectionId;
if (!!((_a = session.remoteConnections.get(connectionId)) === null || _a === void 0 ? void 0 : _a.stream)) {
(_b = session.remoteConnections.get(connectionId)) === null || _b === void 0 ? void 0 : _b.stream.disposeWebRtcPeer();
(_c = session.remoteConnections.get(connectionId)) === null || _c === void 0 ? void 0 : _c.stream.disposeMediaStream();
if ((_d = session.remoteConnections.get(connectionId)) === null || _d === void 0 ? void 0 : _d.stream.streamManager) {
(_e = session.remoteConnections.get(connectionId)) === null || _e === void 0 ? void 0 : _e.stream.streamManager.removeAllVideos();
}
var streamId = (_g = (_f = session.remoteConnections.get(connectionId)) === null || _f === void 0 ? void 0 : _f.stream) === null || _g === void 0 ? void 0 : _g.streamId;
if (!!streamId) {
session.remoteStreamsCreated.delete(streamId);
}
(_h = session.remoteConnections.get(connectionId)) === null || _h === void 0 ? void 0 : _h.dispose();
}
session.remoteConnections.delete(connectionId);
});
};
return SessionDisconnectedEvent;
}(Event_1.Event));
exports.SessionDisconnectedEvent = SessionDisconnectedEvent;
},{"../Logger/OpenViduLogger":81,"./Event":58}],65:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.SignalEvent = void 0;
var Event_1 = require("./Event");
var SignalEvent = (function (_super) {
__extends(SignalEvent, _super);
function SignalEvent(target, type, data, from) {
var _this = _super.call(this, false, target, 'signal') || this;
if (!!type) {
_this.type = 'signal:' + type;
}
_this.data = data;
_this.from = from;
return _this;
}
SignalEvent.prototype.callDefaultBehavior = function () { };
return SignalEvent;
}(Event_1.Event));
exports.SignalEvent = SignalEvent;
},{"./Event":58}],66:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.SpeechToTextEvent = void 0;
var Event_1 = require("./Event");
var SpeechToTextEvent = (function (_super) {
__extends(SpeechToTextEvent, _super);
function SpeechToTextEvent(target, connection, text, reason, raw, lang) {
var _this = _super.call(this, false, target, 'speechToTextMessage') || this;
_this.connection = connection;
_this.text = text;
_this.reason = reason;
_this.raw = raw;
_this.lang = lang;
return _this;
}
SpeechToTextEvent.prototype.callDefaultBehavior = function () { };
return SpeechToTextEvent;
}(Event_1.Event));
exports.SpeechToTextEvent = SpeechToTextEvent;
},{"./Event":58}],67:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.StreamEvent = void 0;
var Event_1 = require("./Event");
var Publisher_1 = require("../../OpenVidu/Publisher");
var Session_1 = require("../../OpenVidu/Session");
var OpenViduLogger_1 = require("../Logger/OpenViduLogger");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var StreamEvent = (function (_super) {
__extends(StreamEvent, _super);
function StreamEvent(cancelable, target, type, stream, reason) {
var _this = _super.call(this, cancelable, target, type) || this;
_this.stream = stream;
_this.reason = reason;
return _this;
}
StreamEvent.prototype.callDefaultBehavior = function () {
if (this.type === 'streamDestroyed') {
if (this.target instanceof Session_1.Session) {
logger.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Session'");
this.stream.disposeWebRtcPeer();
}
else if (this.target instanceof Publisher_1.Publisher) {
logger.info("Calling default behavior upon '" + this.type + "' event dispatched by 'Publisher'");
clearInterval(this.target.screenShareResizeInterval);
this.stream.isLocalStreamReadyToPublish = false;
var openviduPublishers = this.target.openvidu.publishers;
for (var i = 0; i < openviduPublishers.length; i++) {
if (openviduPublishers[i] === this.target) {
openviduPublishers.splice(i, 1);
break;
}
}
}
this.stream.disposeMediaStream();
if (this.stream.streamManager)
this.stream.streamManager.removeAllVideos();
this.stream.session.remoteStreamsCreated.delete(this.stream.streamId);
var remoteConnection = this.stream.session.remoteConnections.get(this.stream.connection.connectionId);
if (!!remoteConnection && !!remoteConnection.remoteOptions) {
var streamOptionsServer = remoteConnection.remoteOptions.streams;
for (var i = streamOptionsServer.length - 1; i >= 0; --i) {
if (streamOptionsServer[i].id === this.stream.streamId) {
streamOptionsServer.splice(i, 1);
}
}
}
}
};
return StreamEvent;
}(Event_1.Event));
exports.StreamEvent = StreamEvent;
},{"../../OpenVidu/Publisher":47,"../../OpenVidu/Session":48,"../Logger/OpenViduLogger":81,"./Event":58}],68:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.StreamManagerEvent = void 0;
var Event_1 = require("./Event");
var StreamManagerEvent = (function (_super) {
__extends(StreamManagerEvent, _super);
function StreamManagerEvent(target, type, value) {
var _this = _super.call(this, false, target, type) || this;
_this.value = value;
return _this;
}
StreamManagerEvent.prototype.callDefaultBehavior = function () { };
return StreamManagerEvent;
}(Event_1.Event));
exports.StreamManagerEvent = StreamManagerEvent;
},{"./Event":58}],69:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.StreamPropertyChangedEvent = void 0;
var Event_1 = require("./Event");
var StreamPropertyChangedEvent = (function (_super) {
__extends(StreamPropertyChangedEvent, _super);
function StreamPropertyChangedEvent(target, stream, changedProperty, newValue, oldValue, reason) {
var _this = _super.call(this, false, target, 'streamPropertyChanged') || this;
_this.stream = stream;
_this.changedProperty = changedProperty;
_this.newValue = newValue;
_this.oldValue = oldValue;
_this.reason = reason;
return _this;
}
StreamPropertyChangedEvent.prototype.callDefaultBehavior = function () { };
return StreamPropertyChangedEvent;
}(Event_1.Event));
exports.StreamPropertyChangedEvent = StreamPropertyChangedEvent;
},{"./Event":58}],70:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.VideoElementEvent = void 0;
var Event_1 = require("./Event");
var VideoElementEvent = (function (_super) {
__extends(VideoElementEvent, _super);
function VideoElementEvent(element, target, type) {
var _this = _super.call(this, false, target, type) || this;
_this.element = element;
return _this;
}
VideoElementEvent.prototype.callDefaultBehavior = function () { };
return VideoElementEvent;
}(Event_1.Event));
exports.VideoElementEvent = VideoElementEvent;
},{"./Event":58}],71:[function(require,module,exports){
function Mapper() {
var sources = {};
this.forEach = function (callback) {
for (var key in sources) {
var source = sources[key];
for (var key2 in source)
callback(source[key2]);
}
};
this.get = function (id, source) {
var ids = sources[source];
if (ids == undefined)
return undefined;
return ids[id];
};
this.remove = function (id, source) {
var ids = sources[source];
if (ids == undefined)
return;
delete ids[id];
for (var i in ids) {
return false;
}
delete sources[source];
};
this.set = function (value, id, source) {
if (value == undefined)
return this.remove(id, source);
var ids = sources[source];
if (ids == undefined)
sources[source] = ids = {};
ids[id] = value;
};
}
Mapper.prototype.pop = function (id, source) {
var value = this.get(id, source);
if (value == undefined)
return undefined;
this.remove(id, source);
return value;
};
module.exports = Mapper;
},{}],72:[function(require,module,exports){
var JsonRpcClient = require('./jsonrpcclient');
exports.JsonRpcClient = JsonRpcClient;
},{"./jsonrpcclient":73}],73:[function(require,module,exports){
var RpcBuilder = require('../');
var WebSocketWithReconnection = require('./transports/webSocketWithReconnection');
var OpenViduLogger = require('../../../Logger/OpenViduLogger').OpenViduLogger;
Date.now =
Date.now ||
function () {
return +new Date();
};
var PING_INTERVAL = 5000;
var RECONNECTING = 'RECONNECTING';
var CONNECTED = 'CONNECTED';
var DISCONNECTED = 'DISCONNECTED';
var Logger = OpenViduLogger.getInstance();
function JsonRpcClient(configuration) {
var self = this;
var wsConfig = configuration.ws;
var notReconnectIfNumLessThan = -1;
var pingNextNum = 0;
var enabledPings = true;
var pingPongStarted = false;
var pingInterval;
var status = DISCONNECTED;
var onreconnecting = wsConfig.onreconnecting;
var onreconnected = wsConfig.onreconnected;
var onconnected = wsConfig.onconnected;
var onerror = wsConfig.onerror;
configuration.rpc.pull = function (params, request) {
request.reply(null, 'push');
};
wsConfig.onreconnecting = function () {
Logger.debug('--------- ONRECONNECTING -----------');
if (status === RECONNECTING) {
Logger.error('Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it');
return;
}
stopPing();
status = RECONNECTING;
if (onreconnecting) {
onreconnecting();
}
};
wsConfig.onreconnected = function () {
Logger.debug('--------- ONRECONNECTED -----------');
if (status === CONNECTED) {
Logger.error('Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it');
return;
}
status = CONNECTED;
updateNotReconnectIfLessThan();
if (onreconnected) {
onreconnected();
}
};
wsConfig.onconnected = function () {
Logger.debug('--------- ONCONNECTED -----------');
if (status === CONNECTED) {
Logger.error('Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it');
return;
}
status = CONNECTED;
enabledPings = true;
usePing();
if (onconnected) {
onconnected();
}
};
wsConfig.onerror = function (error) {
Logger.debug('--------- ONERROR -----------');
status = DISCONNECTED;
stopPing();
if (onerror) {
onerror(error);
}
};
var ws = new WebSocketWithReconnection(wsConfig);
Logger.debug('Connecting websocket to URI: ' + wsConfig.uri);
var rpcBuilderOptions = {
request_timeout: configuration.rpc.requestTimeout,
ping_request_timeout: configuration.rpc.heartbeatRequestTimeout
};
var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws, function (request) {
Logger.debug('Received request: ' + JSON.stringify(request));
try {
var func = configuration.rpc[request.method];
if (func === undefined) {
Logger.error('Method ' + request.method + ' not registered in client');
}
else {
func(request.params, request);
}
}
catch (err) {
Logger.error('Exception processing request: ' + JSON.stringify(request));
Logger.error(err);
}
});
this.send = function (method, params, callback) {
var requestTime = Date.now();
rpc.encode(method, params, function (error, result) {
if (error) {
try {
Logger.error('ERROR:' +
error.message +
' in Request: method:' +
method +
' params:' +
JSON.stringify(params) +
' request:' +
error.request);
if (error.data) {
Logger.error('ERROR DATA:' + JSON.stringify(error.data));
}
}
catch (e) { }
error.requestTime = requestTime;
}
if (callback) {
if (result != undefined && result.value !== 'pong') {
Logger.debug('Response: ' + JSON.stringify(result));
}
callback(error, result);
}
});
};
function updateNotReconnectIfLessThan() {
Logger.debug('notReconnectIfNumLessThan = ' + pingNextNum + ' (old=' + notReconnectIfNumLessThan + ')');
notReconnectIfNumLessThan = pingNextNum;
}
function sendPing() {
if (enabledPings) {
var params = null;
if (pingNextNum == 0 || pingNextNum == notReconnectIfNumLessThan) {
params = {
interval: configuration.heartbeat || PING_INTERVAL
};
}
pingNextNum++;
self.send('ping', params, (function (pingNum) {
return function (error, result) {
if (error) {
Logger.debug('Error in ping request #' + pingNum + ' (' + error.message + ')');
if (pingNum > notReconnectIfNumLessThan) {
enabledPings = false;
updateNotReconnectIfLessThan();
Logger.debug('Server did not respond to ping message #' + pingNum + '. Reconnecting... ');
ws.reconnectWs();
}
}
};
})(pingNextNum));
}
else {
Logger.debug('Trying to send ping, but ping is not enabled');
}
}
function usePing() {
if (!pingPongStarted) {
Logger.debug('Starting ping (if configured)');
pingPongStarted = true;
if (configuration.heartbeat != undefined) {
pingInterval = setInterval(sendPing, configuration.heartbeat);
sendPing();
}
}
}
function stopPing() {
clearInterval(pingInterval);
pingPongStarted = false;
enabledPings = false;
pingNextNum = -1;
rpc.cancel();
}
this.close = function (code, reason) {
Logger.debug('Closing with code: ' + code + ' because: ' + reason);
if (pingInterval != undefined) {
Logger.debug('Clearing ping interval');
clearInterval(pingInterval);
}
pingPongStarted = false;
enabledPings = false;
ws.close(code, reason);
};
this.reconnect = function () {
ws.reconnectWs();
};
this.resetPing = function () {
enabledPings = true;
pingNextNum = 0;
usePing();
};
this.getReadyState = function () {
return ws.getReadyState();
};
}
module.exports = JsonRpcClient;
},{"../":76,"../../../Logger/OpenViduLogger":81,"./transports/webSocketWithReconnection":75}],74:[function(require,module,exports){
var WebSocketWithReconnection = require('./webSocketWithReconnection');
exports.WebSocketWithReconnection = WebSocketWithReconnection;
},{"./webSocketWithReconnection":75}],75:[function(require,module,exports){
'use strict';
var OpenViduLogger = require('../../../../Logger/OpenViduLogger').OpenViduLogger;
var Logger = OpenViduLogger.getInstance();
var MAX_RETRIES = 2000;
var RETRY_TIME_MS = 3000;
var CONNECTING = 0;
var OPEN = 1;
var CLOSING = 2;
var CLOSED = 3;
function WebSocketWithReconnection(config) {
var closing = false;
var registerMessageHandler;
var wsUri = config.uri;
var reconnecting = false;
var ws = new WebSocket(wsUri);
ws.onopen = function () {
Logger.debug('WebSocket connected to ' + wsUri);
if (config.onconnected) {
config.onconnected();
}
};
ws.onerror = function (error) {
Logger.error('Could not connect to ' + wsUri + ' (invoking onerror if defined)', error);
if (config.onerror) {
config.onerror(error);
}
};
var reconnectionOnClose = function () {
if (ws.readyState === CLOSED) {
if (closing) {
Logger.debug('Connection closed by user');
}
else {
if (config.ismasternodecrashed()) {
Logger.error('Master Node has crashed. Stopping reconnection process');
}
else {
Logger.debug('Connection closed unexpectedly. Reconnecting...');
reconnect(MAX_RETRIES, 1);
}
}
}
else {
Logger.debug('Close callback from previous websocket. Ignoring it');
}
};
ws.onclose = reconnectionOnClose;
function reconnect(maxRetries, numRetries) {
Logger.debug('reconnect (attempt #' + numRetries + ', max=' + maxRetries + ')');
if (numRetries === 1) {
if (reconnecting) {
Logger.warn('Trying to reconnect when already reconnecting... Ignoring this reconnection.');
return;
}
else {
reconnecting = true;
}
if (config.onreconnecting) {
config.onreconnecting();
}
}
reconnectAux(maxRetries, numRetries);
}
function addReconnectionQueryParamsIfMissing(uriString) {
var searchParams = new URLSearchParams(new URL(uriString).search);
if (!searchParams.has('reconnect')) {
uriString = Array.from(searchParams).length > 0 ? uriString + '&reconnect=true' : uriString + '?reconnect=true';
}
return uriString;
}
function reconnectAux(maxRetries, numRetries) {
Logger.debug('Reconnection attempt #' + numRetries);
ws.close(4104, 'Connection closed for reconnection');
wsUri = addReconnectionQueryParamsIfMissing(wsUri);
ws = new WebSocket(wsUri);
ws.onopen = function () {
Logger.debug('Reconnected to ' + wsUri + ' after ' + numRetries + ' attempts...');
reconnecting = false;
registerMessageHandler();
if (config.onreconnected()) {
config.onreconnected();
}
ws.onclose = reconnectionOnClose;
};
ws.onerror = function (error) {
Logger.warn('Reconnection error: ', error);
if (numRetries === maxRetries) {
if (config.ondisconnect) {
config.ondisconnect();
}
}
else {
setTimeout(function () {
reconnect(maxRetries, numRetries + 1);
}, RETRY_TIME_MS);
}
};
}
this.close = function (code, reason) {
closing = true;
ws.close(code, reason);
};
this.reconnectWs = function () {
Logger.debug('reconnectWs');
reconnect(MAX_RETRIES, 1);
};
this.send = function (message) {
ws.send(message);
};
this.addEventListener = function (type, callback) {
registerMessageHandler = function () {
ws.addEventListener(type, callback);
};
registerMessageHandler();
};
this.getReadyState = function () {
return ws.readyState;
};
}
module.exports = WebSocketWithReconnection;
},{"../../../../Logger/OpenViduLogger":81}],76:[function(require,module,exports){
var defineProperty_IE8 = false;
if (Object.defineProperty) {
try {
Object.defineProperty({}, 'x', {});
}
catch (e) {
defineProperty_IE8 = true;
}
}
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== 'function') {
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
var EventEmitter = require('events').EventEmitter;
var inherits = require('inherits');
var packers = require('./packers');
var Mapper = require('./Mapper');
var BASE_TIMEOUT = 5000;
function unifyResponseMethods(responseMethods) {
if (!responseMethods)
return {};
for (var key in responseMethods) {
var value = responseMethods[key];
if (typeof value == 'string')
responseMethods[key] = {
response: value
};
}
return responseMethods;
}
function unifyTransport(transport) {
if (!transport)
return;
if (transport instanceof Function)
return {
send: transport
};
if (transport.send instanceof Function)
return transport;
if (transport.postMessage instanceof Function) {
transport.send = transport.postMessage;
return transport;
}
if (transport.write instanceof Function) {
transport.send = transport.write;
return transport;
}
if (transport.onmessage !== undefined)
return;
if (transport.pause instanceof Function)
return;
throw new SyntaxError('Transport is not a function nor a valid object');
}
function RpcNotification(method, params) {
if (defineProperty_IE8) {
this.method = method;
this.params = params;
}
else {
Object.defineProperty(this, 'method', {
value: method,
enumerable: true
});
Object.defineProperty(this, 'params', {
value: params,
enumerable: true
});
}
}
function RpcBuilder(packer, options, transport, onRequest) {
var self = this;
if (!packer)
throw new SyntaxError('Packer is not defined');
if (!packer.pack || !packer.unpack)
throw new SyntaxError('Packer is invalid');
var responseMethods = unifyResponseMethods(packer.responseMethods);
if (options instanceof Function) {
if (transport != undefined)
throw new SyntaxError("There can't be parameters after onRequest");
onRequest = options;
transport = undefined;
options = undefined;
}
if (options && options.send instanceof Function) {
if (transport && !(transport instanceof Function))
throw new SyntaxError('Only a function can be after transport');
onRequest = transport;
transport = options;
options = undefined;
}
if (transport instanceof Function) {
if (onRequest != undefined)
throw new SyntaxError("There can't be parameters after onRequest");
onRequest = transport;
transport = undefined;
}
if (transport && transport.send instanceof Function)
if (onRequest && !(onRequest instanceof Function))
throw new SyntaxError('Only a function can be after transport');
options = options || {};
EventEmitter.call(this);
if (onRequest)
this.on('request', onRequest);
if (defineProperty_IE8)
this.peerID = options.peerID;
else
Object.defineProperty(this, 'peerID', {
value: options.peerID
});
var max_retries = options.max_retries || 0;
function transportMessage(event) {
self.decode(event.data || event);
}
this.getTransport = function () {
return transport;
};
this.setTransport = function (value) {
if (transport) {
if (transport.removeEventListener)
transport.removeEventListener('message', transportMessage);
else if (transport.removeListener)
transport.removeListener('data', transportMessage);
}
if (value) {
if (value.addEventListener)
value.addEventListener('message', transportMessage);
else if (value.addListener)
value.addListener('data', transportMessage);
}
transport = unifyTransport(value);
};
if (!defineProperty_IE8)
Object.defineProperty(this, 'transport', {
get: this.getTransport.bind(this),
set: this.setTransport.bind(this)
});
this.setTransport(transport);
var request_timeout = options.request_timeout || BASE_TIMEOUT;
var ping_request_timeout = options.ping_request_timeout || request_timeout;
var response_timeout = options.response_timeout || BASE_TIMEOUT;
var duplicates_timeout = options.duplicates_timeout || BASE_TIMEOUT;
var requestID = 0;
var requests = new Mapper();
var responses = new Mapper();
var processedResponses = new Mapper();
var message2Key = {};
function storeResponse(message, id, dest) {
var response = {
message: message,
timeout: setTimeout(function () {
responses.remove(id, dest);
}, response_timeout)
};
responses.set(response, id, dest);
}
function storeProcessedResponse(ack, from) {
var timeout = setTimeout(function () {
processedResponses.remove(ack, from);
}, duplicates_timeout);
processedResponses.set(timeout, ack, from);
}
function RpcRequest(method, params, id, from, transport) {
RpcNotification.call(this, method, params);
this.getTransport = function () {
return transport;
};
this.setTransport = function (value) {
transport = unifyTransport(value);
};
if (!defineProperty_IE8)
Object.defineProperty(this, 'transport', {
get: this.getTransport.bind(this),
set: this.setTransport.bind(this)
});
var response = responses.get(id, from);
if (!(transport || self.getTransport())) {
if (defineProperty_IE8)
this.duplicated = Boolean(response);
else
Object.defineProperty(this, 'duplicated', {
value: Boolean(response)
});
}
var responseMethod = responseMethods[method];
this.pack = packer.pack.bind(packer, this, id);
this.reply = function (error, result, transport) {
if (error instanceof Function || (error && error.send instanceof Function)) {
if (result != undefined)
throw new SyntaxError("There can't be parameters after callback");
transport = error;
result = null;
error = undefined;
}
else if (result instanceof Function || (result && result.send instanceof Function)) {
if (transport != undefined)
throw new SyntaxError("There can't be parameters after callback");
transport = result;
result = null;
}
transport = unifyTransport(transport);
if (response)
clearTimeout(response.timeout);
if (from != undefined) {
if (error)
error.dest = from;
if (result)
result.dest = from;
}
var message;
if (error || result != undefined) {
if (self.peerID != undefined) {
if (error)
error.from = self.peerID;
else
result.from = self.peerID;
}
if (responseMethod) {
if (responseMethod.error == undefined && error)
message = {
error: error
};
else {
var method = error ? responseMethod.error : responseMethod.response;
message = {
method: method,
params: error || result
};
}
}
else
message = {
error: error,
result: result
};
message = packer.pack(message, id);
}
else if (response)
message = response.message;
else
message = packer.pack({
result: null
}, id);
storeResponse(message, id, from);
transport = transport || this.getTransport() || self.getTransport();
if (transport)
return transport.send(message);
return message;
};
}
inherits(RpcRequest, RpcNotification);
function cancel(message) {
var key = message2Key[message];
if (!key)
return;
delete message2Key[message];
var request = requests.pop(key.id, key.dest);
if (!request)
return;
clearTimeout(request.timeout);
storeProcessedResponse(key.id, key.dest);
}
this.cancel = function (message) {
if (message)
return cancel(message);
for (var message in message2Key)
cancel(message);
};
this.close = function () {
var transport = this.getTransport();
if (transport && transport.close)
transport.close(4003, 'Cancel request');
this.cancel();
processedResponses.forEach(clearTimeout);
responses.forEach(function (response) {
clearTimeout(response.timeout);
});
};
this.encode = function (method, params, dest, transport, callback) {
if (params instanceof Function) {
if (dest != undefined)
throw new SyntaxError("There can't be parameters after callback");
callback = params;
transport = undefined;
dest = undefined;
params = undefined;
}
else if (dest instanceof Function) {
if (transport != undefined)
throw new SyntaxError("There can't be parameters after callback");
callback = dest;
transport = undefined;
dest = undefined;
}
else if (transport instanceof Function) {
if (callback != undefined)
throw new SyntaxError("There can't be parameters after callback");
callback = transport;
transport = undefined;
}
if (self.peerID != undefined) {
params = params || {};
params.from = self.peerID;
}
if (dest != undefined) {
params = params || {};
params.dest = dest;
}
var message = {
method: method,
params: params
};
if (callback) {
var id = requestID++;
var retried = 0;
message = packer.pack(message, id);
function dispatchCallback(error, result) {
self.cancel(message);
callback(error, result);
}
var request = {
message: message,
callback: dispatchCallback,
responseMethods: responseMethods[method] || {}
};
var encode_transport = unifyTransport(transport);
function sendRequest(transport) {
var rt = method === 'ping' ? ping_request_timeout : request_timeout;
request.timeout = setTimeout(timeout, rt * Math.pow(2, retried++));
message2Key[message] = {
id: id,
dest: dest
};
requests.set(request, id, dest);
transport = transport || encode_transport || self.getTransport();
if (transport)
return transport.send(message);
return message;
}
function retry(transport) {
transport = unifyTransport(transport);
console.warn(retried + ' retry for request message:', message);
var timeout = processedResponses.pop(id, dest);
clearTimeout(timeout);
return sendRequest(transport);
}
function timeout() {
if (retried < max_retries)
return retry(transport);
var error = new Error('Request has timed out');
error.request = message;
error.retry = retry;
dispatchCallback(error);
}
return sendRequest(transport);
}
message = packer.pack(message);
transport = transport || this.getTransport();
if (transport)
return transport.send(message);
return message;
};
this.decode = function (message, transport) {
if (!message)
throw new TypeError('Message is not defined');
try {
message = packer.unpack(message);
}
catch (e) {
return console.debug(e, message);
}
var id = message.id;
var ack = message.ack;
var method = message.method;
var params = message.params || {};
var from = params.from;
var dest = params.dest;
if (self.peerID != undefined && from == self.peerID)
return;
if (id == undefined && ack == undefined) {
var notification = new RpcNotification(method, params);
if (self.emit('request', notification))
return;
return notification;
}
function processRequest() {
transport = unifyTransport(transport) || self.getTransport();
if (transport) {
var response = responses.get(id, from);
if (response)
return transport.send(response.message);
}
var idAck = id != undefined ? id : ack;
var request = new RpcRequest(method, params, idAck, from, transport);
if (self.emit('request', request))
return;
return request;
}
function processResponse(request, error, result) {
request.callback(error, result);
}
function duplicatedResponse(timeout) {
console.warn('Response already processed', message);
clearTimeout(timeout);
storeProcessedResponse(ack, from);
}
if (method) {
if (dest == undefined || dest == self.peerID) {
var request = requests.get(ack, from);
if (request) {
var responseMethods = request.responseMethods;
if (method == responseMethods.error)
return processResponse(request, params);
if (method == responseMethods.response)
return processResponse(request, null, params);
return processRequest();
}
var processed = processedResponses.get(ack, from);
if (processed)
return duplicatedResponse(processed);
}
return processRequest();
}
var error = message.error;
var result = message.result;
if (error && error.dest && error.dest != self.peerID)
return;
if (result && result.dest && result.dest != self.peerID)
return;
var request = requests.get(ack, from);
if (!request) {
var processed = processedResponses.get(ack, from);
if (processed)
return duplicatedResponse(processed);
return console.warn('No callback was defined for this message', message);
}
processResponse(request, error, result);
};
}
inherits(RpcBuilder, EventEmitter);
RpcBuilder.RpcNotification = RpcNotification;
module.exports = RpcBuilder;
var clients = require('./clients');
var transports = require('./clients/transports');
RpcBuilder.clients = clients;
RpcBuilder.clients.transports = transports;
RpcBuilder.packers = packers;
},{"./Mapper":71,"./clients":72,"./clients/transports":74,"./packers":79,"events":1,"inherits":6}],77:[function(require,module,exports){
function pack(message, id) {
var result = {
jsonrpc: '2.0'
};
if (message.method) {
result.method = message.method;
if (message.params)
result.params = message.params;
if (id != undefined)
result.id = id;
}
else if (id != undefined) {
if (message.error) {
if (message.result !== undefined)
throw new TypeError('Both result and error are defined');
result.error = message.error;
}
else if (message.result !== undefined)
result.result = message.result;
else
throw new TypeError('No result or error is defined');
result.id = id;
}
return JSON.stringify(result);
}
function unpack(message) {
var result = message;
if (typeof message === 'string' || message instanceof String) {
result = JSON.parse(message);
}
var version = result.jsonrpc;
if (version !== '2.0')
throw new TypeError("Invalid JsonRPC version '" + version + "': " + message);
if (result.method == undefined) {
if (result.id == undefined)
throw new TypeError('Invalid message: ' + message);
var result_defined = result.result !== undefined;
var error_defined = result.error !== undefined;
if (result_defined && error_defined)
throw new TypeError('Both result and error are defined: ' + message);
if (!result_defined && !error_defined)
throw new TypeError('No result or error is defined: ' + message);
result.ack = result.id;
delete result.id;
}
return result;
}
exports.pack = pack;
exports.unpack = unpack;
},{}],78:[function(require,module,exports){
function pack(message) {
throw new TypeError('Not yet implemented');
}
function unpack(message) {
throw new TypeError('Not yet implemented');
}
exports.pack = pack;
exports.unpack = unpack;
},{}],79:[function(require,module,exports){
var JsonRPC = require('./JsonRPC');
var XmlRPC = require('./XmlRPC');
exports.JsonRPC = JsonRPC;
exports.XmlRPC = XmlRPC;
},{"./JsonRPC":77,"./XmlRPC":78}],80:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConsoleLogger = void 0;
var ConsoleLogger = (function () {
function ConsoleLogger(console) {
this.logger = console;
(this.log = console.log),
(this.info = console.info),
(this.debug = console.debug),
(this.warn = console.warn),
(this.error = console.error);
}
return ConsoleLogger;
}());
exports.ConsoleLogger = ConsoleLogger;
},{}],81:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenViduLogger = void 0;
var jsnlog_1 = require("jsnlog");
var ConsoleLogger_1 = require("./ConsoleLogger");
var OpenViduLoggerConfiguration_1 = require("./OpenViduLoggerConfiguration");
var OpenViduLogger = (function () {
function OpenViduLogger() {
this.JSNLOG_URL = '/openvidu/elk/openvidu-browser-logs';
this.MAX_JSNLOG_BATCH_LOG_MESSAGES = 100;
this.MAX_MSECONDS_BATCH_MESSAGES = 5000;
this.MAX_LENGTH_STRING_JSON = 1000;
this.defaultConsoleLogger = new ConsoleLogger_1.ConsoleLogger(globalThis.console);
this.isProdMode = false;
this.isJSNLogSetup = false;
}
OpenViduLogger.configureJSNLog = function (openVidu, token) {
var _this = this;
try {
if (globalThis['LOG_JSNLOG_RESULTS'] ||
(this.instance &&
openVidu.isAtLeastPro &&
this.instance.isOpenViduBrowserLogsDebugActive(openVidu) &&
this.instance.canConfigureJSNLog(openVidu, this.instance))) {
if (openVidu.sendBrowserLogs === OpenViduLoggerConfiguration_1.OpenViduLoggerConfiguration.debug_app) {
this.instance.replaceWindowConsole();
}
this.instance.isJSNLogSetup = false;
this.instance.info('Configuring JSNLogs.');
var finalUserId_1 = openVidu.finalUserId;
var sessionId_1 = openVidu.session.sessionId;
var beforeSendCallback = function (xhr) {
var parentReadyStateFunction = xhr.onreadystatechange;
xhr.onreadystatechange = function () {
if (_this.isInvalidResponse(xhr)) {
Object.defineProperty(xhr, 'readyState', { value: 4 });
Object.defineProperty(xhr, 'status', { value: 200 });
_this.instance.disableLogger();
}
parentReadyStateFunction();
};
xhr.setRequestHeader('Authorization', 'Basic ' + btoa("".concat(finalUserId_1, "%/%").concat(sessionId_1) + ':' + token));
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('OV-Final-User-Id', finalUserId_1);
xhr.setRequestHeader('OV-Session-Id', sessionId_1);
xhr.setRequestHeader('OV-Token', token);
};
this.instance.currentAppender = jsnlog_1.JL.createAjaxAppender("appender-".concat(finalUserId_1, "-").concat(sessionId_1));
this.instance.currentAppender.setOptions({
beforeSend: beforeSendCallback,
maxBatchSize: 1000,
batchSize: this.instance.MAX_JSNLOG_BATCH_LOG_MESSAGES,
batchTimeout: this.instance.MAX_MSECONDS_BATCH_MESSAGES
});
var logSerializer = function (obj) {
var getCircularReplacer = function () {
var seen = new WeakSet();
return function (key, value) {
if (typeof value === 'object' && value != null) {
if (seen.has(value) || (globalThis.HTMLElement && value instanceof HTMLElement)) {
return;
}
seen.add(value);
}
return value;
};
};
var stringifyJson = JSON.stringify(obj, getCircularReplacer());
if (stringifyJson.length > _this.instance.MAX_LENGTH_STRING_JSON) {
stringifyJson = "".concat(stringifyJson.substring(0, _this.instance.MAX_LENGTH_STRING_JSON), "...");
}
if (globalThis['LOG_JSNLOG_RESULTS']) {
console.log(stringifyJson);
}
return stringifyJson;
};
jsnlog_1.JL.setOptions({
defaultAjaxUrl: openVidu.httpUri + this.instance.JSNLOG_URL,
serialize: logSerializer,
enabled: true
});
(0, jsnlog_1.JL)().setOptions({
appenders: [this.instance.currentAppender]
});
this.instance.isJSNLogSetup = true;
this.instance.loggingSessionId = sessionId_1;
this.instance.info('JSNLog configured.');
}
}
catch (e) {
console.error('Error configuring JSNLog: ');
console.error(e);
this.instance.disableLogger();
}
};
OpenViduLogger.getInstance = function () {
if (!OpenViduLogger.instance) {
OpenViduLogger.instance = new OpenViduLogger();
}
return OpenViduLogger.instance;
};
OpenViduLogger.isInvalidResponse = function (xhr) {
return xhr.status == 401 || xhr.status == 403 || xhr.status == 404 || xhr.status == 0;
};
OpenViduLogger.prototype.canConfigureJSNLog = function (openVidu, logger) {
return openVidu.session.sessionId != logger.loggingSessionId;
};
OpenViduLogger.prototype.isOpenViduBrowserLogsDebugActive = function (openVidu) {
return (openVidu.sendBrowserLogs === OpenViduLoggerConfiguration_1.OpenViduLoggerConfiguration.debug ||
openVidu.sendBrowserLogs === OpenViduLoggerConfiguration_1.OpenViduLoggerConfiguration.debug_app);
};
OpenViduLogger.prototype.getConsoleWithJSNLog = function () {
return (function (openViduLogger) {
return {
log: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
openViduLogger.defaultConsoleLogger.log.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
if (openViduLogger.isJSNLogSetup) {
(0, jsnlog_1.JL)().info(arguments);
}
},
info: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
openViduLogger.defaultConsoleLogger.info.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
if (openViduLogger.isJSNLogSetup) {
(0, jsnlog_1.JL)().info(arguments);
}
},
debug: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
openViduLogger.defaultConsoleLogger.debug.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
},
warn: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
openViduLogger.defaultConsoleLogger.warn.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
if (openViduLogger.isJSNLogSetup) {
(0, jsnlog_1.JL)().warn(arguments);
}
},
error: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
openViduLogger.defaultConsoleLogger.error.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
if (openViduLogger.isJSNLogSetup) {
(0, jsnlog_1.JL)().error(arguments);
}
}
};
})(this);
};
OpenViduLogger.prototype.replaceWindowConsole = function () {
globalThis.console = this.defaultConsoleLogger.logger;
globalThis.console.log = this.getConsoleWithJSNLog().log;
globalThis.console.info = this.getConsoleWithJSNLog().info;
globalThis.console.debug = this.getConsoleWithJSNLog().debug;
globalThis.console.warn = this.getConsoleWithJSNLog().warn;
globalThis.console.error = this.getConsoleWithJSNLog().error;
};
OpenViduLogger.prototype.disableLogger = function () {
jsnlog_1.JL.setOptions({ enabled: false });
this.isJSNLogSetup = false;
this.loggingSessionId = undefined;
this.currentAppender = undefined;
globalThis.console = this.defaultConsoleLogger.logger;
globalThis.console.log = this.defaultConsoleLogger.log;
globalThis.console.info = this.defaultConsoleLogger.info;
globalThis.console.debug = this.defaultConsoleLogger.debug;
globalThis.console.warn = this.defaultConsoleLogger.warn;
globalThis.console.error = this.defaultConsoleLogger.error;
};
OpenViduLogger.prototype.log = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (!this.isProdMode) {
this.defaultConsoleLogger.log.apply(this.defaultConsoleLogger.logger, arguments);
}
if (this.isJSNLogSetup) {
(0, jsnlog_1.JL)().info(arguments);
}
};
OpenViduLogger.prototype.debug = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (!this.isProdMode) {
this.defaultConsoleLogger.debug.apply(this.defaultConsoleLogger.logger, arguments);
}
};
OpenViduLogger.prototype.info = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (!this.isProdMode) {
this.defaultConsoleLogger.info.apply(this.defaultConsoleLogger.logger, arguments);
}
if (this.isJSNLogSetup) {
(0, jsnlog_1.JL)().info(arguments);
}
};
OpenViduLogger.prototype.warn = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
this.defaultConsoleLogger.warn.apply(this.defaultConsoleLogger.logger, arguments);
if (this.isJSNLogSetup) {
(0, jsnlog_1.JL)().warn(arguments);
}
};
OpenViduLogger.prototype.error = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
this.defaultConsoleLogger.error.apply(this.defaultConsoleLogger.logger, arguments);
if (this.isJSNLogSetup) {
(0, jsnlog_1.JL)().error(arguments);
}
};
OpenViduLogger.prototype.flush = function () {
if (this.isJSNLogSetup && this.currentAppender != null) {
this.currentAppender.sendBatch();
}
};
OpenViduLogger.prototype.enableProdMode = function () {
this.isProdMode = true;
};
return OpenViduLogger;
}());
exports.OpenViduLogger = OpenViduLogger;
},{"./ConsoleLogger":80,"./OpenViduLoggerConfiguration":82,"jsnlog":7}],82:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OpenViduLoggerConfiguration = void 0;
var OpenViduLoggerConfiguration;
(function (OpenViduLoggerConfiguration) {
OpenViduLoggerConfiguration["disabled"] = "disabled";
OpenViduLoggerConfiguration["debug"] = "debug";
OpenViduLoggerConfiguration["debug_app"] = "debug_app";
})(OpenViduLoggerConfiguration = exports.OpenViduLoggerConfiguration || (exports.OpenViduLoggerConfiguration = {}));
},{}],83:[function(require,module,exports){
globalThis.getScreenId = function (firefoxString, callback, custom_parameter) {
if (navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) {
callback({
video: true
});
return;
}
if (!!navigator.mozGetUserMedia) {
callback(null, 'firefox', {
video: {
mozMediaSource: firefoxString,
mediaSource: firefoxString
}
});
return;
}
globalThis.addEventListener('message', onIFrameCallback);
function onIFrameCallback(event) {
if (!event.data)
return;
if (event.data.chromeMediaSourceId) {
if (event.data.chromeMediaSourceId === 'PermissionDeniedError') {
callback('permission-denied');
}
else {
callback(null, event.data.chromeMediaSourceId, getScreenConstraints(null, event.data.chromeMediaSourceId, event.data.canRequestAudioTrack));
}
globalThis.removeEventListener('message', onIFrameCallback);
}
if (event.data.chromeExtensionStatus) {
callback(event.data.chromeExtensionStatus, null, getScreenConstraints(event.data.chromeExtensionStatus));
globalThis.removeEventListener('message', onIFrameCallback);
}
}
if (!custom_parameter) {
setTimeout(postGetSourceIdMessage, 100);
}
else {
setTimeout(function () {
postGetSourceIdMessage(custom_parameter);
}, 100);
}
};
function getScreenConstraints(error, sourceId, canRequestAudioTrack) {
var screen_constraints = {
audio: false,
video: {
mandatory: {
chromeMediaSource: error ? 'screen' : 'desktop',
maxWidth: globalThis.screen.width > 1920 ? globalThis.screen.width : 1920,
maxHeight: globalThis.screen.height > 1080 ? globalThis.screen.height : 1080
},
optional: []
}
};
if (!!canRequestAudioTrack) {
screen_constraints.audio = {
mandatory: {
chromeMediaSource: error ? 'screen' : 'desktop'
},
optional: []
};
}
if (sourceId) {
screen_constraints.video.mandatory.chromeMediaSourceId = sourceId;
if (screen_constraints.audio && screen_constraints.audio.mandatory) {
screen_constraints.audio.mandatory.chromeMediaSourceId = sourceId;
}
}
return screen_constraints;
}
function postGetSourceIdMessage(custom_parameter) {
if (!iframe) {
loadIFrame(function () {
postGetSourceIdMessage(custom_parameter);
});
return;
}
if (!iframe.isLoaded) {
setTimeout(function () {
postGetSourceIdMessage(custom_parameter);
}, 100);
return;
}
if (!custom_parameter) {
iframe.contentWindow.postMessage({
captureSourceId: true
}, '*');
}
else if (!!custom_parameter.forEach) {
iframe.contentWindow.postMessage({
captureCustomSourceId: custom_parameter
}, '*');
}
else {
iframe.contentWindow.postMessage({
captureSourceIdWithAudio: true
}, '*');
}
}
var iframe;
globalThis.getScreenConstraints = function (callback) {
loadIFrame(function () {
getScreenId(function (error, sourceId, screen_constraints) {
if (!screen_constraints) {
screen_constraints = {
video: true
};
}
callback(error, screen_constraints.video);
});
});
};
function loadIFrame(loadCallback) {
if (iframe) {
loadCallback();
return;
}
iframe = document.createElement('iframe');
iframe.onload = function () {
iframe.isLoaded = true;
loadCallback();
};
iframe.src = 'https://openvidu.github.io/openvidu-screen-sharing-chrome-extension/';
iframe.style.display = 'none';
(document.body || document.documentElement).appendChild(iframe);
}
globalThis.getChromeExtensionStatus = function (callback) {
if (!!navigator.mozGetUserMedia) {
callback('installed-enabled');
return;
}
globalThis.addEventListener('message', onIFrameCallback);
function onIFrameCallback(event) {
if (!event.data)
return;
if (event.data.chromeExtensionStatus) {
callback(event.data.chromeExtensionStatus);
globalThis.removeEventListener('message', onIFrameCallback);
}
}
setTimeout(postGetChromeExtensionStatusMessage, 100);
};
function postGetChromeExtensionStatusMessage() {
if (!iframe) {
loadIFrame(postGetChromeExtensionStatusMessage);
return;
}
if (!iframe.isLoaded) {
setTimeout(postGetChromeExtensionStatusMessage, 100);
return;
}
iframe.contentWindow.postMessage({
getChromeExtensionStatus: true
}, '*');
}
exports.getScreenId = globalThis.getScreenId;
},{}],84:[function(require,module,exports){
var chromeMediaSource = 'screen';
var sourceId;
var screenCallback;
if (typeof window !== 'undefined' && typeof navigator !== 'undefined' && typeof navigator.userAgent !== 'undefined') {
var isFirefox = typeof window.InstallTrigger !== 'undefined';
var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
var isChrome = !!window.chrome && !isOpera;
window.addEventListener('message', function (event) {
if (event.origin != window.location.origin) {
return;
}
onMessageCallback(event.data);
});
}
function onMessageCallback(data) {
if (data == 'PermissionDeniedError') {
if (screenCallback)
return screenCallback('PermissionDeniedError');
else
throw new Error('PermissionDeniedError');
}
if (data == 'rtcmulticonnection-extension-loaded') {
chromeMediaSource = 'desktop';
}
if (data.sourceId && screenCallback) {
screenCallback((sourceId = data.sourceId), data.canRequestAudioTrack === true);
}
}
function isChromeExtensionAvailable(callback) {
if (!callback)
return;
if (chromeMediaSource == 'desktop')
return callback(true);
window.postMessage('are-you-there', '*');
setTimeout(function () {
if (chromeMediaSource == 'screen') {
callback(false);
}
else
callback(true);
}, 2000);
}
function getSourceId(callback) {
if (!callback)
throw '"callback" parameter is mandatory.';
if (sourceId)
return callback(sourceId);
screenCallback = callback;
window.postMessage('get-sourceId', '*');
}
function getCustomSourceId(arr, callback) {
if (!arr || !arr.forEach)
throw '"arr" parameter is mandatory and it must be an array.';
if (!callback)
throw '"callback" parameter is mandatory.';
if (sourceId)
return callback(sourceId);
screenCallback = callback;
window.postMessage({
'get-custom-sourceId': arr
}, '*');
}
function getSourceIdWithAudio(callback) {
if (!callback)
throw '"callback" parameter is mandatory.';
if (sourceId)
return callback(sourceId);
screenCallback = callback;
window.postMessage('audio-plus-tab', '*');
}
function getChromeExtensionStatus(extensionid, callback) {
if (isFirefox)
return callback('not-chrome');
if (arguments.length != 2) {
callback = extensionid;
extensionid = 'lfcgfepafnobdloecchnfaclibenjold';
}
var image = document.createElement('img');
image.src = 'chrome-extension://' + extensionid + '/icon.png';
image.onload = function () {
chromeMediaSource = 'screen';
window.postMessage('are-you-there', '*');
setTimeout(function () {
if (chromeMediaSource == 'screen') {
callback('installed-disabled');
}
else
callback('installed-enabled');
}, 2000);
};
image.onerror = function () {
callback('not-installed');
};
}
function getScreenConstraintsWithAudio(callback) {
getScreenConstraints(callback, true);
}
function getScreenConstraints(callback, captureSourceIdWithAudio) {
sourceId = '';
var firefoxScreenConstraints = {
mozMediaSource: 'window',
mediaSource: 'window'
};
if (isFirefox)
return callback(null, firefoxScreenConstraints);
var screen_constraints = {
mandatory: {
chromeMediaSource: chromeMediaSource,
maxWidth: screen.width > 1920 ? screen.width : 1920,
maxHeight: screen.height > 1080 ? screen.height : 1080
},
optional: []
};
if (chromeMediaSource == 'desktop' && !sourceId) {
if (captureSourceIdWithAudio) {
getSourceIdWithAudio(function (sourceId, canRequestAudioTrack) {
screen_constraints.mandatory.chromeMediaSourceId = sourceId;
if (canRequestAudioTrack) {
screen_constraints.canRequestAudioTrack = true;
}
callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints);
});
}
else {
getSourceId(function (sourceId) {
screen_constraints.mandatory.chromeMediaSourceId = sourceId;
callback(sourceId == 'PermissionDeniedError' ? sourceId : null, screen_constraints);
});
}
return;
}
if (chromeMediaSource == 'desktop') {
screen_constraints.mandatory.chromeMediaSourceId = sourceId;
}
callback(null, screen_constraints);
}
exports.getScreenConstraints = getScreenConstraints;
exports.getScreenConstraintsWithAudio = getScreenConstraintsWithAudio;
exports.isChromeExtensionAvailable = isChromeExtensionAvailable;
exports.getChromeExtensionStatus = getChromeExtensionStatus;
exports.getSourceId = getSourceId;
},{}],85:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PlatformUtils = void 0;
var platform = require("platform");
var PlatformUtils = (function () {
function PlatformUtils() {
}
PlatformUtils.getInstance = function () {
if (!this.instance) {
this.instance = new PlatformUtils();
}
return PlatformUtils.instance;
};
PlatformUtils.prototype.isChromeBrowser = function () {
return platform.name === 'Chrome';
};
PlatformUtils.prototype.isSafariBrowser = function () {
return platform.name === 'Safari';
};
PlatformUtils.prototype.isChromeMobileBrowser = function () {
return platform.name === 'Chrome Mobile';
};
PlatformUtils.prototype.isFirefoxBrowser = function () {
return platform.name === 'Firefox';
};
PlatformUtils.prototype.isFirefoxMobileBrowser = function () {
return platform.name === 'Firefox Mobile' || platform.name === 'Firefox for iOS';
};
PlatformUtils.prototype.isOperaBrowser = function () {
return platform.name === 'Opera';
};
PlatformUtils.prototype.isOperaMobileBrowser = function () {
return platform.name === 'Opera Mobile';
};
PlatformUtils.prototype.isEdgeBrowser = function () {
var version = (platform === null || platform === void 0 ? void 0 : platform.version) ? parseFloat(platform.version) : -1;
return platform.name === 'Microsoft Edge' && version >= 80;
};
PlatformUtils.prototype.isEdgeMobileBrowser = function () {
var _a, _b;
var version = (platform === null || platform === void 0 ? void 0 : platform.version) ? parseFloat(platform.version) : -1;
return platform.name === 'Microsoft Edge' && (((_a = platform.os) === null || _a === void 0 ? void 0 : _a.family) === 'Android' || ((_b = platform.os) === null || _b === void 0 ? void 0 : _b.family) === 'iOS') && version > 45;
};
PlatformUtils.prototype.isAndroidBrowser = function () {
return platform.name === 'Android Browser';
};
PlatformUtils.prototype.isElectron = function () {
return platform.name === 'Electron';
};
PlatformUtils.prototype.isNodeJs = function () {
return platform.name === 'Node.js';
};
PlatformUtils.prototype.isSamsungBrowser = function () {
return platform.name === 'Samsung Internet Mobile' || platform.name === 'Samsung Internet';
};
PlatformUtils.prototype.isIPhoneOrIPad = function () {
var userAgent = !!platform.ua ? platform.ua : navigator.userAgent;
var isTouchable = 'ontouchend' in document;
var isIPad = /\b(\w*Macintosh\w*)\b/.test(userAgent) && isTouchable;
var isIPhone = /\b(\w*iPhone\w*)\b/.test(userAgent) && /\b(\w*Mobile\w*)\b/.test(userAgent) && isTouchable;
return isIPad || isIPhone;
};
PlatformUtils.prototype.isIOSWithSafari = function () {
var userAgent = !!platform.ua ? platform.ua : navigator.userAgent;
return (this.isIPhoneOrIPad() &&
/\b(\w*Apple\w*)\b/.test(navigator.vendor) &&
/\b(\w*Safari\w*)\b/.test(userAgent) &&
!/\b(\w*CriOS\w*)\b/.test(userAgent) &&
!/\b(\w*FxiOS\w*)\b/.test(userAgent));
};
PlatformUtils.prototype.isIonicIos = function () {
return this.isIPhoneOrIPad() && platform.ua.indexOf('Safari') === -1;
};
PlatformUtils.prototype.isIonicAndroid = function () {
return platform.os.family === 'Android' && platform.name == 'Android Browser';
};
PlatformUtils.prototype.isMobileDevice = function () {
return platform.os.family === 'iOS' || platform.os.family === 'Android';
};
PlatformUtils.prototype.isReactNative = function () {
return false;
};
PlatformUtils.prototype.isChromium = function () {
return (this.isChromeBrowser() ||
this.isChromeMobileBrowser() ||
this.isOperaBrowser() ||
this.isOperaMobileBrowser() ||
this.isEdgeBrowser() ||
this.isEdgeMobileBrowser() ||
this.isSamsungBrowser() ||
this.isIonicAndroid() ||
this.isIonicIos() ||
this.isElectron());
};
PlatformUtils.prototype.canScreenShare = function () {
var version = (platform === null || platform === void 0 ? void 0 : platform.version) ? parseFloat(platform.version) : -1;
if (this.isMobileDevice()) {
return false;
}
return (this.isChromeBrowser() ||
this.isFirefoxBrowser() ||
this.isOperaBrowser() ||
this.isElectron() ||
this.isEdgeBrowser() ||
(this.isSafariBrowser() && version >= 13));
};
PlatformUtils.prototype.getName = function () {
return platform.name || '';
};
PlatformUtils.prototype.getVersion = function () {
return platform.version || '';
};
PlatformUtils.prototype.getFamily = function () {
return platform.os.family || '';
};
PlatformUtils.prototype.getDescription = function () {
return platform.description || '';
};
return PlatformUtils;
}());
exports.PlatformUtils = PlatformUtils;
},{"platform":12}],86:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebRtcPeerSendrecv = exports.WebRtcPeerSendonly = exports.WebRtcPeerRecvonly = exports.WebRtcPeer = void 0;
var freeice = require("freeice");
var uuid_1 = require("uuid");
var ExceptionEvent_1 = require("../Events/ExceptionEvent");
var OpenViduLogger_1 = require("../Logger/OpenViduLogger");
var Platform_1 = require("../Utils/Platform");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var WebRtcPeer = (function () {
function WebRtcPeer(configuration) {
var _this = this;
this.remoteCandidatesQueue = [];
this.localCandidatesQueue = [];
this.iceCandidateList = [];
platform = Platform_1.PlatformUtils.getInstance();
this.configuration = __assign(__assign({}, configuration), { iceServers: !!configuration.iceServers && configuration.iceServers.length > 0 ? configuration.iceServers : freeice(), mediaStream: configuration.mediaStream !== undefined ? configuration.mediaStream : null, mode: !!configuration.mode ? configuration.mode : 'sendrecv', id: !!configuration.id ? configuration.id : this.generateUniqueId() });
logger.debug("[WebRtcPeer] configuration:\n".concat(JSON.stringify(this.configuration, null, 2)));
this.pc = new RTCPeerConnection({ iceServers: this.configuration.iceServers });
this.pc.addEventListener('icecandidate', function (event) {
if (event.candidate !== null) {
var candidateInit = event.candidate;
var iceCandidate = new RTCIceCandidate(candidateInit);
_this.configuration.onIceCandidate(iceCandidate);
if (iceCandidate.candidate !== '') {
_this.localCandidatesQueue.push(iceCandidate);
}
}
});
this.pc.addEventListener('signalingstatechange', function () { return __awaiter(_this, void 0, void 0, function () {
var candidate, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(this.pc.signalingState === 'stable')) return [3, 6];
_a.label = 1;
case 1:
if (!(this.iceCandidateList.length > 0)) return [3, 6];
candidate = this.iceCandidateList.shift();
_a.label = 2;
case 2:
_a.trys.push([2, 4, , 5]);
return [4, this.pc.addIceCandidate(candidate)];
case 3:
_a.sent();
return [3, 5];
case 4:
error_1 = _a.sent();
logger.error('Error when calling RTCPeerConnection#addIceCandidate for RTCPeerConnection ' + this.getId(), error_1);
return [3, 5];
case 5: return [3, 1];
case 6: return [2];
}
});
}); });
}
WebRtcPeer.prototype.getId = function () {
return this.configuration.id;
};
WebRtcPeer.prototype.dispose = function () {
logger.debug('Disposing WebRtcPeer');
if (this.pc) {
if (this.pc.signalingState === 'closed') {
return;
}
this.pc.close();
this.remoteCandidatesQueue = [];
this.localCandidatesQueue = [];
}
};
WebRtcPeer.prototype.createOfferLegacy = function () {
if (!!this.configuration.mediaStream) {
this.deprecatedPeerConnectionTrackApi();
}
var hasAudio = this.configuration.mediaConstraints.audio;
var hasVideo = this.configuration.mediaConstraints.video;
var options = {
offerToReceiveAudio: this.configuration.mode !== 'sendonly' && hasAudio,
offerToReceiveVideo: this.configuration.mode !== 'sendonly' && hasVideo
};
logger.debug('[createOfferLegacy] RTCPeerConnection.createOffer() options:', JSON.stringify(options));
return this.pc.createOffer(options);
};
WebRtcPeer.prototype.createOffer = function () {
var _a, _b, _c, _d, _e, _f, _g, _h;
return __awaiter(this, void 0, void 0, function () {
var _i, _j, track, tcInit, trackSettings, trackConsts, trackWidth, trackHeight, trackPixels, maxLayers, l, layerDiv, encoding, tc, sendParams, needSetParams, error_2, message, _k, _l, kind, sdpOffer, error_3, message;
return __generator(this, function (_m) {
switch (_m.label) {
case 0:
if (!('addTransceiver' in this.pc)) {
logger.warn('[createOffer] Method RTCPeerConnection.addTransceiver() is NOT available; using LEGACY offerToReceive{Audio,Video}');
return [2, this.createOfferLegacy()];
}
else {
logger.debug('[createOffer] Method RTCPeerConnection.addTransceiver() is available; using it');
}
if (!(this.configuration.mode !== 'recvonly')) return [3, 7];
if (!this.configuration.mediaStream) {
throw new Error("[WebRtcPeer.createOffer] Direction is '".concat(this.configuration.mode, "', but no stream was configured to be sent"));
}
_i = 0, _j = this.configuration.mediaStream.getTracks();
_m.label = 1;
case 1:
if (!(_i < _j.length)) return [3, 6];
track = _j[_i];
tcInit = {
direction: this.configuration.mode,
streams: [this.configuration.mediaStream]
};
if (track.kind === 'video' && this.configuration.simulcast) {
trackSettings = track.getSettings();
trackConsts = track.getConstraints();
trackWidth = (_c = (_b = (_a = trackSettings.width) !== null && _a !== void 0 ? _a : trackConsts.width.ideal) !== null && _b !== void 0 ? _b : trackConsts.width) !== null && _c !== void 0 ? _c : 0;
trackHeight = (_f = (_e = (_d = trackSettings.height) !== null && _d !== void 0 ? _d : trackConsts.height.ideal) !== null && _e !== void 0 ? _e : trackConsts.height) !== null && _f !== void 0 ? _f : 0;
logger.info("[createOffer] Video track dimensions: ".concat(trackWidth, "x").concat(trackHeight));
trackPixels = trackWidth * trackHeight;
maxLayers = 0;
if (trackPixels >= 960 * 540) {
maxLayers = 3;
}
else if (trackPixels >= 480 * 270) {
maxLayers = 2;
}
else {
maxLayers = 1;
}
tcInit.sendEncodings = [];
for (l = 0; l < maxLayers; l++) {
layerDiv = Math.pow(2, (maxLayers - l - 1));
encoding = {
rid: 'rdiv' + layerDiv.toString(),
scalabilityMode: 'L1T1'
};
if (['detail', 'text'].includes(track.contentHint)) {
encoding.scaleResolutionDownBy = 1.0;
encoding.maxFramerate = Math.floor(30 / layerDiv);
}
else {
encoding.scaleResolutionDownBy = layerDiv;
}
tcInit.sendEncodings.push(encoding);
}
}
tc = this.pc.addTransceiver(track, tcInit);
if (!(track.kind === 'video')) return [3, 5];
sendParams = tc.sender.getParameters();
needSetParams = false;
if (!((_g = sendParams.degradationPreference) === null || _g === void 0 ? void 0 : _g.length)) {
if (['detail', 'text'].includes(track.contentHint)) {
sendParams.degradationPreference = 'maintain-resolution';
}
else {
sendParams.degradationPreference = 'balanced';
}
logger.info("[createOffer] Video sender Degradation Preference set: ".concat(sendParams.degradationPreference));
needSetParams = true;
}
if (this.configuration.simulcast) {
if (((_h = sendParams.encodings) === null || _h === void 0 ? void 0 : _h.length) !== tcInit.sendEncodings.length) {
sendParams.encodings = tcInit.sendEncodings;
needSetParams = true;
}
}
if (!needSetParams) return [3, 5];
logger.debug("[createOffer] Setting new RTCRtpSendParameters to video sender");
_m.label = 2;
case 2:
_m.trys.push([2, 4, , 5]);
return [4, tc.sender.setParameters(sendParams)];
case 3:
_m.sent();
return [3, 5];
case 4:
error_2 = _m.sent();
message = "[WebRtcPeer.createOffer] Cannot set RTCRtpSendParameters to video sender";
if (error_2 instanceof Error) {
message += ": ".concat(error_2.message);
}
throw new Error(message);
case 5:
_i++;
return [3, 1];
case 6: return [3, 8];
case 7:
for (_k = 0, _l = ['audio', 'video']; _k < _l.length; _k++) {
kind = _l[_k];
if (!this.configuration.mediaConstraints[kind]) {
continue;
}
this.configuration.mediaStream = new MediaStream();
this.pc.addTransceiver(kind, {
direction: this.configuration.mode,
streams: [this.configuration.mediaStream]
});
}
_m.label = 8;
case 8:
_m.trys.push([8, 10, , 11]);
return [4, this.pc.createOffer()];
case 9:
sdpOffer = _m.sent();
return [3, 11];
case 10:
error_3 = _m.sent();
message = "[WebRtcPeer.createOffer] Browser failed creating an SDP Offer";
if (error_3 instanceof Error) {
message += ": ".concat(error_3.message);
}
throw new Error(message);
case 11: return [2, sdpOffer];
}
});
});
};
WebRtcPeer.prototype.deprecatedPeerConnectionTrackApi = function () {
for (var _i = 0, _a = this.configuration.mediaStream.getTracks(); _i < _a.length; _i++) {
var track = _a[_i];
this.pc.addTrack(track, this.configuration.mediaStream);
}
};
WebRtcPeer.prototype.createAnswer = function () {
var _this = this;
return new Promise(function (resolve, reject) {
if ('getTransceivers' in _this.pc) {
logger.debug('[createAnswer] Method RTCPeerConnection.getTransceivers() is available; using it');
var _loop_1 = function (kind) {
if (!_this.configuration.mediaConstraints[kind]) {
return "continue";
}
var tc = _this.pc.getTransceivers().find(function (tc) { return tc.receiver.track.kind === kind; });
if (tc) {
tc.direction = _this.configuration.mode;
}
else {
return { value: reject(new Error("".concat(kind, " requested, but no transceiver was created from remote description"))) };
}
};
for (var _i = 0, _a = ['audio', 'video']; _i < _a.length; _i++) {
var kind = _a[_i];
var state_1 = _loop_1(kind);
if (typeof state_1 === "object")
return state_1.value;
}
_this.pc
.createAnswer()
.then(function (sdpAnswer) { return resolve(sdpAnswer); })
.catch(function (error) { return reject(error); });
}
else {
var offerAudio = void 0, offerVideo = true;
if (!!_this.configuration.mediaConstraints) {
offerAudio =
typeof _this.configuration.mediaConstraints.audio === 'boolean' ? _this.configuration.mediaConstraints.audio : true;
offerVideo =
typeof _this.configuration.mediaConstraints.video === 'boolean' ? _this.configuration.mediaConstraints.video : true;
var constraints = {
offerToReceiveAudio: offerAudio,
offerToReceiveVideo: offerVideo
};
_this.pc.createAnswer(constraints)
.then(function (sdpAnswer) { return resolve(sdpAnswer); })
.catch(function (error) { return reject(error); });
}
}
});
};
WebRtcPeer.prototype.processLocalOffer = function (offer) {
var _this = this;
return new Promise(function (resolve, reject) {
_this.pc
.setLocalDescription(offer)
.then(function () {
var localDescription = _this.pc.localDescription;
if (!!localDescription) {
logger.debug('Local description set', localDescription.sdp);
return resolve();
}
else {
return reject('Local description is not defined');
}
})
.catch(function (error) { return reject(error); });
});
};
WebRtcPeer.prototype.processRemoteOffer = function (sdpOffer) {
var _this = this;
return new Promise(function (resolve, reject) {
var offer = {
type: 'offer',
sdp: sdpOffer
};
logger.debug('SDP offer received, setting remote description', offer);
if (_this.pc.signalingState === 'closed') {
return reject('RTCPeerConnection is closed when trying to set remote description');
}
_this.setRemoteDescription(offer)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
});
};
WebRtcPeer.prototype.processLocalAnswer = function (answer) {
var _this = this;
return new Promise(function (resolve, reject) {
logger.debug('SDP answer created, setting local description');
if (_this.pc.signalingState === 'closed') {
return reject('RTCPeerConnection is closed when trying to set local description');
}
_this.pc
.setLocalDescription(answer)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
});
};
WebRtcPeer.prototype.processRemoteAnswer = function (sdpAnswer) {
var _this = this;
return new Promise(function (resolve, reject) {
var answer = {
type: 'answer',
sdp: sdpAnswer
};
logger.debug('SDP answer received, setting remote description');
if (_this.pc.signalingState === 'closed') {
return reject('RTCPeerConnection is closed when trying to set remote description');
}
_this.setRemoteDescription(answer)
.then(function () {
resolve();
})
.catch(function (error) { return reject(error); });
});
};
WebRtcPeer.prototype.setRemoteDescription = function (sdp) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2, this.pc.setRemoteDescription(sdp)];
});
});
};
WebRtcPeer.prototype.addIceCandidate = function (iceCandidate) {
var _this = this;
return new Promise(function (resolve, reject) {
logger.debug('Remote ICE candidate received', iceCandidate);
_this.remoteCandidatesQueue.push(iceCandidate);
switch (_this.pc.signalingState) {
case 'closed':
reject(new Error('PeerConnection object is closed'));
break;
case 'stable':
if (!!_this.pc.remoteDescription) {
_this.pc
.addIceCandidate(iceCandidate)
.then(function () { return resolve(); })
.catch(function (error) { return reject(error); });
}
else {
_this.iceCandidateList.push(iceCandidate);
resolve();
}
break;
default:
_this.iceCandidateList.push(iceCandidate);
resolve();
}
});
};
WebRtcPeer.prototype.addIceConnectionStateChangeListener = function (otherId) {
var _this = this;
this.pc.addEventListener('iceconnectionstatechange', function () {
var iceConnectionState = _this.pc.iceConnectionState;
switch (iceConnectionState) {
case 'disconnected':
var msg1 = 'IceConnectionState of RTCPeerConnection ' +
_this.configuration.id +
' (' +
otherId +
') change to "disconnected". Possible network disconnection';
logger.warn(msg1);
_this.configuration.onIceConnectionStateException(ExceptionEvent_1.ExceptionEventName.ICE_CONNECTION_DISCONNECTED, msg1);
break;
case 'failed':
var msg2 = 'IceConnectionState of RTCPeerConnection ' + _this.configuration.id + ' (' + otherId + ') to "failed"';
logger.error(msg2);
_this.configuration.onIceConnectionStateException(ExceptionEvent_1.ExceptionEventName.ICE_CONNECTION_FAILED, msg2);
break;
case 'closed':
logger.log('IceConnectionState of RTCPeerConnection ' + _this.configuration.id + ' (' + otherId + ') change to "closed"');
break;
case 'new':
logger.log('IceConnectionState of RTCPeerConnection ' + _this.configuration.id + ' (' + otherId + ') change to "new"');
break;
case 'checking':
logger.log('IceConnectionState of RTCPeerConnection ' + _this.configuration.id + ' (' + otherId + ') change to "checking"');
break;
case 'connected':
logger.log('IceConnectionState of RTCPeerConnection ' + _this.configuration.id + ' (' + otherId + ') change to "connected"');
break;
case 'completed':
logger.log('IceConnectionState of RTCPeerConnection ' + _this.configuration.id + ' (' + otherId + ') change to "completed"');
break;
}
});
};
WebRtcPeer.prototype.generateUniqueId = function () {
return (0, uuid_1.v4)();
};
return WebRtcPeer;
}());
exports.WebRtcPeer = WebRtcPeer;
var WebRtcPeerRecvonly = (function (_super) {
__extends(WebRtcPeerRecvonly, _super);
function WebRtcPeerRecvonly(configuration) {
configuration.mode = 'recvonly';
return _super.call(this, configuration) || this;
}
return WebRtcPeerRecvonly;
}(WebRtcPeer));
exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly;
var WebRtcPeerSendonly = (function (_super) {
__extends(WebRtcPeerSendonly, _super);
function WebRtcPeerSendonly(configuration) {
configuration.mode = 'sendonly';
return _super.call(this, configuration) || this;
}
return WebRtcPeerSendonly;
}(WebRtcPeer));
exports.WebRtcPeerSendonly = WebRtcPeerSendonly;
var WebRtcPeerSendrecv = (function (_super) {
__extends(WebRtcPeerSendrecv, _super);
function WebRtcPeerSendrecv(configuration) {
configuration.mode = 'sendrecv';
return _super.call(this, configuration) || this;
}
return WebRtcPeerSendrecv;
}(WebRtcPeer));
exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv;
},{"../Events/ExceptionEvent":59,"../Logger/OpenViduLogger":81,"../Utils/Platform":85,"freeice":2,"uuid":22}],87:[function(require,module,exports){
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebRtcStats = void 0;
var OpenViduLogger_1 = require("../Logger/OpenViduLogger");
var Platform_1 = require("../Utils/Platform");
var logger = OpenViduLogger_1.OpenViduLogger.getInstance();
var platform;
var WebRtcStats = (function () {
function WebRtcStats(stream) {
this.stream = stream;
this.STATS_ITEM_NAME = 'webrtc-stats-config';
this.webRtcStatsEnabled = false;
this.statsInterval = 1;
platform = Platform_1.PlatformUtils.getInstance();
}
WebRtcStats.prototype.isEnabled = function () {
return this.webRtcStatsEnabled;
};
WebRtcStats.prototype.initWebRtcStats = function () {
var _this = this;
var webrtcObj = localStorage.getItem(this.STATS_ITEM_NAME);
if (!!webrtcObj) {
this.webRtcStatsEnabled = true;
var webrtcStatsConfig = JSON.parse(webrtcObj);
logger.warn('WebRtc stats enabled for stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId);
logger.warn('localStorage item: ' + JSON.stringify(webrtcStatsConfig));
this.POST_URL = webrtcStatsConfig.httpEndpoint;
this.statsInterval = webrtcStatsConfig.interval;
this.webRtcStatsIntervalId = setInterval(function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.sendStatsToHttpEndpoint()];
case 1:
_a.sent();
return [2];
}
});
}); }, this.statsInterval * 1000);
}
else {
logger.debug('WebRtc stats not enabled');
}
};
WebRtcStats.prototype.getSelectedIceCandidateInfo = function () {
var _this = this;
return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var statsReport, transportStat, candidatePairs, localCandidates, remoteCandidates, selectedCandidatePair, selectedCandidatePairId, length_1, iterator, i, candidatePair, localCandidateId, remoteCandidateId, finalLocalCandidate, candList, cand, _i, cand_1, c, finalRemoteCandidate, candList, cand, _a, cand_2, c;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4, this.stream.getRTCPeerConnection().getStats()];
case 1:
statsReport = _b.sent();
candidatePairs = new Map();
localCandidates = new Map();
remoteCandidates = new Map();
statsReport.forEach(function (stat) {
if (stat.type === 'transport' && (platform.isChromium() || platform.isSafariBrowser() || platform.isReactNative())) {
transportStat = stat;
}
switch (stat.type) {
case 'candidate-pair':
candidatePairs.set(stat.id, stat);
break;
case 'local-candidate':
localCandidates.set(stat.id, stat);
break;
case 'remote-candidate':
remoteCandidates.set(stat.id, stat);
break;
}
});
if (transportStat != null) {
selectedCandidatePairId = transportStat.selectedCandidatePairId;
selectedCandidatePair = candidatePairs.get(selectedCandidatePairId);
}
else {
length_1 = candidatePairs.size;
iterator = candidatePairs.values();
for (i = 0; i < length_1; i++) {
candidatePair = iterator.next().value;
if (candidatePair['selected']) {
selectedCandidatePair = candidatePair;
break;
}
}
}
localCandidateId = selectedCandidatePair.localCandidateId;
remoteCandidateId = selectedCandidatePair.remoteCandidateId;
finalLocalCandidate = localCandidates.get(localCandidateId);
if (!!finalLocalCandidate) {
candList = this.stream.getLocalIceCandidateList();
cand = candList.filter(function (c) {
return (!!c.candidate &&
(c.candidate.indexOf(finalLocalCandidate.ip) >= 0 || c.candidate.indexOf(finalLocalCandidate.address) >= 0) &&
c.candidate.indexOf(finalLocalCandidate.port) >= 0);
});
finalLocalCandidate.raw = [];
for (_i = 0, cand_1 = cand; _i < cand_1.length; _i++) {
c = cand_1[_i];
finalLocalCandidate.raw.push(c.candidate);
}
}
else {
finalLocalCandidate = 'ERROR: No active local ICE candidate. Probably ICE-TCP is being used';
}
finalRemoteCandidate = remoteCandidates.get(remoteCandidateId);
if (!!finalRemoteCandidate) {
candList = this.stream.getRemoteIceCandidateList();
cand = candList.filter(function (c) {
return (!!c.candidate &&
(c.candidate.indexOf(finalRemoteCandidate.ip) >= 0 || c.candidate.indexOf(finalRemoteCandidate.address) >= 0) &&
c.candidate.indexOf(finalRemoteCandidate.port) >= 0);
});
finalRemoteCandidate.raw = [];
for (_a = 0, cand_2 = cand; _a < cand_2.length; _a++) {
c = cand_2[_a];
finalRemoteCandidate.raw.push(c.candidate);
}
}
else {
finalRemoteCandidate = 'ERROR: No active remote ICE candidate. Probably ICE-TCP is being used';
}
return [2, resolve({
localCandidate: finalLocalCandidate,
remoteCandidate: finalRemoteCandidate
})];
}
});
}); });
};
WebRtcStats.prototype.stopWebRtcStats = function () {
if (this.webRtcStatsEnabled) {
clearInterval(this.webRtcStatsIntervalId);
logger.warn('WebRtc stats stopped for disposed stream ' + this.stream.streamId + ' of connection ' + this.stream.connection.connectionId);
}
};
WebRtcStats.prototype.sendStats = function (url, response) {
return __awaiter(this, void 0, void 0, function () {
var configuration, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
configuration = {
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(response),
method: 'POST'
};
return [4, fetch(url, configuration)];
case 1:
_a.sent();
return [3, 3];
case 2:
error_1 = _a.sent();
logger.error("sendStats error: ".concat(JSON.stringify(error_1)));
return [3, 3];
case 3: return [2];
}
});
});
};
WebRtcStats.prototype.sendStatsToHttpEndpoint = function () {
return __awaiter(this, void 0, void 0, function () {
var webrtcStats, response, error_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 3, , 4]);
return [4, this.getCommonStats()];
case 1:
webrtcStats = _a.sent();
response = this.generateJSONStatsResponse(webrtcStats);
return [4, this.sendStats(this.POST_URL, response)];
case 2:
_a.sent();
return [3, 4];
case 3:
error_2 = _a.sent();
logger.log(error_2);
return [3, 4];
case 4: return [2];
}
});
});
};
WebRtcStats.prototype.getCommonStats = function () {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
return [2, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () {
var statsReport, response_1, videoTrackStats_1, candidatePairStats_1, error_3;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4, this.stream.getRTCPeerConnection().getStats()];
case 1:
statsReport = _a.sent();
response_1 = this.getWebRtcStatsResponseOutline();
videoTrackStats_1 = ['framesReceived', 'framesDropped', 'framesSent', 'frameHeight', 'frameWidth'];
candidatePairStats_1 = ['availableOutgoingBitrate', 'currentRoundTripTime'];
statsReport.forEach(function (stat) {
var mediaType = stat.mediaType != null ? stat.mediaType : stat.kind;
var addStat = function (direction, key) {
if (stat[key] != null && response_1[direction] != null) {
if (!mediaType && videoTrackStats_1.indexOf(key) > -1) {
mediaType = 'video';
}
if (direction != null && mediaType != null && key != null && response_1[direction][mediaType] != null) {
response_1[direction][mediaType][key] = Number(stat[key]);
}
else if (direction != null && key != null && candidatePairStats_1.includes(key)) {
response_1[direction][key] = Number(stat[key]);
}
}
};
switch (stat.type) {
case 'outbound-rtp':
addStat('outbound', 'bytesSent');
addStat('outbound', 'packetsSent');
addStat('outbound', 'framesEncoded');
addStat('outbound', 'nackCount');
addStat('outbound', 'firCount');
addStat('outbound', 'pliCount');
addStat('outbound', 'qpSum');
break;
case 'inbound-rtp':
addStat('inbound', 'bytesReceived');
addStat('inbound', 'packetsReceived');
addStat('inbound', 'packetsLost');
addStat('inbound', 'jitter');
addStat('inbound', 'framesDecoded');
addStat('inbound', 'nackCount');
addStat('inbound', 'firCount');
addStat('inbound', 'pliCount');
break;
case 'track':
addStat('inbound', 'jitterBufferDelay');
addStat('inbound', 'framesReceived');
addStat('outbound', 'framesDropped');
addStat('outbound', 'framesSent');
addStat(_this.stream.isLocal() ? 'outbound' : 'inbound', 'frameHeight');
addStat(_this.stream.isLocal() ? 'outbound' : 'inbound', 'frameWidth');
break;
case 'candidate-pair':
addStat('candidatepair', 'currentRoundTripTime');
addStat('candidatepair', 'availableOutgoingBitrate');
break;
}
});
if (!(response_1 === null || response_1 === void 0 ? void 0 : response_1.candidatepair) || Object.keys(response_1.candidatepair).length === 0) {
delete response_1.candidatepair;
}
return [2, resolve(response_1)];
case 2:
error_3 = _a.sent();
logger.error('Error getting common stats: ', error_3);
return [2, reject(error_3)];
case 3: return [2];
}
});
}); })];
});
});
};
WebRtcStats.prototype.generateJSONStatsResponse = function (stats) {
return {
'@timestamp': new Date().toISOString(),
participant_id: this.stream.connection.data,
session_id: this.stream.session.sessionId,
platform: platform.getName(),
platform_description: platform.getDescription(),
stream: 'webRTC',
webrtc_stats: stats
};
};
WebRtcStats.prototype.getWebRtcStatsResponseOutline = function () {
if (this.stream.isLocal()) {
return {
outbound: {
audio: {},
video: {}
},
candidatepair: {}
};
}
else {
return {
inbound: {
audio: {},
video: {}
}
};
}
};
return WebRtcStats;
}());
exports.WebRtcStats = WebRtcStats;
},{"../Logger/OpenViduLogger":81,"../Utils/Platform":85}]},{},[41])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2pzbmxvZy9qc25sb2cuanMiLCIuLi9ub2RlX21vZHVsZXMvbWltZS9NaW1lLmpzIiwiLi4vbm9kZV9tb2R1bGVzL21pbWUvbGl0ZS5qcyIsIi4uL25vZGVfbW9kdWxlcy9taW1lL3R5cGVzL3N0YW5kYXJkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCIuLi9ub2RlX21vZHVsZXMvc2VtdmVyL2NsYXNzZXMvc2VtdmVyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3NlbXZlci9mdW5jdGlvbnMvbWFqb3IuanMiLCIuLi9ub2RlX21vZHVsZXMvc2VtdmVyL2Z1bmN0aW9ucy9taW5vci5qcyIsIi4uL25vZGVfbW9kdWxlcy9zZW12ZXIvaW50ZXJuYWwvY29uc3RhbnRzLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3NlbXZlci9pbnRlcm5hbC9kZWJ1Zy5qcyIsIi4uL25vZGVfbW9kdWxlcy9zZW12ZXIvaW50ZXJuYWwvaWRlbnRpZmllcnMuanMiLCIuLi9ub2RlX21vZHVsZXMvc2VtdmVyL2ludGVybmFsL3BhcnNlLW9wdGlvbnMuanMiLCIuLi9ub2RlX21vZHVsZXMvc2VtdmVyL2ludGVybmFsL3JlLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvbWQ1LWJyb3dzZXIuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L25hdGl2ZS1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9uaWwuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L3BhcnNlLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9yZWdleC5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3Qvcm5nLWJyb3dzZXIuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L3NoYTEtYnJvd3Nlci5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3Qvc3RyaW5naWZ5LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC92MS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvdjMuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L3YzNS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvdjQuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L3Y1LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC92YWxpZGF0ZS5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvdmVyc2lvbi5qcyIsIi4uL25vZGVfbW9kdWxlcy93aWxkZW1pdHRlci93aWxkZW1pdHRlci5qcyIsIi4uL25vZGVfbW9kdWxlcy93b2xmeTg3LWV2ZW50ZW1pdHRlci9FdmVudEVtaXR0ZXIuanMiLCIuLi9wYWNrYWdlLmpzb24iLCJNYWluLnRzIiwiT3BlblZpZHUvQ29ubmVjdGlvbi50cyIsIk9wZW5WaWR1L0V2ZW50RGlzcGF0Y2hlci50cyIsIk9wZW5WaWR1L0ZpbHRlci50cyIsIk9wZW5WaWR1L0xvY2FsUmVjb3JkZXIudHMiLCJPcGVuVmlkdS9PcGVuVmlkdS50cyIsIk9wZW5WaWR1L1B1Ymxpc2hlci50cyIsIk9wZW5WaWR1L1Nlc3Npb24udHMiLCJPcGVuVmlkdS9TdHJlYW0udHMiLCJPcGVuVmlkdS9TdHJlYW1NYW5hZ2VyLnRzIiwiT3BlblZpZHUvU3Vic2NyaWJlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvTG9jYWxSZWNvcmRlclN0YXRlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9UeXBlT2ZWaWRlby50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRW51bXMvVmlkZW9JbnNlcnRNb2RlLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvQ29ubmVjdGlvbkV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvQ29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FeGNlcHRpb25FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvTmV0d29ya1F1YWxpdHlMZXZlbENoYW5nZWRFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1B1Ymxpc2hlclNwZWFraW5nRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9SZWNvcmRpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NpZ25hbEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3BlZWNoVG9UZXh0RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvTWFwcGVyLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvaW5kZXguanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9qc29ucnBjY2xpZW50LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL3RyYW5zcG9ydHMvd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbi5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL0pzb25SUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9YbWxSUEMuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvcGFja2Vycy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL0NvbnNvbGVMb2dnZXIudHMiLCJPcGVuVmlkdUludGVybmFsL0xvZ2dlci9PcGVuVmlkdUxvZ2dlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbi50cyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLUF1dG8uanMiLCJPcGVuVmlkdUludGVybmFsL1NjcmVlblNoYXJpbmcvU2NyZWVuLUNhcHR1cmluZy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvVXRpbHMvUGxhdGZvcm0udHMiLCJPcGVuVmlkdUludGVybmFsL1dlYlJ0Y1BlZXIvV2ViUnRjUGVlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjU3RhdHMvV2ViUnRjU3RhdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDamZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzVEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzV1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9SQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RlQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN4REEsZ0RBQStDO0FBQy9DLGlDQUE0QjtBQUU1QixJQUFJLE9BQU8sVUFBVSxLQUFLLFdBQVcsRUFBRTtJQUNuQyxV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RSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJO1lBQzNDLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTO1lBQ3pDLFFBQVEsRUFBRSxRQUFRLENBQUMsT0FBTyxFQUFFO1lBQzVCLG9CQUFvQixFQUFFLFFBQVEsQ0FBQyxjQUFjLEVBQUU7WUFDL0MsTUFBTSxFQUFFLFFBQVE7WUFDaEIsWUFBWSxFQUFFLEtBQUs7U0FDdEIsQ0FBQztJQUNOLENBQUM7SUFFTyxtREFBNkIsR0FBckM7UUFDSSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDdkIsT0FBTztnQkFDSCxRQUFRLEVBQUU7b0JBQ04sS0FBSyxFQUFFLEVBQUU7b0JBQ1QsS0FBSyxFQUFFLEVBQUU7aUJBQ1o7Z0JBQ0QsYUFBYSxFQUFFLEVBQUU7YUFDcEIsQ0FBQztTQUNMO2FBQU07WUFDSCxPQUFPO2dCQUNILE9BQU8sRUFBRTtvQkFDTCxLQUFLLEVBQUUsRUFBRTtvQkFDVCxLQUFLLEVBQUUsRUFBRTtpQkFDWjthQUNKLENBQUM7U0FDTDtJQUNMLENBQUM7SUFDTCxrQkFBQztBQUFELENBdFdBLEFBc1dDLElBQUE7QUF0V1ksa0NBQVciLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgUiA9IHR5cGVvZiBSZWZsZWN0ID09PSAnb2JqZWN0JyA/IFJlZmxlY3QgOiBudWxsXG52YXIgUmVmbGVjdEFwcGx5ID0gUiAmJiB0eXBlb2YgUi5hcHBseSA9PT0gJ2Z1bmN0aW9uJ1xuICA/IFIuYXBwbHlcbiAgOiBmdW5jdGlvbiBSZWZsZWN0QXBwbHkodGFyZ2V0LCByZWNlaXZlciwgYXJncykge1xuICAgIHJldHVybiBGdW5jdGlvbi5wcm90b3R5cGUuYXBwbHkuY2FsbCh0YXJnZXQsIHJlY2VpdmVyLCBhcmdzKTtcbiAgfVxuXG52YXIgUmVmbGVjdE93bktleXNcbmlmIChSICYmIHR5cGVvZiBSLm93bktleXMgPT09ICdmdW5jdGlvbicpIHtcbiAgUmVmbGVjdE93bktleXMgPSBSLm93bktleXNcbn0gZWxzZSBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpXG4gICAgICAuY29uY2F0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHModGFyZ2V0KSk7XG4gIH07XG59IGVsc2Uge1xuICBSZWZsZWN0T3duS2V5cyA9IGZ1bmN0aW9uIFJlZmxlY3RPd25LZXlzKHRhcmdldCkge1xuICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0YXJnZXQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBQcm9jZXNzRW1pdFdhcm5pbmcod2FybmluZykge1xuICBpZiAoY29uc29sZSAmJiBjb25zb2xlLndhcm4pIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbn1cblxudmFyIE51bWJlcklzTmFOID0gTnVtYmVyLmlzTmFOIHx8IGZ1bmN0aW9uIE51bWJlcklzTmFOKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPT0gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgRXZlbnRFbWl0dGVyLmluaXQuY2FsbCh0aGlzKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xubW9kdWxlLmV4cG9ydHMub25jZSA9IG9uY2U7XG5cbi8vIEJhY2t3YXJkcy1jb21wYXQgd2l0aCBub2RlIDAuMTAueFxuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzID0gdW5kZWZpbmVkO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fZXZlbnRzQ291bnQgPSAwO1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5fbWF4TGlzdGVuZXJzID0gdW5kZWZpbmVkO1xuXG4vLyBCeSBkZWZhdWx0IEV2ZW50RW1pdHRlcnMgd2lsbCBwcmludCBhIHdhcm5pbmcgaWYgbW9yZSB0aGFuIDEwIGxpc3RlbmVycyBhcmVcbi8vIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2ggaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG52YXIgZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG5mdW5jdGlvbiBjaGVja0xpc3RlbmVyKGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBGdW5jdGlvbi4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGxpc3RlbmVyKTtcbiAgfVxufVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoRXZlbnRFbWl0dGVyLCAnZGVmYXVsdE1heExpc3RlbmVycycsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gZGVmYXVsdE1heExpc3RlbmVycztcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICBpZiAodHlwZW9mIGFyZyAhPT0gJ251bWJlcicgfHwgYXJnIDwgMCB8fCBOdW1iZXJJc05hTihhcmcpKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIG9mIFwiZGVmYXVsdE1heExpc3RlbmVyc1wiIGlzIG91dCBvZiByYW5nZS4gSXQgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIuIFJlY2VpdmVkICcgKyBhcmcgKyAnLicpO1xuICAgIH1cbiAgICBkZWZhdWx0TWF4TGlzdGVuZXJzID0gYXJnO1xuICB9XG59KTtcblxuRXZlbnRFbWl0dGVyLmluaXQgPSBmdW5jdGlvbigpIHtcblxuICBpZiAodGhpcy5fZXZlbnRzID09PSB1bmRlZmluZWQgfHxcbiAgICAgIHRoaXMuX2V2ZW50cyA9PT0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpLl9ldmVudHMpIHtcbiAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59O1xuXG4vLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3Ncbi8vIHRoYXQgdG8gYmUgaW5jcmVhc2VkLiBTZXQgdG8gemVybyBmb3IgdW5saW1pdGVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMobikge1xuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPCAwIHx8IE51bWJlcklzTmFOKG4pKSB7XG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ1RoZSB2YWx1ZSBvZiBcIm5cIiBpcyBvdXQgb2YgcmFuZ2UuIEl0IG11c3QgYmUgYSBub24tbmVnYXRpdmUgbnVtYmVyLiBSZWNlaXZlZCAnICsgbiArICcuJyk7XG4gIH1cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5mdW5jdGlvbiBfZ2V0TWF4TGlzdGVuZXJzKHRoYXQpIHtcbiAgaWYgKHRoYXQuX21heExpc3RlbmVycyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgcmV0dXJuIHRoYXQuX21heExpc3RlbmVycztcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5nZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiBfZ2V0TWF4TGlzdGVuZXJzKHRoaXMpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdCh0eXBlKSB7XG4gIHZhciBhcmdzID0gW107XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSBhcmdzLnB1c2goYXJndW1lbnRzW2ldKTtcbiAgdmFyIGRvRXJyb3IgPSAodHlwZSA9PT0gJ2Vycm9yJyk7XG5cbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgaWYgKGV2ZW50cyAhPT0gdW5kZWZpbmVkKVxuICAgIGRvRXJyb3IgPSAoZG9FcnJvciAmJiBldmVudHMuZXJyb3IgPT09IHVuZGVmaW5lZCk7XG4gIGVsc2UgaWYgKCFkb0Vycm9yKVxuICAgIHJldHVybiBmYWxzZTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmIChkb0Vycm9yKSB7XG4gICAgdmFyIGVyO1xuICAgIGlmIChhcmdzLmxlbmd0aCA+IDApXG4gICAgICBlciA9IGFyZ3NbMF07XG4gICAgaWYgKGVyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIC8vIE5vdGU6IFRoZSBjb21tZW50cyBvbiB0aGUgYHRocm93YCBsaW5lcyBhcmUgaW50ZW50aW9uYWwsIHRoZXkgc2hvd1xuICAgICAgLy8gdXAgaW4gTm9kZSdzIG91dHB1dCBpZiB0aGlzIHJlc3VsdHMgaW4gYW4gdW5oYW5kbGVkIGV4Y2VwdGlvbi5cbiAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgIH1cbiAgICAvLyBBdCBsZWFzdCBnaXZlIHNvbWUga2luZCBvZiBjb250ZXh0IHRvIHRoZSB1c2VyXG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcignVW5oYW5kbGVkIGVycm9yLicgKyAoZXIgPyAnICgnICsgZXIubWVzc2FnZSArICcpJyA6ICcnKSk7XG4gICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICB0aHJvdyBlcnI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gIH1cblxuICB2YXIgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoaGFuZGxlciA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICBSZWZsZWN0QXBwbHkoaGFuZGxlciwgdGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIFJlZmxlY3RBcHBseShsaXN0ZW5lcnNbaV0sIHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5mdW5jdGlvbiBfYWRkTGlzdGVuZXIodGFyZ2V0LCB0eXBlLCBsaXN0ZW5lciwgcHJlcGVuZCkge1xuICB2YXIgbTtcbiAgdmFyIGV2ZW50cztcbiAgdmFyIGV4aXN0aW5nO1xuXG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0YXJnZXQuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgPyBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICAgICAgLy8gUmUtYXNzaWduIGBldmVudHNgIGJlY2F1c2UgYSBuZXdMaXN0ZW5lciBoYW5kbGVyIGNvdWxkIGhhdmUgY2F1c2VkIHRoZVxuICAgICAgLy8gdGhpcy5fZXZlbnRzIHRvIGJlIGFzc2lnbmVkIHRvIGEgbmV3IG9iamVjdFxuICAgICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gICAgfVxuICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdO1xuICB9XG5cbiAgaWYgKGV4aXN0aW5nID09PSB1bmRlZmluZWQpIHtcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgICsrdGFyZ2V0Ll9ldmVudHNDb3VudDtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIGV4aXN0aW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID1cbiAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgfSBlbHNlIGlmIChwcmVwZW5kKSB7XG4gICAgICBleGlzdGluZy51bnNoaWZ0KGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBtID0gX2dldE1heExpc3RlbmVycyh0YXJnZXQpO1xuICAgIGlmIChtID4gMCAmJiBleGlzdGluZy5sZW5ndGggPiBtICYmICFleGlzdGluZy53YXJuZWQpIHtcbiAgICAgIGV4aXN0aW5nLndhcm5lZCA9IHRydWU7XG4gICAgICAvLyBObyBlcnJvciBjb2RlIGZvciB0aGlzIHNpbmNlIGl0IGlzIGEgV2FybmluZ1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtc3ludGF4XG4gICAgICB2YXIgdyA9IG5ldyBFcnJvcignUG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSBsZWFrIGRldGVjdGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcubGVuZ3RoICsgJyAnICsgU3RyaW5nKHR5cGUpICsgJyBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdhZGRlZC4gVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdpbmNyZWFzZSBsaW1pdCcpO1xuICAgICAgdy5uYW1lID0gJ01heExpc3RlbmVyc0V4Y2VlZGVkV2FybmluZyc7XG4gICAgICB3LmVtaXR0ZXIgPSB0YXJnZXQ7XG4gICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgdy5jb3VudCA9IGV4aXN0aW5nLmxlbmd0aDtcbiAgICAgIFByb2Nlc3NFbWl0V2FybmluZyh3KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZExpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIHRydWUpO1xuICAgIH07XG5cbmZ1bmN0aW9uIG9uY2VXcmFwcGVyKCkge1xuICBpZiAoIXRoaXMuZmlyZWQpIHtcbiAgICB0aGlzLnRhcmdldC5yZW1vdmVMaXN0ZW5lcih0aGlzLnR5cGUsIHRoaXMud3JhcEZuKTtcbiAgICB0aGlzLmZpcmVkID0gdHJ1ZTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmFwcGx5KHRoaXMudGFyZ2V0LCBhcmd1bWVudHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IG9uY2VXcmFwcGVyLmJpbmQoc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG4gICAgICB0aGlzLnByZXBlbmRMaXN0ZW5lcih0eXBlLCBfb25jZVdyYXAodGhpcywgdHlwZSwgbGlzdGVuZXIpKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbi8vIEVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZiBhbmQgb25seSBpZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgdmFyIGxpc3QsIGV2ZW50cywgcG9zaXRpb24sIGksIG9yaWdpbmFsTGlzdGVuZXI7XG5cbiAgICAgIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpO1xuXG4gICAgICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gICAgICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgICBsaXN0ID0gZXZlbnRzW3R5cGVdO1xuICAgICAgaWYgKGxpc3QgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBkZWxldGUgZXZlbnRzW3R5cGVdO1xuICAgICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdC5saXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGxpc3QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcG9zaXRpb24gPSAtMTtcblxuICAgICAgICBmb3IgKGkgPSBsaXN0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKGxpc3RbaV0gPT09IGxpc3RlbmVyIHx8IGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICBvcmlnaW5hbExpc3RlbmVyID0gbGlzdFtpXS5saXN0ZW5lcjtcbiAgICAgICAgICAgIHBvc2l0aW9uID0gaTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSAwKVxuICAgICAgICAgIGxpc3Quc2hpZnQoKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSlcbiAgICAgICAgICBldmVudHNbdHlwZV0gPSBsaXN0WzBdO1xuXG4gICAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgIT09IHVuZGVmaW5lZClcbiAgICAgICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgb3JpZ2luYWxMaXN0ZW5lciB8fCBsaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgICAgIGlmIChldmVudHMucmVtb3ZlTGlzdGVuZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhldmVudHMpO1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgaWYgKGtleSA9PT0gJ3JlbW92ZUxpc3RlbmVyJykgY29udGludWU7XG4gICAgICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygncmVtb3ZlTGlzdGVuZXInKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVycyk7XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbmVycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIExJRk8gb3JkZXJcbiAgICAgICAgZm9yIChpID0gbGlzdGVuZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbmZ1bmN0aW9uIF9saXN0ZW5lcnModGFyZ2V0LCB0eXBlLCB1bndyYXApIHtcbiAgdmFyIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gW107XG5cbiAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG4gIGlmIChldmxpc3RlbmVyID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/XG4gICAgdW53cmFwTGlzdGVuZXJzKGV2bGlzdGVuZXIpIDogYXJyYXlDbG9uZShldmxpc3RlbmVyLCBldmxpc3RlbmVyLmxlbmd0aCk7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24gbGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgdHJ1ZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJhd0xpc3RlbmVycyA9IGZ1bmN0aW9uIHJhd0xpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIubGlzdGVuZXJDb3VudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBlbWl0dGVyLmxpc3RlbmVyQ291bnQodHlwZSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyQ291bnQuY2FsbChlbWl0dGVyLCB0eXBlKTtcbiAgfVxufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lckNvdW50ID0gbGlzdGVuZXJDb3VudDtcbmZ1bmN0aW9uIGxpc3RlbmVyQ291bnQodHlwZSkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuXG4gIGlmIChldmVudHMgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuXG4gICAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9IGVsc2UgaWYgKGV2bGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdE93bktleXModGhpcy5fZXZlbnRzKSA6IFtdO1xufTtcblxuZnVuY3Rpb24gYXJyYXlDbG9uZShhcnIsIG4pIHtcbiAgdmFyIGNvcHkgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKVxuICAgIGNvcHlbaV0gPSBhcnJbaV07XG4gIHJldHVybiBjb3B5O1xufVxuXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICg7IGluZGV4ICsgMSA8IGxpc3QubGVuZ3RoOyBpbmRleCsrKVxuICAgIGxpc3RbaW5kZXhdID0gbGlzdFtpbmRleCArIDFdO1xuICBsaXN0LnBvcCgpO1xufVxuXG5mdW5jdGlvbiB1bndyYXBMaXN0ZW5lcnMoYXJyKSB7XG4gIHZhciByZXQgPSBuZXcgQXJyYXkoYXJyLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcmV0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmV0W2ldID0gYXJyW2ldLmxpc3RlbmVyIHx8IGFycltpXTtcbiAgfVxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBvbmNlKGVtaXR0ZXIsIG5hbWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICBmdW5jdGlvbiBlcnJvckxpc3RlbmVyKGVycikge1xuICAgICAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihuYW1lLCByZXNvbHZlcik7XG4gICAgICByZWplY3QoZXJyKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZXNvbHZlcigpIHtcbiAgICAgIGlmICh0eXBlb2YgZW1pdHRlci5yZW1vdmVMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIGVycm9yTGlzdGVuZXIpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZShbXS5zbGljZS5jYWxsKGFyZ3VtZW50cykpO1xuICAgIH07XG5cbiAgICBldmVudFRhcmdldEFnbm9zdGljQWRkTGlzdGVuZXIoZW1pdHRlciwgbmFtZSwgcmVzb2x2ZXIsIHsgb25jZTogdHJ1ZSB9KTtcbiAgICBpZiAobmFtZSAhPT0gJ2Vycm9yJykge1xuICAgICAgYWRkRXJyb3JIYW5kbGVySWZFdmVudEVtaXR0ZXIoZW1pdHRlciwgZXJyb3JMaXN0ZW5lciwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGFkZEVycm9ySGFuZGxlcklmRXZlbnRFbWl0dGVyKGVtaXR0ZXIsIGhhbmRsZXIsIGZsYWdzKSB7XG4gIGlmICh0eXBlb2YgZW1pdHRlci5vbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGV2ZW50VGFyZ2V0QWdub3N0aWNBZGRMaXN0ZW5lcihlbWl0dGVyLCAnZXJyb3InLCBoYW5kbGVyLCBmbGFncyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZXZlbnRUYXJnZXRBZ25vc3RpY0FkZExpc3RlbmVyKGVtaXR0ZXIsIG5hbWUsIGxpc3RlbmVyLCBmbGFncykge1xuICBpZiAodHlwZW9mIGVtaXR0ZXIub24gPT09ICdmdW5jdGlvbicpIHtcbiAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgZW1pdHRlci5vbmNlKG5hbWUsIGxpc3RlbmVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW1pdHRlci5vbihuYW1lLCBsaXN0ZW5lcik7XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGVvZiBlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAvLyBFdmVudFRhcmdldCBkb2VzIG5vdCBoYXZlIGBlcnJvcmAgZXZlbnQgc2VtYW50aWNzIGxpa2UgTm9kZVxuICAgIC8vIEV2ZW50RW1pdHRlcnMsIHdlIGRvIG5vdCBsaXN0ZW4gZm9yIGBlcnJvcmAgZXZlbnRzIGhlcmUuXG4gICAgZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGZ1bmN0aW9uIHdyYXBMaXN0ZW5lcihhcmcpIHtcbiAgICAgIC8vIElFIGRvZXMgbm90IGhhdmUgYnVpbHRpbiBgeyBvbmNlOiB0cnVlIH1gIHN1cHBvcnQgc28gd2VcbiAgICAgIC8vIGhhdmUgdG8gZG8gaXQgbWFudWFsbHkuXG4gICAgICBpZiAoZmxhZ3Mub25jZSkge1xuICAgICAgICBlbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgd3JhcExpc3RlbmVyKTtcbiAgICAgIH1cbiAgICAgIGxpc3RlbmVyKGFyZyk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIFwiZW1pdHRlclwiIGFyZ3VtZW50IG11c3QgYmUgb2YgdHlwZSBFdmVudEVtaXR0ZXIuIFJlY2VpdmVkIHR5cGUgJyArIHR5cGVvZiBlbWl0dGVyKTtcbiAgfVxufVxuIiwiLyoganNoaW50IG5vZGU6IHRydWUgKi9cbid1c2Ugc3RyaWN0JztcblxudmFyIG5vcm1hbGljZSA9IHJlcXVpcmUoJ25vcm1hbGljZScpO1xuXG4vKipcbiAgIyBmcmVlaWNlXG5cbiAgVGhlIGBmcmVlaWNlYCBtb2R1bGUgaXMgYSBzaW1wbGUgd2F5IG9mIGdldHRpbmcgcmFuZG9tIFNUVU4gb3IgVFVSTiBzZXJ2ZXJcbiAgZm9yIHlvdXIgV2ViUlRDIGFwcGxpY2F0aW9uLiAgVGhlIGxpc3Qgb2Ygc2VydmVycyAoanVzdCBTVFVOIGF0IHRoaXMgc3RhZ2UpXG4gIHdlcmUgc291cmNlZCBmcm9tIHRoaXMgW2dpc3RdKGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL3p6aXVuaS8zNzQxOTMzKS5cblxuICAjIyBFeGFtcGxlIFVzZVxuXG4gIFRoZSBmb2xsb3dpbmcgZGVtb25zdHJhdGVzIGhvdyB5b3UgY2FuIHVzZSBgZnJlZWljZWAgd2l0aFxuICBbcnRjLXF1aWNrY29ubmVjdF0oaHR0cHM6Ly9naXRodWIuY29tL3J0Yy1pby9ydGMtcXVpY2tjb25uZWN0KTpcblxuICA8PDwgZXhhbXBsZXMvcXVpY2tjb25uZWN0LmpzXG5cbiAgQXMgdGhlIGBmcmVlaWNlYCBtb2R1bGUgZ2VuZXJhdGVzIGljZSBzZXJ2ZXJzIGluIGEgbGlzdCBjb21wbGlhbnQgd2l0aCB0aGVcbiAgV2ViUlRDIHNwZWMgeW91IHdpbGwgYmUgYWJsZSB0byB1c2UgaXQgd2l0aCByYXcgYFJUQ1BlZXJDb25uZWN0aW9uYFxuICBjb25zdHJ1Y3RvcnMgYW5kIG90aGVyIFdlYlJUQyBsaWJyYXJpZXMuXG5cbiAgIyMgSGV5LCBkb24ndCB1c2UgbXkgU1RVTi9UVVJOIHNlcnZlciFcblxuICBJZiBmb3Igc29tZSByZWFzb24geW91ciBmcmVlIFNUVU4gb3IgVFVSTiBzZXJ2ZXIgZW5kcyB1cCBpbiB0aGVcbiAgbGlzdCBvZiBzZXJ2ZXJzIChbc3R1bl0oaHR0cHM6Ly9naXRodWIuY29tL0RhbW9uT2VobG1hbi9mcmVlaWNlL2Jsb2IvbWFzdGVyL3N0dW4uanNvbikgb3JcbiAgW3R1cm5dKGh0dHBzOi8vZ2l0aHViLmNvbS9EYW1vbk9laGxtYW4vZnJlZWljZS9ibG9iL21hc3Rlci90dXJuLmpzb24pKVxuICB0aGF0IGlzIHVzZWQgaW4gdGhpcyBtb2R1bGUsIHlvdSBjYW4gZmVlbFxuICBmcmVlIHRvIG9wZW4gYW4gaXNzdWUgb24gdGhpcyByZXBvc2l0b3J5IGFuZCB0aG9zZSBzZXJ2ZXJzIHdpbGwgYmUgcmVtb3ZlZFxuICB3aXRoaW4gMjQgaG91cnMgKG9yIHNvb25lcikuICBUaGlzIGlzIHRoZSBxdWlja2VzdCBhbmQgcHJvYmFibHkgdGhlIG1vc3RcbiAgcG9saXRlIHdheSB0byBoYXZlIHNvbWV0aGluZyByZW1vdmVkIChhbmQgcHJvdmlkZXMgdXMgc29tZSB2aXNpYmlsaXR5XG4gIGlmIHNvbWVvbmUgb3BlbnMgYSBwdWxsIHJlcXVlc3QgcmVxdWVzdGluZyB0aGF0IGEgc2VydmVyIGlzIGFkZGVkKS5cblxuICAjIyBQbGVhc2UgYWRkIG15IHNlcnZlciFcblxuICBJZiB5b3UgaGF2ZSBhIHNlcnZlciB0aGF0IHlvdSB3aXNoIHRvIGFkZCB0byB0aGUgbGlzdCwgdGhhdCdzIGF3ZXNvbWUhIEknbVxuICBzdXJlIEkgc3BlYWsgb24gYmVoYWxmIG9mIGEgd2hvbGUgcGlsZSBvZiBXZWJSVEMgZGV2ZWxvcGVycyB3aG8gc2F5IHRoYW5rcy5cbiAgVG8gZ2V0IGl0IGludG8gdGhlIGxpc3QsIGZlZWwgZnJlZSB0byBlaXRoZXIgb3BlbiBhIHB1bGwgcmVxdWVzdCBvciBpZiB5b3VcbiAgZmluZCB0aGF0IHByb2Nlc3MgYSBiaXQgZGF1bnRpbmcgdGhlbiBqdXN0IGNyZWF0ZSBhbiBpc3N1ZSByZXF1ZXN0aW5nXG4gIHRoZSBhZGRpdGlvbiBvZiB0aGUgc2VydmVyIChtYWtlIHN1cmUgeW91IHByb3ZpZGUgYWxsIHRoZSBkZXRhaWxzLCBhbmQgaWZcbiAgeW91IGhhdmUgYSBUZXJtcyBvZiBTZXJ2aWNlIHRoZW4gaW5jbHVkaW5nIHRoYXQgaW4gdGhlIFBSL2lzc3VlIHdvdWxkIGJlXG4gIGF3ZXNvbWUpLlxuXG4gICMjIEkga25vdyBvZiBhIGZyZWUgc2VydmVyLCBjYW4gSSBhZGQgaXQ/XG5cbiAgU3VyZSwgaWYgeW91IGRvIHlvdXIgaG9tZXdvcmsgYW5kIG1ha2Ugc3VyZSBpdCBpcyBvayB0byB1c2UgKEknbSBjdXJyZW50bHlcbiAgaW4gdGhlIHByb2Nlc3Mgb2YgcmV2aWV3aW5nIHRoZSB0ZXJtcyBvZiB0aG9zZSBTVFVOIHNlcnZlcnMgaW5jbHVkZWQgZnJvbVxuICB0aGUgb3JpZ2luYWwgbGlzdCkuICBJZiBpdCdzIG9rIHRvIGdvLCB0aGVuIHBsZWFzZSBzZWUgdGhlIHByZXZpb3VzIGVudHJ5XG4gIGZvciBob3cgdG8gYWRkIGl0LlxuXG4gICMjIEN1cnJlbnQgTGlzdCBvZiBTZXJ2ZXJzXG5cbiAgKiBjdXJyZW50IGFzIGF0IHRoZSB0aW1lIG9mIGxhc3QgYFJFQURNRS5tZGAgZmlsZSBnZW5lcmF0aW9uXG5cbiAgIyMjIFNUVU5cblxuICA8PDwgc3R1bi5qc29uXG5cbiAgIyMjIFRVUk5cblxuICA8PDwgdHVybi5qc29uXG5cbioqL1xuXG52YXIgZnJlZWljZSA9IGZ1bmN0aW9uKG9wdHMpIHtcbiAgLy8gaWYgYSBsaXN0IG9mIHNlcnZlcnMgaGFzIGJlZW4gcHJvdmlkZWQsIHRoZW4gdXNlIGl0IGluc3RlYWQgb2YgZGVmYXVsdHNcbiAgdmFyIHNlcnZlcnMgPSB7XG4gICAgc3R1bjogKG9wdHMgfHwge30pLnN0dW4gfHwgcmVxdWlyZSgnLi9zdHVuLmpzb24nKSxcbiAgICB0dXJuOiAob3B0cyB8fCB7fSkudHVybiB8fCByZXF1aXJlKCcuL3R1cm4uanNvbicpXG4gIH07XG5cbiAgdmFyIHN0dW5Db3VudCA9IChvcHRzIHx8IHt9KS5zdHVuQ291bnQgfHwgMjtcbiAgdmFyIHR1cm5Db3VudCA9IChvcHRzIHx8IHt9KS50dXJuQ291bnQgfHwgMDtcbiAgdmFyIHNlbGVjdGVkO1xuXG4gIGZ1bmN0aW9uIGdldFNlcnZlcnModHlwZSwgY291bnQpIHtcbiAgICB2YXIgb3V0ID0gW107XG4gICAgdmFyIGlucHV0ID0gW10uY29uY2F0KHNlcnZlcnNbdHlwZV0pO1xuICAgIHZhciBpZHg7XG5cbiAgICB3aGlsZSAoaW5wdXQubGVuZ3RoICYmIG91dC5sZW5ndGggPCBjb3VudCkge1xuICAgICAgaWR4ID0gKE1hdGgucmFuZG9tKCkgKiBpbnB1dC5sZW5ndGgpIHwgMDtcbiAgICAgIG91dCA9IG91dC5jb25jYXQoaW5wdXQuc3BsaWNlKGlkeCwgMSkpO1xuICAgIH1cblxuICAgIHJldHVybiBvdXQubWFwKGZ1bmN0aW9uKHVybCkge1xuICAgICAgICAvL0lmIGl0J3MgYSBub3QgYSBzdHJpbmcsIGRvbid0IHRyeSB0byBcIm5vcm1hbGljZVwiIGl0IG90aGVyd2lzZSB1c2luZyB0eXBlOnVybCB3aWxsIHNjcmV3IGl0IHVwXG4gICAgICAgIGlmICgodHlwZW9mIHVybCAhPT0gJ3N0cmluZycpICYmICghICh1cmwgaW5zdGFuY2VvZiBTdHJpbmcpKSkge1xuICAgICAgICAgICAgcmV0dXJuIHVybDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBub3JtYWxpY2UodHlwZSArICc6JyArIHVybCk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIGFkZCBzdHVuIHNlcnZlcnNcbiAgc2VsZWN0ZWQgPSBbXS5jb25jYXQoZ2V0U2VydmVycygnc3R1bicsIHN0dW5Db3VudCkpO1xuXG4gIGlmICh0dXJuQ291bnQpIHtcbiAgICBzZWxlY3RlZCA9IHNlbGVjdGVkLmNvbmNhdChnZXRTZXJ2ZXJzKCd0dXJuJywgdHVybkNvdW50KSk7XG4gIH1cblxuICByZXR1cm4gc2VsZWN0ZWQ7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZyZWVpY2U7IiwibW9kdWxlLmV4cG9ydHM9W1xuICBcInN0dW4ubC5nb29nbGUuY29tOjE5MzAyXCIsXG4gIFwic3R1bjEubC5nb29nbGUuY29tOjE5MzAyXCIsXG4gIFwic3R1bjIubC5nb29nbGUuY29tOjE5MzAyXCIsXG4gIFwic3R1bjMubC5nb29nbGUuY29tOjE5MzAyXCIsXG4gIFwic3R1bjQubC5nb29nbGUuY29tOjE5MzAyXCIsXG4gIFwic3R1bi5la2lnYS5uZXRcIixcbiAgXCJzdHVuLmlkZWFzaXAuY29tXCIsXG4gIFwic3R1bi5zY2hsdW5kLmRlXCIsXG4gIFwic3R1bi5zdHVucHJvdG9jb2wub3JnOjM0NzhcIixcbiAgXCJzdHVuLnZvaXBhcm91bmQuY29tXCIsXG4gIFwic3R1bi52b2lwYnVzdGVyLmNvbVwiLFxuICBcInN0dW4udm9pcHN0dW50LmNvbVwiLFxuICBcInN0dW4udm94Z3JhdGlhLm9yZ1wiXG5dXG4iLCJtb2R1bGUuZXhwb3J0cz1bXVxuIiwidmFyIFdpbGRFbWl0dGVyID0gcmVxdWlyZSgnd2lsZGVtaXR0ZXInKTtcblxuZnVuY3Rpb24gZ2V0TWF4Vm9sdW1lIChhbmFseXNlciwgZmZ0Qmlucykge1xuICB2YXIgbWF4Vm9sdW1lID0gLUluZmluaXR5O1xuICBhbmFseXNlci5nZXRGbG9hdEZyZXF1ZW5jeURhdGEoZmZ0Qmlucyk7XG5cbiAgZm9yKHZhciBpPTQsIGlpPWZmdEJpbnMubGVuZ3RoOyBpIDwgaWk7IGkrKykge1xuICAgIGlmIChmZnRCaW5zW2ldID4gbWF4Vm9sdW1lICYmIGZmdEJpbnNbaV0gPCAwKSB7XG4gICAgICBtYXhWb2x1bWUgPSBmZnRCaW5zW2ldO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gbWF4Vm9sdW1lO1xufVxuXG5cbnZhciBhdWRpb0NvbnRleHRUeXBlO1xuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG4gIGF1ZGlvQ29udGV4dFR5cGUgPSB3aW5kb3cuQXVkaW9Db250ZXh0IHx8IHdpbmRvdy53ZWJraXRBdWRpb0NvbnRleHQ7XG59XG4vLyB1c2UgYSBzaW5nbGUgYXVkaW8gY29udGV4dCBkdWUgdG8gaGFyZHdhcmUgbGltaXRzXG52YXIgYXVkaW9Db250ZXh0ID0gbnVsbDtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oc3RyZWFtLCBvcHRpb25zKSB7XG4gIHZhciBoYXJrZXIgPSBuZXcgV2lsZEVtaXR0ZXIoKTtcblxuICAvLyBtYWtlIGl0IG5vdCBicmVhayBpbiBub24tc3VwcG9ydGVkIGJyb3dzZXJzXG4gIGlmICghYXVkaW9Db250ZXh0VHlwZSkgcmV0dXJuIGhhcmtlcjtcblxuICAvL0NvbmZpZ1xuICB2YXIgb3B0aW9ucyA9IG9wdGlvbnMgfHwge30sXG4gICAgICBzbW9vdGhpbmcgPSAob3B0aW9ucy5zbW9vdGhpbmcgfHwgMC4xKSxcbiAgICAgIGludGVydmFsID0gKG9wdGlvbnMuaW50ZXJ2YWwgfHwgNTApLFxuICAgICAgdGhyZXNob2xkID0gb3B0aW9ucy50aHJlc2hvbGQsXG4gICAgICBwbGF5ID0gb3B0aW9ucy5wbGF5LFxuICAgICAgaGlzdG9yeSA9IG9wdGlvbnMuaGlzdG9yeSB8fCAxMCxcbiAgICAgIHJ1bm5pbmcgPSB0cnVlO1xuXG4gIC8vIEVuc3VyZSB0aGF0IGp1c3QgYSBzaW5nbGUgQXVkaW9Db250ZXh0IGlzIGludGVybmFsbHkgY3JlYXRlZFxuICBhdWRpb0NvbnRleHQgPSBvcHRpb25zLmF1ZGlvQ29udGV4dCB8fCBhdWRpb0NvbnRleHQgfHwgbmV3IGF1ZGlvQ29udGV4dFR5cGUoKTtcblxuICB2YXIgc291cmNlTm9kZSwgZmZ0QmlucywgYW5hbHlzZXI7XG5cbiAgYW5hbHlzZXIgPSBhdWRpb0NvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgYW5hbHlzZXIuZmZ0U2l6ZSA9IDUxMjtcbiAgYW5hbHlzZXIuc21vb3RoaW5nVGltZUNvbnN0YW50ID0gc21vb3RoaW5nO1xuICBmZnRCaW5zID0gbmV3IEZsb2F0MzJBcnJheShhbmFseXNlci5mcmVxdWVuY3lCaW5Db3VudCk7XG5cbiAgaWYgKHN0cmVhbS5qcXVlcnkpIHN0cmVhbSA9IHN0cmVhbVswXTtcbiAgaWYgKHN0cmVhbSBpbnN0YW5jZW9mIEhUTUxBdWRpb0VsZW1lbnQgfHwgc3RyZWFtIGluc3RhbmNlb2YgSFRNTFZpZGVvRWxlbWVudCkge1xuICAgIC8vQXVkaW8gVGFnXG4gICAgc291cmNlTm9kZSA9IGF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYUVsZW1lbnRTb3VyY2Uoc3RyZWFtKTtcbiAgICBpZiAodHlwZW9mIHBsYXkgPT09ICd1bmRlZmluZWQnKSBwbGF5ID0gdHJ1ZTtcbiAgICB0aHJlc2hvbGQgPSB0aHJlc2hvbGQgfHwgLTUwO1xuICB9IGVsc2Uge1xuICAgIC8vV2ViUlRDIFN0cmVhbVxuICAgIHNvdXJjZU5vZGUgPSBhdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2Uoc3RyZWFtKTtcbiAgICB0aHJlc2hvbGQgPSB0aHJlc2hvbGQgfHwgLTUwO1xuICB9XG5cbiAgc291cmNlTm9kZS5jb25uZWN0KGFuYWx5c2VyKTtcbiAgaWYgKHBsYXkpIGFuYWx5c2VyLmNvbm5lY3QoYXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcblxuICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcblxuICBoYXJrZXIuc3VzcGVuZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQuc3VzcGVuZCgpO1xuICB9XG4gIGhhcmtlci5yZXN1bWUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXVkaW9Db250ZXh0LnJlc3VtZSgpO1xuICB9XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShoYXJrZXIsICdzdGF0ZScsIHsgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXVkaW9Db250ZXh0LnN0YXRlO1xuICB9fSk7XG4gIGF1ZGlvQ29udGV4dC5vbnN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7XG4gICAgaGFya2VyLmVtaXQoJ3N0YXRlX2NoYW5nZScsIGF1ZGlvQ29udGV4dC5zdGF0ZSk7XG4gIH1cblxuICBoYXJrZXIuc2V0VGhyZXNob2xkID0gZnVuY3Rpb24odCkge1xuICAgIHRocmVzaG9sZCA9IHQ7XG4gIH07XG5cbiAgaGFya2VyLnNldEludGVydmFsID0gZnVuY3Rpb24oaSkge1xuICAgIGludGVydmFsID0gaTtcbiAgfTtcblxuICBoYXJrZXIuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgIHJ1bm5pbmcgPSBmYWxzZTtcbiAgICBoYXJrZXIuZW1pdCgndm9sdW1lX2NoYW5nZScsIC0xMDAsIHRocmVzaG9sZCk7XG4gICAgaWYgKGhhcmtlci5zcGVha2luZykge1xuICAgICAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG4gICAgICBoYXJrZXIuZW1pdCgnc3RvcHBlZF9zcGVha2luZycpO1xuICAgIH1cbiAgICBhbmFseXNlci5kaXNjb25uZWN0KCk7XG4gICAgc291cmNlTm9kZS5kaXNjb25uZWN0KCk7XG4gIH07XG4gIGhhcmtlci5zcGVha2luZ0hpc3RvcnkgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBoaXN0b3J5OyBpKyspIHtcbiAgICAgIGhhcmtlci5zcGVha2luZ0hpc3RvcnkucHVzaCgwKTtcbiAgfVxuXG4gIC8vIFBvbGwgdGhlIGFuYWx5c2VyIG5vZGUgdG8gZGV0ZXJtaW5lIGlmIHNwZWFraW5nXG4gIC8vIGFuZCBlbWl0IGV2ZW50cyBpZiBjaGFuZ2VkXG4gIHZhciBsb29wZXIgPSBmdW5jdGlvbigpIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXG4gICAgICAvL2NoZWNrIGlmIHN0b3AgaGFzIGJlZW4gY2FsbGVkXG4gICAgICBpZighcnVubmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBjdXJyZW50Vm9sdW1lID0gZ2V0TWF4Vm9sdW1lKGFuYWx5c2VyLCBmZnRCaW5zKTtcblxuICAgICAgaGFya2VyLmVtaXQoJ3ZvbHVtZV9jaGFuZ2UnLCBjdXJyZW50Vm9sdW1lLCB0aHJlc2hvbGQpO1xuXG4gICAgICB2YXIgaGlzdG9yeSA9IDA7XG4gICAgICBpZiAoY3VycmVudFZvbHVtZSA+IHRocmVzaG9sZCAmJiAhaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICAgIC8vIHRyaWdnZXIgcXVpY2tseSwgc2hvcnQgaGlzdG9yeVxuICAgICAgICBmb3IgKHZhciBpID0gaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGggLSAzOyBpIDwgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGhpc3RvcnkgKz0gaGFya2VyLnNwZWFraW5nSGlzdG9yeVtpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGlzdG9yeSA+PSAyKSB7XG4gICAgICAgICAgaGFya2VyLnNwZWFraW5nID0gdHJ1ZTtcbiAgICAgICAgICBoYXJrZXIuZW1pdCgnc3BlYWtpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChjdXJyZW50Vm9sdW1lIDwgdGhyZXNob2xkICYmIGhhcmtlci5zcGVha2luZykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhhcmtlci5zcGVha2luZ0hpc3RvcnkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBoaXN0b3J5ICs9IGhhcmtlci5zcGVha2luZ0hpc3RvcnlbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhpc3RvcnkgPT0gMCkge1xuICAgICAgICAgIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuICAgICAgICAgIGhhcmtlci5lbWl0KCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGhhcmtlci5zcGVha2luZ0hpc3Rvcnkuc2hpZnQoKTtcbiAgICAgIGhhcmtlci5zcGVha2luZ0hpc3RvcnkucHVzaCgwICsgKGN1cnJlbnRWb2x1bWUgPiB0aHJlc2hvbGQpKTtcblxuICAgICAgbG9vcGVyKCk7XG4gICAgfSwgaW50ZXJ2YWwpO1xuICB9O1xuICBsb29wZXIoKTtcblxuICByZXR1cm4gaGFya2VyO1xufVxuIiwiaWYgKHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gIC8vIGltcGxlbWVudGF0aW9uIGZyb20gc3RhbmRhcmQgbm9kZS5qcyAndXRpbCcgbW9kdWxlXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgaWYgKHN1cGVyQ3Rvcikge1xuICAgICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gb2xkIHNjaG9vbCBzaGltIGZvciBvbGQgYnJvd3NlcnNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgdmFyIFRlbXBDdG9yID0gZnVuY3Rpb24gKCkge31cbiAgICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICAgIGN0b3IucHJvdG90eXBlID0gbmV3IFRlbXBDdG9yKClcbiAgICAgIGN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY3RvclxuICAgIH1cbiAgfVxufVxuIiwiLyogXHJcbiAqIEpTTkxvZyAyLjMwLjBcclxuICogT3BlbiBzb3VyY2UgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLlxyXG4gKiBDb3B5cmlnaHQgMjAxMi0yMDE3IE1hdHRpanMgUGVyZGVjayBBbGwgcmlnaHRzIHJlc2VydmVkLlxyXG4gKi9cclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuZnVuY3Rpb24gSkwobG9nZ2VyTmFtZSkge1xyXG4gICAgLy8gSWYgbmFtZSBpcyBlbXB0eSwgcmV0dXJuIHRoZSByb290IGxvZ2dlclxyXG4gICAgaWYgKCFsb2dnZXJOYW1lKSB7XHJcbiAgICAgICAgcmV0dXJuIEpMLl9fO1xyXG4gICAgfVxyXG4gICAgLy8gSW1wbGVtZW50cyBBcnJheS5yZWR1Y2UuIEpTTkxvZyBzdXBwb3J0cyBJRTgrIGFuZCByZWR1Y2UgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGF0IGJyb3dzZXIuXHJcbiAgICAvLyBTYW1lIGludGVyZmFjZSBhcyB0aGUgc3RhbmRhcmQgcmVkdWNlLCBleGNlcHQgdGhhdCBcclxuICAgIGlmICghQXJyYXkucHJvdG90eXBlLnJlZHVjZSkge1xyXG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5yZWR1Y2UgPSBmdW5jdGlvbiAoY2FsbGJhY2ssIGluaXRpYWxWYWx1ZSkge1xyXG4gICAgICAgICAgICB2YXIgcHJldmlvdXNWYWx1ZSA9IGluaXRpYWxWYWx1ZTtcclxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBwcmV2aW91c1ZhbHVlID0gY2FsbGJhY2socHJldmlvdXNWYWx1ZSwgdGhpc1tpXSwgaSwgdGhpcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHByZXZpb3VzVmFsdWU7XHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIHZhciBhY2N1bXVsYXRlZExvZ2dlck5hbWUgPSAnJztcclxuICAgIHZhciBsb2dnZXIgPSAoJy4nICsgbG9nZ2VyTmFtZSkuc3BsaXQoJy4nKS5yZWR1Y2UoZnVuY3Rpb24gKHByZXYsIGN1cnIsIGlkeCwgYXJyKSB7XHJcbiAgICAgICAgLy8gaWYgbG9nZ2VybmFtZSBpcyBhLmIuYywgdGhhbiBjdXJyZW50TG9nZ2VyIHdpbGwgYmUgc2V0IHRvIHRoZSBsb2dnZXJzXHJcbiAgICAgICAgLy8gcm9vdCAgIChwcmV2OiBKTCwgY3VycjogJycpXHJcbiAgICAgICAgLy8gYSAgICAgIChwcmV2OiBKTC5fXywgY3VycjogJ2EnKVxyXG4gICAgICAgIC8vIGEuYiAgICAocHJldjogSkwuX18uX19hLCBjdXJyOiAnYicpXHJcbiAgICAgICAgLy8gYS5iLmMgIChwcmV2OiBKTC5fXy5fX2EuX19hLmIsIGN1cnI6ICdjJylcclxuICAgICAgICAvLyBOb3RlIHRoYXQgd2hlbiBhIG5ldyBsb2dnZXIgbmFtZSBpcyBlbmNvdW50ZXJlZCAoc3VjaCBhcyAnYS5iLmMnKSxcclxuICAgICAgICAvLyBhIG5ldyBsb2dnZXIgb2JqZWN0IGlzIGNyZWF0ZWQgYW5kIGFkZGVkIGFzIGEgcHJvcGVydHkgdG8gdGhlIHBhcmVudCAoJ2EuYicpLlxyXG4gICAgICAgIC8vIFRoZSByb290IGxvZ2dlciBpcyBhZGRlZCBhcyBhIHByb3BlcnR5IG9mIHRoZSBKTCBvYmplY3QgaXRzZWxmLlxyXG4gICAgICAgIC8vIEl0IGlzIGVzc2VudGlhbCB0aGF0IHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSBjb250YWluaW5nIHRoZSBjaGlsZCBsb2dnZXJcclxuICAgICAgICAvLyBjb250YWlucyB0aGUgZnVsbCAncGF0aCcgbmFtZSBvZiB0aGUgY2hpbGQgbG9nZ2VyICgnYS5iLmMnKSBpbnN0ZWFkIG9mXHJcbiAgICAgICAgLy8ganVzdCB0aGUgYml0IGFmdGVyIHRoZSBsYXN0IHBlcmlvZCAoJ2MnKS5cclxuICAgICAgICAvLyBUaGlzIGlzIGJlY2F1c2UgdGhlIHBhcmVudCBpbmhlcml0cyBwcm9wZXJ0aWVzIGZyb20gaXRzIGFuY2VzdG9ycy5cclxuICAgICAgICAvLyBTbyBpZiB0aGUgcm9vdCBoYXMgYSBjaGlsZCBsb2dnZXIgJ2MnIChzdG9yZWQgaW4gYSBwcm9wZXJ0eSAnYycgb2YgdGhlIHJvb3QgbG9nZ2VyKSxcclxuICAgICAgICAvLyB0aGVuIGxvZ2dlciAnYS5iJyBoYXMgdGhhdCBzYW1lIHByb3BlcnR5ICdjJyB0aHJvdWdoIGluaGVyaXRhbmNlLlxyXG4gICAgICAgIC8vIFRoZSBuYW1lcyBvZiB0aGUgbG9nZ2VyIHByb3BlcnRpZXMgc3RhcnQgd2l0aCBfXywgc28gdGhlIHJvb3QgbG9nZ2VyIFxyXG4gICAgICAgIC8vICh3aGljaCBoYXMgbmFtZSAnJyksIGhhcyBhIG5pY2UgcHJvcGVydHkgbmFtZSAnX18nLiAgICAgICAgICAgICAgXHJcbiAgICAgICAgLy8gYWNjdW11bGF0ZWRMb2dnZXJOYW1lIGV2YWx1YXRlcyBmYWxzZSAoJycgaXMgZmFsc3kpIGluIGZpcnN0IGl0ZXJhdGlvbiB3aGVuIHByZXYgaXMgdGhlIHJvb3QgbG9nZ2VyLlxyXG4gICAgICAgIC8vIGFjY3VtdWxhdGVkTG9nZ2VyTmFtZSB3aWxsIGJlIHRoZSBsb2dnZXIgbmFtZSBjb3JyZXNwb25kaW5nIHdpdGggdGhlIGxvZ2dlciBpbiBjdXJyZW50TG9nZ2VyLlxyXG4gICAgICAgIC8vIEtlZXAgaW4gbWluZCB0aGF0IHRoZSBjdXJyZW50TG9nZ2VyIG1heSBub3QgYmUgZGVmaW5lZCB5ZXQsIHNvIGNhbid0IGdldCB0aGUgbmFtZSBmcm9tXHJcbiAgICAgICAgLy8gdGhlIGN1cnJlbnRMb2dnZXIgb2JqZWN0IGl0c2VsZi4gXHJcbiAgICAgICAgaWYgKGFjY3VtdWxhdGVkTG9nZ2VyTmFtZSkge1xyXG4gICAgICAgICAgICBhY2N1bXVsYXRlZExvZ2dlck5hbWUgKz0gJy4nICsgY3VycjtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGFjY3VtdWxhdGVkTG9nZ2VyTmFtZSA9IGN1cnI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBjdXJyZW50TG9nZ2VyID0gcHJldlsnX18nICsgYWNjdW11bGF0ZWRMb2dnZXJOYW1lXTtcclxuICAgICAgICAvLyBJZiB0aGUgY3VycmVudExvZ2dlciAob3IgdGhlIGFjdHVhbCBsb2dnZXIgYmVpbmcgc291Z2h0KSBkb2VzIG5vdCB5ZXQgZXhpc3QsIFxyXG4gICAgICAgIC8vIGNyZWF0ZSBpdCBub3cuXHJcbiAgICAgICAgaWYgKGN1cnJlbnRMb2dnZXIgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAvLyBTZXQgdGhlIHByb3RvdHlwZSBvZiB0aGUgTG9nZ2VyIGNvbnN0cnVjdG9yIGZ1bmN0aW9uIHRvIHRoZSBwYXJlbnQgb2YgdGhlIGxvZ2dlclxyXG4gICAgICAgICAgICAvLyB0byBiZSBjcmVhdGVkLiBUaGlzIHdheSwgX19wcm90byBvZiB0aGUgbmV3IGxvZ2dlciBvYmplY3Qgd2lsbCBwb2ludCBhdCB0aGUgcGFyZW50LlxyXG4gICAgICAgICAgICAvLyBXaGVuIGxvZ2dlci5sZXZlbCBpcyBldmFsdWF0ZWQgYW5kIGlzIG5vdCBwcmVzZW50LCB0aGUgSmF2YVNjcmlwdCBydW50aW1lIHdpbGwgXHJcbiAgICAgICAgICAgIC8vIHdhbGsgZG93biB0aGUgcHJvdG90eXBlIGNoYWluIHRvIGZpbmQgdGhlIGZpcnN0IGFuY2VzdG9yIHdpdGggYSBsZXZlbCBwcm9wZXJ0eS5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gTm90ZSB0aGF0IHByZXYgYXQgdGhpcyBwb2ludCByZWZlcnMgdG8gdGhlIHBhcmVudCBsb2dnZXIuXHJcbiAgICAgICAgICAgIEpMLkxvZ2dlci5wcm90b3R5cGUgPSBwcmV2O1xyXG4gICAgICAgICAgICBjdXJyZW50TG9nZ2VyID0gbmV3IEpMLkxvZ2dlcihhY2N1bXVsYXRlZExvZ2dlck5hbWUpO1xyXG4gICAgICAgICAgICBwcmV2WydfXycgKyBhY2N1bXVsYXRlZExvZ2dlck5hbWVdID0gY3VycmVudExvZ2dlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGN1cnJlbnRMb2dnZXI7XHJcbiAgICB9LCBKTC5fXyk7XHJcbiAgICByZXR1cm4gbG9nZ2VyO1xyXG59XHJcbihmdW5jdGlvbiAoSkwpIHtcclxuICAgIC8vIEluaXRpYWxpc2UgcmVxdWVzdElkIHRvIGVtcHR5IHN0cmluZy4gSWYgeW91IGRvbid0IGRvIHRoaXMgYW5kIHRoZSB1c2VyXHJcbiAgICAvLyBkb2VzIG5vdCBzZXQgaXQgdmlhIHNldE9wdGlvbnMsIHRoZW4gdGhlIEpTTkxvZy1SZXF1ZXN0SWQgaGVhZGVyIHdpbGxcclxuICAgIC8vIGhhdmUgdmFsdWUgXCJ1bmRlZmluZWRcIiwgd2hpY2ggZG9lc24ndCBsb29rIGdvb2QgaW4gYSBsb2cuXHJcbiAgICAvL1xyXG4gICAgLy8gTm90ZSB0aGF0IHlvdSBhbHdheXMgd2FudCB0byBzZW5kIGEgcmVxdWVzdElkIGFzIHBhcnQgb2YgbG9nIHJlcXVlc3RzLFxyXG4gICAgLy8gb3RoZXJ3aXNlIHRoZSBzZXJ2ZXIgc2lkZSBjb21wb25lbnQgZG9lc24ndCBrbm93IHRoaXMgaXMgYSBsb2cgcmVxdWVzdFxyXG4gICAgLy8gYW5kIG1heSBjcmVhdGUgYSBuZXcgcmVxdWVzdCBpZCBmb3IgdGhlIGxvZyByZXF1ZXN0LCBjYXVzaW5nIGNvbmZ1c2lvblxyXG4gICAgLy8gaW4gdGhlIGxvZy5cclxuICAgIEpMLnJlcXVlc3RJZCA9ICcnO1xyXG4gICAgLy8gTnVtYmVyIHVuaXF1ZWx5IGlkZW50aWZ5aW5nIGV2ZXJ5IGxvZyBlbnRyeSB3aXRoaW4gdGhlIHJlcXVlc3QuXHJcbiAgICBKTC5lbnRyeUlkID0gMDtcclxuICAgIC8vIEFsbG93IHByb3BlcnR5IGluamVjdGlvbiBvZiB0aGVzZSBjbGFzc2VzLCB0byBlbmFibGUgdW5pdCB0ZXN0aW5nXHJcbiAgICBKTC5fY3JlYXRlWE1MSHR0cFJlcXVlc3QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3QoKTsgfTtcclxuICAgIEpMLl9nZXRUaW1lID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gKG5ldyBEYXRlKS5nZXRUaW1lKCk7IH07XHJcbiAgICBKTC5fY29uc29sZSA9IGNvbnNvbGU7XHJcbiAgICAvLyAtLS0tLSBwcml2YXRlIHZhcmlhYmxlc1xyXG4gICAgSkwuX2FwcGVuZGVyTmFtZXMgPSBbXTtcclxuICAgIC8qKlxyXG4gICAgQ29waWVzIHRoZSB2YWx1ZSBvZiBhIHByb3BlcnR5IGZyb20gb25lIG9iamVjdCB0byB0aGUgb3RoZXIuXHJcbiAgICBUaGlzIGlzIHVzZWQgdG8gY29weSBwcm9wZXJ0eSB2YWx1ZXMgYXMgcGFydCBvZiBzZXRPcHRpb24gZm9yIGxvZ2dlcnMgYW5kIGFwcGVuZGVycy5cclxuXHJcbiAgICBCZWNhdXNlIGxvZ2dlcnMgaW5oZXJpdCBwcm9wZXJ0eSB2YWx1ZXMgZnJvbSB0aGVpciBwYXJlbnRzLCBpdCBpcyBpbXBvcnRhbnQgbmV2ZXIgdG9cclxuICAgIGNyZWF0ZSBhIHByb3BlcnR5IG9uIGEgbG9nZ2VyIGlmIHRoZSBpbnRlbnQgaXMgdG8gaW5oZXJpdCBmcm9tIHRoZSBwYXJlbnQuXHJcblxyXG4gICAgQ29weWluZyBydWxlczpcclxuICAgIDEpIGlmIHRoZSBmcm9tIHByb3BlcnR5IGlzIHVuZGVmaW5lZCAoZm9yIGV4YW1wbGUsIG5vdCBtZW50aW9uZWQgaW4gYSBKU09OIG9iamVjdCksIHRoZVxyXG4gICAgICAgdG8gcHJvcGVydHkgaXMgbm90IGFmZmVjdGVkIGF0IGFsbC5cclxuICAgIDIpIGlmIHRoZSBmcm9tIHByb3BlcnR5IGlzIG51bGwsIHRoZSB0byBwcm9wZXJ0eSBpcyBkZWxldGVkIChzbyB0aGUgbG9nZ2VyIHdpbGwgaW5oZXJpdCBmcm9tXHJcbiAgICAgICBpdHMgcGFyZW50KS5cclxuICAgIDMpIE90aGVyd2lzZSwgdGhlIGZyb20gcHJvcGVydHkgaXMgY29waWVkIHRvIHRoZSB0byBwcm9wZXJ0eS5cclxuICAgICovXHJcbiAgICBmdW5jdGlvbiBjb3B5UHJvcGVydHkocHJvcGVydHlOYW1lLCBmcm9tLCB0bykge1xyXG4gICAgICAgIGlmIChmcm9tW3Byb3BlcnR5TmFtZV0gPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChmcm9tW3Byb3BlcnR5TmFtZV0gPT09IG51bGwpIHtcclxuICAgICAgICAgICAgZGVsZXRlIHRvW3Byb3BlcnR5TmFtZV07XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdG9bcHJvcGVydHlOYW1lXSA9IGZyb21bcHJvcGVydHlOYW1lXTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgUmV0dXJucyB0cnVlIGlmIGEgbG9nIHNob3VsZCBnbyBhaGVhZC5cclxuICAgIERvZXMgbm90IGNoZWNrIGxldmVsLlxyXG5cclxuICAgIEBwYXJhbSBmaWx0ZXJzXHJcbiAgICAgICAgRmlsdGVycyB0aGF0IGRldGVybWluZSB3aGV0aGVyIGEgbG9nIGNhbiBnbyBhaGVhZC5cclxuICAgICovXHJcbiAgICBmdW5jdGlvbiBhbGxvdyhmaWx0ZXJzKSB7XHJcbiAgICAgICAgLy8gSWYgZW5hYmxlZCBpcyBub3QgbnVsbCBvciB1bmRlZmluZWQsIHRoZW4gaWYgaXQgaXMgZmFsc2UsIHRoZW4gcmV0dXJuIGZhbHNlXHJcbiAgICAgICAgLy8gTm90ZSB0aGF0IHVuZGVmaW5lZD09bnVsbCAoISlcclxuICAgICAgICBpZiAoIShKTC5lbmFibGVkID09IG51bGwpKSB7XHJcbiAgICAgICAgICAgIGlmICghSkwuZW5hYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIElmIHRoZSByZWdleCBjb250YWlucyBhIGJ1ZywgdGhhdCB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbi5cclxuICAgICAgICAvLyBJZ25vcmUgdGhpcywgYW5kIHBhc3MgdGhlIGxvZyBpdGVtIChiZXR0ZXIgdG9vIG11Y2ggdGhhbiB0b28gbGl0dGxlKS5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZmlsdGVycy51c2VyQWdlbnRSZWdleCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFuZXcgUmVnRXhwKGZpbHRlcnMudXNlckFnZW50UmVnZXgpLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHsgfVxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmaWx0ZXJzLmlwUmVnZXggJiYgSkwuY2xpZW50SVApIHtcclxuICAgICAgICAgICAgICAgIGlmICghbmV3IFJlZ0V4cChmaWx0ZXJzLmlwUmVnZXgpLnRlc3QoSkwuY2xpZW50SVApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7IH1cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgUmV0dXJucyB0cnVlIGlmIGEgbG9nIHNob3VsZCBnbyBhaGVhZCwgYmFzZWQgb24gdGhlIG1lc3NhZ2UuXHJcblxyXG4gICAgQHBhcmFtIGZpbHRlcnNcclxuICAgICAgICBGaWx0ZXJzIHRoYXQgZGV0ZXJtaW5lIHdoZXRoZXIgYSBsb2cgY2FuIGdvIGFoZWFkLlxyXG5cclxuICAgIEBwYXJhbSBtZXNzYWdlXHJcbiAgICAgICAgTWVzc2FnZSB0byBiZSBsb2dnZWQuXHJcbiAgICAqL1xyXG4gICAgZnVuY3Rpb24gYWxsb3dNZXNzYWdlKGZpbHRlcnMsIG1lc3NhZ2UpIHtcclxuICAgICAgICAvLyBJZiB0aGUgcmVnZXggY29udGFpbnMgYSBidWcsIHRoYXQgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24uXHJcbiAgICAgICAgLy8gSWdub3JlIHRoaXMsIGFuZCBwYXNzIHRoZSBsb2cgaXRlbSAoYmV0dGVyIHRvbyBtdWNoIHRoYW4gdG9vIGxpdHRsZSkuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGZpbHRlcnMuZGlzYWxsb3cpIHtcclxuICAgICAgICAgICAgICAgIGlmIChuZXcgUmVnRXhwKGZpbHRlcnMuZGlzYWxsb3cpLnRlc3QobWVzc2FnZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHsgfVxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgLy8gSWYgbG9nT2JqZWN0IGlzIGEgZnVuY3Rpb24sIHRoZSBmdW5jdGlvbiBpcyBldmFsdWF0ZWQgKHdpdGhvdXQgcGFyYW1ldGVycylcclxuICAgIC8vIGFuZCB0aGUgcmVzdWx0IHJldHVybmVkLlxyXG4gICAgLy8gT3RoZXJ3aXNlLCBsb2dPYmplY3QgaXRzZWxmIGlzIHJldHVybmVkLlxyXG4gICAgZnVuY3Rpb24gc3RyaW5naWZ5TG9nT2JqZWN0RnVuY3Rpb24obG9nT2JqZWN0KSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBsb2dPYmplY3QgPT0gXCJmdW5jdGlvblwiKSB7XHJcbiAgICAgICAgICAgIGlmIChsb2dPYmplY3QgaW5zdGFuY2VvZiBSZWdFeHApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBsb2dPYmplY3QudG9TdHJpbmcoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBsb2dPYmplY3QoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbG9nT2JqZWN0O1xyXG4gICAgfVxyXG4gICAgdmFyIFN0cmluZ2lmaWVkTG9nT2JqZWN0ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vICogbXNnIC0gXHJcbiAgICAgICAgLy8gICAgICBpZiB0aGUgbG9nT2JqZWN0IGlzIGEgc2NhbGFyIChhZnRlciBwb3NzaWJsZSBmdW5jdGlvbiBldmFsdWF0aW9uKSwgdGhpcyBpcyBzZXQgdG9cclxuICAgICAgICAvLyAgICAgIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIHNjYWxhci4gT3RoZXJ3aXNlIGl0IGlzIGxlZnQgdW5kZWZpbmVkLlxyXG4gICAgICAgIC8vICogbWV0YSAtXHJcbiAgICAgICAgLy8gICAgICBpZiB0aGUgbG9nT2JqZWN0IGlzIGFuIG9iamVjdCAoYWZ0ZXIgcG9zc2libGUgZnVuY3Rpb24gZXZhbHVhdGlvbiksIHRoaXMgaXMgc2V0IHRvXHJcbiAgICAgICAgLy8gICAgICB0aGF0IG9iamVjdC4gT3RoZXJ3aXNlIGl0IGlzIGxlZnQgdW5kZWZpbmVkLlxyXG4gICAgICAgIC8vICogZmluYWxTdHJpbmcgLVxyXG4gICAgICAgIC8vICAgICAgVGhpcyBpcyBzZXQgdG8gdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBsb2dPYmplY3QgKGFmdGVyIHBvc3NpYmxlIGZ1bmN0aW9uIGV2YWx1YXRpb24pLFxyXG4gICAgICAgIC8vICAgICAgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIGl0IGlzIGFuIHNjYWxhciBvciBhbiBvYmplY3QuIEFuIG9iamVjdCBpcyBzdHJpbmdpZmllZCB0byBhIEpTT04gc3RyaW5nLlxyXG4gICAgICAgIC8vICAgICAgTm90ZSB0aGF0IHlvdSBjYW4ndCBjYWxsIHRoaXMgZmllbGQgXCJmaW5hbFwiLCBiZWNhdXNlIGFzIHNvbWUgcG9pbnQgdGhpcyB3YXMgYSByZXNlcnZlZFxyXG4gICAgICAgIC8vICAgICAgSmF2YVNjcmlwdCBrZXl3b3JkIGFuZCB1c2luZyBmaW5hbCB0cmlwcyB1cCBzb21lIG1pbmlmaWVycy5cclxuICAgICAgICBmdW5jdGlvbiBTdHJpbmdpZmllZExvZ09iamVjdChtc2csIG1ldGEsIGZpbmFsU3RyaW5nKSB7XHJcbiAgICAgICAgICAgIHRoaXMubXNnID0gbXNnO1xyXG4gICAgICAgICAgICB0aGlzLm1ldGEgPSBtZXRhO1xyXG4gICAgICAgICAgICB0aGlzLmZpbmFsU3RyaW5nID0gZmluYWxTdHJpbmc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBTdHJpbmdpZmllZExvZ09iamVjdDtcclxuICAgIH0oKSk7XHJcbiAgICAvLyBUYWtlcyBhIGxvZ09iamVjdCwgd2hpY2ggY2FuIGJlIFxyXG4gICAgLy8gKiBhIHNjYWxhclxyXG4gICAgLy8gKiBhbiBvYmplY3RcclxuICAgIC8vICogYSBwYXJhbWV0ZXJsZXNzIGZ1bmN0aW9uLCB3aGljaCByZXR1cm5zIHRoZSBzY2FsYXIgb3Igb2JqZWN0IHRvIGxvZy5cclxuICAgIC8vIFJldHVybnMgYSBzdHJpbmdpZmllZExvZ09iamVjdFxyXG4gICAgZnVuY3Rpb24gc3RyaW5naWZ5TG9nT2JqZWN0KGxvZ09iamVjdCkge1xyXG4gICAgICAgIC8vIE5vdGUgdGhhdCB0aGlzIHdvcmtzIGlmIGxvZ09iamVjdCBpcyBudWxsLlxyXG4gICAgICAgIC8vIHR5cGVvZiBudWxsIGlzIG9iamVjdC5cclxuICAgICAgICAvLyBKU09OLnN0cmluZ2lmeShudWxsKSByZXR1cm5zIFwibnVsbFwiLlxyXG4gICAgICAgIHZhciBhY3R1YWxMb2dPYmplY3QgPSBzdHJpbmdpZnlMb2dPYmplY3RGdW5jdGlvbihsb2dPYmplY3QpO1xyXG4gICAgICAgIHZhciBmaW5hbFN0cmluZztcclxuICAgICAgICAvLyBOb3RlIHRoYXQgdHlwZW9mIGFjdHVhbExvZ09iamVjdCBzaG91bGQgbm90IGJlIFwiZnVuY3Rpb25cIiwgYmVjYXVzZSB0aGF0IGhhcyBcclxuICAgICAgICAvLyBiZWVuIHJlc29sdmVkIHdpdGggc3RyaW5naWZ5TG9nT2JqZWN0RnVuY3Rpb24uXHJcbiAgICAgICAgc3dpdGNoICh0eXBlb2YgYWN0dWFsTG9nT2JqZWN0KSB7XHJcbiAgICAgICAgICAgIGNhc2UgXCJzdHJpbmdcIjpcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5naWZpZWRMb2dPYmplY3QoYWN0dWFsTG9nT2JqZWN0LCBudWxsLCBhY3R1YWxMb2dPYmplY3QpO1xyXG4gICAgICAgICAgICBjYXNlIFwibnVtYmVyXCI6XHJcbiAgICAgICAgICAgICAgICBmaW5hbFN0cmluZyA9IGFjdHVhbExvZ09iamVjdC50b1N0cmluZygpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdpZmllZExvZ09iamVjdChmaW5hbFN0cmluZywgbnVsbCwgZmluYWxTdHJpbmcpO1xyXG4gICAgICAgICAgICBjYXNlIFwiYm9vbGVhblwiOlxyXG4gICAgICAgICAgICAgICAgZmluYWxTdHJpbmcgPSBhY3R1YWxMb2dPYmplY3QudG9TdHJpbmcoKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5naWZpZWRMb2dPYmplY3QoZmluYWxTdHJpbmcsIG51bGwsIGZpbmFsU3RyaW5nKTtcclxuICAgICAgICAgICAgY2FzZSBcInVuZGVmaW5lZFwiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdpZmllZExvZ09iamVjdChcInVuZGVmaW5lZFwiLCBudWxsLCBcInVuZGVmaW5lZFwiKTtcclxuICAgICAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxyXG4gICAgICAgICAgICAgICAgaWYgKChhY3R1YWxMb2dPYmplY3QgaW5zdGFuY2VvZiBSZWdFeHApIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgKGFjdHVhbExvZ09iamVjdCBpbnN0YW5jZW9mIFN0cmluZykgfHxcclxuICAgICAgICAgICAgICAgICAgICAoYWN0dWFsTG9nT2JqZWN0IGluc3RhbmNlb2YgTnVtYmVyKSB8fFxyXG4gICAgICAgICAgICAgICAgICAgIChhY3R1YWxMb2dPYmplY3QgaW5zdGFuY2VvZiBCb29sZWFuKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbmFsU3RyaW5nID0gYWN0dWFsTG9nT2JqZWN0LnRvU3RyaW5nKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdpZmllZExvZ09iamVjdChmaW5hbFN0cmluZywgbnVsbCwgZmluYWxTdHJpbmcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBKTC5zZXJpYWxpemUgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxTdHJpbmcgPSBKTC5zZXJpYWxpemUuY2FsbCh0aGlzLCBhY3R1YWxMb2dPYmplY3QpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxTdHJpbmcgPSBKU09OLnN0cmluZ2lmeShhY3R1YWxMb2dPYmplY3QpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIG1zZyBmaWVsZCB0byBcIlwiIGluc3RlYWQgb2YgbnVsbC4gU29tZSBXaW5zdG9uIHRyYW5zcG9ydHNcclxuICAgICAgICAgICAgICAgICAgICAvLyBhc3N1bWUgdGhhdCB0aGUgbXNnIGZpZWxkIGlzIG5vdCBudWxsLlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5naWZpZWRMb2dPYmplY3QoXCJcIiwgYWN0dWFsTG9nT2JqZWN0LCBmaW5hbFN0cmluZyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZ2lmaWVkTG9nT2JqZWN0KFwidW5rbm93blwiLCBudWxsLCBcInVua25vd25cIik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gc2V0T3B0aW9ucyhvcHRpb25zKSB7XHJcbiAgICAgICAgY29weVByb3BlcnR5KFwiZW5hYmxlZFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICBjb3B5UHJvcGVydHkoXCJtYXhNZXNzYWdlc1wiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICBjb3B5UHJvcGVydHkoXCJkZWZhdWx0QWpheFVybFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICBjb3B5UHJvcGVydHkoXCJjbGllbnRJUFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICBjb3B5UHJvcGVydHkoXCJyZXF1ZXN0SWRcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgY29weVByb3BlcnR5KFwiZGVmYXVsdEJlZm9yZVNlbmRcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgY29weVByb3BlcnR5KFwic2VyaWFsaXplXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfVxyXG4gICAgSkwuc2V0T3B0aW9ucyA9IHNldE9wdGlvbnM7XHJcbiAgICBmdW5jdGlvbiBnZXRBbGxMZXZlbCgpIHsgcmV0dXJuIC0yMTQ3NDgzNjQ4OyB9XHJcbiAgICBKTC5nZXRBbGxMZXZlbCA9IGdldEFsbExldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0VHJhY2VMZXZlbCgpIHsgcmV0dXJuIDEwMDA7IH1cclxuICAgIEpMLmdldFRyYWNlTGV2ZWwgPSBnZXRUcmFjZUxldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0RGVidWdMZXZlbCgpIHsgcmV0dXJuIDIwMDA7IH1cclxuICAgIEpMLmdldERlYnVnTGV2ZWwgPSBnZXREZWJ1Z0xldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0SW5mb0xldmVsKCkgeyByZXR1cm4gMzAwMDsgfVxyXG4gICAgSkwuZ2V0SW5mb0xldmVsID0gZ2V0SW5mb0xldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0V2FybkxldmVsKCkgeyByZXR1cm4gNDAwMDsgfVxyXG4gICAgSkwuZ2V0V2FybkxldmVsID0gZ2V0V2FybkxldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0RXJyb3JMZXZlbCgpIHsgcmV0dXJuIDUwMDA7IH1cclxuICAgIEpMLmdldEVycm9yTGV2ZWwgPSBnZXRFcnJvckxldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0RmF0YWxMZXZlbCgpIHsgcmV0dXJuIDYwMDA7IH1cclxuICAgIEpMLmdldEZhdGFsTGV2ZWwgPSBnZXRGYXRhbExldmVsO1xyXG4gICAgZnVuY3Rpb24gZ2V0T2ZmTGV2ZWwoKSB7IHJldHVybiAyMTQ3NDgzNjQ3OyB9XHJcbiAgICBKTC5nZXRPZmZMZXZlbCA9IGdldE9mZkxldmVsO1xyXG4gICAgZnVuY3Rpb24gbGV2ZWxUb1N0cmluZyhsZXZlbCkge1xyXG4gICAgICAgIGlmIChsZXZlbCA8PSAxMDAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcInRyYWNlXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChsZXZlbCA8PSAyMDAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcImRlYnVnXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChsZXZlbCA8PSAzMDAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcImluZm9cIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGxldmVsIDw9IDQwMDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIFwid2FyblwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAobGV2ZWwgPD0gNTAwMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gXCJlcnJvclwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gXCJmYXRhbFwiO1xyXG4gICAgfVxyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICB2YXIgRXhjZXB0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIGRhdGEgcmVwbGFjZXMgbWVzc2FnZS4gSXQgdGFrZXMgbm90IGp1c3Qgc3RyaW5ncywgYnV0IGFsc28gb2JqZWN0cyBhbmQgZnVuY3Rpb25zLCBqdXN0IGxpa2UgdGhlIGxvZyBmdW5jdGlvbi5cclxuICAgICAgICAvLyBpbnRlcm5hbGx5LCB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGlzIHN0b3JlZCBpbiB0aGUgbWVzc2FnZSBwcm9wZXJ0eSAoaW5oZXJpdGVkIGZyb20gRXJyb3IpXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBpbm5lcjogaW5uZXIgZXhjZXB0aW9uLiBDYW4gYmUgbnVsbCBvciB1bmRlZmluZWQuIFxyXG4gICAgICAgIGZ1bmN0aW9uIEV4Y2VwdGlvbihkYXRhLCBpbm5lcikge1xyXG4gICAgICAgICAgICB0aGlzLmlubmVyID0gaW5uZXI7XHJcbiAgICAgICAgICAgIHRoaXMubmFtZSA9IFwiSkwuRXhjZXB0aW9uXCI7XHJcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZSA9IHN0cmluZ2lmeUxvZ09iamVjdChkYXRhKS5maW5hbFN0cmluZztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIEV4Y2VwdGlvbjtcclxuICAgIH0oKSk7XHJcbiAgICBKTC5FeGNlcHRpb24gPSBFeGNlcHRpb247XHJcbiAgICAvLyBEZXJpdmUgRXhjZXB0aW9uIGZyb20gRXJyb3IgKGEgSG9zdCBvYmplY3QpLCBzbyBicm93c2Vyc1xyXG4gICAgLy8gYXJlIG1vcmUgbGlrZWx5IHRvIHByb2R1Y2UgYSBzdGFjayB0cmFjZSBmb3IgaXQgaW4gdGhlaXIgY29uc29sZS5cclxuICAgIC8vXHJcbiAgICAvLyBOb3RlIHRoYXQgaW5zdGFuY2VvZiBhZ2FpbnN0IGFuIG9iamVjdCBjcmVhdGVkIHdpdGggdGhpcyBjb25zdHJ1Y3RvclxyXG4gICAgLy8gd2lsbCByZXR1cm4gdHJ1ZSBpbiB0aGVzZSBjYXNlczpcclxuICAgIC8vIDxvYmplY3Q+IGluc3RhbmNlb2YgSkwuRXhjZXB0aW9uKTtcclxuICAgIC8vIDxvYmplY3Q+IGluc3RhbmNlb2YgRXJyb3IpO1xyXG4gICAgRXhjZXB0aW9uLnByb3RvdHlwZSA9IG5ldyBFcnJvcigpO1xyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICB2YXIgTG9nSXRlbSA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBsOiBsZXZlbFxyXG4gICAgICAgIC8vIG06IG1lc3NhZ2VcclxuICAgICAgICAvLyBuOiBsb2dnZXIgbmFtZVxyXG4gICAgICAgIC8vIHQgKHRpbWVTdGFtcCkgaXMgbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBzaW5jZSAxIEphbnVhcnkgMTk3MCAwMDowMDowMCBVVENcclxuICAgICAgICAvLyB1OiBudW1iZXIgdW5pcXVlbHkgaWRlbnRpZnlpbmcgdGhpcyBlbnRyeSBmb3IgdGhpcyByZXF1ZXN0LlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gS2VlcGluZyB0aGUgcHJvcGVydHkgbmFtZXMgcmVhbGx5IHNob3J0LCBiZWNhdXNlIHRoZXkgd2lsbCBiZSBzZW50IGluIHRoZVxyXG4gICAgICAgIC8vIEpTT04gcGF5bG9hZCB0byB0aGUgc2VydmVyLlxyXG4gICAgICAgIGZ1bmN0aW9uIExvZ0l0ZW0obCwgbSwgbiwgdCwgdSkge1xyXG4gICAgICAgICAgICB0aGlzLmwgPSBsO1xyXG4gICAgICAgICAgICB0aGlzLm0gPSBtO1xyXG4gICAgICAgICAgICB0aGlzLm4gPSBuO1xyXG4gICAgICAgICAgICB0aGlzLnQgPSB0O1xyXG4gICAgICAgICAgICB0aGlzLnUgPSB1O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gTG9nSXRlbTtcclxuICAgIH0oKSk7XHJcbiAgICBKTC5Mb2dJdGVtID0gTG9nSXRlbTtcclxuICAgIGZ1bmN0aW9uIG5ld0xvZ0l0ZW0obGV2ZWxOYnIsIG1lc3NhZ2UsIGxvZ2dlck5hbWUpIHtcclxuICAgICAgICBKTC5lbnRyeUlkKys7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBMb2dJdGVtKGxldmVsTmJyLCBtZXNzYWdlLCBsb2dnZXJOYW1lLCBKTC5fZ2V0VGltZSgpLCBKTC5lbnRyeUlkKTtcclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIGNsZWFyVGltZXIodGltZXIpIHtcclxuICAgICAgICBpZiAodGltZXIuaWQpIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyLmlkKTtcclxuICAgICAgICAgICAgdGltZXIuaWQgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGZ1bmN0aW9uIHNldFRpbWVyKHRpbWVyLCB0aW1lb3V0TXMsIGNhbGxiYWNrKSB7XHJcbiAgICAgICAgdmFyIHRoYXQgPSB0aGlzO1xyXG4gICAgICAgIGlmICghdGltZXIuaWQpIHtcclxuICAgICAgICAgICAgdGltZXIuaWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIC8vIHVzZSBjYWxsIHRvIGVuc3VyZSB0aGF0IHRoZSB0aGlzIGFzIHVzZWQgaW5zaWRlIHNlbmRCYXRjaCB3aGVuIGl0IHJ1bnMgaXMgdGhlXHJcbiAgICAgICAgICAgICAgICAvLyBzYW1lIHRoaXMgYXQgdGhpcyBwb2ludC5cclxuICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwodGhhdCk7XHJcbiAgICAgICAgICAgIH0sIHRpbWVvdXRNcyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgdmFyIEFwcGVuZGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIHNlbmRMb2dJdGVtcyB0YWtlcyBhbiBhcnJheSBvZiBsb2cgaXRlbXMuIEl0IHdpbGwgYmUgY2FsbGVkIHdoZW5cclxuICAgICAgICAvLyB0aGUgYXBwZW5kZXIgaGFzIGl0ZW1zIHRvIHByb2Nlc3MgKHN1Y2ggYXMsIHNlbmQgdG8gdGhlIHNlcnZlcikuXHJcbiAgICAgICAgLy8gc2VuZExvZ0l0ZW1zIHdpbGwgY2FsbCBzdWNjZXNzQ2FsbGJhY2sgYWZ0ZXIgdGhlIGl0ZW1zIGhhdmUgYmVlbiBzdWNjZXNzZnVsbHkgc2VudC5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIE5vdGUgdGhhdCBhZnRlciBzZW5kTG9nSXRlbXMgcmV0dXJucywgdGhlIGFwcGVuZGVyIG1heSB0cnVuY2F0ZVxyXG4gICAgICAgIC8vIHRoZSBMb2dJdGVtIGFycmF5LCBzbyB0aGUgZnVuY3Rpb24gaGFzIHRvIGNvcHkgdGhlIGNvbnRlbnQgb2YgdGhlIGFycmF5XHJcbiAgICAgICAgLy8gaW4gc29tZSBmYXNoaW9uIChlZy4gc2VyaWFsaXplKSBiZWZvcmUgcmV0dXJuaW5nLlxyXG4gICAgICAgIGZ1bmN0aW9uIEFwcGVuZGVyKGFwcGVuZGVyTmFtZSwgc2VuZExvZ0l0ZW1zKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYXBwZW5kZXJOYW1lID0gYXBwZW5kZXJOYW1lO1xyXG4gICAgICAgICAgICB0aGlzLnNlbmRMb2dJdGVtcyA9IHNlbmRMb2dJdGVtcztcclxuICAgICAgICAgICAgdGhpcy5sZXZlbCA9IEpMLmdldFRyYWNlTGV2ZWwoKTtcclxuICAgICAgICAgICAgLy8gc2V0IHRvIHN1cGVyIGhpZ2ggbGV2ZWwsIHNvIGlmIHVzZXIgaW5jcmVhc2VzIGxldmVsLCBsZXZlbCBpcyB1bmxpa2VseSB0byBnZXQgXHJcbiAgICAgICAgICAgIC8vIGFib3ZlIHNlbmRXaXRoQnVmZmVyTGV2ZWxcclxuICAgICAgICAgICAgdGhpcy5zZW5kV2l0aEJ1ZmZlckxldmVsID0gMjE0NzQ4MzY0NztcclxuICAgICAgICAgICAgdGhpcy5zdG9yZUluQnVmZmVyTGV2ZWwgPSAtMjE0NzQ4MzY0ODtcclxuICAgICAgICAgICAgdGhpcy5idWZmZXJTaXplID0gMDsgLy8gYnVmZmVyaW5nIHN3aXRjaCBvZmYgYnkgZGVmYXVsdFxyXG4gICAgICAgICAgICB0aGlzLmJhdGNoU2l6ZSA9IDE7XHJcbiAgICAgICAgICAgIHRoaXMubWF4QmF0Y2hTaXplID0gMjA7XHJcbiAgICAgICAgICAgIHRoaXMuYmF0Y2hUaW1lb3V0ID0gMjE0NzQ4MzY0NztcclxuICAgICAgICAgICAgdGhpcy5zZW5kVGltZW91dCA9IDUwMDA7XHJcbiAgICAgICAgICAgIC8vIEhvbGRzIGFsbCBsb2cgaXRlbXMgd2l0aCBsZXZlbHMgaGlnaGVyIHRoYW4gc3RvcmVJbkJ1ZmZlckxldmVsIFxyXG4gICAgICAgICAgICAvLyBidXQgbG93ZXIgdGhhbiBsZXZlbC4gVGhlc2UgaXRlbXMgbWF5IG5ldmVyIGJlIHNlbnQuXHJcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gW107XHJcbiAgICAgICAgICAgIC8vIEhvbGRzIGFsbCBpdGVtcyB0aGF0IHdlIGRvIHdhbnQgdG8gc2VuZCwgdW50aWwgd2UgaGF2ZSBhIGZ1bGxcclxuICAgICAgICAgICAgLy8gYmF0Y2ggKGFzIGRldGVybWluZWQgYnkgYmF0Y2hTaXplKS5cclxuICAgICAgICAgICAgdGhpcy5iYXRjaEJ1ZmZlciA9IFtdO1xyXG4gICAgICAgICAgICAvLyBIb2xkcyB0aGUgaWQgb2YgdGhlIHRpbWVyIGltcGxlbWVudGluZyB0aGUgYmF0Y2ggdGltZW91dC5cclxuICAgICAgICAgICAgLy8gQ2FuIGJlIG51bGwuXHJcbiAgICAgICAgICAgIC8vIFRoaXMgaXMgYW4gb2JqZWN0LCBzbyBpdCBjYW4gYmUgcGFzc2VkIHRvIGEgbWV0aG9kIHRoYXQgdXBkYXRlZCB0aGUgdGltZXIgdmFyaWFibGUuXHJcbiAgICAgICAgICAgIHRoaXMuYmF0Y2hUaW1lb3V0VGltZXIgPSB7IGlkOiBudWxsIH07XHJcbiAgICAgICAgICAgIC8vIEhvbGRzIHRoZSBpZCBvZiB0aGUgdGltZXIgaW1wbGVtZW50aW5nIHRoZSBzZW5kIHRpbWVvdXQuXHJcbiAgICAgICAgICAgIC8vIENhbiBiZSBudWxsLlxyXG4gICAgICAgICAgICB0aGlzLnNlbmRUaW1lb3V0VGltZXIgPSB7IGlkOiBudWxsIH07XHJcbiAgICAgICAgICAgIC8vIE51bWJlciBvZiBsb2cgaXRlbXMgdGhhdCBoYXMgYmVlbiBza2lwcGVkIGR1ZSB0byBiYXRjaCBidWZmZXIgYXQgbWF4IHNpemUsXHJcbiAgICAgICAgICAgIC8vIHNpbmNlIGFwcGVuZGVyIGNyZWF0aW9uIG9yIHNpbmNlIGNyZWF0aW9uIG9mIHRoZSBsYXN0IFwic2tpcHBlZFwiIHdhcm5pbmcgbG9nIGVudHJ5LlxyXG4gICAgICAgICAgICB0aGlzLm5ickxvZ0l0ZW1zU2tpcHBlZCA9IDA7XHJcbiAgICAgICAgICAgIC8vIFdpbGwgYmUgMCBpZiBubyBsb2cgcmVxdWVzdCBpcyBvdXRzdGFuZGluZyBhdCB0aGUgbW9tZW50LlxyXG4gICAgICAgICAgICAvLyBPdGhlcndpc2UgdGhlIG51bWJlciBvZiBsb2cgaXRlbXMgaW4gdGhlIG91dHN0YW5kaW5nIHJlcXVlc3QuXHJcbiAgICAgICAgICAgIHRoaXMubmJyTG9nSXRlbXNCZWluZ1NlbnQgPSAwO1xyXG4gICAgICAgICAgICB2YXIgZW1wdHlOYW1lRXJyb3JNZXNzYWdlID0gXCJUcnlpbmcgdG8gY3JlYXRlIGFuIGFwcGVuZGVyIHdpdGhvdXQgYSBuYW1lIG9yIHdpdGggYW4gZW1wdHkgbmFtZVwiO1xyXG4gICAgICAgICAgICAvLyBUaGlzIGV2YWx1YXRlcyB0byB0cnVlIGlmIGFwcGVuZGVyTmFtZSBpcyBlaXRoZXIgbnVsbCBvciB1bmRlZmluZWQhXHJcbiAgICAgICAgICAgIC8vIERvIG5vdCBjaGVjayBoZXJlIGlmIHRoZSBuYW1lIGlzIFwiXCIsIGJlY2F1c2UgdGhhdCB3b3VsZCBzdG9wIHlvdSBjcmVhdGluZyB0aGUgXHJcbiAgICAgICAgICAgIC8vIGRlZmF1bHQgYXBwZW5kZXIuXHJcbiAgICAgICAgICAgIGlmIChhcHBlbmRlck5hbWUgPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlbXB0eU5hbWVFcnJvck1lc3NhZ2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKEpMLl9hcHBlbmRlck5hbWVzLmluZGV4T2YoYXBwZW5kZXJOYW1lKSAhPSAtMSkge1xyXG4gICAgICAgICAgICAgICAgLy8gSWYgdXNlciBwYXNzZWQgaW4gXCJcIiwgdGhhdCB3aWxsIG5vdyBoYXZlIGJlZW4gcGlja2VkIHVwIGFzIGEgZHVwbGljYXRlXHJcbiAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIGRlZmF1bHQgYXBwZW5kZXIgYWxzbyB1c2VzIFwiXCIuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWFwcGVuZGVyTmFtZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVtcHR5TmFtZUVycm9yTWVzc2FnZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRocm93IFwiTXVsdGlwbGUgYXBwZW5kZXJzIHVzZSB0aGUgc2FtZSBuYW1lIFwiICsgYXBwZW5kZXJOYW1lO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIEpMLl9hcHBlbmRlck5hbWVzLnB1c2goYXBwZW5kZXJOYW1lKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgQXBwZW5kZXIucHJvdG90eXBlLmFkZExvZ0l0ZW1zVG9CdWZmZXIgPSBmdW5jdGlvbiAobG9nSXRlbXMpIHtcclxuICAgICAgICAgICAgLy8gSWYgdGhlIGJhdGNoIGJ1ZmZlciBoYXMgcmVhY2hlZCBpdHMgbWF4aW11bSBsaW1pdCwgXHJcbiAgICAgICAgICAgIC8vIHNraXAgdGhlIGxvZyBpdGVtIGFuZCBpbmNyZWFzZSB0aGUgXCJza2lwcGVkIGl0ZW1zXCIgY291bnRlci5cclxuICAgICAgICAgICAgaWYgKHRoaXMuYmF0Y2hCdWZmZXIubGVuZ3RoID49IHRoaXMubWF4QmF0Y2hTaXplKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm5ickxvZ0l0ZW1zU2tpcHBlZCArPSBsb2dJdGVtcy5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gSWYgbWF4TWVzc2FnZXMgaXMgbm90IG51bGwgb3IgdW5kZWZpbmVkLCB0aGVuIGRlY3JlYXNlIGl0IGJ5IHRoZSBiYXRjaCBzaXplLlxyXG4gICAgICAgICAgICAvLyBUaGlzIGNhbiByZXN1bHQgaW4gYSBuZWdhdGl2ZSBtYXhNZXNzYWdlcy5cclxuICAgICAgICAgICAgLy8gTm90ZSB0aGF0IHVuZGVmaW5lZD09bnVsbCAoISlcclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gTm90ZSB0aGF0IHdlIG1heSBiZSBzZW5kaW5nIG1vcmUgbWVzc2FnZXMgdGhhbiB0aGUgbWF4TWVzc2FnZXMgbGltaXQgYWxsb3dzLFxyXG4gICAgICAgICAgICAvLyBpZiB3ZSBzdG9yZWQgdHJhY2UgbWVzc2FnZXMuIFJhdGlvbmFsZSBpcyB0aGUgYnVmZmVyIGZvciB0cmFjZSBtZXNzYWdlcyBpcyBsaW1pdGVkLFxyXG4gICAgICAgICAgICAvLyBhbmQgaWYgd2UgY3V0IG9mZiBhdCBleGFjdGx5IG1heE1lc3NhZ2VzLCB3ZSdkIGFsc28gbG9vc2UgdGhlIGhpZ2ggc2V2ZXJpdHkgbWVzc2FnZVxyXG4gICAgICAgICAgICAvLyB0aGF0IGNhdXNlZCB0aGUgdHJhY2UgbWVzc2FnZXMgdG8gYmUgc2VudCAodW5sZXNzIHdlIGNhdGVyIGZvciB0aGlzIHNwZWNpZmljYWxseSwgd2hpY2hcclxuICAgICAgICAgICAgLy8gaXMgbW9yZSBjb21wbGV4aXR5KS5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIG11bHRpcGxlIGFwcGVuZGVycyBzZW5kaW5nIHRoZSBzYW1lIG1lc3NhZ2UsIG1heE1lc3NhZ2Ugd2lsbCBiZSBkZWNyZWFzZWRcclxuICAgICAgICAgICAgLy8gYnkgZWFjaCBhcHBlbmRlciBmb3IgdGhlIHNhbWUgbWVzc2FnZS4gVGhpcyBpczpcclxuICAgICAgICAgICAgLy8gMSkgb25seSBhcHBlbmRlcnMga25vdyB3aGV0aGVyIGEgbWVzc2FnZSB3aWxsIGFjdHVhbGx5IGJlIHNlbnQgKGJhc2VkIG9uIHN0b3JlSW5CdWZmZXJMZXZlbCksXHJcbiAgICAgICAgICAgIC8vICAgIHNvIHRoZSBsb2dnZXJzIGNvdWxkbid0IGRvIHRoaXMgdXBkYXRlO1xyXG4gICAgICAgICAgICAvLyAyKSBpZiB5b3UgaGF2ZSBtdWx0aXBsZSBhcHBlbmRlcnMgaGl0dGluZyB0aGUgc2FtZSBzZXJ2ZXIsIHRoaXMgbWF5IGJlIHdoYXQgeW91IHdhbnQuXHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgIC8vIEluIG1vc3QgY2FzZXMgdGhlcmUgaXMgb25seSAxIGFwcGVuZGVyLCBzbyB0aGlzIHRoZW4gZG9lc24ndCBtYXR0ZXIuXHJcbiAgICAgICAgICAgIGlmICghKEpMLm1heE1lc3NhZ2VzID09IG51bGwpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoSkwubWF4TWVzc2FnZXMgPCAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgSkwubWF4TWVzc2FnZXMgLT0gbG9nSXRlbXMubGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuYmF0Y2hCdWZmZXIgPSB0aGlzLmJhdGNoQnVmZmVyLmNvbmNhdChsb2dJdGVtcyk7XHJcbiAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgdGhlIGZpcnN0IGl0ZW0gaW4gdGhlIGJ1ZmZlciwgc2V0IHRoZSB0aW1lclxyXG4gICAgICAgICAgICAvLyB0byBlbnN1cmUgaXQgd2lsbCBiZSBzZW50IHdpdGhpbiB0aGUgdGltZW91dCBwZXJpb2QuXHJcbiAgICAgICAgICAgIC8vIElmIGl0IGlzIG5vdCB0aGUgZmlyc3QgaXRlbSwgbGVhdmUgdGhlIHRpbWVyIGFsb25lIHNvIHRvIG5vdCB0byBcclxuICAgICAgICAgICAgLy8gaW5jcmVhc2UgdGhlIHRpbWVvdXQgZm9yIHRoZSBmaXJzdCBpdGVtLlxyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBUbyBkZXRlcm1pbmUgaWYgdGhpcyBpcyB0aGUgZmlyc3QgaXRlbSwgbG9vayBhdCB0aGUgdGltZXIgdmFyaWFibGUuXHJcbiAgICAgICAgICAgIC8vIERvIG5vdCBsb29rIGF0IHRoZSBidWZmZXIgbGVuZ3RoLCBiZWNhdXNlIHdlIGFsc28gcHV0IGl0ZW1zIGluIHRoZSBidWZmZXJcclxuICAgICAgICAgICAgLy8gdmlhIGEgY29uY2F0IChieXBhc3NpbmcgdGhpcyBmdW5jdGlvbikuXHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgIC8vIFRoZSBzZXRUaW1lciBtZXRob2Qgb25seSBzZXRzIHRoZSB0aW1lciBpZiBpdCBpcyBub3QgYWxyZWFkeSBydW5uaW5nLlxyXG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XHJcbiAgICAgICAgICAgIHNldFRpbWVyKHRoaXMuYmF0Y2hUaW1lb3V0VGltZXIsIHRoaXMuYmF0Y2hUaW1lb3V0LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGF0LnNlbmRCYXRjaC5jYWxsKHRoYXQpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIDtcclxuICAgICAgICBBcHBlbmRlci5wcm90b3R5cGUuYmF0Y2hCdWZmZXJIYXNPdmVyZHVlTWVzc2FnZXMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5iYXRjaEJ1ZmZlci5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgdmFyIG1lc3NhZ2VBZ2VNcyA9IEpMLl9nZXRUaW1lKCkgLSB0aGlzLmJhdGNoQnVmZmVyW2ldLnQ7XHJcbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZUFnZU1zID4gdGhpcy5iYXRjaFRpbWVvdXQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYgbm8gbW9yZSBtZXNzYWdlIHdpbGwgZXZlciBiZSBhZGRlZCB0byB0aGUgYmF0Y2ggYnVmZmVyLFxyXG4gICAgICAgIC8vIGJ1dCB0aGUgYmF0Y2ggYnVmZmVyIGhhcyBtZXNzYWdlcyBub3cgLSBzbyBpZiB0aGVyZSBhcmUgbm90IGVub3VnaCB0byBtYWtlIHVwIGEgYmF0Y2gsXHJcbiAgICAgICAgLy8gYW5kIHRoZXJlIGlzIG5vIGJhdGNoIHRpbWVvdXQsIHRoZW4gdGhleSB3aWxsIG5ldmVyIGJlIHNlbnQuIFRoaXMgaXMgZXNwZWNpYWxseSBpbXBvcnRhbnQgaWYgXHJcbiAgICAgICAgLy8gbWF4TWVzc2FnZXMgd2FzIHJlYWNoZWQgd2hpbGUganNubG9nLmpzIHdhcyByZXRyeWluZyBzZW5kaW5nIG1lc3NhZ2VzIHRvIHRoZSBzZXJ2ZXIuXHJcbiAgICAgICAgQXBwZW5kZXIucHJvdG90eXBlLmJhdGNoQnVmZmVySGFzU3RyYW5kZWRNZXNzYWdlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gKCEoSkwubWF4TWVzc2FnZXMgPT0gbnVsbCkpICYmIChKTC5tYXhNZXNzYWdlcyA8IDEpICYmICh0aGlzLmJhdGNoQnVmZmVyLmxlbmd0aCA+IDApO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgQXBwZW5kZXIucHJvdG90eXBlLnNlbmRCYXRjaElmQ29tcGxldGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICgodGhpcy5iYXRjaEJ1ZmZlci5sZW5ndGggPj0gdGhpcy5iYXRjaFNpemUpIHx8XHJcbiAgICAgICAgICAgICAgICB0aGlzLmJhdGNoQnVmZmVySGFzT3ZlcmR1ZU1lc3NhZ2VzKCkgfHxcclxuICAgICAgICAgICAgICAgIHRoaXMuYmF0Y2hCdWZmZXJIYXNTdHJhbmRlZE1lc3NhZ2UoKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZW5kQmF0Y2goKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgQXBwZW5kZXIucHJvdG90eXBlLm9uU2VuZGluZ0VuZGVkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjbGVhclRpbWVyKHRoaXMuc2VuZFRpbWVvdXRUaW1lcik7XHJcbiAgICAgICAgICAgIHRoaXMubmJyTG9nSXRlbXNCZWluZ1NlbnQgPSAwO1xyXG4gICAgICAgICAgICB0aGlzLnNlbmRCYXRjaElmQ29tcGxldGUoKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIEFwcGVuZGVyLnByb3RvdHlwZS5zZXRPcHRpb25zID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwibGV2ZWxcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImlwUmVnZXhcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcInVzZXJBZ2VudFJlZ2V4XCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJkaXNhbGxvd1wiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwic2VuZFdpdGhCdWZmZXJMZXZlbFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwic3RvcmVJbkJ1ZmZlckxldmVsXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJidWZmZXJTaXplXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJiYXRjaFNpemVcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcIm1heEJhdGNoU2l6ZVwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwiYmF0Y2hUaW1lb3V0XCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJzZW5kVGltZW91dFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuYnVmZmVyU2l6ZSA8IHRoaXMuYnVmZmVyLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5idWZmZXIubGVuZ3RoID0gdGhpcy5idWZmZXJTaXplO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm1heEJhdGNoU2l6ZSA8IHRoaXMuYmF0Y2hTaXplKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSkwuRXhjZXB0aW9uKHtcclxuICAgICAgICAgICAgICAgICAgICBcIm1lc3NhZ2VcIjogXCJtYXhCYXRjaFNpemUgY2Fubm90IGJlIHNtYWxsZXIgdGhhbiBiYXRjaFNpemVcIixcclxuICAgICAgICAgICAgICAgICAgICBcIm1heEJhdGNoU2l6ZVwiOiB0aGlzLm1heEJhdGNoU2l6ZSxcclxuICAgICAgICAgICAgICAgICAgICBcImJhdGNoU2l6ZVwiOiB0aGlzLmJhdGNoU2l6ZVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICBDYWxsZWQgYnkgYSBsb2dnZXIgdG8gbG9nIGEgbG9nIGl0ZW0uXHJcbiAgICAgICAgSWYgaW4gcmVzcG9uc2UgdG8gdGhpcyBjYWxsIG9uZSBvciBtb3JlIGxvZyBpdGVtcyBuZWVkIHRvIGJlIHByb2Nlc3NlZFxyXG4gICAgICAgIChlZy4sIHNlbnQgdG8gdGhlIHNlcnZlciksIHRoaXMgbWV0aG9kIGNhbGxzIHRoaXMuc2VuZExvZ0l0ZW1zXHJcbiAgICAgICAgd2l0aCBhbiBhcnJheSB3aXRoIGFsbCBpdGVtcyB0byBiZSBwcm9jZXNzZWQuXHJcblxyXG4gICAgICAgIE5vdGUgdGhhdCB0aGUgbmFtZSBhbmQgcGFyYW1ldGVycyBvZiB0aGlzIGZ1bmN0aW9uIG11c3QgbWF0Y2ggdGhvc2Ugb2YgdGhlIGxvZyBmdW5jdGlvbiBvZlxyXG4gICAgICAgIGEgV2luc3RvbiB0cmFuc3BvcnQgb2JqZWN0LCBzbyB0aGF0IHVzZXJzIGNhbiB1c2UgdGhlc2UgdHJhbnNwb3J0cyBhcyBhcHBlbmRlcnMuXHJcbiAgICAgICAgVGhhdCBpcyB3aHkgdGhlcmUgYXJlIG1hbnkgcGFyYW1ldGVycyB0aGF0IGFyZSBub3QgYWN0dWFsbHkgdXNlZCBieSB0aGlzIGZ1bmN0aW9uLlxyXG5cclxuICAgICAgICBsZXZlbCAtIHN0cmluZyB3aXRoIHRoZSBsZXZlbCAoXCJ0cmFjZVwiLCBcImRlYnVnXCIsIGV0Yy4pIE9ubHkgdXNlZCBieSBXaW5zdG9uIHRyYW5zcG9ydHMuXHJcbiAgICAgICAgbXNnIC0gaHVtYW4gcmVhZGFibGUgbWVzc2FnZS4gVW5kZWZpbmVkIGlmIHRoZSBsb2cgaXRlbSBpcyBhbiBvYmplY3QuIE9ubHkgdXNlZCBieSBXaW5zdG9uIHRyYW5zcG9ydHMuXHJcbiAgICAgICAgbWV0YSAtIGxvZyBvYmplY3QuIEFsd2F5cyBkZWZpbmVkLCBiZWNhdXNlIGF0IGxlYXN0IGl0IGNvbnRhaW5zIHRoZSBsb2dnZXIgbmFtZS4gT25seSB1c2VkIGJ5IFdpbnN0b24gdHJhbnNwb3J0cy5cclxuICAgICAgICBjYWxsYmFjayAtIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhlIGxvZyBpdGVtIGhhcyBiZWVuIGxvZ2dlZC4gT25seSB1c2VkIGJ5IFdpbnN0b24gdHJhbnNwb3J0cy5cclxuICAgICAgICBsZXZlbE5iciAtIGxldmVsIGFzIGEgbnVtYmVyLiBOb3QgdXNlZCBieSBXaW5zdG9uIHRyYW5zcG9ydHMuXHJcbiAgICAgICAgbWVzc2FnZSAtIGxvZyBpdGVtLiBJZiB0aGUgdXNlciBsb2dnZWQgYW4gb2JqZWN0LCB0aGlzIGlzIHRoZSBKU09OIHN0cmluZy4gIE5vdCB1c2VkIGJ5IFdpbnN0b24gdHJhbnNwb3J0cy5cclxuICAgICAgICBsb2dnZXJOYW1lOiBuYW1lIG9mIHRoZSBsb2dnZXIuICBOb3QgdXNlZCBieSBXaW5zdG9uIHRyYW5zcG9ydHMuXHJcbiAgICAgICAgKi9cclxuICAgICAgICBBcHBlbmRlci5wcm90b3R5cGUubG9nID0gZnVuY3Rpb24gKGxldmVsLCBtc2csIG1ldGEsIGNhbGxiYWNrLCBsZXZlbE5iciwgbWVzc2FnZSwgbG9nZ2VyTmFtZSkge1xyXG4gICAgICAgICAgICB2YXIgbG9nSXRlbTtcclxuICAgICAgICAgICAgaWYgKCFhbGxvdyh0aGlzKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICghYWxsb3dNZXNzYWdlKHRoaXMsIG1lc3NhZ2UpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGxldmVsTmJyIDwgdGhpcy5zdG9yZUluQnVmZmVyTGV2ZWwpIHtcclxuICAgICAgICAgICAgICAgIC8vIElnbm9yZSB0aGUgbG9nIGl0ZW0gY29tcGxldGVseVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGxvZ0l0ZW0gPSBuZXdMb2dJdGVtKGxldmVsTmJyLCBtZXNzYWdlLCBsb2dnZXJOYW1lKTtcclxuICAgICAgICAgICAgaWYgKGxldmVsTmJyIDwgdGhpcy5sZXZlbCkge1xyXG4gICAgICAgICAgICAgICAgLy8gU3RvcmUgaW4gdGhlIGhvbGQgYnVmZmVyLiBEbyBub3Qgc2VuZC5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmJ1ZmZlclNpemUgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5idWZmZXIucHVzaChsb2dJdGVtKTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBJZiB3ZSBleGNlZWRlZCBtYXggYnVmZmVyIHNpemUsIHJlbW92ZSBvbGRlc3QgaXRlbVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sZW5ndGggPiB0aGlzLmJ1ZmZlclNpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5idWZmZXIuc2hpZnQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gV2FudCB0byBzZW5kIHRoZSBpdGVtXHJcbiAgICAgICAgICAgIHRoaXMuYWRkTG9nSXRlbXNUb0J1ZmZlcihbbG9nSXRlbV0pO1xyXG4gICAgICAgICAgICBpZiAobGV2ZWxOYnIgPj0gdGhpcy5zZW5kV2l0aEJ1ZmZlckxldmVsKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBXYW50IHRvIHNlbmQgdGhlIGNvbnRlbnRzIG9mIHRoZSBidWZmZXIuXHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gU2VuZCB0aGUgYnVmZmVyIEFGVEVSIHNlbmRpbmcgdGhlIGhpZ2ggcHJpb3JpdHkgaXRlbS5cclxuICAgICAgICAgICAgICAgIC8vIElmIHlvdSB3ZXJlIHRvIHNlbmQgdGhlIGhpZ2ggcHJpb3JpdHkgaXRlbSBhZnRlciB0aGUgYnVmZmVyLFxyXG4gICAgICAgICAgICAgICAgLy8gaWYgd2UncmUgY2xvc2UgdG8gbWF4TWVzc2FnZXMgb3IgbWF4QmF0Y2hTaXplLFxyXG4gICAgICAgICAgICAgICAgLy8gdGhlbiB0aGUgdHJhY2UgbWVzc2FnZXMgaW4gdGhlIGJ1ZmZlciBjb3VsZCBjcm93ZCBvdXQgdGhlIGFjdHVhbCBoaWdoIHByaW9yaXR5IGl0ZW0uXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5idWZmZXIubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRMb2dJdGVtc1RvQnVmZmVyKHRoaXMuYnVmZmVyKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1ZmZlci5sZW5ndGggPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuc2VuZEJhdGNoSWZDb21wbGV0ZSgpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgO1xyXG4gICAgICAgIC8vIFByb2Nlc3NlcyB0aGUgYmF0Y2ggYnVmZmVyXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBNYWtlIHRoaXMgcHVibGljLCBzbyBpdCBjYW4gYmUgY2FsbGVkIGZyb20gb3V0c2lkZSB0aGUgbGlicmFyeSxcclxuICAgICAgICAvLyB3aGVuIHRoZSBwYWdlIGlzIHVubG9hZGVkLlxyXG4gICAgICAgIEFwcGVuZGVyLnByb3RvdHlwZS5zZW5kQmF0Y2ggPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIERvIG5vdCBjbGVhciB0aGUgYmF0Y2ggdGltZXIgaWYgeW91IGRvbid0IGdvIGFoZWFkIGhlcmUgYmVjYXVzZVxyXG4gICAgICAgICAgICAvLyBhIHNlbmQgaXMgYWxyZWFkeSBpbiBwcm9ncmVzcy4gT3RoZXJ3aXNlIHRoZSBtZXNzYWdlcyB0aGF0IHdlcmUgc3RvcHBlZCBmcm9tIGdvaW5nIG91dFxyXG4gICAgICAgICAgICAvLyBtYXkgZ2V0IGlnbm9yZWQgYmVjYXVzZSB0aGUgYmF0Y2ggdGltZXIgbmV2ZXIgd2VudCBvZmYuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLm5ickxvZ0l0ZW1zQmVpbmdTZW50ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNsZWFyVGltZXIodGhpcy5iYXRjaFRpbWVvdXRUaW1lcik7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmJhdGNoQnVmZmVyLmxlbmd0aCA9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gRGVjaWRlZCBhdCB0aGlzIHBvaW50IHRvIHNlbmQgY29udGVudHMgb2YgdGhlIGJ1ZmZlclxyXG4gICAgICAgICAgICB0aGlzLm5ickxvZ0l0ZW1zQmVpbmdTZW50ID0gdGhpcy5iYXRjaEJ1ZmZlci5sZW5ndGg7XHJcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcztcclxuICAgICAgICAgICAgc2V0VGltZXIodGhpcy5zZW5kVGltZW91dFRpbWVyLCB0aGlzLnNlbmRUaW1lb3V0LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGF0Lm9uU2VuZGluZ0VuZGVkLmNhbGwodGhhdCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0aGlzLnNlbmRMb2dJdGVtcyh0aGlzLmJhdGNoQnVmZmVyLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBMb2cgZW50cmllcyBoYXZlIGJlZW4gc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gc2VydmVyXHJcbiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGZpcnN0IChuYnJMb2dJdGVtc0JlaW5nU2VudCkgaXRlbXMgaW4gdGhlIGJhdGNoIGJ1ZmZlciwgYmVjYXVzZSB0aGV5IGFyZSB0aGUgb25lc1xyXG4gICAgICAgICAgICAgICAgLy8gdGhhdCB3ZXJlIHNlbnQuXHJcbiAgICAgICAgICAgICAgICB0aGF0LmJhdGNoQnVmZmVyLnNwbGljZSgwLCB0aGF0Lm5ickxvZ0l0ZW1zQmVpbmdTZW50KTtcclxuICAgICAgICAgICAgICAgIC8vIElmIGl0ZW1zIGhhZCB0byBiZSBza2lwcGVkLCBhZGQgYSBXQVJOIG1lc3NhZ2VcclxuICAgICAgICAgICAgICAgIGlmICh0aGF0Lm5ickxvZ0l0ZW1zU2tpcHBlZCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGF0LmJhdGNoQnVmZmVyLnB1c2gobmV3TG9nSXRlbShnZXRXYXJuTGV2ZWwoKSwgXCJMb3N0IFwiICsgdGhhdC5uYnJMb2dJdGVtc1NraXBwZWQgKyBcIiBtZXNzYWdlcy4gRWl0aGVyIGNvbm5lY3Rpb24gd2l0aCB0aGUgc2VydmVyIHdhcyBkb3duIG9yIGxvZ2dpbmcgd2FzIGRpc2FibGVkIHZpYSB0aGUgZW5hYmxlZCBvcHRpb24uIFJlZHVjZSBsb3N0IG1lc3NhZ2VzIGJ5IGluY3JlYXNpbmcgdGhlIGFqYXhBcHBlbmRlciBvcHRpb24gbWF4QmF0Y2hTaXplLlwiLCB0aGF0LmFwcGVuZGVyTmFtZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoYXQubmJyTG9nSXRlbXNTa2lwcGVkID0gMDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoYXQub25TZW5kaW5nRW5kZWQuY2FsbCh0aGF0KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gQXBwZW5kZXI7XHJcbiAgICB9KCkpO1xyXG4gICAgSkwuQXBwZW5kZXIgPSBBcHBlbmRlcjtcclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgdmFyIEFqYXhBcHBlbmRlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgICAgICBfX2V4dGVuZHMoQWpheEFwcGVuZGVyLCBfc3VwZXIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIEFqYXhBcHBlbmRlcihhcHBlbmRlck5hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIF9zdXBlci5jYWxsKHRoaXMsIGFwcGVuZGVyTmFtZSwgQWpheEFwcGVuZGVyLnByb3RvdHlwZS5zZW5kTG9nSXRlbXNBamF4KSB8fCB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBBamF4QXBwZW5kZXIucHJvdG90eXBlLnNldE9wdGlvbnMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJ1cmxcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImJlZm9yZVNlbmRcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIF9zdXBlci5wcm90b3R5cGUuc2V0T3B0aW9ucy5jYWxsKHRoaXMsIG9wdGlvbnMpO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9O1xyXG4gICAgICAgIEFqYXhBcHBlbmRlci5wcm90b3R5cGUuc2VuZExvZ0l0ZW1zQWpheCA9IGZ1bmN0aW9uIChsb2dJdGVtcywgc3VjY2Vzc0NhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIC8vIEpTT04uc3RyaW5naWZ5IGlzIG9ubHkgc3VwcG9ydGVkIG9uIElFOCtcclxuICAgICAgICAgICAgLy8gVXNlIHRyeS1jYXRjaCBpbiBjYXNlIHdlIGdldCBhbiBleGNlcHRpb24gaGVyZS5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gVGhlIFwiclwiIGZpZWxkIGlzIG5vdyBvYnNvbGV0ZS4gV2hlbiB3cml0aW5nIGEgc2VydmVyIHNpZGUgY29tcG9uZW50LCBcclxuICAgICAgICAgICAgLy8gcmVhZCB0aGUgSFRUUCBoZWFkZXIgXCJKU05Mb2ctUmVxdWVzdElkXCJcclxuICAgICAgICAgICAgLy8gdG8gZ2V0IHRoZSByZXF1ZXN0IGlkLlxyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBUaGUgLk5ldCBzZXJ2ZXIgc2lkZSBjb21wb25lbnRcclxuICAgICAgICAgICAgLy8gbm93IHVzZXMgdGhlIEpTTkxvZy1SZXF1ZXN0SWQgSFRUUCBIZWFkZXIsIGJlY2F1c2UgdGhpcyBhbGxvd3MgaXQgdG9cclxuICAgICAgICAgICAgLy8gZGV0ZWN0IHdoZXRoZXIgdGhlIGluY29taW5nIHJlcXVlc3QgaGFzIGEgcmVxdWVzdCBpZC5cclxuICAgICAgICAgICAgLy8gSWYgdGhlIHJlcXVlc3QgaWQgd2VyZSBpbiB0aGUganNvbiBwYXlsb2FkLCBpdCB3b3VsZCBoYXZlIHRvIHJlYWQgdGhlIGpzb25cclxuICAgICAgICAgICAgLy8gZnJvbSB0aGUgc3RyZWFtLCBpbnRlcmZlcmluZyB3aXRoIG5vcm1hbCBub24tbG9nZ2luZyByZXF1ZXN0cy5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gVG8gc2VlIHdoYXQgY2hhcmFjdGVycyB5b3UgY2FuIHVzZSBpbiB0aGUgSFRUUCBoZWFkZXIsIHZpc2l0OlxyXG4gICAgICAgICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzM1NjEzODEvY3VzdG9tLWh0dHAtaGVhZGVycy1uYW1pbmctY29udmVudGlvbnMvMzU2MTM5OSMzNTYxMzk5XHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgIC8vIEl0IG5lZWRzIHRoaXMgYWJpbGl0eSwgc28gdXNlcnMgb2YgTkxvZyBjYW4gc2V0IGEgcmVxdWVzdElkIHZhcmlhYmxlIGluIE5Mb2dcclxuICAgICAgICAgICAgLy8gYmVmb3JlIHRoZSBzZXJ2ZXIgc2lkZSBjb21wb25lbnQgdHJpZXMgdG8gbG9nIHRoZSBjbGllbnQgc2lkZSBsb2cgbWVzc2FnZVxyXG4gICAgICAgICAgICAvLyB0aHJvdWdoIGFuIE5Mb2cgbG9nZ2VyLlxyXG4gICAgICAgICAgICAvLyBVbmxpa2UgTG9nNE5ldCwgTkxvZyBkb2Vzbid0IGFsbG93IHlvdSB0byByZWdpc3RlciBhbiBvYmplY3Qgd2hvc2UgVG9TdHJpbmcoKVxyXG4gICAgICAgICAgICAvLyBpcyBvbmx5IGNhbGxlZCB3aGVuIGl0IHRyaWVzIHRvIGxvZyBzb21ldGhpbmcsIHNvIHRoZSByZXF1ZXN0SWQgaGFzIHRvIGJlIFxyXG4gICAgICAgICAgICAvLyBkZXRlcm1pbmVkIHJpZ2h0IGF0IHRoZSBzdGFydCBvZiByZXF1ZXN0IHByb2Nlc3NpbmcuXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAvLyBEbyBub3Qgc2VuZCBsb2dzLCBpZiBKTC5lbmFibGVkIGlzIHNldCB0byBmYWxzZS5cclxuICAgICAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgICAgICAvLyBEbyBub3QgY2FsbCBzdWNjZXNzQ2FsbGJhY2sgaGVyZS4gQWZ0ZXIgZWFjaCB0aW1lb3V0LCBqc25sb2cgd2lsbCByZXRyeSBzZW5kaW5nIHRoZSBtZXNzYWdlLlxyXG4gICAgICAgICAgICAgICAgLy8gSWYganNubG9nIGdldHMgcmUtZW5hYmxlZCwgaXQgd2lsbCB0aGVuIGxvZyB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzIGxvZ2dlZC5cclxuICAgICAgICAgICAgICAgIC8vIElmIGl0IGRvZXNuJ3QgZ2V0IHJlLWVuYWJsZWQsIGFtb3VudCBvZiBjcHUgY3ljbGVzIHdhc3RlZCBpcyBtaW5pbWFsLlxyXG4gICAgICAgICAgICAgICAgaWYgKCFhbGxvdyh0aGlzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIElmIGEgcmVxdWVzdCBpcyBpbiBwcm9ncmVzcywgYWJvcnQgaXQuXHJcbiAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UsIGl0IG1heSBjYWxsIHRoZSBzdWNjZXNzIGNhbGxiYWNrLCB3aGljaCB3aWxsIGJlIHZlcnkgY29uZnVzaW5nLlxyXG4gICAgICAgICAgICAgICAgLy8gSXQgbWF5IGFsc28gc3RvcCB0aGUgaW5mbGlnaHQgcmVxdWVzdCBmcm9tIHJlc3VsdGluZyBpbiBhIGxvZyBhdCB0aGUgc2VydmVyLlxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMueGhyICYmICh0aGlzLnhoci5yZWFkeVN0YXRlICE9IDApICYmICh0aGlzLnhoci5yZWFkeVN0YXRlICE9IDQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy54aHIuYWJvcnQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIEJlY2F1c2UgYSByZWFjdC1uYXRpdmUgWE1MSHR0cFJlcXVlc3QgY2Fubm90IGJlIHJldXNlZCBpdCBuZWVkcyB0byBiZSByZWNyZWF0ZWQgd2l0aCBlYWNoIHJlcXVlc3RcclxuICAgICAgICAgICAgICAgIHRoaXMueGhyID0gSkwuX2NyZWF0ZVhNTEh0dHBSZXF1ZXN0KCk7XHJcbiAgICAgICAgICAgICAgICAvLyBPbmx5IGRldGVybWluZSB0aGUgdXJsIHJpZ2h0IGJlZm9yZSB5b3Ugc2VuZCBhIGxvZyByZXF1ZXN0LlxyXG4gICAgICAgICAgICAgICAgLy8gRG8gbm90IHNldCB0aGUgdXJsIHdoZW4gY29uc3RydWN0aW5nIHRoZSBhcHBlbmRlci5cclxuICAgICAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGJlY2F1c2UgdGhlIHNlcnZlciBzaWRlIGNvbXBvbmVudCBzZXRzIGRlZmF1bHRBamF4VXJsXHJcbiAgICAgICAgICAgICAgICAvLyBpbiBhIGNhbGwgdG8gc2V0T3B0aW9ucywgQUZURVIgdGhlIEpMIG9iamVjdCBhbmQgdGhlIGRlZmF1bHQgYXBwZW5kZXJcclxuICAgICAgICAgICAgICAgIC8vIGhhdmUgYmVlbiBjcmVhdGVkLiBcclxuICAgICAgICAgICAgICAgIHZhciBhamF4VXJsID0gXCIvanNubG9nLmxvZ2dlclwiO1xyXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBldmFsdWF0ZXMgdG8gdHJ1ZSBpZiBkZWZhdWx0QWpheFVybCBpcyBudWxsIG9yIHVuZGVmaW5lZFxyXG4gICAgICAgICAgICAgICAgaWYgKCEoSkwuZGVmYXVsdEFqYXhVcmwgPT0gbnVsbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBhamF4VXJsID0gSkwuZGVmYXVsdEFqYXhVcmw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy51cmwpIHtcclxuICAgICAgICAgICAgICAgICAgICBhamF4VXJsID0gdGhpcy51cmw7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGlzLnhoci5vcGVuKCdQT1NUJywgYWpheFVybCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnhoci5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy54aHIuc2V0UmVxdWVzdEhlYWRlcignSlNOTG9nLVJlcXVlc3RJZCcsIEpMLnJlcXVlc3RJZCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gT24gbW9zdCBicm93c2VycywgaWYgdGhlIHJlcXVlc3QgZmFpbHMgKGVnLiBpbnRlcm5ldCBpcyBnb25lKSxcclxuICAgICAgICAgICAgICAgICAgICAvLyBpdCB3aWxsIHNldCB4aHIucmVhZHlTdGF0ZSA9PSA0IGFuZCB4aHIuc3RhdHVzICE9IDIwMCAoMCBpZiByZXF1ZXN0IGNvdWxkIG5vdCBiZSBzZW50KSBpbW1lZGlhdGVseS5cclxuICAgICAgICAgICAgICAgICAgICAvLyBIb3dldmVyLCBFZGdlIGFuZCBJRSB3aWxsIG5vdCBjaGFuZ2UgdGhlIHJlYWR5U3RhdGUgYXQgYWxsIGlmIHRoZSBpbnRlcm5ldCBnb2VzIGF3YXkgd2hpbGUgd2FpdGluZ1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGZvciBhIHJlc3BvbnNlLlxyXG4gICAgICAgICAgICAgICAgICAgIC8vIFNvbWUgc2VydmVycyB3aWxsIHJldHVybiBhIDIwNCAoc3VjY2Vzcywgbm8gY29udGVudCkgd2hlbiB0aGUgSlNOTG9nIGVuZHBvaW50XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gcmV0dXJucyB0aGUgZW1wdHkgcmVzcG9uc2UuIFNvIGNoZWNrIG9uIGFueSBjb2RlIGluIHRoZSAyLi4gcmFuZ2UsIG5vdCBqdXN0IDIwMC5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoKHRoYXQueGhyLnJlYWR5U3RhdGUgPT0gNCkgJiYgKHRoYXQueGhyLnN0YXR1cyA+PSAyMDAgJiYgdGhhdC54aHIuc3RhdHVzIDwgMzAwKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2soKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgdmFyIGpzb24gPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcjogSkwucmVxdWVzdElkLFxyXG4gICAgICAgICAgICAgICAgICAgIGxnOiBsb2dJdGVtc1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIC8vIGNhbGwgYmVmb3JlU2VuZCBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgLy8gZmlyc3QgdHJ5IHRoZSBjYWxsYmFjayBvbiB0aGUgYXBwZW5kZXJcclxuICAgICAgICAgICAgICAgIC8vIHRoZW4gdGhlIGdsb2JhbCBkZWZhdWx0QmVmb3JlU2VuZCBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmJlZm9yZVNlbmQgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmJlZm9yZVNlbmQuY2FsbCh0aGlzLCB0aGlzLnhociwganNvbik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgSkwuZGVmYXVsdEJlZm9yZVNlbmQgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgICAgICAgICBKTC5kZWZhdWx0QmVmb3JlU2VuZC5jYWxsKHRoaXMsIHRoaXMueGhyLCBqc29uKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHZhciBmaW5hbG1zZyA9IEpTT04uc3RyaW5naWZ5KGpzb24pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy54aHIuc2VuZChmaW5hbG1zZyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHsgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgcmV0dXJuIEFqYXhBcHBlbmRlcjtcclxuICAgIH0oQXBwZW5kZXIpKTtcclxuICAgIEpMLkFqYXhBcHBlbmRlciA9IEFqYXhBcHBlbmRlcjtcclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgdmFyIENvbnNvbGVBcHBlbmRlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgICAgICBfX2V4dGVuZHMoQ29uc29sZUFwcGVuZGVyLCBfc3VwZXIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIENvbnNvbGVBcHBlbmRlcihhcHBlbmRlck5hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIF9zdXBlci5jYWxsKHRoaXMsIGFwcGVuZGVyTmFtZSwgQ29uc29sZUFwcGVuZGVyLnByb3RvdHlwZS5zZW5kTG9nSXRlbXNDb25zb2xlKSB8fCB0aGlzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBDb25zb2xlQXBwZW5kZXIucHJvdG90eXBlLmNsb2cgPSBmdW5jdGlvbiAobG9nRW50cnkpIHtcclxuICAgICAgICAgICAgSkwuX2NvbnNvbGUubG9nKGxvZ0VudHJ5KTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIENvbnNvbGVBcHBlbmRlci5wcm90b3R5cGUuY2Vycm9yID0gZnVuY3Rpb24gKGxvZ0VudHJ5KSB7XHJcbiAgICAgICAgICAgIGlmIChKTC5fY29uc29sZS5lcnJvcikge1xyXG4gICAgICAgICAgICAgICAgSkwuX2NvbnNvbGUuZXJyb3IobG9nRW50cnkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jbG9nKGxvZ0VudHJ5KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgQ29uc29sZUFwcGVuZGVyLnByb3RvdHlwZS5jd2FybiA9IGZ1bmN0aW9uIChsb2dFbnRyeSkge1xyXG4gICAgICAgICAgICBpZiAoSkwuX2NvbnNvbGUud2Fybikge1xyXG4gICAgICAgICAgICAgICAgSkwuX2NvbnNvbGUud2Fybihsb2dFbnRyeSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNsb2cobG9nRW50cnkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBDb25zb2xlQXBwZW5kZXIucHJvdG90eXBlLmNpbmZvID0gZnVuY3Rpb24gKGxvZ0VudHJ5KSB7XHJcbiAgICAgICAgICAgIGlmIChKTC5fY29uc29sZS5pbmZvKSB7XHJcbiAgICAgICAgICAgICAgICBKTC5fY29uc29sZS5pbmZvKGxvZ0VudHJ5KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2xvZyhsb2dFbnRyeSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIElFMTEgaGFzIGEgY29uc29sZS5kZWJ1ZyBmdW5jdGlvbi4gQnV0IGl0cyBjb25zb2xlIGRvZXNuJ3QgaGF2ZSBcclxuICAgICAgICAvLyB0aGUgb3B0aW9uIHRvIHNob3cvaGlkZSBkZWJ1ZyBtZXNzYWdlcyAodGhlIHNhbWUgd2F5IENocm9tZSBhbmQgRkYgZG8pLFxyXG4gICAgICAgIC8vIGV2ZW4gdGhvdWdoIGl0IGRvZXMgaGF2ZSBzdWNoIGJ1dHRvbnMgZm9yIEVycm9yLCBXYXJuLCBJbmZvLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gRm9yIG5vdywgdGhpcyBtZWFucyB0aGF0IGRlYnVnIG1lc3NhZ2VzIGNhbiBub3QgYmUgaGlkZGVuIG9uIElFLlxyXG4gICAgICAgIC8vIExpdmUgd2l0aCB0aGlzLCBzZWVpbmcgdGhhdCBpdCB3b3JrcyBmaW5lIG9uIEZGIGFuZCBDaHJvbWUsIHdoaWNoXHJcbiAgICAgICAgLy8gd2lsbCBiZSBtdWNoIG1vcmUgcG9wdWxhciB3aXRoIGRldmVsb3BlcnMuXHJcbiAgICAgICAgQ29uc29sZUFwcGVuZGVyLnByb3RvdHlwZS5jZGVidWcgPSBmdW5jdGlvbiAobG9nRW50cnkpIHtcclxuICAgICAgICAgICAgaWYgKEpMLl9jb25zb2xlLmRlYnVnKSB7XHJcbiAgICAgICAgICAgICAgICBKTC5fY29uc29sZS5kZWJ1Zyhsb2dFbnRyeSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNpbmZvKGxvZ0VudHJ5KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgQ29uc29sZUFwcGVuZGVyLnByb3RvdHlwZS5zZW5kTG9nSXRlbXNDb25zb2xlID0gZnVuY3Rpb24gKGxvZ0l0ZW1zLCBzdWNjZXNzQ2FsbGJhY2spIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIC8vIERvIG5vdCBzZW5kIGxvZ3MsIGlmIEpMLmVuYWJsZWQgaXMgc2V0IHRvIGZhbHNlXHJcbiAgICAgICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAgICAgLy8gRG8gbm90IGNhbGwgc3VjY2Vzc0NhbGxiYWNrIGhlcmUuIEFmdGVyIGVhY2ggdGltZW91dCwganNubG9nIHdpbGwgcmV0cnkgc2VuZGluZyB0aGUgbWVzc2FnZS5cclxuICAgICAgICAgICAgICAgIC8vIElmIGpzbmxvZyBnZXRzIHJlLWVuYWJsZWQsIGl0IHdpbGwgdGhlbiBsb2cgdGhlIG51bWJlciBvZiBtZXNzYWdlcyBsb2dnZWQuXHJcbiAgICAgICAgICAgICAgICAvLyBJZiBpdCBkb2Vzbid0IGdldCByZS1lbmFibGVkLCBhbW91bnQgb2YgY3B1IGN5Y2xlcyB3YXN0ZWQgaXMgbWluaW1hbC5cclxuICAgICAgICAgICAgICAgIGlmICghYWxsb3codGhpcykpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoIUpMLl9jb25zb2xlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIGk7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbG9nSXRlbXMubGVuZ3RoOyArK2kpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbGkgPSBsb2dJdGVtc1tpXTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbXNnID0gbGkubiArIFwiOiBcIiArIGxpLm07XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gT25seSBsb2cgdGhlIHRpbWVzdGFtcCBpZiB3ZSdyZSBvbiB0aGUgc2VydmVyXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gKHdpbmRvdyBpcyB1bmRlZmluZWQpLiBPbiB0aGUgYnJvd3NlciwgdGhlIHVzZXJcclxuICAgICAgICAgICAgICAgICAgICAvLyBzZWVzIHRoZSBsb2cgZW50cnkgcHJvYmFibHkgaW1tZWRpYXRlbHksIHNvIGluIHRoYXQgY2FzZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZSB0aW1lc3RhbXAgaXMgY2x1dHRlci5cclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbXNnID0gbmV3IERhdGUobGkudCkgKyBcIiB8IFwiICsgbXNnO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAobGkubCA8PSBKTC5nZXREZWJ1Z0xldmVsKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jZGVidWcobXNnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobGkubCA8PSBKTC5nZXRJbmZvTGV2ZWwoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNpbmZvKG1zZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGxpLmwgPD0gSkwuZ2V0V2FybkxldmVsKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jd2Fybihtc2cpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jZXJyb3IobXNnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2soKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiBDb25zb2xlQXBwZW5kZXI7XHJcbiAgICB9KEFwcGVuZGVyKSk7XHJcbiAgICBKTC5Db25zb2xlQXBwZW5kZXIgPSBDb25zb2xlQXBwZW5kZXI7XHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgdmFyIExvZ2dlciA9IC8qKiBAY2xhc3MgKi8gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBmdW5jdGlvbiBMb2dnZXIobG9nZ2VyTmFtZSkge1xyXG4gICAgICAgICAgICB0aGlzLmxvZ2dlck5hbWUgPSBsb2dnZXJOYW1lO1xyXG4gICAgICAgICAgICAvLyBDcmVhdGUgc2VlblJleGVzLCBvdGhlcndpc2UgdGhpcyBsb2dnZXIgd2lsbCB1c2UgdGhlIHNlZW5SZXhlc1xyXG4gICAgICAgICAgICAvLyBvZiBpdHMgcGFyZW50IHZpYSB0aGUgcHJvdG90eXBlIGNoYWluLlxyXG4gICAgICAgICAgICB0aGlzLnNlZW5SZWdleGVzID0gW107XHJcbiAgICAgICAgfVxyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUuc2V0T3B0aW9ucyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImxldmVsXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJ1c2VyQWdlbnRSZWdleFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwiZGlzYWxsb3dcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImlwUmVnZXhcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImFwcGVuZGVyc1wiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwib25jZU9ubHlcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIC8vIFJlc2V0IHNlZW5SZWdleGVzLCBpbiBjYXNlIG9uY2VPbmx5IGhhcyBiZWVuIGNoYW5nZWQuXHJcbiAgICAgICAgICAgIHRoaXMuc2VlblJlZ2V4ZXMgPSBbXTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBUdXJucyBhbiBleGNlcHRpb24gaW50byBhbiBvYmplY3QgdGhhdCBjYW4gYmUgc2VudCB0byB0aGUgc2VydmVyLlxyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUuYnVpbGRFeGNlcHRpb25PYmplY3QgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICB2YXIgZXhjT2JqZWN0ID0ge307XHJcbiAgICAgICAgICAgIGlmIChlLnN0YWNrKSB7XHJcbiAgICAgICAgICAgICAgICBleGNPYmplY3Quc3RhY2sgPSBlLnN0YWNrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZXhjT2JqZWN0LmUgPSBlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlLm1lc3NhZ2UpIHtcclxuICAgICAgICAgICAgICAgIGV4Y09iamVjdC5tZXNzYWdlID0gZS5tZXNzYWdlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgIGV4Y09iamVjdC5uYW1lID0gZS5uYW1lO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlLmRhdGEpIHtcclxuICAgICAgICAgICAgICAgIGV4Y09iamVjdC5kYXRhID0gZS5kYXRhO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChlLmlubmVyKSB7XHJcbiAgICAgICAgICAgICAgICBleGNPYmplY3QuaW5uZXIgPSB0aGlzLmJ1aWxkRXhjZXB0aW9uT2JqZWN0KGUuaW5uZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBleGNPYmplY3Q7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBMb2dzIGEgbG9nIGl0ZW0uXHJcbiAgICAgICAgLy8gUGFyYW1ldGVyIGUgY29udGFpbnMgYW4gZXhjZXB0aW9uIChvciBudWxsIG9yIHVuZGVmaW5lZCkuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBSZWFzb24gdGhhdCBwcm9jZXNzaW5nIGV4Y2VwdGlvbnMgaXMgZG9uZSBhdCB0aGlzIGxvdyBsZXZlbCBpcyB0aGF0XHJcbiAgICAgICAgLy8gMSkgbm8gbmVlZCB0byBzcGVuZCB0aGUgY3B1IGN5Y2xlcyBpZiB0aGUgbG9nZ2VyIGlzIHN3aXRjaGVkIG9mZlxyXG4gICAgICAgIC8vIDIpIGZhdGFsRXhjZXB0aW9uIHRha2VzIGJvdGggYSBsb2dPYmplY3QgYW5kIGFuIGV4Y2VwdGlvbiwgYW5kIHRoZSBsb2dPYmplY3RcclxuICAgICAgICAvLyAgICBtYXkgYmUgYSBmdW5jdGlvbiB0aGF0IHNob3VsZCBvbmx5IGJlIGV4ZWN1dGVkIGlmIHRoZSBsb2dnZXIgaXMgc3dpdGNoZWQgb24uXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBJZiBhbiBleGNlcHRpb24gaXMgcGFzc2VkIGluLCB0aGUgY29udGVudHMgb2YgbG9nT2JqZWN0IGlzIGF0dGFjaGVkIHRvIHRoZSBleGNlcHRpb25cclxuICAgICAgICAvLyBvYmplY3QgaW4gYSBuZXcgcHJvcGVydHkgbG9nRGF0YS5cclxuICAgICAgICAvLyBUaGUgcmVzdWx0aW5nIGV4Y2VwdGlvbiBvYmplY3QgaXMgdGhhbiB3b3JrZWQgaW50byBhIG1lc3NhZ2UgdG8gdGhlIHNlcnZlci5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGV4Y2VwdGlvbiwgbG9nT2JqZWN0IGl0c2VsZiBpcyB3b3JrZWQgaW50byB0aGUgbWVzc2FnZSB0byB0aGUgc2VydmVyLlxyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUubG9nID0gZnVuY3Rpb24gKGxldmVsLCBsb2dPYmplY3QsIGUpIHtcclxuICAgICAgICAgICAgdmFyIGkgPSAwO1xyXG4gICAgICAgICAgICB2YXIgY29tcG9zaXRlTWVzc2FnZTtcclxuICAgICAgICAgICAgdmFyIGV4Y09iamVjdDtcclxuICAgICAgICAgICAgLy8gSWYgd2UgY2FuJ3QgZmluZCBhbnkgYXBwZW5kZXJzLCBkbyBub3RoaW5nXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5hcHBlbmRlcnMpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICgoKGxldmVsID49IHRoaXMubGV2ZWwpKSAmJiBhbGxvdyh0aGlzKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBleGNPYmplY3QgPSB0aGlzLmJ1aWxkRXhjZXB0aW9uT2JqZWN0KGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGV4Y09iamVjdC5sb2dEYXRhID0gc3RyaW5naWZ5TG9nT2JqZWN0RnVuY3Rpb24obG9nT2JqZWN0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4Y09iamVjdCA9IGxvZ09iamVjdDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbXBvc2l0ZU1lc3NhZ2UgPSBzdHJpbmdpZnlMb2dPYmplY3QoZXhjT2JqZWN0KTtcclxuICAgICAgICAgICAgICAgIGlmIChhbGxvd01lc3NhZ2UodGhpcywgY29tcG9zaXRlTWVzc2FnZS5maW5hbFN0cmluZykpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBTZWUgd2hldGhlciBtZXNzYWdlIGlzIGEgZHVwbGljYXRlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMub25jZU9ubHkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaSA9IHRoaXMub25jZU9ubHkubGVuZ3RoIC0gMTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGkgPj0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ldyBSZWdFeHAodGhpcy5vbmNlT25seVtpXSkudGVzdChjb21wb3NpdGVNZXNzYWdlLmZpbmFsU3RyaW5nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnNlZW5SZWdleGVzW2ldKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlZW5SZWdleGVzW2ldID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyBQYXNzIG1lc3NhZ2UgdG8gYWxsIGFwcGVuZGVyc1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIE5vdGUgdGhhdCB0aGVzZSBhcHBlbmRlcnMgY291bGQgYmUgV2luc3RvbiB0cmFuc3BvcnRzXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2ZsYXRpcm9uL3dpbnN0b25cclxuICAgICAgICAgICAgICAgICAgICBjb21wb3NpdGVNZXNzYWdlLm1ldGEgPSBjb21wb3NpdGVNZXNzYWdlLm1ldGEgfHwge307XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gTm90ZSB0aGF0IGlmIHRoZSB1c2VyIGlzIGxvZ2dpbmcgYW4gb2JqZWN0LCBjb21wb3NpdGVNZXNzYWdlLm1ldGEgd2lsbCBob2xkIGEgcmVmZXJlbmNlIHRvIHRoYXQgb2JqZWN0LlxyXG4gICAgICAgICAgICAgICAgICAgIC8vIERvIG5vdCBhZGQgZmllbGRzIHRvIGNvbXBvc2l0ZU1lc3NhZ2UubWV0YSwgb3RoZXJ3aXNlIHRoZSB1c2VyJ3Mgb2JqZWN0IHdpbGwgZ2V0IHRoYXQgZmllbGQgb3V0IG9mIHRoZSBibHVlLlxyXG4gICAgICAgICAgICAgICAgICAgIGkgPSB0aGlzLmFwcGVuZGVycy5sZW5ndGggLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChpID49IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hcHBlbmRlcnNbaV0ubG9nKGxldmVsVG9TdHJpbmcobGV2ZWwpLCBjb21wb3NpdGVNZXNzYWdlLm1zZywgY29tcG9zaXRlTWVzc2FnZS5tZXRhLCBmdW5jdGlvbiAoKSB7IH0sIGxldmVsLCBjb21wb3NpdGVNZXNzYWdlLmZpbmFsU3RyaW5nLCB0aGlzLmxvZ2dlck5hbWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpLS07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgTG9nZ2VyLnByb3RvdHlwZS50cmFjZSA9IGZ1bmN0aW9uIChsb2dPYmplY3QpIHsgcmV0dXJuIHRoaXMubG9nKGdldFRyYWNlTGV2ZWwoKSwgbG9nT2JqZWN0KTsgfTtcclxuICAgICAgICBMb2dnZXIucHJvdG90eXBlLmRlYnVnID0gZnVuY3Rpb24gKGxvZ09iamVjdCkgeyByZXR1cm4gdGhpcy5sb2coZ2V0RGVidWdMZXZlbCgpLCBsb2dPYmplY3QpOyB9O1xyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUuaW5mbyA9IGZ1bmN0aW9uIChsb2dPYmplY3QpIHsgcmV0dXJuIHRoaXMubG9nKGdldEluZm9MZXZlbCgpLCBsb2dPYmplY3QpOyB9O1xyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUud2FybiA9IGZ1bmN0aW9uIChsb2dPYmplY3QpIHsgcmV0dXJuIHRoaXMubG9nKGdldFdhcm5MZXZlbCgpLCBsb2dPYmplY3QpOyB9O1xyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUuZXJyb3IgPSBmdW5jdGlvbiAobG9nT2JqZWN0KSB7IHJldHVybiB0aGlzLmxvZyhnZXRFcnJvckxldmVsKCksIGxvZ09iamVjdCk7IH07XHJcbiAgICAgICAgTG9nZ2VyLnByb3RvdHlwZS5mYXRhbCA9IGZ1bmN0aW9uIChsb2dPYmplY3QpIHsgcmV0dXJuIHRoaXMubG9nKGdldEZhdGFsTGV2ZWwoKSwgbG9nT2JqZWN0KTsgfTtcclxuICAgICAgICBMb2dnZXIucHJvdG90eXBlLmZhdGFsRXhjZXB0aW9uID0gZnVuY3Rpb24gKGxvZ09iamVjdCwgZSkgeyByZXR1cm4gdGhpcy5sb2coZ2V0RmF0YWxMZXZlbCgpLCBsb2dPYmplY3QsIGUpOyB9O1xyXG4gICAgICAgIHJldHVybiBMb2dnZXI7XHJcbiAgICB9KCkpO1xyXG4gICAgSkwuTG9nZ2VyID0gTG9nZ2VyO1xyXG4gICAgZnVuY3Rpb24gY3JlYXRlQWpheEFwcGVuZGVyKGFwcGVuZGVyTmFtZSkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQWpheEFwcGVuZGVyKGFwcGVuZGVyTmFtZSk7XHJcbiAgICB9XHJcbiAgICBKTC5jcmVhdGVBamF4QXBwZW5kZXIgPSBjcmVhdGVBamF4QXBwZW5kZXI7XHJcbiAgICBmdW5jdGlvbiBjcmVhdGVDb25zb2xlQXBwZW5kZXIoYXBwZW5kZXJOYW1lKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBDb25zb2xlQXBwZW5kZXIoYXBwZW5kZXJOYW1lKTtcclxuICAgIH1cclxuICAgIEpMLmNyZWF0ZUNvbnNvbGVBcHBlbmRlciA9IGNyZWF0ZUNvbnNvbGVBcHBlbmRlcjtcclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICAvLyBJbiB0aGUgYnJvd3NlciwgdGhlIGRlZmF1bHQgYXBwZW5kZXIgaXMgdGhlIEFqYXhBcHBlbmRlci5cclxuICAgIC8vIFVuZGVyIG5vZGVqcyAod2hlcmUgdGhlcmUgaXMgbm8gXCJ3aW5kb3dcIiksIHVzZSB0aGUgQ29uc29sZUFwcGVuZGVyIGluc3RlYWQuXHJcbiAgICAvLyBcclxuICAgIC8vIERvIE5PVCBjcmVhdGUgYW4gQWpheEFwcGVuZGVyIG9iamVjdCBpZiB5b3UgYXJlIG5vdCBvbiBhIGJyb3dzZXIgKHRoYXQgaXMsIHdpbmRvdyBpcyBub3QgZGVmaW5lZCkuXHJcbiAgICAvLyBUaGF0IHdvdWxkIHRyeSB0byBjcmVhdGUgYW4gWG1sSHR0cFJlcXVlc3Qgb2JqZWN0LCB3aGljaCB3aWxsIGNyYXNoIG91dHNpZGUgYSBicm93c2VyLlxyXG4gICAgdmFyIGRlZmF1bHRBcHBlbmRlcjtcclxuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIGRlZmF1bHRBcHBlbmRlciA9IG5ldyBBamF4QXBwZW5kZXIoXCJcIik7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgICBkZWZhdWx0QXBwZW5kZXIgPSBuZXcgQ29uc29sZUFwcGVuZGVyKFwiXCIpO1xyXG4gICAgfVxyXG4gICAgLy8gQ3JlYXRlIHJvb3QgbG9nZ2VyXHJcbiAgICAvL1xyXG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgdGhlIHBhcmVudCBvZiBhbGwgb3RoZXIgbG9nZ2Vycy5cclxuICAgIC8vIExvZ2dlciBcInhcIiB3aWxsIGJlIHN0b3JlZCBhdFxyXG4gICAgLy8gSkwuX18ueFxyXG4gICAgLy8gTG9nZ2VyIFwieC55XCIgYXRcclxuICAgIC8vIEpMLl9fLngueVxyXG4gICAgSkwuX18gPSBuZXcgSkwuTG9nZ2VyKFwiXCIpO1xyXG4gICAgSkwuX18uc2V0T3B0aW9ucyh7XHJcbiAgICAgICAgbGV2ZWw6IEpMLmdldERlYnVnTGV2ZWwoKSxcclxuICAgICAgICBhcHBlbmRlcnM6IFtkZWZhdWx0QXBwZW5kZXJdXHJcbiAgICB9KTtcclxufSkoSkwgfHwgKEpMID0ge30pKTtcclxuaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgLy8gQWxsb3dzIFN5c3RlbUpzIHRvIGltcG9ydCBqc25sb2cuanMuIFNlZVxyXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21wZXJkZWNrL2pzbmxvZy5qcy9pc3N1ZXMvNTZcclxuICAgIGV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XHJcbiAgICBleHBvcnRzLkpMID0gSkw7XHJcbn1cclxuLy8gU3VwcG9ydCBBTUQgbW9kdWxlIGZvcm1hdFxyXG52YXIgZGVmaW5lO1xyXG5pZiAodHlwZW9mIGRlZmluZSA9PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcclxuICAgIGRlZmluZSgnanNubG9nJywgW10sIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gSkw7XHJcbiAgICB9KTtcclxufVxyXG4vLyBJZiB0aGUgX19qc25sb2dfY29uZmlndXJlIGdsb2JhbCBmdW5jdGlvbiBoYXMgYmVlblxyXG4vLyBjcmVhdGVkLCBjYWxsIGl0IG5vdy4gVGhpcyBhbGxvd3MgeW91IHRvIGNyZWF0ZSBhIGdsb2JhbCBmdW5jdGlvblxyXG4vLyBzZXR0aW5nIGxvZ2dlciBvcHRpb25zIGV0Yy4gaW5saW5lIGluIHRoZSBwYWdlIGJlZm9yZSBqc25sb2cuanNcclxuLy8gaGFzIGJlZW4gbG9hZGVkLlxyXG5pZiAodHlwZW9mIF9fanNubG9nX2NvbmZpZ3VyZSA9PSAnZnVuY3Rpb24nKSB7XHJcbiAgICBfX2pzbmxvZ19jb25maWd1cmUoSkwpO1xyXG59XHJcbi8vIENyZWF0ZSBvbmVycm9yIGhhbmRsZXIgdG8gbG9nIHVuY2F1Z2h0IGV4Y2VwdGlvbnMgdG8gdGhlIHNlcnZlciBzaWRlIGxvZywgYnV0IG9ubHkgaWYgdGhlcmUgXHJcbi8vIGlzIG5vIHN1Y2ggaGFuZGxlciBhbHJlYWR5LlxyXG4vLyBNdXN0IHVzZSBcInR5cGVvZiB3aW5kb3dcIiBoZXJlLCBiZWNhdXNlIGluIE5vZGVKcywgd2luZG93IGlzIG5vdCBkZWZpbmVkIGF0IGFsbCwgc28gY2Fubm90IHJlZmVyIHRvIHdpbmRvdyBpbiBhbnkgd2F5LlxyXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgIXdpbmRvdy5vbmVycm9yKSB7XHJcbiAgICB3aW5kb3cub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvck1zZywgdXJsLCBsaW5lTnVtYmVyLCBjb2x1bW4sIGVycm9yT2JqKSB7XHJcbiAgICAgICAgLy8gU2VuZCBvYmplY3Qgd2l0aCBhbGwgZGF0YSB0byBzZXJ2ZXIgc2lkZSBsb2csIHVzaW5nIHNldmVyaXR5IGZhdGFsLCBcclxuICAgICAgICAvLyBmcm9tIGxvZ2dlciBcIm9uZXJyb3JMb2dnZXJcIlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gVXNlIGVycm9yTXNnLm1lc3NhZ2UgaWYgYXZhaWxhYmxlLCBzbyBBbmd1bGFyIDQgdGVtcGxhdGUgZXJyb3JzIHdpbGwgYmUgbG9nZ2VkLlxyXG4gICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbXBlcmRlY2svanNubG9nLmpzL3B1bGwvNjhcclxuICAgICAgICBKTChcIm9uZXJyb3JMb2dnZXJcIikuZmF0YWxFeGNlcHRpb24oe1xyXG4gICAgICAgICAgICBcIm1zZ1wiOiBcIlVuY2F1Z2h0IEV4Y2VwdGlvblwiLFxyXG4gICAgICAgICAgICBcImVycm9yTXNnXCI6IGVycm9yTXNnID8gKGVycm9yTXNnLm1lc3NhZ2UgfHwgZXJyb3JNc2cpIDogJycsXHJcbiAgICAgICAgICAgIFwidXJsXCI6IHVybCxcclxuICAgICAgICAgICAgXCJsaW5lIG51bWJlclwiOiBsaW5lTnVtYmVyLCBcImNvbHVtblwiOiBjb2x1bW5cclxuICAgICAgICB9LCBlcnJvck9iaik7XHJcbiAgICAgICAgLy8gVGVsbCBicm93c2VyIHRvIHJ1biBpdHMgb3duIGVycm9yIGhhbmRsZXIgYXMgd2VsbCAgIFxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH07XHJcbn1cclxuLy8gRGVhbCB3aXRoIHVuaGFuZGxlZCBleGNlcHRpb25zIHRocm93biBpbiBwcm9taXNlc1xyXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgIXdpbmRvdy5vbnVuaGFuZGxlZHJlamVjdGlvbikge1xyXG4gICAgd2luZG93Lm9udW5oYW5kbGVkcmVqZWN0aW9uID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgLy8gU2VuZCBvYmplY3Qgd2l0aCBhbGwgZGF0YSB0byBzZXJ2ZXIgc2lkZSBsb2csIHVzaW5nIHNldmVyaXR5IGZhdGFsLCBcclxuICAgICAgICAvLyBmcm9tIGxvZ2dlciBcIm9uZXJyb3JMb2dnZXJcIi5cclxuICAgICAgICAvLyBOZWVkIHRvIGNoZWNrIGJvdGggZXZlbnQucmVhc29uLm1lc3NhZ2UgYW5kIGV2ZW50Lm1lc3NhZ2UsXHJcbiAgICAgICAgLy8gYmVjYXVzZSBTeXN0ZW1KcyB3cmFwcyBleGNlcHRpb25zIGFuZCB0aHJvd3MgYSBuZXcgb2JqZWN0IHdoaWNoIGRvZXNuJ3QgaGF2ZSBhIHJlYXNvbiBwcm9wZXJ0eS5cclxuICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3N5c3RlbWpzL3N5c3RlbWpzL2lzc3Vlcy8xMzA5XHJcbiAgICAgICAgSkwoXCJvbmVycm9yTG9nZ2VyXCIpLmZhdGFsRXhjZXB0aW9uKHtcclxuICAgICAgICAgICAgXCJtc2dcIjogXCJ1bmhhbmRsZWRyZWplY3Rpb25cIixcclxuICAgICAgICAgICAgXCJlcnJvck1zZ1wiOiBldmVudC5yZWFzb24gPyBldmVudC5yZWFzb24ubWVzc2FnZSA6IGV2ZW50Lm1lc3NhZ2UgfHwgbnVsbFxyXG4gICAgICAgIH0sIGV2ZW50LnJlYXNvbik7XHJcbiAgICB9O1xyXG59XHJcbiIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBAcGFyYW0gdHlwZU1hcCBbT2JqZWN0XSBNYXAgb2YgTUlNRSB0eXBlIC0+IEFycmF5W2V4dGVuc2lvbnNdXG4gKiBAcGFyYW0gLi4uXG4gKi9cbmZ1bmN0aW9uIE1pbWUoKSB7XG4gIHRoaXMuX3R5cGVzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgdGhpcy5fZXh0ZW5zaW9ucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICB0aGlzLmRlZmluZShhcmd1bWVudHNbaV0pO1xuICB9XG5cbiAgdGhpcy5kZWZpbmUgPSB0aGlzLmRlZmluZS5iaW5kKHRoaXMpO1xuICB0aGlzLmdldFR5cGUgPSB0aGlzLmdldFR5cGUuYmluZCh0aGlzKTtcbiAgdGhpcy5nZXRFeHRlbnNpb24gPSB0aGlzLmdldEV4dGVuc2lvbi5iaW5kKHRoaXMpO1xufVxuXG4vKipcbiAqIERlZmluZSBtaW1ldHlwZSAtPiBleHRlbnNpb24gbWFwcGluZ3MuICBFYWNoIGtleSBpcyBhIG1pbWUtdHlwZSB0aGF0IG1hcHNcbiAqIHRvIGFuIGFycmF5IG9mIGV4dGVuc2lvbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSB0eXBlLiAgVGhlIGZpcnN0IGV4dGVuc2lvbiBpc1xuICogdXNlZCBhcyB0aGUgZGVmYXVsdCBleHRlbnNpb24gZm9yIHRoZSB0eXBlLlxuICpcbiAqIGUuZy4gbWltZS5kZWZpbmUoeydhdWRpby9vZ2cnLCBbJ29nYScsICdvZ2cnLCAnc3B4J119KTtcbiAqXG4gKiBJZiBhIHR5cGUgZGVjbGFyZXMgYW4gZXh0ZW5zaW9uIHRoYXQgaGFzIGFscmVhZHkgYmVlbiBkZWZpbmVkLCBhbiBlcnJvciB3aWxsXG4gKiBiZSB0aHJvd24uICBUbyBzdXBwcmVzcyB0aGlzIGVycm9yIGFuZCBmb3JjZSB0aGUgZXh0ZW5zaW9uIHRvIGJlIGFzc29jaWF0ZWRcbiAqIHdpdGggdGhlIG5ldyB0eXBlLCBwYXNzIGBmb3JjZWA9dHJ1ZS4gIEFsdGVybmF0aXZlbHksIHlvdSBtYXkgcHJlZml4IHRoZVxuICogZXh0ZW5zaW9uIHdpdGggXCIqXCIgdG8gbWFwIHRoZSB0eXBlIHRvIGV4dGVuc2lvbiwgd2l0aG91dCBtYXBwaW5nIHRoZVxuICogZXh0ZW5zaW9uIHRvIHRoZSB0eXBlLlxuICpcbiAqIGUuZy4gbWltZS5kZWZpbmUoeydhdWRpby93YXYnLCBbJ3dhdiddfSwgeydhdWRpby94LXdhdicsIFsnKndhdiddfSk7XG4gKlxuICpcbiAqIEBwYXJhbSBtYXAgKE9iamVjdCkgdHlwZSBkZWZpbml0aW9uc1xuICogQHBhcmFtIGZvcmNlIChCb29sZWFuKSBpZiB0cnVlLCBmb3JjZSBvdmVycmlkaW5nIG9mIGV4aXN0aW5nIGRlZmluaXRpb25zXG4gKi9cbk1pbWUucHJvdG90eXBlLmRlZmluZSA9IGZ1bmN0aW9uKHR5cGVNYXAsIGZvcmNlKSB7XG4gIGZvciAobGV0IHR5cGUgaW4gdHlwZU1hcCkge1xuICAgIGxldCBleHRlbnNpb25zID0gdHlwZU1hcFt0eXBlXS5tYXAoZnVuY3Rpb24odCkge1xuICAgICAgcmV0dXJuIHQudG9Mb3dlckNhc2UoKTtcbiAgICB9KTtcbiAgICB0eXBlID0gdHlwZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBleHRlbnNpb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBleHQgPSBleHRlbnNpb25zW2ldO1xuXG4gICAgICAvLyAnKicgcHJlZml4ID0gbm90IHRoZSBwcmVmZXJyZWQgdHlwZSBmb3IgdGhpcyBleHRlbnNpb24uICBTbyBmaXh1cCB0aGVcbiAgICAgIC8vIGV4dGVuc2lvbiwgYW5kIHNraXAgaXQuXG4gICAgICBpZiAoZXh0WzBdID09PSAnKicpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmICghZm9yY2UgJiYgKGV4dCBpbiB0aGlzLl90eXBlcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICdBdHRlbXB0IHRvIGNoYW5nZSBtYXBwaW5nIGZvciBcIicgKyBleHQgK1xuICAgICAgICAgICdcIiBleHRlbnNpb24gZnJvbSBcIicgKyB0aGlzLl90eXBlc1tleHRdICsgJ1wiIHRvIFwiJyArIHR5cGUgK1xuICAgICAgICAgICdcIi4gUGFzcyBgZm9yY2U9dHJ1ZWAgdG8gYWxsb3cgdGhpcywgb3RoZXJ3aXNlIHJlbW92ZSBcIicgKyBleHQgK1xuICAgICAgICAgICdcIiBmcm9tIHRoZSBsaXN0IG9mIGV4dGVuc2lvbnMgZm9yIFwiJyArIHR5cGUgKyAnXCIuJ1xuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl90eXBlc1tleHRdID0gdHlwZTtcbiAgICB9XG5cbiAgICAvLyBVc2UgZmlyc3QgZXh0ZW5zaW9uIGFzIGRlZmF1bHRcbiAgICBpZiAoZm9yY2UgfHwgIXRoaXMuX2V4dGVuc2lvbnNbdHlwZV0pIHtcbiAgICAgIGNvbnN0IGV4dCA9IGV4dGVuc2lvbnNbMF07XG4gICAgICB0aGlzLl9leHRlbnNpb25zW3R5cGVdID0gKGV4dFswXSAhPT0gJyonKSA/IGV4dCA6IGV4dC5zdWJzdHIoMSk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIExvb2t1cCBhIG1pbWUgdHlwZSBiYXNlZCBvbiBleHRlbnNpb25cbiAqL1xuTWltZS5wcm90b3R5cGUuZ2V0VHlwZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgcGF0aCA9IFN0cmluZyhwYXRoKTtcbiAgbGV0IGxhc3QgPSBwYXRoLnJlcGxhY2UoL14uKlsvXFxcXF0vLCAnJykudG9Mb3dlckNhc2UoKTtcbiAgbGV0IGV4dCA9IGxhc3QucmVwbGFjZSgvXi4qXFwuLywgJycpLnRvTG93ZXJDYXNlKCk7XG5cbiAgbGV0IGhhc1BhdGggPSBsYXN0Lmxlbmd0aCA8IHBhdGgubGVuZ3RoO1xuICBsZXQgaGFzRG90ID0gZXh0Lmxlbmd0aCA8IGxhc3QubGVuZ3RoIC0gMTtcblxuICByZXR1cm4gKGhhc0RvdCB8fCAhaGFzUGF0aCkgJiYgdGhpcy5fdHlwZXNbZXh0XSB8fCBudWxsO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gZmlsZSBleHRlbnNpb24gYXNzb2NpYXRlZCB3aXRoIGEgbWltZSB0eXBlXG4gKi9cbk1pbWUucHJvdG90eXBlLmdldEV4dGVuc2lvbiA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdHlwZSA9IC9eXFxzKihbXjtcXHNdKikvLnRlc3QodHlwZSkgJiYgUmVnRXhwLiQxO1xuICByZXR1cm4gdHlwZSAmJiB0aGlzLl9leHRlbnNpb25zW3R5cGUudG9Mb3dlckNhc2UoKV0gfHwgbnVsbDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gTWltZTtcbiIsIid1c2Ugc3RyaWN0JztcblxubGV0IE1pbWUgPSByZXF1aXJlKCcuL01pbWUnKTtcbm1vZHVsZS5leHBvcnRzID0gbmV3IE1pbWUocmVxdWlyZSgnLi90eXBlcy9zdGFuZGFyZCcpKTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1wiYXBwbGljYXRpb24vYW5kcmV3LWluc2V0XCI6W1wiZXpcIl0sXCJhcHBsaWNhdGlvbi9hcHBsaXh3YXJlXCI6W1wiYXdcIl0sXCJhcHBsaWNhdGlvbi9hdG9tK3htbFwiOltcImF0b21cIl0sXCJhcHBsaWNhdGlvbi9hdG9tY2F0K3htbFwiOltcImF0b21jYXRcIl0sXCJhcHBsaWNhdGlvbi9hdG9tZGVsZXRlZCt4bWxcIjpbXCJhdG9tZGVsZXRlZFwiXSxcImFwcGxpY2F0aW9uL2F0b21zdmMreG1sXCI6W1wiYXRvbXN2Y1wiXSxcImFwcGxpY2F0aW9uL2F0c2MtZHdkK3htbFwiOltcImR3ZFwiXSxcImFwcGxpY2F0aW9uL2F0c2MtaGVsZCt4bWxcIjpbXCJoZWxkXCJdLFwiYXBwbGljYXRpb24vYXRzYy1yc2F0K3htbFwiOltcInJzYXRcIl0sXCJhcHBsaWNhdGlvbi9iZG9jXCI6W1wiYmRvY1wiXSxcImFwcGxpY2F0aW9uL2NhbGVuZGFyK3htbFwiOltcInhjc1wiXSxcImFwcGxpY2F0aW9uL2NjeG1sK3htbFwiOltcImNjeG1sXCJdLFwiYXBwbGljYXRpb24vY2RmeCt4bWxcIjpbXCJjZGZ4XCJdLFwiYXBwbGljYXRpb24vY2RtaS1jYXBhYmlsaXR5XCI6W1wiY2RtaWFcIl0sXCJhcHBsaWNhdGlvbi9jZG1pLWNvbnRhaW5lclwiOltcImNkbWljXCJdLFwiYXBwbGljYXRpb24vY2RtaS1kb21haW5cIjpbXCJjZG1pZFwiXSxcImFwcGxpY2F0aW9uL2NkbWktb2JqZWN0XCI6W1wiY2RtaW9cIl0sXCJhcHBsaWNhdGlvbi9jZG1pLXF1ZXVlXCI6W1wiY2RtaXFcIl0sXCJhcHBsaWNhdGlvbi9jdS1zZWVtZVwiOltcImN1XCJdLFwiYXBwbGljYXRpb24vZGFzaCt4bWxcIjpbXCJtcGRcIl0sXCJhcHBsaWNhdGlvbi9kYXZtb3VudCt4bWxcIjpbXCJkYXZtb3VudFwiXSxcImFwcGxpY2F0aW9uL2RvY2Jvb2sreG1sXCI6W1wiZGJrXCJdLFwiYXBwbGljYXRpb24vZHNzYytkZXJcIjpbXCJkc3NjXCJdLFwiYXBwbGljYXRpb24vZHNzYyt4bWxcIjpbXCJ4ZHNzY1wiXSxcImFwcGxpY2F0aW9uL2VjbWFzY3JpcHRcIjpbXCJlc1wiLFwiZWNtYVwiXSxcImFwcGxpY2F0aW9uL2VtbWEreG1sXCI6W1wiZW1tYVwiXSxcImFwcGxpY2F0aW9uL2Vtb3Rpb25tbCt4bWxcIjpbXCJlbW90aW9ubWxcIl0sXCJhcHBsaWNhdGlvbi9lcHViK3ppcFwiOltcImVwdWJcIl0sXCJhcHBsaWNhdGlvbi9leGlcIjpbXCJleGlcIl0sXCJhcHBsaWNhdGlvbi9leHByZXNzXCI6W1wiZXhwXCJdLFwiYXBwbGljYXRpb24vZmR0K3htbFwiOltcImZkdFwiXSxcImFwcGxpY2F0aW9uL2ZvbnQtdGRwZnJcIjpbXCJwZnJcIl0sXCJhcHBsaWNhdGlvbi9nZW8ranNvblwiOltcImdlb2pzb25cIl0sXCJhcHBsaWNhdGlvbi9nbWwreG1sXCI6W1wiZ21sXCJdLFwiYXBwbGljYXRpb24vZ3B4K3htbFwiOltcImdweFwiXSxcImFwcGxpY2F0aW9uL2d4ZlwiOltcImd4ZlwiXSxcImFwcGxpY2F0aW9uL2d6aXBcIjpbXCJnelwiXSxcImFwcGxpY2F0aW9uL2hqc29uXCI6W1wiaGpzb25cIl0sXCJhcHBsaWNhdGlvbi9oeXBlcnN0dWRpb1wiOltcInN0a1wiXSxcImFwcGxpY2F0aW9uL2lua21sK3htbFwiOltcImlua1wiLFwiaW5rbWxcIl0sXCJhcHBsaWNhdGlvbi9pcGZpeFwiOltcImlwZml4XCJdLFwiYXBwbGljYXRpb24vaXRzK3htbFwiOltcIml0c1wiXSxcImFwcGxpY2F0aW9uL2phdmEtYXJjaGl2ZVwiOltcImphclwiLFwid2FyXCIsXCJlYXJcIl0sXCJhcHBsaWNhdGlvbi9qYXZhLXNlcmlhbGl6ZWQtb2JqZWN0XCI6W1wic2VyXCJdLFwiYXBwbGljYXRpb24vamF2YS12bVwiOltcImNsYXNzXCJdLFwiYXBwbGljYXRpb24vamF2YXNjcmlwdFwiOltcImpzXCIsXCJtanNcIl0sXCJhcHBsaWNhdGlvbi9qc29uXCI6W1wianNvblwiLFwibWFwXCJdLFwiYXBwbGljYXRpb24vanNvbjVcIjpbXCJqc29uNVwiXSxcImFwcGxpY2F0aW9uL2pzb25tbCtqc29uXCI6W1wianNvbm1sXCJdLFwiYXBwbGljYXRpb24vbGQranNvblwiOltcImpzb25sZFwiXSxcImFwcGxpY2F0aW9uL2xncit4bWxcIjpbXCJsZ3JcIl0sXCJhcHBsaWNhdGlvbi9sb3N0K3htbFwiOltcImxvc3R4bWxcIl0sXCJhcHBsaWNhdGlvbi9tYWMtYmluaGV4NDBcIjpbXCJocXhcIl0sXCJhcHBsaWNhdGlvbi9tYWMtY29tcGFjdHByb1wiOltcImNwdFwiXSxcImFwcGxpY2F0aW9uL21hZHMreG1sXCI6W1wibWFkc1wiXSxcImFwcGxpY2F0aW9uL21hbmlmZXN0K2pzb25cIjpbXCJ3ZWJtYW5pZmVzdFwiXSxcImFwcGxpY2F0aW9uL21hcmNcIjpbXCJtcmNcIl0sXCJhcHBsaWNhdGlvbi9tYXJjeG1sK3htbFwiOltcIm1yY3hcIl0sXCJhcHBsaWNhdGlvbi9tYXRoZW1hdGljYVwiOltcIm1hXCIsXCJuYlwiLFwibWJcIl0sXCJhcHBsaWNhdGlvbi9tYXRobWwreG1sXCI6W1wibWF0aG1sXCJdLFwiYXBwbGljYXRpb24vbWJveFwiOltcIm1ib3hcIl0sXCJhcHBsaWNhdGlvbi9tZWRpYXNlcnZlcmNvbnRyb2wreG1sXCI6W1wibXNjbWxcIl0sXCJhcHBsaWNhdGlvbi9tZXRhbGluayt4bWxcIjpbXCJtZXRhbGlua1wiXSxcImFwcGxpY2F0aW9uL21ldGFsaW5rNCt4bWxcIjpbXCJtZXRhNFwiXSxcImFwcGxpY2F0aW9uL21ldHMreG1sXCI6W1wibWV0c1wiXSxcImFwcGxpY2F0aW9uL21tdC1hZWkreG1sXCI6W1wibWFlaVwiXSxcImFwcGxpY2F0aW9uL21tdC11c2QreG1sXCI6W1wibXVzZFwiXSxcImFwcGxpY2F0aW9uL21vZHMreG1sXCI6W1wibW9kc1wiXSxcImFwcGxpY2F0aW9uL21wMjFcIjpbXCJtMjFcIixcIm1wMjFcIl0sXCJhcHBsaWNhdGlvbi9tcDRcIjpbXCJtcDRzXCIsXCJtNHBcIl0sXCJhcHBsaWNhdGlvbi9tc3dvcmRcIjpbXCJkb2NcIixcImRvdFwiXSxcImFwcGxpY2F0aW9uL214ZlwiOltcIm14ZlwiXSxcImFwcGxpY2F0aW9uL24tcXVhZHNcIjpbXCJucVwiXSxcImFwcGxpY2F0aW9uL24tdHJpcGxlc1wiOltcIm50XCJdLFwiYXBwbGljYXRpb24vbm9kZVwiOltcImNqc1wiXSxcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiOltcImJpblwiLFwiZG1zXCIsXCJscmZcIixcIm1hclwiLFwic29cIixcImRpc3RcIixcImRpc3R6XCIsXCJwa2dcIixcImJwa1wiLFwiZHVtcFwiLFwiZWxjXCIsXCJkZXBsb3lcIixcImV4ZVwiLFwiZGxsXCIsXCJkZWJcIixcImRtZ1wiLFwiaXNvXCIsXCJpbWdcIixcIm1zaVwiLFwibXNwXCIsXCJtc21cIixcImJ1ZmZlclwiXSxcImFwcGxpY2F0aW9uL29kYVwiOltcIm9kYVwiXSxcImFwcGxpY2F0aW9uL29lYnBzLXBhY2thZ2UreG1sXCI6W1wib3BmXCJdLFwiYXBwbGljYXRpb24vb2dnXCI6W1wib2d4XCJdLFwiYXBwbGljYXRpb24vb21kb2MreG1sXCI6W1wib21kb2NcIl0sXCJhcHBsaWNhdGlvbi9vbmVub3RlXCI6W1wib25ldG9jXCIsXCJvbmV0b2MyXCIsXCJvbmV0bXBcIixcIm9uZXBrZ1wiXSxcImFwcGxpY2F0aW9uL294cHNcIjpbXCJveHBzXCJdLFwiYXBwbGljYXRpb24vcDJwLW92ZXJsYXkreG1sXCI6W1wicmVsb1wiXSxcImFwcGxpY2F0aW9uL3BhdGNoLW9wcy1lcnJvcit4bWxcIjpbXCJ4ZXJcIl0sXCJhcHBsaWNhdGlvbi9wZGZcIjpbXCJwZGZcIl0sXCJhcHBsaWNhdGlvbi9wZ3AtZW5jcnlwdGVkXCI6W1wicGdwXCJdLFwiYXBwbGljYXRpb24vcGdwLXNpZ25hdHVyZVwiOltcImFzY1wiLFwic2lnXCJdLFwiYXBwbGljYXRpb24vcGljcy1ydWxlc1wiOltcInByZlwiXSxcImFwcGxpY2F0aW9uL3BrY3MxMFwiOltcInAxMFwiXSxcImFwcGxpY2F0aW9uL3BrY3M3LW1pbWVcIjpbXCJwN21cIixcInA3Y1wiXSxcImFwcGxpY2F0aW9uL3BrY3M3LXNpZ25hdHVyZVwiOltcInA3c1wiXSxcImFwcGxpY2F0aW9uL3BrY3M4XCI6W1wicDhcIl0sXCJhcHBsaWNhdGlvbi9wa2l4LWF0dHItY2VydFwiOltcImFjXCJdLFwiYXBwbGljYXRpb24vcGtpeC1jZXJ0XCI6W1wiY2VyXCJdLFwiYXBwbGljYXRpb24vcGtpeC1jcmxcIjpbXCJjcmxcIl0sXCJhcHBsaWNhdGlvbi9wa2l4LXBraXBhdGhcIjpbXCJwa2lwYXRoXCJdLFwiYXBwbGljYXRpb24vcGtpeGNtcFwiOltcInBraVwiXSxcImFwcGxpY2F0aW9uL3Bscyt4bWxcIjpbXCJwbHNcIl0sXCJhcHBsaWNhdGlvbi9wb3N0c2NyaXB0XCI6W1wiYWlcIixcImVwc1wiLFwicHNcIl0sXCJhcHBsaWNhdGlvbi9wcm92ZW5hbmNlK3htbFwiOltcInByb3Z4XCJdLFwiYXBwbGljYXRpb24vcHNrYyt4bWxcIjpbXCJwc2tjeG1sXCJdLFwiYXBwbGljYXRpb24vcmFtbCt5YW1sXCI6W1wicmFtbFwiXSxcImFwcGxpY2F0aW9uL3JkZit4bWxcIjpbXCJyZGZcIixcIm93bFwiXSxcImFwcGxpY2F0aW9uL3JlZ2luZm8reG1sXCI6W1wicmlmXCJdLFwiYXBwbGljYXRpb24vcmVsYXgtbmctY29tcGFjdC1zeW50YXhcIjpbXCJybmNcIl0sXCJhcHBsaWNhdGlvbi9yZXNvdXJjZS1saXN0cyt4bWxcIjpbXCJybFwiXSxcImFwcGxpY2F0aW9uL3Jlc291cmNlLWxpc3RzLWRpZmYreG1sXCI6W1wicmxkXCJdLFwiYXBwbGljYXRpb24vcmxzLXNlcnZpY2VzK3htbFwiOltcInJzXCJdLFwiYXBwbGljYXRpb24vcm91dGUtYXBkK3htbFwiOltcInJhcGRcIl0sXCJhcHBsaWNhdGlvbi9yb3V0ZS1zLXRzaWQreG1sXCI6W1wic2xzXCJdLFwiYXBwbGljYXRpb24vcm91dGUtdXNkK3htbFwiOltcInJ1c2RcIl0sXCJhcHBsaWNhdGlvbi9ycGtpLWdob3N0YnVzdGVyc1wiOltcImdiclwiXSxcImFwcGxpY2F0aW9uL3Jwa2ktbWFuaWZlc3RcIjpbXCJtZnRcIl0sXCJhcHBsaWNhdGlvbi9ycGtpLXJvYVwiOltcInJvYVwiXSxcImFwcGxpY2F0aW9uL3JzZCt4bWxcIjpbXCJyc2RcIl0sXCJhcHBsaWNhdGlvbi9yc3MreG1sXCI6W1wicnNzXCJdLFwiYXBwbGljYXRpb24vcnRmXCI6W1wicnRmXCJdLFwiYXBwbGljYXRpb24vc2JtbCt4bWxcIjpbXCJzYm1sXCJdLFwiYXBwbGljYXRpb24vc2N2cC1jdi1yZXF1ZXN0XCI6W1wic2NxXCJdLFwiYXBwbGljYXRpb24vc2N2cC1jdi1yZXNwb25zZVwiOltcInNjc1wiXSxcImFwcGxpY2F0aW9uL3NjdnAtdnAtcmVxdWVzdFwiOltcInNwcVwiXSxcImFwcGxpY2F0aW9uL3NjdnAtdnAtcmVzcG9uc2VcIjpbXCJzcHBcIl0sXCJhcHBsaWNhdGlvbi9zZHBcIjpbXCJzZHBcIl0sXCJhcHBsaWNhdGlvbi9zZW5tbCt4bWxcIjpbXCJzZW5tbHhcIl0sXCJhcHBsaWNhdGlvbi9zZW5zbWwreG1sXCI6W1wic2Vuc21seFwiXSxcImFwcGxpY2F0aW9uL3NldC1wYXltZW50LWluaXRpYXRpb25cIjpbXCJzZXRwYXlcIl0sXCJhcHBsaWNhdGlvbi9zZXQtcmVnaXN0cmF0aW9uLWluaXRpYXRpb25cIjpbXCJzZXRyZWdcIl0sXCJhcHBsaWNhdGlvbi9zaGYreG1sXCI6W1wic2hmXCJdLFwiYXBwbGljYXRpb24vc2lldmVcIjpbXCJzaXZcIixcInNpZXZlXCJdLFwiYXBwbGljYXRpb24vc21pbCt4bWxcIjpbXCJzbWlcIixcInNtaWxcIl0sXCJhcHBsaWNhdGlvbi9zcGFycWwtcXVlcnlcIjpbXCJycVwiXSxcImFwcGxpY2F0aW9uL3NwYXJxbC1yZXN1bHRzK3htbFwiOltcInNyeFwiXSxcImFwcGxpY2F0aW9uL3NyZ3NcIjpbXCJncmFtXCJdLFwiYXBwbGljYXRpb24vc3Jncyt4bWxcIjpbXCJncnhtbFwiXSxcImFwcGxpY2F0aW9uL3NydSt4bWxcIjpbXCJzcnVcIl0sXCJhcHBsaWNhdGlvbi9zc2RsK3htbFwiOltcInNzZGxcIl0sXCJhcHBsaWNhdGlvbi9zc21sK3htbFwiOltcInNzbWxcIl0sXCJhcHBsaWNhdGlvbi9zd2lkK3htbFwiOltcInN3aWR0YWdcIl0sXCJhcHBsaWNhdGlvbi90ZWkreG1sXCI6W1widGVpXCIsXCJ0ZWljb3JwdXNcIl0sXCJhcHBsaWNhdGlvbi90aHJhdWQreG1sXCI6W1widGZpXCJdLFwiYXBwbGljYXRpb24vdGltZXN0YW1wZWQtZGF0YVwiOltcInRzZFwiXSxcImFwcGxpY2F0aW9uL3RvbWxcIjpbXCJ0b21sXCJdLFwiYXBwbGljYXRpb24vdHJpZ1wiOltcInRyaWdcIl0sXCJhcHBsaWNhdGlvbi90dG1sK3htbFwiOltcInR0bWxcIl0sXCJhcHBsaWNhdGlvbi91Ympzb25cIjpbXCJ1YmpcIl0sXCJhcHBsaWNhdGlvbi91cmMtcmVzc2hlZXQreG1sXCI6W1wicnNoZWV0XCJdLFwiYXBwbGljYXRpb24vdXJjLXRhcmdldGRlc2MreG1sXCI6W1widGRcIl0sXCJhcHBsaWNhdGlvbi92b2ljZXhtbCt4bWxcIjpbXCJ2eG1sXCJdLFwiYXBwbGljYXRpb24vd2FzbVwiOltcIndhc21cIl0sXCJhcHBsaWNhdGlvbi93aWRnZXRcIjpbXCJ3Z3RcIl0sXCJhcHBsaWNhdGlvbi93aW5obHBcIjpbXCJobHBcIl0sXCJhcHBsaWNhdGlvbi93c2RsK3htbFwiOltcIndzZGxcIl0sXCJhcHBsaWNhdGlvbi93c3BvbGljeSt4bWxcIjpbXCJ3c3BvbGljeVwiXSxcImFwcGxpY2F0aW9uL3hhbWwreG1sXCI6W1wieGFtbFwiXSxcImFwcGxpY2F0aW9uL3hjYXAtYXR0K3htbFwiOltcInhhdlwiXSxcImFwcGxpY2F0aW9uL3hjYXAtY2Fwcyt4bWxcIjpbXCJ4Y2FcIl0sXCJhcHBsaWNhdGlvbi94Y2FwLWRpZmYreG1sXCI6W1wieGRmXCJdLFwiYXBwbGljYXRpb24veGNhcC1lbCt4bWxcIjpbXCJ4ZWxcIl0sXCJhcHBsaWNhdGlvbi94Y2FwLW5zK3htbFwiOltcInhuc1wiXSxcImFwcGxpY2F0aW9uL3hlbmMreG1sXCI6W1wieGVuY1wiXSxcImFwcGxpY2F0aW9uL3hodG1sK3htbFwiOltcInhodG1sXCIsXCJ4aHRcIl0sXCJhcHBsaWNhdGlvbi94bGlmZit4bWxcIjpbXCJ4bGZcIl0sXCJhcHBsaWNhdGlvbi94bWxcIjpbXCJ4bWxcIixcInhzbFwiLFwieHNkXCIsXCJybmdcIl0sXCJhcHBsaWNhdGlvbi94bWwtZHRkXCI6W1wiZHRkXCJdLFwiYXBwbGljYXRpb24veG9wK3htbFwiOltcInhvcFwiXSxcImFwcGxpY2F0aW9uL3hwcm9jK3htbFwiOltcInhwbFwiXSxcImFwcGxpY2F0aW9uL3hzbHQreG1sXCI6W1wiKnhzbFwiLFwieHNsdFwiXSxcImFwcGxpY2F0aW9uL3hzcGYreG1sXCI6W1wieHNwZlwiXSxcImFwcGxpY2F0aW9uL3h2K3htbFwiOltcIm14bWxcIixcInhodm1sXCIsXCJ4dm1sXCIsXCJ4dm1cIl0sXCJhcHBsaWNhdGlvbi95YW5nXCI6W1wieWFuZ1wiXSxcImFwcGxpY2F0aW9uL3lpbit4bWxcIjpbXCJ5aW5cIl0sXCJhcHBsaWNhdGlvbi96aXBcIjpbXCJ6aXBcIl0sXCJhdWRpby8zZ3BwXCI6W1wiKjNncHBcIl0sXCJhdWRpby9hZHBjbVwiOltcImFkcFwiXSxcImF1ZGlvL2FtclwiOltcImFtclwiXSxcImF1ZGlvL2Jhc2ljXCI6W1wiYXVcIixcInNuZFwiXSxcImF1ZGlvL21pZGlcIjpbXCJtaWRcIixcIm1pZGlcIixcImthclwiLFwicm1pXCJdLFwiYXVkaW8vbW9iaWxlLXhtZlwiOltcIm14bWZcIl0sXCJhdWRpby9tcDNcIjpbXCIqbXAzXCJdLFwiYXVkaW8vbXA0XCI6W1wibTRhXCIsXCJtcDRhXCJdLFwiYXVkaW8vbXBlZ1wiOltcIm1wZ2FcIixcIm1wMlwiLFwibXAyYVwiLFwibXAzXCIsXCJtMmFcIixcIm0zYVwiXSxcImF1ZGlvL29nZ1wiOltcIm9nYVwiLFwib2dnXCIsXCJzcHhcIixcIm9wdXNcIl0sXCJhdWRpby9zM21cIjpbXCJzM21cIl0sXCJhdWRpby9zaWxrXCI6W1wic2lsXCJdLFwiYXVkaW8vd2F2XCI6W1wid2F2XCJdLFwiYXVkaW8vd2F2ZVwiOltcIip3YXZcIl0sXCJhdWRpby93ZWJtXCI6W1wid2ViYVwiXSxcImF1ZGlvL3htXCI6W1wieG1cIl0sXCJmb250L2NvbGxlY3Rpb25cIjpbXCJ0dGNcIl0sXCJmb250L290ZlwiOltcIm90ZlwiXSxcImZvbnQvdHRmXCI6W1widHRmXCJdLFwiZm9udC93b2ZmXCI6W1wid29mZlwiXSxcImZvbnQvd29mZjJcIjpbXCJ3b2ZmMlwiXSxcImltYWdlL2FjZXNcIjpbXCJleHJcIl0sXCJpbWFnZS9hcG5nXCI6W1wiYXBuZ1wiXSxcImltYWdlL2F2aWZcIjpbXCJhdmlmXCJdLFwiaW1hZ2UvYm1wXCI6W1wiYm1wXCJdLFwiaW1hZ2UvY2dtXCI6W1wiY2dtXCJdLFwiaW1hZ2UvZGljb20tcmxlXCI6W1wiZHJsZVwiXSxcImltYWdlL2VtZlwiOltcImVtZlwiXSxcImltYWdlL2ZpdHNcIjpbXCJmaXRzXCJdLFwiaW1hZ2UvZzNmYXhcIjpbXCJnM1wiXSxcImltYWdlL2dpZlwiOltcImdpZlwiXSxcImltYWdlL2hlaWNcIjpbXCJoZWljXCJdLFwiaW1hZ2UvaGVpYy1zZXF1ZW5jZVwiOltcImhlaWNzXCJdLFwiaW1hZ2UvaGVpZlwiOltcImhlaWZcIl0sXCJpbWFnZS9oZWlmLXNlcXVlbmNlXCI6W1wiaGVpZnNcIl0sXCJpbWFnZS9oZWoya1wiOltcImhlajJcIl0sXCJpbWFnZS9oc2oyXCI6W1wiaHNqMlwiXSxcImltYWdlL2llZlwiOltcImllZlwiXSxcImltYWdlL2psc1wiOltcImpsc1wiXSxcImltYWdlL2pwMlwiOltcImpwMlwiLFwianBnMlwiXSxcImltYWdlL2pwZWdcIjpbXCJqcGVnXCIsXCJqcGdcIixcImpwZVwiXSxcImltYWdlL2pwaFwiOltcImpwaFwiXSxcImltYWdlL2pwaGNcIjpbXCJqaGNcIl0sXCJpbWFnZS9qcG1cIjpbXCJqcG1cIl0sXCJpbWFnZS9qcHhcIjpbXCJqcHhcIixcImpwZlwiXSxcImltYWdlL2p4clwiOltcImp4clwiXSxcImltYWdlL2p4cmFcIjpbXCJqeHJhXCJdLFwiaW1hZ2Uvanhyc1wiOltcImp4cnNcIl0sXCJpbWFnZS9qeHNcIjpbXCJqeHNcIl0sXCJpbWFnZS9qeHNjXCI6W1wianhzY1wiXSxcImltYWdlL2p4c2lcIjpbXCJqeHNpXCJdLFwiaW1hZ2Uvanhzc1wiOltcImp4c3NcIl0sXCJpbWFnZS9rdHhcIjpbXCJrdHhcIl0sXCJpbWFnZS9rdHgyXCI6W1wia3R4MlwiXSxcImltYWdlL3BuZ1wiOltcInBuZ1wiXSxcImltYWdlL3NnaVwiOltcInNnaVwiXSxcImltYWdlL3N2Zyt4bWxcIjpbXCJzdmdcIixcInN2Z3pcIl0sXCJpbWFnZS90MzhcIjpbXCJ0MzhcIl0sXCJpbWFnZS90aWZmXCI6W1widGlmXCIsXCJ0aWZmXCJdLFwiaW1hZ2UvdGlmZi1meFwiOltcInRmeFwiXSxcImltYWdlL3dlYnBcIjpbXCJ3ZWJwXCJdLFwiaW1hZ2Uvd21mXCI6W1wid21mXCJdLFwibWVzc2FnZS9kaXNwb3NpdGlvbi1ub3RpZmljYXRpb25cIjpbXCJkaXNwb3NpdGlvbi1ub3RpZmljYXRpb25cIl0sXCJtZXNzYWdlL2dsb2JhbFwiOltcInU4bXNnXCJdLFwibWVzc2FnZS9nbG9iYWwtZGVsaXZlcnktc3RhdHVzXCI6W1widThkc25cIl0sXCJtZXNzYWdlL2dsb2JhbC1kaXNwb3NpdGlvbi1ub3RpZmljYXRpb25cIjpbXCJ1OG1kblwiXSxcIm1lc3NhZ2UvZ2xvYmFsLWhlYWRlcnNcIjpbXCJ1OGhkclwiXSxcIm1lc3NhZ2UvcmZjODIyXCI6W1wiZW1sXCIsXCJtaW1lXCJdLFwibW9kZWwvM21mXCI6W1wiM21mXCJdLFwibW9kZWwvZ2x0Zitqc29uXCI6W1wiZ2x0ZlwiXSxcIm1vZGVsL2dsdGYtYmluYXJ5XCI6W1wiZ2xiXCJdLFwibW9kZWwvaWdlc1wiOltcImlnc1wiLFwiaWdlc1wiXSxcIm1vZGVsL21lc2hcIjpbXCJtc2hcIixcIm1lc2hcIixcInNpbG9cIl0sXCJtb2RlbC9tdGxcIjpbXCJtdGxcIl0sXCJtb2RlbC9vYmpcIjpbXCJvYmpcIl0sXCJtb2RlbC9zdGVwK3htbFwiOltcInN0cHhcIl0sXCJtb2RlbC9zdGVwK3ppcFwiOltcInN0cHpcIl0sXCJtb2RlbC9zdGVwLXhtbCt6aXBcIjpbXCJzdHB4elwiXSxcIm1vZGVsL3N0bFwiOltcInN0bFwiXSxcIm1vZGVsL3ZybWxcIjpbXCJ3cmxcIixcInZybWxcIl0sXCJtb2RlbC94M2QrYmluYXJ5XCI6W1wiKngzZGJcIixcIngzZGJ6XCJdLFwibW9kZWwveDNkK2Zhc3RpbmZvc2V0XCI6W1wieDNkYlwiXSxcIm1vZGVsL3gzZCt2cm1sXCI6W1wiKngzZHZcIixcIngzZHZ6XCJdLFwibW9kZWwveDNkK3htbFwiOltcIngzZFwiLFwieDNkelwiXSxcIm1vZGVsL3gzZC12cm1sXCI6W1wieDNkdlwiXSxcInRleHQvY2FjaGUtbWFuaWZlc3RcIjpbXCJhcHBjYWNoZVwiLFwibWFuaWZlc3RcIl0sXCJ0ZXh0L2NhbGVuZGFyXCI6W1wiaWNzXCIsXCJpZmJcIl0sXCJ0ZXh0L2NvZmZlZXNjcmlwdFwiOltcImNvZmZlZVwiLFwibGl0Y29mZmVlXCJdLFwidGV4dC9jc3NcIjpbXCJjc3NcIl0sXCJ0ZXh0L2NzdlwiOltcImNzdlwiXSxcInRleHQvaHRtbFwiOltcImh0bWxcIixcImh0bVwiLFwic2h0bWxcIl0sXCJ0ZXh0L2phZGVcIjpbXCJqYWRlXCJdLFwidGV4dC9qc3hcIjpbXCJqc3hcIl0sXCJ0ZXh0L2xlc3NcIjpbXCJsZXNzXCJdLFwidGV4dC9tYXJrZG93blwiOltcIm1hcmtkb3duXCIsXCJtZFwiXSxcInRleHQvbWF0aG1sXCI6W1wibW1sXCJdLFwidGV4dC9tZHhcIjpbXCJtZHhcIl0sXCJ0ZXh0L24zXCI6W1wibjNcIl0sXCJ0ZXh0L3BsYWluXCI6W1widHh0XCIsXCJ0ZXh0XCIsXCJjb25mXCIsXCJkZWZcIixcImxpc3RcIixcImxvZ1wiLFwiaW5cIixcImluaVwiXSxcInRleHQvcmljaHRleHRcIjpbXCJydHhcIl0sXCJ0ZXh0L3J0ZlwiOltcIipydGZcIl0sXCJ0ZXh0L3NnbWxcIjpbXCJzZ21sXCIsXCJzZ21cIl0sXCJ0ZXh0L3NoZXhcIjpbXCJzaGV4XCJdLFwidGV4dC9zbGltXCI6W1wic2xpbVwiLFwic2xtXCJdLFwidGV4dC9zcGR4XCI6W1wic3BkeFwiXSxcInRleHQvc3R5bHVzXCI6W1wic3R5bHVzXCIsXCJzdHlsXCJdLFwidGV4dC90YWItc2VwYXJhdGVkLXZhbHVlc1wiOltcInRzdlwiXSxcInRleHQvdHJvZmZcIjpbXCJ0XCIsXCJ0clwiLFwicm9mZlwiLFwibWFuXCIsXCJtZVwiLFwibXNcIl0sXCJ0ZXh0L3R1cnRsZVwiOltcInR0bFwiXSxcInRleHQvdXJpLWxpc3RcIjpbXCJ1cmlcIixcInVyaXNcIixcInVybHNcIl0sXCJ0ZXh0L3ZjYXJkXCI6W1widmNhcmRcIl0sXCJ0ZXh0L3Z0dFwiOltcInZ0dFwiXSxcInRleHQveG1sXCI6W1wiKnhtbFwiXSxcInRleHQveWFtbFwiOltcInlhbWxcIixcInltbFwiXSxcInZpZGVvLzNncHBcIjpbXCIzZ3BcIixcIjNncHBcIl0sXCJ2aWRlby8zZ3BwMlwiOltcIjNnMlwiXSxcInZpZGVvL2gyNjFcIjpbXCJoMjYxXCJdLFwidmlkZW8vaDI2M1wiOltcImgyNjNcIl0sXCJ2aWRlby9oMjY0XCI6W1wiaDI2NFwiXSxcInZpZGVvL2lzby5zZWdtZW50XCI6W1wibTRzXCJdLFwidmlkZW8vanBlZ1wiOltcImpwZ3ZcIl0sXCJ2aWRlby9qcG1cIjpbXCIqanBtXCIsXCJqcGdtXCJdLFwidmlkZW8vbWoyXCI6W1wibWoyXCIsXCJtanAyXCJdLFwidmlkZW8vbXAydFwiOltcInRzXCJdLFwidmlkZW8vbXA0XCI6W1wibXA0XCIsXCJtcDR2XCIsXCJtcGc0XCJdLFwidmlkZW8vbXBlZ1wiOltcIm1wZWdcIixcIm1wZ1wiLFwibXBlXCIsXCJtMXZcIixcIm0ydlwiXSxcInZpZGVvL29nZ1wiOltcIm9ndlwiXSxcInZpZGVvL3F1aWNrdGltZVwiOltcInF0XCIsXCJtb3ZcIl0sXCJ2aWRlby93ZWJtXCI6W1wid2VibVwiXX07IiwiLyoqXG4gICMgbm9ybWFsaWNlXG5cbiAgTm9ybWFsaXplIGFuIGljZSBzZXJ2ZXIgY29uZmlndXJhdGlvbiBvYmplY3QgKG9yIHBsYWluIG9sZCBzdHJpbmcpIGludG8gYSBmb3JtYXRcbiAgdGhhdCBpcyB1c2FibGUgaW4gYWxsIGJyb3dzZXJzIHN1cHBvcnRpbmcgV2ViUlRDLiAgUHJpbWFyaWx5IHRoaXMgbW9kdWxlIGlzIGRlc2lnbmVkXG4gIHRvIGhlbHAgd2l0aCB0aGUgdHJhbnNpdGlvbiBvZiB0aGUgYHVybGAgYXR0cmlidXRlIG9mIHRoZSBjb25maWd1cmF0aW9uIG9iamVjdCB0b1xuICB0aGUgYHVybHNgIGF0dHJpYnV0ZS5cblxuICAjIyBFeGFtcGxlIFVzYWdlXG5cbiAgPDw8IGV4YW1wbGVzL3NpbXBsZS5qc1xuXG4qKi9cblxudmFyIHByb3RvY29scyA9IFtcbiAgJ3N0dW46JyxcbiAgJ3R1cm46J1xuXTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihpbnB1dCkge1xuICB2YXIgdXJsID0gKGlucHV0IHx8IHt9KS51cmwgfHwgaW5wdXQ7XG4gIHZhciBwcm90b2NvbDtcbiAgdmFyIHBhcnRzO1xuICB2YXIgb3V0cHV0ID0ge307XG5cbiAgLy8gaWYgd2UgZG9uJ3QgaGF2ZSBhIHN0cmluZyB1cmwsIHRoZW4gYWxsb3cgdGhlIGlucHV0IHRvIHBhc3N0aHJvdWdoXG4gIGlmICh0eXBlb2YgdXJsICE9ICdzdHJpbmcnICYmICghICh1cmwgaW5zdGFuY2VvZiBTdHJpbmcpKSkge1xuICAgIHJldHVybiBpbnB1dDtcbiAgfVxuXG4gIC8vIHRyaW0gdGhlIHVybCBzdHJpbmcsIGFuZCBjb252ZXJ0IHRvIGFuIGFycmF5XG4gIHVybCA9IHVybC50cmltKCk7XG5cbiAgLy8gaWYgdGhlIHByb3RvY29sIGlzIG5vdCBrbm93biwgdGhlbiBwYXNzdGhyb3VnaFxuICBwcm90b2NvbCA9IHByb3RvY29sc1twcm90b2NvbHMuaW5kZXhPZih1cmwuc2xpY2UoMCwgNSkpXTtcbiAgaWYgKCEgcHJvdG9jb2wpIHtcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cblxuICAvLyBub3cgbGV0J3MgYXR0YWNrIHRoZSByZW1haW5pbmcgdXJsIHBhcnRzXG4gIHVybCA9IHVybC5zbGljZSg1KTtcbiAgcGFydHMgPSB1cmwuc3BsaXQoJ0AnKTtcblxuICBvdXRwdXQudXNlcm5hbWUgPSBpbnB1dC51c2VybmFtZTtcbiAgb3V0cHV0LmNyZWRlbnRpYWwgPSBpbnB1dC5jcmVkZW50aWFsO1xuICAvLyBpZiB3ZSBoYXZlIGFuIGF1dGhlbnRpY2F0aW9uIHBhcnQsIHRoZW4gc2V0IHRoZSBjcmVkZW50aWFsc1xuICBpZiAocGFydHMubGVuZ3RoID4gMSkge1xuICAgIHVybCA9IHBhcnRzWzFdO1xuICAgIHBhcnRzID0gcGFydHNbMF0uc3BsaXQoJzonKTtcblxuICAgIC8vIGFkZCB0aGUgb3V0cHV0IGNyZWRlbnRpYWwgYW5kIHVzZXJuYW1lXG4gICAgb3V0cHV0LnVzZXJuYW1lID0gcGFydHNbMF07XG4gICAgb3V0cHV0LmNyZWRlbnRpYWwgPSAoaW5wdXQgfHwge30pLmNyZWRlbnRpYWwgfHwgcGFydHNbMV0gfHwgJyc7XG4gIH1cblxuICBvdXRwdXQudXJsID0gcHJvdG9jb2wgKyB1cmw7XG4gIG91dHB1dC51cmxzID0gWyBvdXRwdXQudXJsIF07XG5cbiAgcmV0dXJuIG91dHB1dDtcbn07XG4iLCIvKiFcbiAqIFBsYXRmb3JtLmpzIHYxLjMuNlxuICogQ29weXJpZ2h0IDIwMTQtMjAyMCBCZW5qYW1pbiBUYW5cbiAqIENvcHlyaWdodCAyMDExLTIwMTMgSm9obi1EYXZpZCBEYWx0b25cbiAqIEF2YWlsYWJsZSB1bmRlciBNSVQgbGljZW5zZVxuICovXG47KGZ1bmN0aW9uKCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLyoqIFVzZWQgdG8gZGV0ZXJtaW5lIGlmIHZhbHVlcyBhcmUgb2YgdGhlIGxhbmd1YWdlIHR5cGUgYE9iamVjdGAuICovXG4gIHZhciBvYmplY3RUeXBlcyA9IHtcbiAgICAnZnVuY3Rpb24nOiB0cnVlLFxuICAgICdvYmplY3QnOiB0cnVlXG4gIH07XG5cbiAgLyoqIFVzZWQgYXMgYSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciByb290ID0gKG9iamVjdFR5cGVzW3R5cGVvZiB3aW5kb3ddICYmIHdpbmRvdykgfHwgdGhpcztcblxuICAvKiogQmFja3VwIHBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciBvbGRSb290ID0gcm9vdDtcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqL1xuICB2YXIgZnJlZUV4cG9ydHMgPSBvYmplY3RUeXBlc1t0eXBlb2YgZXhwb3J0c10gJiYgZXhwb3J0cztcblxuICAvKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovXG4gIHZhciBmcmVlTW9kdWxlID0gb2JqZWN0VHlwZXNbdHlwZW9mIG1vZHVsZV0gJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMgb3IgQnJvd3NlcmlmaWVkIGNvZGUgYW5kIHVzZSBpdCBhcyBgcm9vdGAuICovXG4gIHZhciBmcmVlR2xvYmFsID0gZnJlZUV4cG9ydHMgJiYgZnJlZU1vZHVsZSAmJiB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbDtcbiAgaWYgKGZyZWVHbG9iYWwgJiYgKGZyZWVHbG9iYWwuZ2xvYmFsID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWwud2luZG93ID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWwuc2VsZiA9PT0gZnJlZUdsb2JhbCkpIHtcbiAgICByb290ID0gZnJlZUdsb2JhbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2VkIGFzIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbiBhcnJheS1saWtlIG9iamVjdC5cbiAgICogU2VlIHRoZSBbRVM2IHNwZWNdKGh0dHA6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLXRvbGVuZ3RoKVxuICAgKiBmb3IgbW9yZSBkZXRhaWxzLlxuICAgKi9cbiAgdmFyIG1heFNhZmVJbnRlZ2VyID0gTWF0aC5wb3coMiwgNTMpIC0gMTtcblxuICAvKiogUmVndWxhciBleHByZXNzaW9uIHRvIGRldGVjdCBPcGVyYS4gKi9cbiAgdmFyIHJlT3BlcmEgPSAvXFxiT3BlcmEvO1xuXG4gIC8qKiBQb3NzaWJsZSBnbG9iYWwgb2JqZWN0LiAqL1xuICB2YXIgdGhpc0JpbmRpbmcgPSB0aGlzO1xuXG4gIC8qKiBVc2VkIGZvciBuYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMuICovXG4gIHZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbiAgLyoqIFVzZWQgdG8gY2hlY2sgZm9yIG93biBwcm9wZXJ0aWVzIG9mIGFuIG9iamVjdC4gKi9cbiAgdmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbiAgLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgaW50ZXJuYWwgYFtbQ2xhc3NdXWAgb2YgdmFsdWVzLiAqL1xuICB2YXIgdG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ2FwaXRhbGl6ZXMgYSBzdHJpbmcgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgVGhlIHN0cmluZyB0byBjYXBpdGFsaXplLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY2FwaXRhbGl6ZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gY2FwaXRhbGl6ZShzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSBTdHJpbmcoc3RyaW5nKTtcbiAgICByZXR1cm4gc3RyaW5nLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyaW5nLnNsaWNlKDEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgdXRpbGl0eSBmdW5jdGlvbiB0byBjbGVhbiB1cCB0aGUgT1MgbmFtZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9zIFRoZSBPUyBuYW1lIHRvIGNsZWFuIHVwLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3BhdHRlcm5dIEEgYFJlZ0V4cGAgcGF0dGVybiBtYXRjaGluZyB0aGUgT1MgbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtsYWJlbF0gQSBsYWJlbCBmb3IgdGhlIE9TLlxuICAgKi9cbiAgZnVuY3Rpb24gY2xlYW51cE9TKG9zLCBwYXR0ZXJuLCBsYWJlbCkge1xuICAgIC8vIFBsYXRmb3JtIHRva2VucyBhcmUgZGVmaW5lZCBhdDpcbiAgICAvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1Mzc1MDMoVlMuODUpLmFzcHhcbiAgICAvLyBodHRwOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDA4MTEyMjA1Mzk1MC9odHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1Mzc1MDMoVlMuODUpLmFzcHhcbiAgICB2YXIgZGF0YSA9IHtcbiAgICAgICcxMC4wJzogJzEwJyxcbiAgICAgICc2LjQnOiAgJzEwIFRlY2huaWNhbCBQcmV2aWV3JyxcbiAgICAgICc2LjMnOiAgJzguMScsXG4gICAgICAnNi4yJzogICc4JyxcbiAgICAgICc2LjEnOiAgJ1NlcnZlciAyMDA4IFIyIC8gNycsXG4gICAgICAnNi4wJzogICdTZXJ2ZXIgMjAwOCAvIFZpc3RhJyxcbiAgICAgICc1LjInOiAgJ1NlcnZlciAyMDAzIC8gWFAgNjQtYml0JyxcbiAgICAgICc1LjEnOiAgJ1hQJyxcbiAgICAgICc1LjAxJzogJzIwMDAgU1AxJyxcbiAgICAgICc1LjAnOiAgJzIwMDAnLFxuICAgICAgJzQuMCc6ICAnTlQnLFxuICAgICAgJzQuOTAnOiAnTUUnXG4gICAgfTtcbiAgICAvLyBEZXRlY3QgV2luZG93cyB2ZXJzaW9uIGZyb20gcGxhdGZvcm0gdG9rZW5zLlxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsICYmIC9eV2luL2kudGVzdChvcykgJiYgIS9eV2luZG93cyBQaG9uZSAvaS50ZXN0KG9zKSAmJlxuICAgICAgICAoZGF0YSA9IGRhdGFbL1tcXGQuXSskLy5leGVjKG9zKV0pKSB7XG4gICAgICBvcyA9ICdXaW5kb3dzICcgKyBkYXRhO1xuICAgIH1cbiAgICAvLyBDb3JyZWN0IGNoYXJhY3RlciBjYXNlIGFuZCBjbGVhbnVwIHN0cmluZy5cbiAgICBvcyA9IFN0cmluZyhvcyk7XG5cbiAgICBpZiAocGF0dGVybiAmJiBsYWJlbCkge1xuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cChwYXR0ZXJuLCAnaScpLCBsYWJlbCk7XG4gICAgfVxuXG4gICAgb3MgPSBmb3JtYXQoXG4gICAgICBvcy5yZXBsYWNlKC8gY2UkL2ksICcgQ0UnKVxuICAgICAgICAucmVwbGFjZSgvXFxiaHB3L2ksICd3ZWInKVxuICAgICAgICAucmVwbGFjZSgvXFxiTWFjaW50b3NoXFxiLywgJ01hYyBPUycpXG4gICAgICAgIC5yZXBsYWNlKC9fUG93ZXJQQ1xcYi9pLCAnIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihPUyBYKSBbXiBcXGRdKy9pLCAnJDEnKVxuICAgICAgICAucmVwbGFjZSgvXFxiTWFjIChPUyBYKVxcYi8sICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXC8oXFxkKS8sICcgJDEnKVxuICAgICAgICAucmVwbGFjZSgvXy9nLCAnLicpXG4gICAgICAgIC5yZXBsYWNlKC8oPzogQmVQQ3xbIC5dKmZjWyBcXGQuXSspJC9pLCAnJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYng4NlxcLjY0XFxiL2dpLCAneDg2XzY0JylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihXaW5kb3dzIFBob25lKSBPU1xcYi8sICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGIoQ2hyb21lIE9TIFxcdyspIFtcXGQuXStcXGIvLCAnJDEnKVxuICAgICAgICAuc3BsaXQoJyBvbiAnKVswXVxuICAgICk7XG5cbiAgICByZXR1cm4gb3M7XG4gIH1cblxuICAvKipcbiAgICogQW4gaXRlcmF0aW9uIHV0aWxpdHkgZm9yIGFycmF5cyBhbmQgb2JqZWN0cy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheXxPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gZWFjaChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IG9iamVjdCA/IG9iamVjdC5sZW5ndGggOiAwO1xuXG4gICAgaWYgKHR5cGVvZiBsZW5ndGggPT0gJ251bWJlcicgJiYgbGVuZ3RoID4gLTEgJiYgbGVuZ3RoIDw9IG1heFNhZmVJbnRlZ2VyKSB7XG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgICAgICBjYWxsYmFjayhvYmplY3RbaW5kZXhdLCBpbmRleCwgb2JqZWN0KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yT3duKG9iamVjdCwgY2FsbGJhY2spO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUcmltIGFuZCBjb25kaXRpb25hbGx5IGNhcGl0YWxpemUgc3RyaW5nIHZhbHVlcy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGZvcm1hdC5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGZvcm1hdHRlZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBmb3JtYXQoc3RyaW5nKSB7XG4gICAgc3RyaW5nID0gdHJpbShzdHJpbmcpO1xuICAgIHJldHVybiAvXig/OndlYk9TfGkoPzpPU3xQKSkvLnRlc3Qoc3RyaW5nKVxuICAgICAgPyBzdHJpbmdcbiAgICAgIDogY2FwaXRhbGl6ZShzdHJpbmcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0ZXJhdGVzIG92ZXIgYW4gb2JqZWN0J3Mgb3duIHByb3BlcnRpZXMsIGV4ZWN1dGluZyB0aGUgYGNhbGxiYWNrYCBmb3IgZWFjaC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGV4ZWN1dGVkIHBlciBvd24gcHJvcGVydHkuXG4gICAqL1xuICBmdW5jdGlvbiBmb3JPd24ob2JqZWN0LCBjYWxsYmFjaykge1xuICAgIGZvciAodmFyIGtleSBpbiBvYmplY3QpIHtcbiAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkge1xuICAgICAgICBjYWxsYmFjayhvYmplY3Rba2V5XSwga2V5LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiBhIHZhbHVlLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGBbW0NsYXNzXV1gLlxuICAgKi9cbiAgZnVuY3Rpb24gZ2V0Q2xhc3NPZih2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSA9PSBudWxsXG4gICAgICA/IGNhcGl0YWxpemUodmFsdWUpXG4gICAgICA6IHRvU3RyaW5nLmNhbGwodmFsdWUpLnNsaWNlKDgsIC0xKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIb3N0IG9iamVjdHMgY2FuIHJldHVybiB0eXBlIHZhbHVlcyB0aGF0IGFyZSBkaWZmZXJlbnQgZnJvbSB0aGVpciBhY3R1YWxcbiAgICogZGF0YSB0eXBlLiBUaGUgb2JqZWN0cyB3ZSBhcmUgY29uY2VybmVkIHdpdGggdXN1YWxseSByZXR1cm4gbm9uLXByaW1pdGl2ZVxuICAgKiB0eXBlcyBvZiBcIm9iamVjdFwiLCBcImZ1bmN0aW9uXCIsIG9yIFwidW5rbm93blwiLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgb3duZXIgb2YgdGhlIHByb3BlcnR5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcHJvcGVydHkgVGhlIHByb3BlcnR5IHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHByb3BlcnR5IHZhbHVlIGlzIGEgbm9uLXByaW1pdGl2ZSwgZWxzZSBgZmFsc2VgLlxuICAgKi9cbiAgZnVuY3Rpb24gaXNIb3N0VHlwZShvYmplY3QsIHByb3BlcnR5KSB7XG4gICAgdmFyIHR5cGUgPSBvYmplY3QgIT0gbnVsbCA/IHR5cGVvZiBvYmplY3RbcHJvcGVydHldIDogJ251bWJlcic7XG4gICAgcmV0dXJuICEvXig/OmJvb2xlYW58bnVtYmVyfHN0cmluZ3x1bmRlZmluZWQpJC8udGVzdCh0eXBlKSAmJlxuICAgICAgKHR5cGUgPT0gJ29iamVjdCcgPyAhIW9iamVjdFtwcm9wZXJ0eV0gOiB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcmVwYXJlcyBhIHN0cmluZyBmb3IgdXNlIGluIGEgYFJlZ0V4cGAgYnkgbWFraW5nIGh5cGhlbnMgYW5kIHNwYWNlcyBvcHRpb25hbC5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIHF1YWxpZnkuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBxdWFsaWZpZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gcXVhbGlmeShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvKFsgLV0pKD8hJCkvZywgJyQxPycpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgYmFyZS1ib25lcyBgQXJyYXkjcmVkdWNlYCBsaWtlIHV0aWxpdHkgZnVuY3Rpb24uXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBmdW5jdGlvbiBjYWxsZWQgcGVyIGl0ZXJhdGlvbi5cbiAgICogQHJldHVybnMgeyp9IFRoZSBhY2N1bXVsYXRlZCByZXN1bHQuXG4gICAqL1xuICBmdW5jdGlvbiByZWR1Y2UoYXJyYXksIGNhbGxiYWNrKSB7XG4gICAgdmFyIGFjY3VtdWxhdG9yID0gbnVsbDtcbiAgICBlYWNoKGFycmF5LCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gY2FsbGJhY2soYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgYXJyYXkpO1xuICAgIH0pO1xuICAgIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UgZnJvbSBhIHN0cmluZy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIHRyaW0uXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSB0cmltbWVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIHRyaW0oc3RyaW5nKSB7XG4gICAgcmV0dXJuIFN0cmluZyhzdHJpbmcpLnJlcGxhY2UoL14gK3wgKyQvZywgJycpO1xuICB9XG5cbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgcGxhdGZvcm0gb2JqZWN0LlxuICAgKlxuICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICogQHBhcmFtIHtPYmplY3R8c3RyaW5nfSBbdWE9bmF2aWdhdG9yLnVzZXJBZ2VudF0gVGhlIHVzZXIgYWdlbnQgc3RyaW5nIG9yXG4gICAqICBjb250ZXh0IG9iamVjdC5cbiAgICogQHJldHVybnMge09iamVjdH0gQSBwbGF0Zm9ybSBvYmplY3QuXG4gICAqL1xuICBmdW5jdGlvbiBwYXJzZSh1YSkge1xuXG4gICAgLyoqIFRoZSBlbnZpcm9ubWVudCBjb250ZXh0IG9iamVjdC4gKi9cbiAgICB2YXIgY29udGV4dCA9IHJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBmbGFnIHdoZW4gYSBjdXN0b20gY29udGV4dCBpcyBwcm92aWRlZC4gKi9cbiAgICB2YXIgaXNDdXN0b21Db250ZXh0ID0gdWEgJiYgdHlwZW9mIHVhID09ICdvYmplY3QnICYmIGdldENsYXNzT2YodWEpICE9ICdTdHJpbmcnO1xuXG4gICAgLy8gSnVnZ2xlIGFyZ3VtZW50cy5cbiAgICBpZiAoaXNDdXN0b21Db250ZXh0KSB7XG4gICAgICBjb250ZXh0ID0gdWE7XG4gICAgICB1YSA9IG51bGw7XG4gICAgfVxuXG4gICAgLyoqIEJyb3dzZXIgbmF2aWdhdG9yIG9iamVjdC4gKi9cbiAgICB2YXIgbmF2ID0gY29udGV4dC5uYXZpZ2F0b3IgfHwge307XG5cbiAgICAvKiogQnJvd3NlciB1c2VyIGFnZW50IHN0cmluZy4gKi9cbiAgICB2YXIgdXNlckFnZW50ID0gbmF2LnVzZXJBZ2VudCB8fCAnJztcblxuICAgIHVhIHx8ICh1YSA9IHVzZXJBZ2VudCk7XG5cbiAgICAvKiogVXNlZCB0byBmbGFnIHdoZW4gYHRoaXNCaW5kaW5nYCBpcyB0aGUgW01vZHVsZVNjb3BlXS4gKi9cbiAgICB2YXIgaXNNb2R1bGVTY29wZSA9IGlzQ3VzdG9tQ29udGV4dCB8fCB0aGlzQmluZGluZyA9PSBvbGRSb290O1xuXG4gICAgLyoqIFVzZWQgdG8gZGV0ZWN0IGlmIGJyb3dzZXIgaXMgbGlrZSBDaHJvbWUuICovXG4gICAgdmFyIGxpa2VDaHJvbWUgPSBpc0N1c3RvbUNvbnRleHRcbiAgICAgID8gISFuYXYubGlrZUNocm9tZVxuICAgICAgOiAvXFxiQ2hyb21lXFxiLy50ZXN0KHVhKSAmJiAhL2ludGVybmFsfFxcbi9pLnRlc3QodG9TdHJpbmcudG9TdHJpbmcoKSk7XG5cbiAgICAvKiogSW50ZXJuYWwgYFtbQ2xhc3NdXWAgdmFsdWUgc2hvcnRjdXRzLiAqL1xuICAgIHZhciBvYmplY3RDbGFzcyA9ICdPYmplY3QnLFxuICAgICAgICBhaXJSdW50aW1lQ2xhc3MgPSBpc0N1c3RvbUNvbnRleHQgPyBvYmplY3RDbGFzcyA6ICdTY3JpcHRCcmlkZ2luZ1Byb3h5T2JqZWN0JyxcbiAgICAgICAgZW52aXJvQ2xhc3MgPSBpc0N1c3RvbUNvbnRleHQgPyBvYmplY3RDbGFzcyA6ICdFbnZpcm9ubWVudCcsXG4gICAgICAgIGphdmFDbGFzcyA9IChpc0N1c3RvbUNvbnRleHQgJiYgY29udGV4dC5qYXZhKSA/ICdKYXZhUGFja2FnZScgOiBnZXRDbGFzc09mKGNvbnRleHQuamF2YSksXG4gICAgICAgIHBoYW50b21DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1J1bnRpbWVPYmplY3QnO1xuXG4gICAgLyoqIERldGVjdCBKYXZhIGVudmlyb25tZW50cy4gKi9cbiAgICB2YXIgamF2YSA9IC9cXGJKYXZhLy50ZXN0KGphdmFDbGFzcykgJiYgY29udGV4dC5qYXZhO1xuXG4gICAgLyoqIERldGVjdCBSaGluby4gKi9cbiAgICB2YXIgcmhpbm8gPSBqYXZhICYmIGdldENsYXNzT2YoY29udGV4dC5lbnZpcm9ubWVudCkgPT0gZW52aXJvQ2xhc3M7XG5cbiAgICAvKiogQSBjaGFyYWN0ZXIgdG8gcmVwcmVzZW50IGFscGhhLiAqL1xuICAgIHZhciBhbHBoYSA9IGphdmEgPyAnYScgOiAnXFx1MDNiMSc7XG5cbiAgICAvKiogQSBjaGFyYWN0ZXIgdG8gcmVwcmVzZW50IGJldGEuICovXG4gICAgdmFyIGJldGEgPSBqYXZhID8gJ2InIDogJ1xcdTAzYjInO1xuXG4gICAgLyoqIEJyb3dzZXIgZG9jdW1lbnQgb2JqZWN0LiAqL1xuICAgIHZhciBkb2MgPSBjb250ZXh0LmRvY3VtZW50IHx8IHt9O1xuXG4gICAgLyoqXG4gICAgICogRGV0ZWN0IE9wZXJhIGJyb3dzZXIgKFByZXN0by1iYXNlZCkuXG4gICAgICogaHR0cDovL3d3dy5ob3d0b2NyZWF0ZS5jby51ay9vcGVyYVN0dWZmL29wZXJhT2JqZWN0Lmh0bWxcbiAgICAgKiBodHRwOi8vZGV2Lm9wZXJhLmNvbS9hcnRpY2xlcy92aWV3L29wZXJhLW1pbmktd2ViLWNvbnRlbnQtYXV0aG9yaW5nLWd1aWRlbGluZXMvI29wZXJhbWluaVxuICAgICAqL1xuICAgIHZhciBvcGVyYSA9IGNvbnRleHQub3BlcmFtaW5pIHx8IGNvbnRleHQub3BlcmE7XG5cbiAgICAvKiogT3BlcmEgYFtbQ2xhc3NdXWAuICovXG4gICAgdmFyIG9wZXJhQ2xhc3MgPSByZU9wZXJhLnRlc3Qob3BlcmFDbGFzcyA9IChpc0N1c3RvbUNvbnRleHQgJiYgb3BlcmEpID8gb3BlcmFbJ1tbQ2xhc3NdXSddIDogZ2V0Q2xhc3NPZihvcGVyYSkpXG4gICAgICA/IG9wZXJhQ2xhc3NcbiAgICAgIDogKG9wZXJhID0gbnVsbCk7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKiogVGVtcG9yYXJ5IHZhcmlhYmxlIHVzZWQgb3ZlciB0aGUgc2NyaXB0J3MgbGlmZXRpbWUuICovXG4gICAgdmFyIGRhdGE7XG5cbiAgICAvKiogVGhlIENQVSBhcmNoaXRlY3R1cmUuICovXG4gICAgdmFyIGFyY2ggPSB1YTtcblxuICAgIC8qKiBQbGF0Zm9ybSBkZXNjcmlwdGlvbiBhcnJheS4gKi9cbiAgICB2YXIgZGVzY3JpcHRpb24gPSBbXTtcblxuICAgIC8qKiBQbGF0Zm9ybSBhbHBoYS9iZXRhIGluZGljYXRvci4gKi9cbiAgICB2YXIgcHJlcmVsZWFzZSA9IG51bGw7XG5cbiAgICAvKiogQSBmbGFnIHRvIGluZGljYXRlIHRoYXQgZW52aXJvbm1lbnQgZmVhdHVyZXMgc2hvdWxkIGJlIHVzZWQgdG8gcmVzb2x2ZSB0aGUgcGxhdGZvcm0uICovXG4gICAgdmFyIHVzZUZlYXR1cmVzID0gdWEgPT0gdXNlckFnZW50O1xuXG4gICAgLyoqIFRoZSBicm93c2VyL2Vudmlyb25tZW50IHZlcnNpb24uICovXG4gICAgdmFyIHZlcnNpb24gPSB1c2VGZWF0dXJlcyAmJiBvcGVyYSAmJiB0eXBlb2Ygb3BlcmEudmVyc2lvbiA9PSAnZnVuY3Rpb24nICYmIG9wZXJhLnZlcnNpb24oKTtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgaWYgdGhlIE9TIGVuZHMgd2l0aCBcIi8gVmVyc2lvblwiICovXG4gICAgdmFyIGlzU3BlY2lhbENhc2VkT1M7XG5cbiAgICAvKiBEZXRlY3RhYmxlIGxheW91dCBlbmdpbmVzIChvcmRlciBpcyBpbXBvcnRhbnQpLiAqL1xuICAgIHZhciBsYXlvdXQgPSBnZXRMYXlvdXQoW1xuICAgICAgeyAnbGFiZWwnOiAnRWRnZUhUTUwnLCAncGF0dGVybic6ICdFZGdlJyB9LFxuICAgICAgJ1RyaWRlbnQnLFxuICAgICAgeyAnbGFiZWwnOiAnV2ViS2l0JywgJ3BhdHRlcm4nOiAnQXBwbGVXZWJLaXQnIH0sXG4gICAgICAnaUNhYicsXG4gICAgICAnUHJlc3RvJyxcbiAgICAgICdOZXRGcm9udCcsXG4gICAgICAnVGFzbWFuJyxcbiAgICAgICdLSFRNTCcsXG4gICAgICAnR2Vja28nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIGJyb3dzZXIgbmFtZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIG5hbWUgPSBnZXROYW1lKFtcbiAgICAgICdBZG9iZSBBSVInLFxuICAgICAgJ0Fyb3JhJyxcbiAgICAgICdBdmFudCBCcm93c2VyJyxcbiAgICAgICdCcmVhY2gnLFxuICAgICAgJ0NhbWlubycsXG4gICAgICAnRWxlY3Ryb24nLFxuICAgICAgJ0VwaXBoYW55JyxcbiAgICAgICdGZW5uZWMnLFxuICAgICAgJ0Zsb2NrJyxcbiAgICAgICdHYWxlb24nLFxuICAgICAgJ0dyZWVuQnJvd3NlcicsXG4gICAgICAnaUNhYicsXG4gICAgICAnSWNld2Vhc2VsJyxcbiAgICAgICdLLU1lbGVvbicsXG4gICAgICAnS29ucXVlcm9yJyxcbiAgICAgICdMdW5hc2NhcGUnLFxuICAgICAgJ01heHRob24nLFxuICAgICAgeyAnbGFiZWwnOiAnTWljcm9zb2Z0IEVkZ2UnLCAncGF0dGVybic6ICcoPzpFZGdlfEVkZ3xFZGdBfEVkZ2lPUyknIH0sXG4gICAgICAnTWlkb3JpJyxcbiAgICAgICdOb29rIEJyb3dzZXInLFxuICAgICAgJ1BhbGVNb29uJyxcbiAgICAgICdQaGFudG9tSlMnLFxuICAgICAgJ1JhdmVuJyxcbiAgICAgICdSZWtvbnEnLFxuICAgICAgJ1JvY2tNZWx0JyxcbiAgICAgIHsgJ2xhYmVsJzogJ1NhbXN1bmcgSW50ZXJuZXQnLCAncGF0dGVybic6ICdTYW1zdW5nQnJvd3NlcicgfSxcbiAgICAgICdTZWFNb25rZXknLFxuICAgICAgeyAnbGFiZWwnOiAnU2lsaycsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdTbGVpcG5pcicsXG4gICAgICAnU2xpbUJyb3dzZXInLFxuICAgICAgeyAnbGFiZWwnOiAnU1JXYXJlIElyb24nLCAncGF0dGVybic6ICdJcm9uJyB9LFxuICAgICAgJ1N1bnJpc2UnLFxuICAgICAgJ1N3aWZ0Zm94JyxcbiAgICAgICdWaXZhbGRpJyxcbiAgICAgICdXYXRlcmZveCcsXG4gICAgICAnV2ViUG9zaXRpdmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWWFuZGV4IEJyb3dzZXInLCAncGF0dGVybic6ICdZYUJyb3dzZXInIH0sXG4gICAgICB7ICdsYWJlbCc6ICdVQyBCcm93c2VyJywgJ3BhdHRlcm4nOiAnVUNCcm93c2VyJyB9LFxuICAgICAgJ09wZXJhIE1pbmknLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEgTWluaScsICdwYXR0ZXJuJzogJ09QaU9TJyB9LFxuICAgICAgJ09wZXJhJyxcbiAgICAgIHsgJ2xhYmVsJzogJ09wZXJhJywgJ3BhdHRlcm4nOiAnT1BSJyB9LFxuICAgICAgJ0Nocm9taXVtJyxcbiAgICAgICdDaHJvbWUnLFxuICAgICAgeyAnbGFiZWwnOiAnQ2hyb21lJywgJ3BhdHRlcm4nOiAnKD86SGVhZGxlc3NDaHJvbWUpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnQ2hyb21lIE1vYmlsZScsICdwYXR0ZXJuJzogJyg/OkNyaU9TfENyTW8pJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCcsICdwYXR0ZXJuJzogJyg/OkZpcmVmb3h8TWluZWZpZWxkKScgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0ZpcmVmb3ggZm9yIGlPUycsICdwYXR0ZXJuJzogJ0Z4aU9TJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdJRU1vYmlsZScgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0lFJywgJ3BhdHRlcm4nOiAnTVNJRScgfSxcbiAgICAgICdTYWZhcmknXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIHByb2R1Y3RzIChvcmRlciBpcyBpbXBvcnRhbnQpLiAqL1xuICAgIHZhciBwcm9kdWN0ID0gZ2V0UHJvZHVjdChbXG4gICAgICB7ICdsYWJlbCc6ICdCbGFja0JlcnJ5JywgJ3BhdHRlcm4nOiAnQkIxMCcgfSxcbiAgICAgICdCbGFja0JlcnJ5JyxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTJywgJ3BhdHRlcm4nOiAnR1QtSTkwMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzInLCAncGF0dGVybic6ICdHVC1JOTEwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMycsICdwYXR0ZXJuJzogJ0dULUk5MzAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM0JywgJ3BhdHRlcm4nOiAnR1QtSTk1MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzUnLCAncGF0dGVybic6ICdTTS1HOTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2JywgJ3BhdHRlcm4nOiAnU00tRzkyMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNiBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkyNScgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNycsICdwYXR0ZXJuJzogJ1NNLUc5MzAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzcgRWRnZScsICdwYXR0ZXJuJzogJ1NNLUc5MzUnIH0sXG4gICAgICAnR29vZ2xlIFRWJyxcbiAgICAgICdMdW1pYScsXG4gICAgICAnaVBhZCcsXG4gICAgICAnaVBvZCcsXG4gICAgICAnaVBob25lJyxcbiAgICAgICdLaW5kbGUnLFxuICAgICAgeyAnbGFiZWwnOiAnS2luZGxlIEZpcmUnLCAncGF0dGVybic6ICcoPzpDbG91ZDl8U2lsay1BY2NlbGVyYXRlZCknIH0sXG4gICAgICAnTmV4dXMnLFxuICAgICAgJ05vb2snLFxuICAgICAgJ1BsYXlCb29rJyxcbiAgICAgICdQbGF5U3RhdGlvbiBWaXRhJyxcbiAgICAgICdQbGF5U3RhdGlvbicsXG4gICAgICAnVG91Y2hQYWQnLFxuICAgICAgJ1RyYW5zZm9ybWVyJyxcbiAgICAgIHsgJ2xhYmVsJzogJ1dpaSBVJywgJ3BhdHRlcm4nOiAnV2lpVScgfSxcbiAgICAgICdXaWknLFxuICAgICAgJ1hib3ggT25lJyxcbiAgICAgIHsgJ2xhYmVsJzogJ1hib3ggMzYwJywgJ3BhdHRlcm4nOiAnWGJveCcgfSxcbiAgICAgICdYb29tJ1xuICAgIF0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBtYW51ZmFjdHVyZXJzLiAqL1xuICAgIHZhciBtYW51ZmFjdHVyZXIgPSBnZXRNYW51ZmFjdHVyZXIoe1xuICAgICAgJ0FwcGxlJzogeyAnaVBhZCc6IDEsICdpUGhvbmUnOiAxLCAnaVBvZCc6IDEgfSxcbiAgICAgICdBbGNhdGVsJzoge30sXG4gICAgICAnQXJjaG9zJzoge30sXG4gICAgICAnQW1hem9uJzogeyAnS2luZGxlJzogMSwgJ0tpbmRsZSBGaXJlJzogMSB9LFxuICAgICAgJ0FzdXMnOiB7ICdUcmFuc2Zvcm1lcic6IDEgfSxcbiAgICAgICdCYXJuZXMgJiBOb2JsZSc6IHsgJ05vb2snOiAxIH0sXG4gICAgICAnQmxhY2tCZXJyeSc6IHsgJ1BsYXlCb29rJzogMSB9LFxuICAgICAgJ0dvb2dsZSc6IHsgJ0dvb2dsZSBUVic6IDEsICdOZXh1cyc6IDEgfSxcbiAgICAgICdIUCc6IHsgJ1RvdWNoUGFkJzogMSB9LFxuICAgICAgJ0hUQyc6IHt9LFxuICAgICAgJ0h1YXdlaSc6IHt9LFxuICAgICAgJ0xlbm92byc6IHt9LFxuICAgICAgJ0xHJzoge30sXG4gICAgICAnTWljcm9zb2Z0JzogeyAnWGJveCc6IDEsICdYYm94IE9uZSc6IDEgfSxcbiAgICAgICdNb3Rvcm9sYSc6IHsgJ1hvb20nOiAxIH0sXG4gICAgICAnTmludGVuZG8nOiB7ICdXaWkgVSc6IDEsICAnV2lpJzogMSB9LFxuICAgICAgJ05va2lhJzogeyAnTHVtaWEnOiAxIH0sXG4gICAgICAnT3Bwbyc6IHt9LFxuICAgICAgJ1NhbXN1bmcnOiB7ICdHYWxheHkgUyc6IDEsICdHYWxheHkgUzInOiAxLCAnR2FsYXh5IFMzJzogMSwgJ0dhbGF4eSBTNCc6IDEgfSxcbiAgICAgICdTb255JzogeyAnUGxheVN0YXRpb24nOiAxLCAnUGxheVN0YXRpb24gVml0YSc6IDEgfSxcbiAgICAgICdYaWFvbWknOiB7ICdNaSc6IDEsICdSZWRtaSc6IDEgfVxuICAgIH0pO1xuXG4gICAgLyogRGV0ZWN0YWJsZSBvcGVyYXRpbmcgc3lzdGVtcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgb3MgPSBnZXRPUyhbXG4gICAgICAnV2luZG93cyBQaG9uZScsXG4gICAgICAnS2FpT1MnLFxuICAgICAgJ0FuZHJvaWQnLFxuICAgICAgJ0NlbnRPUycsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgT1MnLCAncGF0dGVybic6ICdDck9TJyB9LFxuICAgICAgJ0RlYmlhbicsXG4gICAgICB7ICdsYWJlbCc6ICdEcmFnb25GbHkgQlNEJywgJ3BhdHRlcm4nOiAnRHJhZ29uRmx5JyB9LFxuICAgICAgJ0ZlZG9yYScsXG4gICAgICAnRnJlZUJTRCcsXG4gICAgICAnR2VudG9vJyxcbiAgICAgICdIYWlrdScsXG4gICAgICAnS3VidW50dScsXG4gICAgICAnTGludXggTWludCcsXG4gICAgICAnT3BlbkJTRCcsXG4gICAgICAnUmVkIEhhdCcsXG4gICAgICAnU3VTRScsXG4gICAgICAnVWJ1bnR1JyxcbiAgICAgICdYdWJ1bnR1JyxcbiAgICAgICdDeWd3aW4nLFxuICAgICAgJ1N5bWJpYW4gT1MnLFxuICAgICAgJ2hwd09TJyxcbiAgICAgICd3ZWJPUyAnLFxuICAgICAgJ3dlYk9TJyxcbiAgICAgICdUYWJsZXQgT1MnLFxuICAgICAgJ1RpemVuJyxcbiAgICAgICdMaW51eCcsXG4gICAgICAnTWFjIE9TIFgnLFxuICAgICAgJ01hY2ludG9zaCcsXG4gICAgICAnTWFjJyxcbiAgICAgICdXaW5kb3dzIDk4OycsXG4gICAgICAnV2luZG93cyAnXG4gICAgXSk7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgbGF5b3V0IGVuZ2luZSBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCBsYXlvdXQgZW5naW5lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldExheW91dChndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCB8fCBSZWdFeHAoJ1xcXFxiJyArIChcbiAgICAgICAgICBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpXG4gICAgICAgICkgKyAnXFxcXGInLCAnaScpLmV4ZWModWEpICYmIChndWVzcy5sYWJlbCB8fCBndWVzcyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgbWFudWZhY3R1cmVyIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBvYmplY3Qgb2YgZ3Vlc3Nlcy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCBtYW51ZmFjdHVyZXIuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0TWFudWZhY3R1cmVyKGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gICAgICAgIC8vIExvb2t1cCB0aGUgbWFudWZhY3R1cmVyIGJ5IHByb2R1Y3Qgb3Igc2NhbiB0aGUgVUEgZm9yIHRoZSBtYW51ZmFjdHVyZXIuXG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgKFxuICAgICAgICAgIHZhbHVlW3Byb2R1Y3RdIHx8XG4gICAgICAgICAgdmFsdWVbL15bYS16XSsoPzogK1thLXpdK1xcYikqL2kuZXhlYyhwcm9kdWN0KV0gfHxcbiAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHF1YWxpZnkoa2V5KSArICcoPzpcXFxcYnxcXFxcdypcXFxcZCknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICkgJiYga2V5O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIGJyb3dzZXIgbmFtZSBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCBicm93c2VyIG5hbWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0TmFtZShndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCB8fCBSZWdFeHAoJ1xcXFxiJyArIChcbiAgICAgICAgICBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpXG4gICAgICAgICkgKyAnXFxcXGInLCAnaScpLmV4ZWModWEpICYmIChndWVzcy5sYWJlbCB8fCBndWVzcyk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgT1MgbmFtZSBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCBPUyBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldE9TKGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICB2YXIgcGF0dGVybiA9IGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcyk7XG4gICAgICAgIGlmICghcmVzdWx0ICYmIChyZXN1bHQgPVxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnKD86L1tcXFxcZC5dK3xbIFxcXFx3Ll0qKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgICAgICkpIHtcbiAgICAgICAgICByZXN1bHQgPSBjbGVhbnVwT1MocmVzdWx0LCBwYXR0ZXJuLCBndWVzcy5sYWJlbCB8fCBndWVzcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBwcm9kdWN0IG5hbWUgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgcHJvZHVjdCBuYW1lLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFByb2R1Y3QoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHZhciBwYXR0ZXJuID0gZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKTtcbiAgICAgICAgaWYgKCFyZXN1bHQgJiYgKHJlc3VsdCA9XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcgKlxcXFxkK1suXFxcXHdfXSonLCAnaScpLmV4ZWModWEpIHx8XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcgKlxcXFx3Ky1bXFxcXHddKicsICdpJykuZXhlYyh1YSkgfHxcbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyg/OjsgKig/OlthLXpdK1tfLV0pP1thLXpdK1xcXFxkK3xbXiAoKTstXSopJywgJ2knKS5leGVjKHVhKVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIC8vIFNwbGl0IGJ5IGZvcndhcmQgc2xhc2ggYW5kIGFwcGVuZCBwcm9kdWN0IHZlcnNpb24gaWYgbmVlZGVkLlxuICAgICAgICAgIGlmICgocmVzdWx0ID0gU3RyaW5nKChndWVzcy5sYWJlbCAmJiAhUmVnRXhwKHBhdHRlcm4sICdpJykudGVzdChndWVzcy5sYWJlbCkpID8gZ3Vlc3MubGFiZWwgOiByZXN1bHQpLnNwbGl0KCcvJykpWzFdICYmICEvW1xcZC5dKy8udGVzdChyZXN1bHRbMF0pKSB7XG4gICAgICAgICAgICByZXN1bHRbMF0gKz0gJyAnICsgcmVzdWx0WzFdO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBDb3JyZWN0IGNoYXJhY3RlciBjYXNlIGFuZCBjbGVhbnVwIHN0cmluZy5cbiAgICAgICAgICBndWVzcyA9IGd1ZXNzLmxhYmVsIHx8IGd1ZXNzO1xuICAgICAgICAgIHJlc3VsdCA9IGZvcm1hdChyZXN1bHRbMF1cbiAgICAgICAgICAgIC5yZXBsYWNlKFJlZ0V4cChwYXR0ZXJuLCAnaScpLCBndWVzcylcbiAgICAgICAgICAgIC5yZXBsYWNlKFJlZ0V4cCgnOyAqKD86JyArIGd1ZXNzICsgJ1tfLV0pPycsICdpJyksICcgJylcbiAgICAgICAgICAgIC5yZXBsYWNlKFJlZ0V4cCgnKCcgKyBndWVzcyArICcpWy1fLl0/KFxcXFx3KScsICdpJyksICckMSAkMicpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzb2x2ZXMgdGhlIHZlcnNpb24gdXNpbmcgYW4gYXJyYXkgb2YgVUEgcGF0dGVybnMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IHBhdHRlcm5zIEFuIGFycmF5IG9mIFVBIHBhdHRlcm5zLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIHZlcnNpb24uXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0VmVyc2lvbihwYXR0ZXJucykge1xuICAgICAgcmV0dXJuIHJlZHVjZShwYXR0ZXJucywgZnVuY3Rpb24ocmVzdWx0LCBwYXR0ZXJuKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgKFJlZ0V4cChwYXR0ZXJuICtcbiAgICAgICAgICAnKD86LVtcXFxcZC5dKy98KD86IGZvciBbXFxcXHctXSspP1sgLy1dKShbXFxcXGQuXStbXiAoKTsvXy1dKiknLCAnaScpLmV4ZWModWEpIHx8IDApWzFdIHx8IG51bGw7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGBwbGF0Zm9ybS5kZXNjcmlwdGlvbmAgd2hlbiB0aGUgcGxhdGZvcm0gb2JqZWN0IGlzIGNvZXJjZWQgdG8gYSBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbmFtZSB0b1N0cmluZ1xuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgYHBsYXRmb3JtLmRlc2NyaXB0aW9uYCBpZiBhdmFpbGFibGUsIGVsc2UgYW4gZW1wdHkgc3RyaW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHRvU3RyaW5nUGxhdGZvcm0oKSB7XG4gICAgICByZXR1cm4gdGhpcy5kZXNjcmlwdGlvbiB8fCAnJztcbiAgICB9XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvLyBDb252ZXJ0IGxheW91dCB0byBhbiBhcnJheSBzbyB3ZSBjYW4gYWRkIGV4dHJhIGRldGFpbHMuXG4gICAgbGF5b3V0ICYmIChsYXlvdXQgPSBbbGF5b3V0XSk7XG5cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBwcm9kdWN0cy5cbiAgICAvLyBCcm93c2VycyBvbiBBbmRyb2lkIGRldmljZXMgdHlwaWNhbGx5IHByb3ZpZGUgdGhlaXIgcHJvZHVjdCBJRFMgYWZ0ZXIgXCJBbmRyb2lkO1wiXG4gICAgLy8gdXAgdG8gXCJCdWlsZFwiIG9yIFwiKSBBcHBsZVdlYktpdFwiLlxuICAgIC8vIEV4YW1wbGU6XG4gICAgLy8gXCJNb3ppbGxhLzUuMCAoTGludXg7IEFuZHJvaWQgOC4xLjA7IE1vdG8gRyAoNSkgUGx1cykgQXBwbGVXZWJLaXQvNTM3LjM2XG4gICAgLy8gKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvNzAuMC4zNTM4LjgwIE1vYmlsZSBTYWZhcmkvNTM3LjM2XCJcbiAgICBpZiAoL1xcYkFuZHJvaWRcXGIvLnRlc3Qob3MpICYmICFwcm9kdWN0ICYmXG4gICAgICAgIChkYXRhID0gL1xcYkFuZHJvaWRbXjtdKjsoLio/KSg/OkJ1aWxkfFxcKSBBcHBsZVdlYktpdClcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIHByb2R1Y3QgPSB0cmltKGRhdGFbMV0pXG4gICAgICAgIC8vIFJlcGxhY2UgYW55IGxhbmd1YWdlIGNvZGVzIChlZy4gXCJlbi1VU1wiKS5cbiAgICAgICAgLnJlcGxhY2UoL15bYS16XXsyfS1bYS16XXsyfTtcXHMqL2ksICcnKVxuICAgICAgICB8fCBudWxsO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJvZHVjdCBuYW1lcyB0aGF0IGNvbnRhaW4gdGhlaXIgbWFudWZhY3R1cmVyJ3MgbmFtZS5cbiAgICBpZiAobWFudWZhY3R1cmVyICYmICFwcm9kdWN0KSB7XG4gICAgICBwcm9kdWN0ID0gZ2V0UHJvZHVjdChbbWFudWZhY3R1cmVyXSk7XG4gICAgfSBlbHNlIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCkge1xuICAgICAgcHJvZHVjdCA9IHByb2R1Y3RcbiAgICAgICAgLnJlcGxhY2UoUmVnRXhwKCdeKCcgKyBxdWFsaWZ5KG1hbnVmYWN0dXJlcikgKyAnKVstXy5cXFxcc10nLCAnaScpLCBtYW51ZmFjdHVyZXIgKyAnICcpXG4gICAgICAgIC5yZXBsYWNlKFJlZ0V4cCgnXignICsgcXVhbGlmeShtYW51ZmFjdHVyZXIpICsgJylbLV8uXT8oXFxcXHcpJywgJ2knKSwgbWFudWZhY3R1cmVyICsgJyAkMicpO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBHb29nbGUgVFYuXG4gICAgaWYgKChkYXRhID0gL1xcYkdvb2dsZSBUVlxcYi8uZXhlYyhwcm9kdWN0KSkpIHtcbiAgICAgIHByb2R1Y3QgPSBkYXRhWzBdO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc2ltdWxhdG9ycy5cbiAgICBpZiAoL1xcYlNpbXVsYXRvclxcYi9pLnRlc3QodWEpKSB7XG4gICAgICBwcm9kdWN0ID0gKHByb2R1Y3QgPyBwcm9kdWN0ICsgJyAnIDogJycpICsgJ1NpbXVsYXRvcic7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBNaW5pIDgrIHJ1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUgb24gaU9TLlxuICAgIGlmIChuYW1lID09ICdPcGVyYSBNaW5pJyAmJiAvXFxiT1BpT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdydW5uaW5nIGluIFR1cmJvL1VuY29tcHJlc3NlZCBtb2RlJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBNb2JpbGUgMTEuXG4gICAgaWYgKG5hbWUgPT0gJ0lFJyAmJiAvXFxibGlrZSBpUGhvbmUgT1NcXGIvLnRlc3QodWEpKSB7XG4gICAgICBkYXRhID0gcGFyc2UodWEucmVwbGFjZSgvbGlrZSBpUGhvbmUgT1MvLCAnJykpO1xuICAgICAgbWFudWZhY3R1cmVyID0gZGF0YS5tYW51ZmFjdHVyZXI7XG4gICAgICBwcm9kdWN0ID0gZGF0YS5wcm9kdWN0O1xuICAgIH1cbiAgICAvLyBEZXRlY3QgaU9TLlxuICAgIGVsc2UgaWYgKC9eaVAvLnRlc3QocHJvZHVjdCkpIHtcbiAgICAgIG5hbWUgfHwgKG5hbWUgPSAnU2FmYXJpJyk7XG4gICAgICBvcyA9ICdpT1MnICsgKChkYXRhID0gLyBPUyAoW1xcZF9dKykvaS5leGVjKHVhKSlcbiAgICAgICAgPyAnICcgKyBkYXRhWzFdLnJlcGxhY2UoL18vZywgJy4nKVxuICAgICAgICA6ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEt1YnVudHUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnS29ucXVlcm9yJyAmJiAvXkxpbnV4XFxiL2kudGVzdChvcykpIHtcbiAgICAgIG9zID0gJ0t1YnVudHUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgQW5kcm9pZCBicm93c2Vycy5cbiAgICBlbHNlIGlmICgobWFudWZhY3R1cmVyICYmIG1hbnVmYWN0dXJlciAhPSAnR29vZ2xlJyAmJlxuICAgICAgICAoKC9DaHJvbWUvLnRlc3QobmFtZSkgJiYgIS9cXGJNb2JpbGUgU2FmYXJpXFxiL2kudGVzdCh1YSkpIHx8IC9cXGJWaXRhXFxiLy50ZXN0KHByb2R1Y3QpKSkgfHxcbiAgICAgICAgKC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSAmJiAvXkNocm9tZS8udGVzdChuYW1lKSAmJiAvXFxiVmVyc2lvblxcLy9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSA9ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgICAgb3MgPSAvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6ICdBbmRyb2lkJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFNpbGsgZGVza3RvcC9hY2NlbGVyYXRlZCBtb2Rlcy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdTaWxrJykge1xuICAgICAgaWYgKCEvXFxiTW9iaS9pLnRlc3QodWEpKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQnO1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICgvQWNjZWxlcmF0ZWQgKj0gKnRydWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdhY2NlbGVyYXRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgVUMgQnJvd3NlciBzcGVlZCBtb2RlLlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ1VDIEJyb3dzZXInICYmIC9cXGJVQ1dFQlxcYi8udGVzdCh1YSkpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ3NwZWVkIG1vZGUnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFBhbGVNb29uIGlkZW50aWZ5aW5nIGFzIEZpcmVmb3guXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnUGFsZU1vb24nICYmIChkYXRhID0gL1xcYkZpcmVmb3hcXC8oW1xcZC5dKylcXGIvLmV4ZWModWEpKSkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgnaWRlbnRpZnlpbmcgYXMgRmlyZWZveCAnICsgZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBGaXJlZm94IE9TIGFuZCBwcm9kdWN0cyBydW5uaW5nIEZpcmVmb3guXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnRmlyZWZveCcgJiYgKGRhdGEgPSAvXFxiKE1vYmlsZXxUYWJsZXR8VFYpXFxiL2kuZXhlYyh1YSkpKSB7XG4gICAgICBvcyB8fCAob3MgPSAnRmlyZWZveCBPUycpO1xuICAgICAgcHJvZHVjdCB8fCAocHJvZHVjdCA9IGRhdGFbMV0pO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgZmFsc2UgcG9zaXRpdmVzIGZvciBGaXJlZm94L1NhZmFyaS5cbiAgICBlbHNlIGlmICghbmFtZSB8fCAoZGF0YSA9ICEvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgL1xcYig/OkZpcmVmb3h8U2FmYXJpKVxcYi8uZXhlYyhuYW1lKSkpIHtcbiAgICAgIC8vIEVzY2FwZSB0aGUgYC9gIGZvciBGaXJlZm94IDEuXG4gICAgICBpZiAobmFtZSAmJiAhcHJvZHVjdCAmJiAvW1xcLyxdfF5bXihdKz9cXCkvLnRlc3QodWEuc2xpY2UodWEuaW5kZXhPZihkYXRhICsgJy8nKSArIDgpKSkge1xuICAgICAgICAvLyBDbGVhciBuYW1lIG9mIGZhbHNlIHBvc2l0aXZlcy5cbiAgICAgICAgbmFtZSA9IG51bGw7XG4gICAgICB9XG4gICAgICAvLyBSZWFzc2lnbiBhIGdlbmVyaWMgbmFtZS5cbiAgICAgIGlmICgoZGF0YSA9IHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IG9zKSAmJlxuICAgICAgICAgIChwcm9kdWN0IHx8IG1hbnVmYWN0dXJlciB8fCAvXFxiKD86QW5kcm9pZHxTeW1iaWFuIE9TfFRhYmxldCBPU3x3ZWJPUylcXGIvLnRlc3Qob3MpKSkge1xuICAgICAgICBuYW1lID0gL1thLXpdKyg/OiBIYXQpPy9pLmV4ZWMoL1xcYkFuZHJvaWRcXGIvLnRlc3Qob3MpID8gb3MgOiBkYXRhKSArICcgQnJvd3Nlcic7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEFkZCBDaHJvbWUgdmVyc2lvbiB0byBkZXNjcmlwdGlvbiBmb3IgRWxlY3Ryb24uXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnRWxlY3Ryb24nICYmIChkYXRhID0gKC9cXGJDaHJvbWVcXC8oW1xcZC5dKylcXGIvLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgnQ2hyb21pdW0gJyArIGRhdGEpO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgbm9uLU9wZXJhIChQcmVzdG8tYmFzZWQpIHZlcnNpb25zIChvcmRlciBpcyBpbXBvcnRhbnQpLlxuICAgIGlmICghdmVyc2lvbikge1xuICAgICAgdmVyc2lvbiA9IGdldFZlcnNpb24oW1xuICAgICAgICAnKD86Q2xvdWQ5fENyaU9TfENyTW98RWRnZXxFZGd8RWRnQXxFZGdpT1N8RnhpT1N8SGVhZGxlc3NDaHJvbWV8SUVNb2JpbGV8SXJvbnxPcGVyYSA/TWluaXxPUGlPU3xPUFJ8UmF2ZW58U2Ftc3VuZ0Jyb3dzZXJ8U2lsayg/IS9bXFxcXGQuXSskKXxVQ0Jyb3dzZXJ8WWFCcm93c2VyKScsXG4gICAgICAgICdWZXJzaW9uJyxcbiAgICAgICAgcXVhbGlmeShuYW1lKSxcbiAgICAgICAgJyg/OkZpcmVmb3h8TWluZWZpZWxkfE5ldEZyb250KSdcbiAgICAgIF0pO1xuICAgIH1cbiAgICAvLyBEZXRlY3Qgc3R1YmJvcm4gbGF5b3V0IGVuZ2luZXMuXG4gICAgaWYgKChkYXRhID1cbiAgICAgICAgICBsYXlvdXQgPT0gJ2lDYWInICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPiAzICYmICdXZWJLaXQnIHx8XG4gICAgICAgICAgL1xcYk9wZXJhXFxiLy50ZXN0KG5hbWUpICYmICgvXFxiT1BSXFxiLy50ZXN0KHVhKSA/ICdCbGluaycgOiAnUHJlc3RvJykgfHxcbiAgICAgICAgICAvXFxiKD86TWlkb3JpfE5vb2t8U2FmYXJpKVxcYi9pLnRlc3QodWEpICYmICEvXig/OlRyaWRlbnR8RWRnZUhUTUwpJC8udGVzdChsYXlvdXQpICYmICdXZWJLaXQnIHx8XG4gICAgICAgICAgIWxheW91dCAmJiAvXFxiTVNJRVxcYi9pLnRlc3QodWEpICYmIChvcyA9PSAnTWFjIE9TJyA/ICdUYXNtYW4nIDogJ1RyaWRlbnQnKSB8fFxuICAgICAgICAgIGxheW91dCA9PSAnV2ViS2l0JyAmJiAvXFxiUGxheVN0YXRpb25cXGIoPyEgVml0YVxcYikvaS50ZXN0KG5hbWUpICYmICdOZXRGcm9udCdcbiAgICAgICAgKSkge1xuICAgICAgbGF5b3V0ID0gW2RhdGFdO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA3IGRlc2t0b3AgbW9kZS5cbiAgICBpZiAobmFtZSA9PSAnSUUnICYmIChkYXRhID0gKC87ICooPzpYQkxXUHxadW5lV1ApKFxcZCspL2kuZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBuYW1lICs9ICcgTW9iaWxlJztcbiAgICAgIG9zID0gJ1dpbmRvd3MgUGhvbmUgJyArICgvXFwrJC8udGVzdChkYXRhKSA/IGRhdGEgOiBkYXRhICsgJy54Jyk7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IFdpbmRvd3MgUGhvbmUgOC54IGRlc2t0b3AgbW9kZS5cbiAgICBlbHNlIGlmICgvXFxiV1BEZXNrdG9wXFxiL2kudGVzdCh1YSkpIHtcbiAgICAgIG5hbWUgPSAnSUUgTW9iaWxlJztcbiAgICAgIG9zID0gJ1dpbmRvd3MgUGhvbmUgOC54JztcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgICAgdmVyc2lvbiB8fCAodmVyc2lvbiA9ICgvXFxicnY6KFtcXGQuXSspLy5leGVjKHVhKSB8fCAwKVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSAxMSBpZGVudGlmeWluZyBhcyBvdGhlciBicm93c2Vycy5cbiAgICBlbHNlIGlmIChuYW1lICE9ICdJRScgJiYgbGF5b3V0ID09ICdUcmlkZW50JyAmJiAoZGF0YSA9IC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpKSkge1xuICAgICAgaWYgKG5hbWUpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnaWRlbnRpZnlpbmcgYXMgJyArIG5hbWUgKyAodmVyc2lvbiA/ICcgJyArIHZlcnNpb24gOiAnJykpO1xuICAgICAgfVxuICAgICAgbmFtZSA9ICdJRSc7XG4gICAgICB2ZXJzaW9uID0gZGF0YVsxXTtcbiAgICB9XG4gICAgLy8gTGV2ZXJhZ2UgZW52aXJvbm1lbnQgZmVhdHVyZXMuXG4gICAgaWYgKHVzZUZlYXR1cmVzKSB7XG4gICAgICAvLyBEZXRlY3Qgc2VydmVyLXNpZGUgZW52aXJvbm1lbnRzLlxuICAgICAgLy8gUmhpbm8gaGFzIGEgZ2xvYmFsIGZ1bmN0aW9uIHdoaWxlIG90aGVycyBoYXZlIGEgZ2xvYmFsIG9iamVjdC5cbiAgICAgIGlmIChpc0hvc3RUeXBlKGNvbnRleHQsICdnbG9iYWwnKSkge1xuICAgICAgICBpZiAoamF2YSkge1xuICAgICAgICAgIGRhdGEgPSBqYXZhLmxhbmcuU3lzdGVtO1xuICAgICAgICAgIGFyY2ggPSBkYXRhLmdldFByb3BlcnR5KCdvcy5hcmNoJyk7XG4gICAgICAgICAgb3MgPSBvcyB8fCBkYXRhLmdldFByb3BlcnR5KCdvcy5uYW1lJykgKyAnICcgKyBkYXRhLmdldFByb3BlcnR5KCdvcy52ZXJzaW9uJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJoaW5vKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZlcnNpb24gPSBjb250ZXh0LnJlcXVpcmUoJ3JpbmdvL2VuZ2luZScpLnZlcnNpb24uam9pbignLicpO1xuICAgICAgICAgICAgbmFtZSA9ICdSaW5nb0pTJztcbiAgICAgICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgICAgIGlmICgoZGF0YSA9IGNvbnRleHQuc3lzdGVtKSAmJiBkYXRhLmdsb2JhbC5zeXN0ZW0gPT0gY29udGV4dC5zeXN0ZW0pIHtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOYXJ3aGFsJztcbiAgICAgICAgICAgICAgb3MgfHwgKG9zID0gZGF0YVswXS5vcyB8fCBudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgICAgICBuYW1lID0gJ1JoaW5vJztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoXG4gICAgICAgICAgdHlwZW9mIGNvbnRleHQucHJvY2VzcyA9PSAnb2JqZWN0JyAmJiAhY29udGV4dC5wcm9jZXNzLmJyb3dzZXIgJiZcbiAgICAgICAgICAoZGF0YSA9IGNvbnRleHQucHJvY2VzcylcbiAgICAgICAgKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zID09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMuZWxlY3Ryb24gPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdFbGVjdHJvbic7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLmVsZWN0cm9uO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5udyA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgdmVyc2lvbiwgJ05vZGUgJyArIGRhdGEudmVyc2lvbnMubm9kZSk7XG4gICAgICAgICAgICAgIG5hbWUgPSAnTlcuanMnO1xuICAgICAgICAgICAgICB2ZXJzaW9uID0gZGF0YS52ZXJzaW9ucy5udztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgICAgICBuYW1lID0gJ05vZGUuanMnO1xuICAgICAgICAgICAgYXJjaCA9IGRhdGEuYXJjaDtcbiAgICAgICAgICAgIG9zID0gZGF0YS5wbGF0Zm9ybTtcbiAgICAgICAgICAgIHZlcnNpb24gPSAvW1xcZC5dKy8uZXhlYyhkYXRhLnZlcnNpb24pO1xuICAgICAgICAgICAgdmVyc2lvbiA9IHZlcnNpb24gPyB2ZXJzaW9uWzBdIDogbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBBZG9iZSBBSVIuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5ydW50aW1lKSkgPT0gYWlyUnVudGltZUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnQWRvYmUgQUlSJztcbiAgICAgICAgb3MgPSBkYXRhLmZsYXNoLnN5c3RlbS5DYXBhYmlsaXRpZXMub3M7XG4gICAgICB9XG4gICAgICAvLyBEZXRlY3QgUGhhbnRvbUpTLlxuICAgICAgZWxzZSBpZiAoZ2V0Q2xhc3NPZigoZGF0YSA9IGNvbnRleHQucGhhbnRvbSkpID09IHBoYW50b21DbGFzcykge1xuICAgICAgICBuYW1lID0gJ1BoYW50b21KUyc7XG4gICAgICAgIHZlcnNpb24gPSAoZGF0YSA9IGRhdGEudmVyc2lvbiB8fCBudWxsKSAmJiAoZGF0YS5tYWpvciArICcuJyArIGRhdGEubWlub3IgKyAnLicgKyBkYXRhLnBhdGNoKTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSBjb21wYXRpYmlsaXR5IG1vZGVzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgKGRhdGEgPSAvXFxiVHJpZGVudFxcLyhcXGQrKS9pLmV4ZWModWEpKSkge1xuICAgICAgICAvLyBXZSdyZSBpbiBjb21wYXRpYmlsaXR5IG1vZGUgd2hlbiB0aGUgVHJpZGVudCB2ZXJzaW9uICsgNCBkb2Vzbid0XG4gICAgICAgIC8vIGVxdWFsIHRoZSBkb2N1bWVudCBtb2RlLlxuICAgICAgICB2ZXJzaW9uID0gW3ZlcnNpb24sIGRvYy5kb2N1bWVudE1vZGVdO1xuICAgICAgICBpZiAoKGRhdGEgPSArZGF0YVsxXSArIDQpICE9IHZlcnNpb25bMV0pIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdJRSAnICsgdmVyc2lvblsxXSArICcgbW9kZScpO1xuICAgICAgICAgIGxheW91dCAmJiAobGF5b3V0WzFdID0gJycpO1xuICAgICAgICAgIHZlcnNpb25bMV0gPSBkYXRhO1xuICAgICAgICB9XG4gICAgICAgIHZlcnNpb24gPSBuYW1lID09ICdJRScgPyBTdHJpbmcodmVyc2lvblsxXS50b0ZpeGVkKDEpKSA6IHZlcnNpb25bMF07XG4gICAgICB9XG4gICAgICAvLyBEZXRlY3QgSUUgMTEgbWFza2luZyBhcyBvdGhlciBicm93c2Vycy5cbiAgICAgIGVsc2UgaWYgKHR5cGVvZiBkb2MuZG9jdW1lbnRNb2RlID09ICdudW1iZXInICYmIC9eKD86Q2hyb21lfEZpcmVmb3gpXFxiLy50ZXN0KG5hbWUpKSB7XG4gICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ21hc2tpbmcgYXMgJyArIG5hbWUgKyAnICcgKyB2ZXJzaW9uKTtcbiAgICAgICAgbmFtZSA9ICdJRSc7XG4gICAgICAgIHZlcnNpb24gPSAnMTEuMCc7XG4gICAgICAgIGxheW91dCA9IFsnVHJpZGVudCddO1xuICAgICAgICBvcyA9ICdXaW5kb3dzJztcbiAgICAgIH1cbiAgICAgIG9zID0gb3MgJiYgZm9ybWF0KG9zKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IHByZXJlbGVhc2UgcGhhc2VzLlxuICAgIGlmICh2ZXJzaW9uICYmIChkYXRhID1cbiAgICAgICAgICAvKD86W2FiXXxkcHxwcmV8W2FiXVxcZCtwcmUpKD86XFxkK1xcKz8pPyQvaS5leGVjKHZlcnNpb24pIHx8XG4gICAgICAgICAgLyg/OmFscGhhfGJldGEpKD86ID9cXGQpPy9pLmV4ZWModWEgKyAnOycgKyAodXNlRmVhdHVyZXMgJiYgbmF2LmFwcE1pbm9yVmVyc2lvbikpIHx8XG4gICAgICAgICAgL1xcYk1pbmVmaWVsZFxcYi9pLnRlc3QodWEpICYmICdhJ1xuICAgICAgICApKSB7XG4gICAgICBwcmVyZWxlYXNlID0gL2IvaS50ZXN0KGRhdGEpID8gJ2JldGEnIDogJ2FscGhhJztcbiAgICAgIHZlcnNpb24gPSB2ZXJzaW9uLnJlcGxhY2UoUmVnRXhwKGRhdGEgKyAnXFxcXCs/JCcpLCAnJykgK1xuICAgICAgICAocHJlcmVsZWFzZSA9PSAnYmV0YScgPyBiZXRhIDogYWxwaGEpICsgKC9cXGQrXFwrPy8uZXhlYyhkYXRhKSB8fCAnJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBGaXJlZm94IE1vYmlsZS5cbiAgICBpZiAobmFtZSA9PSAnRmVubmVjJyB8fCBuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiKD86QW5kcm9pZHxGaXJlZm94IE9TfEthaU9TKVxcYi8udGVzdChvcykpIHtcbiAgICAgIG5hbWUgPSAnRmlyZWZveCBNb2JpbGUnO1xuICAgIH1cbiAgICAvLyBPYnNjdXJlIE1heHRob24ncyB1bnJlbGlhYmxlIHZlcnNpb24uXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnTWF4dGhvbicgJiYgdmVyc2lvbikge1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZSgvXFwuW1xcZC5dKy8sICcueCcpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgWGJveCAzNjAgYW5kIFhib3ggT25lLlxuICAgIGVsc2UgaWYgKC9cXGJYYm94XFxiL2kudGVzdChwcm9kdWN0KSkge1xuICAgICAgaWYgKHByb2R1Y3QgPT0gJ1hib3ggMzYwJykge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnICYmIC9cXGJJRU1vYmlsZVxcYi8udGVzdCh1YSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnbW9iaWxlIG1vZGUnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIG1vYmlsZSBwb3N0Zml4LlxuICAgIGVsc2UgaWYgKCgvXig/OkNocm9tZXxJRXxPcGVyYSkkLy50ZXN0KG5hbWUpIHx8IG5hbWUgJiYgIXByb2R1Y3QgJiYgIS9Ccm93c2VyfE1vYmkvLnRlc3QobmFtZSkpICYmXG4gICAgICAgIChvcyA9PSAnV2luZG93cyBDRScgfHwgL01vYmkvaS50ZXN0KHVhKSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgSUUgcGxhdGZvcm0gcHJldmlldy5cbiAgICBlbHNlIGlmIChuYW1lID09ICdJRScgJiYgdXNlRmVhdHVyZXMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmIChjb250ZXh0LmV4dGVybmFsID09PSBudWxsKSB7XG4gICAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgncGxhdGZvcm0gcHJldmlldycpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZW1iZWRkZWQnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gRGV0ZWN0IEJsYWNrQmVycnkgT1MgdmVyc2lvbi5cbiAgICAvLyBodHRwOi8vZG9jcy5ibGFja2JlcnJ5LmNvbS9lbi9kZXZlbG9wZXJzL2RlbGl2ZXJhYmxlcy8xODE2OS9IVFRQX2hlYWRlcnNfc2VudF9ieV9CQl9Ccm93c2VyXzEyMzQ5MTFfMTEuanNwXG4gICAgZWxzZSBpZiAoKC9cXGJCbGFja0JlcnJ5XFxiLy50ZXN0KHByb2R1Y3QpIHx8IC9cXGJCQjEwXFxiLy50ZXN0KHVhKSkgJiYgKGRhdGEgPVxuICAgICAgICAgIChSZWdFeHAocHJvZHVjdC5yZXBsYWNlKC8gKy9nLCAnIConKSArICcvKFsuXFxcXGRdKyknLCAnaScpLmV4ZWModWEpIHx8IDApWzFdIHx8XG4gICAgICAgICAgdmVyc2lvblxuICAgICAgICApKSB7XG4gICAgICBkYXRhID0gW2RhdGEsIC9CQjEwLy50ZXN0KHVhKV07XG4gICAgICBvcyA9IChkYXRhWzFdID8gKHByb2R1Y3QgPSBudWxsLCBtYW51ZmFjdHVyZXIgPSAnQmxhY2tCZXJyeScpIDogJ0RldmljZSBTb2Z0d2FyZScpICsgJyAnICsgZGF0YVswXTtcbiAgICAgIHZlcnNpb24gPSBudWxsO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgT3BlcmEgaWRlbnRpZnlpbmcvbWFza2luZyBpdHNlbGYgYXMgYW5vdGhlciBicm93c2VyLlxuICAgIC8vIGh0dHA6Ly93d3cub3BlcmEuY29tL3N1cHBvcnQva2Ivdmlldy84NDMvXG4gICAgZWxzZSBpZiAodGhpcyAhPSBmb3JPd24gJiYgcHJvZHVjdCAhPSAnV2lpJyAmJiAoXG4gICAgICAgICAgKHVzZUZlYXR1cmVzICYmIG9wZXJhKSB8fFxuICAgICAgICAgICgvT3BlcmEvLnRlc3QobmFtZSkgJiYgL1xcYig/Ok1TSUV8RmlyZWZveClcXGIvaS50ZXN0KHVhKSkgfHxcbiAgICAgICAgICAobmFtZSA9PSAnRmlyZWZveCcgJiYgL1xcYk9TIFggKD86XFxkK1xcLil7Mix9Ly50ZXN0KG9zKSkgfHxcbiAgICAgICAgICAobmFtZSA9PSAnSUUnICYmIChcbiAgICAgICAgICAgIChvcyAmJiAhL15XaW4vLnRlc3Qob3MpICYmIHZlcnNpb24gPiA1LjUpIHx8XG4gICAgICAgICAgICAvXFxiV2luZG93cyBYUFxcYi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDggfHxcbiAgICAgICAgICAgIHZlcnNpb24gPT0gOCAmJiAhL1xcYlRyaWRlbnRcXGIvLnRlc3QodWEpXG4gICAgICAgICAgKSlcbiAgICAgICAgKSAmJiAhcmVPcGVyYS50ZXN0KChkYXRhID0gcGFyc2UuY2FsbChmb3JPd24sIHVhLnJlcGxhY2UocmVPcGVyYSwgJycpICsgJzsnKSkpICYmIGRhdGEubmFtZSkge1xuICAgICAgLy8gV2hlbiBcImlkZW50aWZ5aW5nXCIsIHRoZSBVQSBjb250YWlucyBib3RoIE9wZXJhIGFuZCB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBkYXRhID0gJ2luZyBhcyAnICsgZGF0YS5uYW1lICsgKChkYXRhID0gZGF0YS52ZXJzaW9uKSA/ICcgJyArIGRhdGEgOiAnJyk7XG4gICAgICBpZiAocmVPcGVyYS50ZXN0KG5hbWUpKSB7XG4gICAgICAgIGlmICgvXFxiSUVcXGIvLnRlc3QoZGF0YSkgJiYgb3MgPT0gJ01hYyBPUycpIHtcbiAgICAgICAgICBvcyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YSA9ICdpZGVudGlmeScgKyBkYXRhO1xuICAgICAgfVxuICAgICAgLy8gV2hlbiBcIm1hc2tpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIG9ubHkgdGhlIG90aGVyIGJyb3dzZXIncyBuYW1lLlxuICAgICAgZWxzZSB7XG4gICAgICAgIGRhdGEgPSAnbWFzaycgKyBkYXRhO1xuICAgICAgICBpZiAob3BlcmFDbGFzcykge1xuICAgICAgICAgIG5hbWUgPSBmb3JtYXQob3BlcmFDbGFzcy5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCAnJDEgJDInKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmFtZSA9ICdPcGVyYSc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSkge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXVzZUZlYXR1cmVzKSB7XG4gICAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxheW91dCA9IFsnUHJlc3RvJ107XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKGRhdGEpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2ViS2l0IE5pZ2h0bHkgYW5kIGFwcHJveGltYXRlIENocm9tZS9TYWZhcmkgdmVyc2lvbnMuXG4gICAgaWYgKChkYXRhID0gKC9cXGJBcHBsZVdlYktpdFxcLyhbXFxkLl0rXFwrPykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIC8vIENvcnJlY3QgYnVpbGQgbnVtYmVyIGZvciBudW1lcmljIGNvbXBhcmlzb24uXG4gICAgICAvLyAoZS5nLiBcIjUzMi41XCIgYmVjb21lcyBcIjUzMi4wNVwiKVxuICAgICAgZGF0YSA9IFtwYXJzZUZsb2F0KGRhdGEucmVwbGFjZSgvXFwuKFxcZCkkLywgJy4wJDEnKSksIGRhdGFdO1xuICAgICAgLy8gTmlnaHRseSBidWlsZHMgYXJlIHBvc3RmaXhlZCB3aXRoIGEgXCIrXCIuXG4gICAgICBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiBkYXRhWzFdLnNsaWNlKC0xKSA9PSAnKycpIHtcbiAgICAgICAgbmFtZSA9ICdXZWJLaXQgTmlnaHRseSc7XG4gICAgICAgIHByZXJlbGVhc2UgPSAnYWxwaGEnO1xuICAgICAgICB2ZXJzaW9uID0gZGF0YVsxXS5zbGljZSgwLCAtMSk7XG4gICAgICB9XG4gICAgICAvLyBDbGVhciBpbmNvcnJlY3QgYnJvd3NlciB2ZXJzaW9ucy5cbiAgICAgIGVsc2UgaWYgKHZlcnNpb24gPT0gZGF0YVsxXSB8fFxuICAgICAgICAgIHZlcnNpb24gPT0gKGRhdGFbMl0gPSAoL1xcYlNhZmFyaVxcLyhbXFxkLl0rXFwrPykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9XG4gICAgICAvLyBVc2UgdGhlIGZ1bGwgQ2hyb21lIHZlcnNpb24gd2hlbiBhdmFpbGFibGUuXG4gICAgICBkYXRhWzFdID0gKC9cXGIoPzpIZWFkbGVzcyk/Q2hyb21lXFwvKFtcXGQuXSspL2kuZXhlYyh1YSkgfHwgMClbMV07XG4gICAgICAvLyBEZXRlY3QgQmxpbmsgbGF5b3V0IGVuZ2luZS5cbiAgICAgIGlmIChkYXRhWzBdID09IDUzNy4zNiAmJiBkYXRhWzJdID09IDUzNy4zNiAmJiBwYXJzZUZsb2F0KGRhdGFbMV0pID49IDI4ICYmIGxheW91dCA9PSAnV2ViS2l0Jykge1xuICAgICAgICBsYXlvdXQgPSBbJ0JsaW5rJ107XG4gICAgICB9XG4gICAgICAvLyBEZXRlY3QgSmF2YVNjcmlwdENvcmUuXG4gICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzY3Njg0NzQvaG93LWNhbi1pLWRldGVjdC13aGljaC1qYXZhc2NyaXB0LWVuZ2luZS12OC1vci1qc2MtaXMtdXNlZC1hdC1ydW50aW1lLWluLWFuZHJvaVxuICAgICAgaWYgKCF1c2VGZWF0dXJlcyB8fCAoIWxpa2VDaHJvbWUgJiYgIWRhdGFbMV0pKSB7XG4gICAgICAgIGxheW91dCAmJiAobGF5b3V0WzFdID0gJ2xpa2UgU2FmYXJpJyk7XG4gICAgICAgIGRhdGEgPSAoZGF0YSA9IGRhdGFbMF0sIGRhdGEgPCA0MDAgPyAxIDogZGF0YSA8IDUwMCA/IDIgOiBkYXRhIDwgNTI2ID8gMyA6IGRhdGEgPCA1MzMgPyA0IDogZGF0YSA8IDUzNCA/ICc0KycgOiBkYXRhIDwgNTM1ID8gNSA6IGRhdGEgPCA1MzcgPyA2IDogZGF0YSA8IDUzOCA/IDcgOiBkYXRhIDwgNjAxID8gOCA6IGRhdGEgPCA2MDIgPyA5IDogZGF0YSA8IDYwNCA/IDEwIDogZGF0YSA8IDYwNiA/IDExIDogZGF0YSA8IDYwOCA/IDEyIDogJzEyJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSA9ICdsaWtlIENocm9tZScpO1xuICAgICAgICBkYXRhID0gZGF0YVsxXSB8fCAoZGF0YSA9IGRhdGFbMF0sIGRhdGEgPCA1MzAgPyAxIDogZGF0YSA8IDUzMiA/IDIgOiBkYXRhIDwgNTMyLjA1ID8gMyA6IGRhdGEgPCA1MzMgPyA0IDogZGF0YSA8IDUzNC4wMyA/IDUgOiBkYXRhIDwgNTM0LjA3ID8gNiA6IGRhdGEgPCA1MzQuMTAgPyA3IDogZGF0YSA8IDUzNC4xMyA/IDggOiBkYXRhIDwgNTM0LjE2ID8gOSA6IGRhdGEgPCA1MzQuMjQgPyAxMCA6IGRhdGEgPCA1MzQuMzAgPyAxMSA6IGRhdGEgPCA1MzUuMDEgPyAxMiA6IGRhdGEgPCA1MzUuMDIgPyAnMTMrJyA6IGRhdGEgPCA1MzUuMDcgPyAxNSA6IGRhdGEgPCA1MzUuMTEgPyAxNiA6IGRhdGEgPCA1MzUuMTkgPyAxNyA6IGRhdGEgPCA1MzYuMDUgPyAxOCA6IGRhdGEgPCA1MzYuMTAgPyAxOSA6IGRhdGEgPCA1MzcuMDEgPyAyMCA6IGRhdGEgPCA1MzcuMTEgPyAnMjErJyA6IGRhdGEgPCA1MzcuMTMgPyAyMyA6IGRhdGEgPCA1MzcuMTggPyAyNCA6IGRhdGEgPCA1MzcuMjQgPyAyNSA6IGRhdGEgPCA1MzcuMzYgPyAyNiA6IGxheW91dCAhPSAnQmxpbmsnID8gJzI3JyA6ICcyOCcpO1xuICAgICAgfVxuICAgICAgLy8gQWRkIHRoZSBwb3N0Zml4IG9mIFwiLnhcIiBvciBcIitcIiBmb3IgYXBwcm94aW1hdGUgdmVyc2lvbnMuXG4gICAgICBsYXlvdXQgJiYgKGxheW91dFsxXSArPSAnICcgKyAoZGF0YSArPSB0eXBlb2YgZGF0YSA9PSAnbnVtYmVyJyA/ICcueCcgOiAvWy4rXS8udGVzdChkYXRhKSA/ICcnIDogJysnKSk7XG4gICAgICAvLyBPYnNjdXJlIHZlcnNpb24gZm9yIHNvbWUgU2FmYXJpIDEtMiByZWxlYXNlcy5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmICghdmVyc2lvbiB8fCBwYXJzZUludCh2ZXJzaW9uKSA+IDQ1KSkge1xuICAgICAgICB2ZXJzaW9uID0gZGF0YTtcbiAgICAgIH0gZWxzZSBpZiAobmFtZSA9PSAnQ2hyb21lJyAmJiAvXFxiSGVhZGxlc3NDaHJvbWUvaS50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdoZWFkbGVzcycpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgT3BlcmEgZGVza3RvcCBtb2Rlcy5cbiAgICBpZiAobmFtZSA9PSAnT3BlcmEnICYmICAoZGF0YSA9IC9cXGJ6Ym92fHp2YXYkLy5leGVjKG9zKSkpIHtcbiAgICAgIG5hbWUgKz0gJyAnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICBpZiAoZGF0YSA9PSAnenZhdicpIHtcbiAgICAgICAgbmFtZSArPSAnTWluaSc7XG4gICAgICAgIHZlcnNpb24gPSBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmFtZSArPSAnTW9iaWxlJztcbiAgICAgIH1cbiAgICAgIG9zID0gb3MucmVwbGFjZShSZWdFeHAoJyAqJyArIGRhdGEgKyAnJCcpLCAnJyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBDaHJvbWUgZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ1NhZmFyaScgJiYgL1xcYkNocm9tZVxcYi8uZXhlYyhsYXlvdXQgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICBuYW1lID0gJ0Nocm9tZSBNb2JpbGUnO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG5cbiAgICAgIGlmICgvXFxiT1MgWFxcYi8udGVzdChvcykpIHtcbiAgICAgICAgbWFudWZhY3R1cmVyID0gJ0FwcGxlJztcbiAgICAgICAgb3MgPSAnaU9TIDQuMysnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3MgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBOZXdlciB2ZXJzaW9ucyBvZiBTUldhcmUgSXJvbiB1c2VzIHRoZSBDaHJvbWUgdGFnIHRvIGluZGljYXRlIGl0cyB2ZXJzaW9uIG51bWJlci5cbiAgICBlbHNlIGlmICgvXFxiU1JXYXJlIElyb25cXGIvLnRlc3QobmFtZSkgJiYgIXZlcnNpb24pIHtcbiAgICAgIHZlcnNpb24gPSBnZXRWZXJzaW9uKCdDaHJvbWUnKTtcbiAgICB9XG4gICAgLy8gU3RyaXAgaW5jb3JyZWN0IE9TIHZlcnNpb25zLlxuICAgIGlmICh2ZXJzaW9uICYmIHZlcnNpb24uaW5kZXhPZigoZGF0YSA9IC9bXFxkLl0rJC8uZXhlYyhvcykpKSA9PSAwICYmXG4gICAgICAgIHVhLmluZGV4T2YoJy8nICsgZGF0YSArICctJykgPiAtMSkge1xuICAgICAgb3MgPSB0cmltKG9zLnJlcGxhY2UoZGF0YSwgJycpKTtcbiAgICB9XG4gICAgLy8gRW5zdXJlIE9TIGRvZXMgbm90IGluY2x1ZGUgdGhlIGJyb3dzZXIgbmFtZS5cbiAgICBpZiAob3MgJiYgb3MuaW5kZXhPZihuYW1lKSAhPSAtMSAmJiAhUmVnRXhwKG5hbWUgKyAnIE9TJykudGVzdChvcykpIHtcbiAgICAgIG9zID0gb3MucmVwbGFjZShSZWdFeHAoJyAqJyArIHF1YWxpZnkobmFtZSkgKyAnIConKSwgJycpO1xuICAgIH1cbiAgICAvLyBBZGQgbGF5b3V0IGVuZ2luZS5cbiAgICBpZiAobGF5b3V0ICYmICEvXFxiKD86QXZhbnR8Tm9vaylcXGIvLnRlc3QobmFtZSkgJiYgKFxuICAgICAgICAvQnJvd3NlcnxMdW5hc2NhcGV8TWF4dGhvbi8udGVzdChuYW1lKSB8fFxuICAgICAgICBuYW1lICE9ICdTYWZhcmknICYmIC9eaU9TLy50ZXN0KG9zKSAmJiAvXFxiU2FmYXJpXFxiLy50ZXN0KGxheW91dFsxXSkgfHxcbiAgICAgICAgL14oPzpBZG9iZXxBcm9yYXxCcmVhY2h8TWlkb3JpfE9wZXJhfFBoYW50b218UmVrb25xfFJvY2t8U2Ftc3VuZyBJbnRlcm5ldHxTbGVpcG5pcnxTUldhcmUgSXJvbnxWaXZhbGRpfFdlYikvLnRlc3QobmFtZSkgJiYgbGF5b3V0WzFdKSkge1xuICAgICAgLy8gRG9uJ3QgYWRkIGxheW91dCBkZXRhaWxzIHRvIGRlc2NyaXB0aW9uIGlmIHRoZXkgYXJlIGZhbHNleS5cbiAgICAgIChkYXRhID0gbGF5b3V0W2xheW91dC5sZW5ndGggLSAxXSkgJiYgZGVzY3JpcHRpb24ucHVzaChkYXRhKTtcbiAgICB9XG4gICAgLy8gQ29tYmluZSBjb250ZXh0dWFsIGluZm9ybWF0aW9uLlxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIGRlc2NyaXB0aW9uID0gWycoJyArIGRlc2NyaXB0aW9uLmpvaW4oJzsgJykgKyAnKSddO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgbWFudWZhY3R1cmVyIHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgcHJvZHVjdCAmJiBwcm9kdWN0LmluZGV4T2YobWFudWZhY3R1cmVyKSA8IDApIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ29uICcgKyBtYW51ZmFjdHVyZXIpO1xuICAgIH1cbiAgICAvLyBBcHBlbmQgcHJvZHVjdCB0byBkZXNjcmlwdGlvbi5cbiAgICBpZiAocHJvZHVjdCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgoL15vbiAvLnRlc3QoZGVzY3JpcHRpb25bZGVzY3JpcHRpb24ubGVuZ3RoIC0gMV0pID8gJycgOiAnb24gJykgKyBwcm9kdWN0KTtcbiAgICB9XG4gICAgLy8gUGFyc2UgdGhlIE9TIGludG8gYW4gb2JqZWN0LlxuICAgIGlmIChvcykge1xuICAgICAgZGF0YSA9IC8gKFtcXGQuK10rKSQvLmV4ZWMob3MpO1xuICAgICAgaXNTcGVjaWFsQ2FzZWRPUyA9IGRhdGEgJiYgb3MuY2hhckF0KG9zLmxlbmd0aCAtIGRhdGFbMF0ubGVuZ3RoIC0gMSkgPT0gJy8nO1xuICAgICAgb3MgPSB7XG4gICAgICAgICdhcmNoaXRlY3R1cmUnOiAzMixcbiAgICAgICAgJ2ZhbWlseSc6IChkYXRhICYmICFpc1NwZWNpYWxDYXNlZE9TKSA/IG9zLnJlcGxhY2UoZGF0YVswXSwgJycpIDogb3MsXG4gICAgICAgICd2ZXJzaW9uJzogZGF0YSA/IGRhdGFbMV0gOiBudWxsLFxuICAgICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICB2YXIgdmVyc2lvbiA9IHRoaXMudmVyc2lvbjtcbiAgICAgICAgICByZXR1cm4gdGhpcy5mYW1pbHkgKyAoKHZlcnNpb24gJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gJyAnICsgdmVyc2lvbiA6ICcnKSArICh0aGlzLmFyY2hpdGVjdHVyZSA9PSA2NCA/ICcgNjQtYml0JyA6ICcnKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gQWRkIGJyb3dzZXIvT1MgYXJjaGl0ZWN0dXJlLlxuICAgIGlmICgoZGF0YSA9IC9cXGIoPzpBTUR8SUF8V2lufFdPV3x4ODZffHgpNjRcXGIvaS5leGVjKGFyY2gpKSAmJiAhL1xcYmk2ODZcXGIvaS50ZXN0KGFyY2gpKSB7XG4gICAgICBpZiAob3MpIHtcbiAgICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgICAgIG9zLmZhbWlseSA9IG9zLmZhbWlseS5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSksICcnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgICBuYW1lICYmICgvXFxiV09XNjRcXGIvaS50ZXN0KHVhKSB8fFxuICAgICAgICAgICh1c2VGZWF0dXJlcyAmJiAvXFx3KD86ODZ8MzIpJC8udGVzdChuYXYuY3B1Q2xhc3MgfHwgbmF2LnBsYXRmb3JtKSAmJiAhL1xcYldpbjY0OyB4NjRcXGIvaS50ZXN0KHVhKSkpXG4gICAgICApIHtcbiAgICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnMzItYml0Jyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENocm9tZSAzOSBhbmQgYWJvdmUgb24gT1MgWCBpcyBhbHdheXMgNjQtYml0LlxuICAgIGVsc2UgaWYgKFxuICAgICAgICBvcyAmJiAvXk9TIFgvLnRlc3Qob3MuZmFtaWx5KSAmJlxuICAgICAgICBuYW1lID09ICdDaHJvbWUnICYmIHBhcnNlRmxvYXQodmVyc2lvbikgPj0gMzlcbiAgICApIHtcbiAgICAgIG9zLmFyY2hpdGVjdHVyZSA9IDY0O1xuICAgIH1cblxuICAgIHVhIHx8ICh1YSA9IG51bGwpO1xuXG4gICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgLyoqXG4gICAgICogVGhlIHBsYXRmb3JtIG9iamVjdC5cbiAgICAgKlxuICAgICAqIEBuYW1lIHBsYXRmb3JtXG4gICAgICogQHR5cGUgT2JqZWN0XG4gICAgICovXG4gICAgdmFyIHBsYXRmb3JtID0ge307XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gZGVzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3NlcidzIGxheW91dCBlbmdpbmUuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gbGF5b3V0IGVuZ2luZXMgaW5jbHVkZTpcbiAgICAgKiBcIkJsaW5rXCIsIFwiRWRnZUhUTUxcIiwgXCJHZWNrb1wiLCBcIlRyaWRlbnRcIiBhbmQgXCJXZWJLaXRcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5sYXlvdXQgPSBsYXlvdXQgJiYgbGF5b3V0WzBdO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QncyBtYW51ZmFjdHVyZXIuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBtYW51ZmFjdHVyZXJzIGluY2x1ZGU6XG4gICAgICogXCJBcHBsZVwiLCBcIkFyY2hvc1wiLCBcIkFtYXpvblwiLCBcIkFzdXNcIiwgXCJCYXJuZXMgJiBOb2JsZVwiLCBcIkJsYWNrQmVycnlcIixcbiAgICAgKiBcIkdvb2dsZVwiLCBcIkhQXCIsIFwiSFRDXCIsIFwiTEdcIiwgXCJNaWNyb3NvZnRcIiwgXCJNb3Rvcm9sYVwiLCBcIk5pbnRlbmRvXCIsXG4gICAgICogXCJOb2tpYVwiLCBcIlNhbXN1bmdcIiBhbmQgXCJTb255XCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubWFudWZhY3R1cmVyID0gbWFudWZhY3R1cmVyO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIGJyb3dzZXIvZW52aXJvbm1lbnQuXG4gICAgICpcbiAgICAgKiBUaGUgbGlzdCBvZiBjb21tb24gYnJvd3NlciBuYW1lcyBpbmNsdWRlOlxuICAgICAqIFwiQ2hyb21lXCIsIFwiRWxlY3Ryb25cIiwgXCJGaXJlZm94XCIsIFwiRmlyZWZveCBmb3IgaU9TXCIsIFwiSUVcIixcbiAgICAgKiBcIk1pY3Jvc29mdCBFZGdlXCIsIFwiUGhhbnRvbUpTXCIsIFwiU2FmYXJpXCIsIFwiU2VhTW9ua2V5XCIsIFwiU2lsa1wiLFxuICAgICAqIFwiT3BlcmEgTWluaVwiIGFuZCBcIk9wZXJhXCJcbiAgICAgKlxuICAgICAqIE1vYmlsZSB2ZXJzaW9ucyBvZiBzb21lIGJyb3dzZXJzIGhhdmUgXCJNb2JpbGVcIiBhcHBlbmRlZCB0byB0aGVpciBuYW1lOlxuICAgICAqIGVnLiBcIkNocm9tZSBNb2JpbGVcIiwgXCJGaXJlZm94IE1vYmlsZVwiLCBcIklFIE1vYmlsZVwiIGFuZCBcIk9wZXJhIE1vYmlsZVwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm5hbWUgPSBuYW1lO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGFscGhhL2JldGEgcmVsZWFzZSBpbmRpY2F0b3IuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByZXJlbGVhc2UgPSBwcmVyZWxlYXNlO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIHByb2R1Y3QgaG9zdGluZyB0aGUgYnJvd3Nlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBwcm9kdWN0cyBpbmNsdWRlOlxuICAgICAqXG4gICAgICogXCJCbGFja0JlcnJ5XCIsIFwiR2FsYXh5IFM0XCIsIFwiTHVtaWFcIiwgXCJpUGFkXCIsIFwiaVBvZFwiLCBcImlQaG9uZVwiLCBcIktpbmRsZVwiLFxuICAgICAqIFwiS2luZGxlIEZpcmVcIiwgXCJOZXh1c1wiLCBcIk5vb2tcIiwgXCJQbGF5Qm9va1wiLCBcIlRvdWNoUGFkXCIgYW5kIFwiVHJhbnNmb3JtZXJcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5wcm9kdWN0ID0gcHJvZHVjdDtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyJ3MgdXNlciBhZ2VudCBzdHJpbmcuXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnVhID0gdWE7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYnJvd3Nlci9lbnZpcm9ubWVudCB2ZXJzaW9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS52ZXJzaW9uID0gbmFtZSAmJiB2ZXJzaW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGluZyBzeXN0ZW0uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5vcyA9IG9zIHx8IHtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZSB0aGUgT1MgaXMgYnVpbHQgZm9yLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgbnVtYmVyfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2FyY2hpdGVjdHVyZSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIGZhbWlseSBvZiB0aGUgT1MuXG4gICAgICAgKlxuICAgICAgICogQ29tbW9uIHZhbHVlcyBpbmNsdWRlOlxuICAgICAgICogXCJXaW5kb3dzXCIsIFwiV2luZG93cyBTZXJ2ZXIgMjAwOCBSMiAvIDdcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IC8gVmlzdGFcIixcbiAgICAgICAqIFwiV2luZG93cyBYUFwiLCBcIk9TIFhcIiwgXCJMaW51eFwiLCBcIlVidW50dVwiLCBcIkRlYmlhblwiLCBcIkZlZG9yYVwiLCBcIlJlZCBIYXRcIixcbiAgICAgICAqIFwiU3VTRVwiLCBcIkFuZHJvaWRcIiwgXCJpT1NcIiBhbmQgXCJXaW5kb3dzIFBob25lXCJcbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm0ub3NcbiAgICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICAgKi9cbiAgICAgICdmYW1pbHknOiBudWxsLFxuXG4gICAgICAvKipcbiAgICAgICAqIFRoZSB2ZXJzaW9uIG9mIHRoZSBPUy5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm0ub3NcbiAgICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICAgKi9cbiAgICAgICd2ZXJzaW9uJzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBSZXR1cm5zIHRoZSBPUyBzdHJpbmcuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgT1Mgc3RyaW5nLlxuICAgICAgICovXG4gICAgICAndG9TdHJpbmcnOiBmdW5jdGlvbigpIHsgcmV0dXJuICdudWxsJzsgfVxuICAgIH07XG5cbiAgICBwbGF0Zm9ybS5wYXJzZSA9IHBhcnNlO1xuICAgIHBsYXRmb3JtLnRvU3RyaW5nID0gdG9TdHJpbmdQbGF0Zm9ybTtcblxuICAgIGlmIChwbGF0Zm9ybS52ZXJzaW9uKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KHZlcnNpb24pO1xuICAgIH1cbiAgICBpZiAocGxhdGZvcm0ubmFtZSkge1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdChuYW1lKTtcbiAgICB9XG4gICAgaWYgKG9zICYmIG5hbWUgJiYgIShvcyA9PSBTdHJpbmcob3MpLnNwbGl0KCcgJylbMF0gJiYgKG9zID09IG5hbWUuc3BsaXQoJyAnKVswXSB8fCBwcm9kdWN0KSkpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2gocHJvZHVjdCA/ICcoJyArIG9zICsgJyknIDogJ29uICcgKyBvcyk7XG4gICAgfVxuICAgIGlmIChkZXNjcmlwdGlvbi5sZW5ndGgpIHtcbiAgICAgIHBsYXRmb3JtLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb24uam9pbignICcpO1xuICAgIH1cbiAgICByZXR1cm4gcGxhdGZvcm07XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvLyBFeHBvcnQgcGxhdGZvcm0uXG4gIHZhciBwbGF0Zm9ybSA9IHBhcnNlKCk7XG5cbiAgLy8gU29tZSBBTUQgYnVpbGQgb3B0aW1pemVycywgbGlrZSByLmpzLCBjaGVjayBmb3IgY29uZGl0aW9uIHBhdHRlcm5zIGxpa2UgdGhlIGZvbGxvd2luZzpcbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgZGVmaW5lLmFtZCA9PSAnb2JqZWN0JyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgLy8gRXhwb3NlIHBsYXRmb3JtIG9uIHRoZSBnbG9iYWwgb2JqZWN0IHRvIHByZXZlbnQgZXJyb3JzIHdoZW4gcGxhdGZvcm0gaXNcbiAgICAvLyBsb2FkZWQgYnkgYSBzY3JpcHQgdGFnIGluIHRoZSBwcmVzZW5jZSBvZiBhbiBBTUQgbG9hZGVyLlxuICAgIC8vIFNlZSBodHRwOi8vcmVxdWlyZWpzLm9yZy9kb2NzL2Vycm9ycy5odG1sI21pc21hdGNoIGZvciBtb3JlIGRldGFpbHMuXG4gICAgcm9vdC5wbGF0Zm9ybSA9IHBsYXRmb3JtO1xuXG4gICAgLy8gRGVmaW5lIGFzIGFuIGFub255bW91cyBtb2R1bGUgc28gcGxhdGZvcm0gY2FuIGJlIGFsaWFzZWQgdGhyb3VnaCBwYXRoIG1hcHBpbmcuXG4gICAgZGVmaW5lKGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHBsYXRmb3JtO1xuICAgIH0pO1xuICB9XG4gIC8vIENoZWNrIGZvciBgZXhwb3J0c2AgYWZ0ZXIgYGRlZmluZWAgaW4gY2FzZSBhIGJ1aWxkIG9wdGltaXplciBhZGRzIGFuIGBleHBvcnRzYCBvYmplY3QuXG4gIGVsc2UgaWYgKGZyZWVFeHBvcnRzICYmIGZyZWVNb2R1bGUpIHtcbiAgICAvLyBFeHBvcnQgZm9yIENvbW1vbkpTIHN1cHBvcnQuXG4gICAgZm9yT3duKHBsYXRmb3JtLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgICBmcmVlRXhwb3J0c1trZXldID0gdmFsdWU7XG4gICAgfSk7XG4gIH1cbiAgZWxzZSB7XG4gICAgLy8gRXhwb3J0IHRvIHRoZSBnbG9iYWwgb2JqZWN0LlxuICAgIHJvb3QucGxhdGZvcm0gPSBwbGF0Zm9ybTtcbiAgfVxufS5jYWxsKHRoaXMpKTtcbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG4vLyBjYWNoZWQgZnJvbSB3aGF0ZXZlciBnbG9iYWwgaXMgcHJlc2VudCBzbyB0aGF0IHRlc3QgcnVubmVycyB0aGF0IHN0dWIgaXRcbi8vIGRvbid0IGJyZWFrIHRoaW5ncy4gIEJ1dCB3ZSBuZWVkIHRvIHdyYXAgaXQgaW4gYSB0cnkgY2F0Y2ggaW4gY2FzZSBpdCBpc1xuLy8gd3JhcHBlZCBpbiBzdHJpY3QgbW9kZSBjb2RlIHdoaWNoIGRvZXNuJ3QgZGVmaW5lIGFueSBnbG9iYWxzLiAgSXQncyBpbnNpZGUgYVxuLy8gZnVuY3Rpb24gYmVjYXVzZSB0cnkvY2F0Y2hlcyBkZW9wdGltaXplIGluIGNlcnRhaW4gZW5naW5lcy5cblxudmFyIGNhY2hlZFNldFRpbWVvdXQ7XG52YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O1xuXG5mdW5jdGlvbiBkZWZhdWx0U2V0VGltb3V0KCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc2V0VGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuZnVuY3Rpb24gZGVmYXVsdENsZWFyVGltZW91dCAoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWQnKTtcbn1cbihmdW5jdGlvbiAoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXRUaW1lb3V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjYWNoZWRTZXRUaW1lb3V0ID0gZGVmYXVsdFNldFRpbW91dDtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiBjbGVhclRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGRlZmF1bHRDbGVhclRpbWVvdXQ7XG4gICAgfVxufSAoKSlcbmZ1bmN0aW9uIHJ1blRpbWVvdXQoZnVuKSB7XG4gICAgaWYgKGNhY2hlZFNldFRpbWVvdXQgPT09IHNldFRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIC8vIGlmIHNldFRpbWVvdXQgd2Fzbid0IGF2YWlsYWJsZSBidXQgd2FzIGxhdHRlciBkZWZpbmVkXG4gICAgaWYgKChjYWNoZWRTZXRUaW1lb3V0ID09PSBkZWZhdWx0U2V0VGltb3V0IHx8ICFjYWNoZWRTZXRUaW1lb3V0KSAmJiBzZXRUaW1lb3V0KSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICAvLyB3aGVuIHdoZW4gc29tZWJvZHkgaGFzIHNjcmV3ZWQgd2l0aCBzZXRUaW1lb3V0IGJ1dCBubyBJLkUuIG1hZGRuZXNzXG4gICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfSBjYXRjaChlKXtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIGluIEkuRS4gYnV0IHRoZSBzY3JpcHQgaGFzIGJlZW4gZXZhbGVkIHNvIEkuRS4gZG9lc24ndCB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbChudWxsLCBmdW4sIDApO1xuICAgICAgICB9IGNhdGNoKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3JcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwodGhpcywgZnVuLCAwKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG59XG5mdW5jdGlvbiBydW5DbGVhclRpbWVvdXQobWFya2VyKSB7XG4gICAgaWYgKGNhY2hlZENsZWFyVGltZW91dCA9PT0gY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIC8vbm9ybWFsIGVudmlyb21lbnRzIGluIHNhbmUgc2l0dWF0aW9uc1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIC8vIGlmIGNsZWFyVGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZENsZWFyVGltZW91dCA9PT0gZGVmYXVsdENsZWFyVGltZW91dCB8fCAhY2FjaGVkQ2xlYXJUaW1lb3V0KSAmJiBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICByZXR1cm4gY2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0ICB0cnVzdCB0aGUgZ2xvYmFsIG9iamVjdCB3aGVuIGNhbGxlZCBub3JtYWxseVxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKG51bGwsIG1hcmtlcik7XG4gICAgICAgIH0gY2F0Y2ggKGUpe1xuICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2hlbiBpdCdzIGEgdmVyc2lvbiBvZiBJLkUuIHRoYXQgbXVzdCBoYXZlIHRoZSBnbG9iYWwgb2JqZWN0IGZvciAndGhpcycsIGhvcGZ1bGx5IG91ciBjb250ZXh0IGNvcnJlY3Qgb3RoZXJ3aXNlIGl0IHdpbGwgdGhyb3cgYSBnbG9iYWwgZXJyb3IuXG4gICAgICAgICAgICAvLyBTb21lIHZlcnNpb25zIG9mIEkuRS4gaGF2ZSBkaWZmZXJlbnQgcnVsZXMgZm9yIGNsZWFyVGltZW91dCB2cyBzZXRUaW1lb3V0XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwodGhpcywgbWFya2VyKTtcbiAgICAgICAgfVxuICAgIH1cblxuXG5cbn1cbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG52YXIgY3VycmVudFF1ZXVlO1xudmFyIHF1ZXVlSW5kZXggPSAtMTtcblxuZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCkge1xuICAgIGlmICghZHJhaW5pbmcgfHwgIWN1cnJlbnRRdWV1ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgaWYgKGN1cnJlbnRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcXVldWUgPSBjdXJyZW50UXVldWUuY29uY2F0KHF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgfVxuICAgIGlmIChxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgZHJhaW5RdWV1ZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhaW5RdWV1ZSgpIHtcbiAgICBpZiAoZHJhaW5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgdGltZW91dCA9IHJ1blRpbWVvdXQoY2xlYW5VcE5leHRUaWNrKTtcbiAgICBkcmFpbmluZyA9IHRydWU7XG5cbiAgICB2YXIgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIHdoaWxlKGxlbikge1xuICAgICAgICBjdXJyZW50UXVldWUgPSBxdWV1ZTtcbiAgICAgICAgcXVldWUgPSBbXTtcbiAgICAgICAgd2hpbGUgKCsrcXVldWVJbmRleCA8IGxlbikge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRRdWV1ZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgY3VycmVudFF1ZXVlID0gbnVsbDtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIHJ1bkNsZWFyVGltZW91dCh0aW1lb3V0KTtcbn1cblxucHJvY2Vzcy5uZXh0VGljayA9IGZ1bmN0aW9uIChmdW4pIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBxdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1biwgYXJncykpO1xuICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG4gICAgICAgIHJ1blRpbWVvdXQoZHJhaW5RdWV1ZSk7XG4gICAgfVxufTtcblxuLy8gdjggbGlrZXMgcHJlZGljdGlibGUgb2JqZWN0c1xuZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG4gICAgdGhpcy5mdW4gPSBmdW47XG4gICAgdGhpcy5hcnJheSA9IGFycmF5O1xufVxuSXRlbS5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZnVuLmFwcGx5KG51bGwsIHRoaXMuYXJyYXkpO1xufTtcbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xucHJvY2Vzcy52ZXJzaW9uID0gJyc7IC8vIGVtcHR5IHN0cmluZyB0byBhdm9pZCByZWdleHAgaXNzdWVzXG5wcm9jZXNzLnZlcnNpb25zID0ge307XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5wcm9jZXNzLm9uID0gbm9vcDtcbnByb2Nlc3MuYWRkTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5vbmNlID0gbm9vcDtcbnByb2Nlc3Mub2ZmID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xucHJvY2Vzcy5lbWl0ID0gbm9vcDtcbnByb2Nlc3MucHJlcGVuZExpc3RlbmVyID0gbm9vcDtcbnByb2Nlc3MucHJlcGVuZE9uY2VMaXN0ZW5lciA9IG5vb3A7XG5cbnByb2Nlc3MubGlzdGVuZXJzID0gZnVuY3Rpb24gKG5hbWUpIHsgcmV0dXJuIFtdIH1cblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iLCJjb25zdCBkZWJ1ZyA9IHJlcXVpcmUoJy4uL2ludGVybmFsL2RlYnVnJylcbmNvbnN0IHsgTUFYX0xFTkdUSCwgTUFYX1NBRkVfSU5URUdFUiB9ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvY29uc3RhbnRzJylcbmNvbnN0IHsgcmUsIHQgfSA9IHJlcXVpcmUoJy4uL2ludGVybmFsL3JlJylcblxuY29uc3QgcGFyc2VPcHRpb25zID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvcGFyc2Utb3B0aW9ucycpXG5jb25zdCB7IGNvbXBhcmVJZGVudGlmaWVycyB9ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvaWRlbnRpZmllcnMnKVxuY2xhc3MgU2VtVmVyIHtcbiAgY29uc3RydWN0b3IgKHZlcnNpb24sIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gcGFyc2VPcHRpb25zKG9wdGlvbnMpXG5cbiAgICBpZiAodmVyc2lvbiBpbnN0YW5jZW9mIFNlbVZlcikge1xuICAgICAgaWYgKHZlcnNpb24ubG9vc2UgPT09ICEhb3B0aW9ucy5sb29zZSAmJlxuICAgICAgICAgIHZlcnNpb24uaW5jbHVkZVByZXJlbGVhc2UgPT09ICEhb3B0aW9ucy5pbmNsdWRlUHJlcmVsZWFzZSkge1xuICAgICAgICByZXR1cm4gdmVyc2lvblxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmVyc2lvbiA9IHZlcnNpb24udmVyc2lvblxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHZlcnNpb24gIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBJbnZhbGlkIFZlcnNpb246ICR7dmVyc2lvbn1gKVxuICAgIH1cblxuICAgIGlmICh2ZXJzaW9uLmxlbmd0aCA+IE1BWF9MRU5HVEgpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgIGB2ZXJzaW9uIGlzIGxvbmdlciB0aGFuICR7TUFYX0xFTkdUSH0gY2hhcmFjdGVyc2BcbiAgICAgIClcbiAgICB9XG5cbiAgICBkZWJ1ZygnU2VtVmVyJywgdmVyc2lvbiwgb3B0aW9ucylcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zXG4gICAgdGhpcy5sb29zZSA9ICEhb3B0aW9ucy5sb29zZVxuICAgIC8vIHRoaXMgaXNuJ3QgYWN0dWFsbHkgcmVsZXZhbnQgZm9yIHZlcnNpb25zLCBidXQga2VlcCBpdCBzbyB0aGF0IHdlXG4gICAgLy8gZG9uJ3QgcnVuIGludG8gdHJvdWJsZSBwYXNzaW5nIHRoaXMub3B0aW9ucyBhcm91bmQuXG4gICAgdGhpcy5pbmNsdWRlUHJlcmVsZWFzZSA9ICEhb3B0aW9ucy5pbmNsdWRlUHJlcmVsZWFzZVxuXG4gICAgY29uc3QgbSA9IHZlcnNpb24udHJpbSgpLm1hdGNoKG9wdGlvbnMubG9vc2UgPyByZVt0LkxPT1NFXSA6IHJlW3QuRlVMTF0pXG5cbiAgICBpZiAoIW0pIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgVmVyc2lvbjogJHt2ZXJzaW9ufWApXG4gICAgfVxuXG4gICAgdGhpcy5yYXcgPSB2ZXJzaW9uXG5cbiAgICAvLyB0aGVzZSBhcmUgYWN0dWFsbHkgbnVtYmVyc1xuICAgIHRoaXMubWFqb3IgPSArbVsxXVxuICAgIHRoaXMubWlub3IgPSArbVsyXVxuICAgIHRoaXMucGF0Y2ggPSArbVszXVxuXG4gICAgaWYgKHRoaXMubWFqb3IgPiBNQVhfU0FGRV9JTlRFR0VSIHx8IHRoaXMubWFqb3IgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1ham9yIHZlcnNpb24nKVxuICAgIH1cblxuICAgIGlmICh0aGlzLm1pbm9yID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLm1pbm9yIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBtaW5vciB2ZXJzaW9uJylcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wYXRjaCA+IE1BWF9TQUZFX0lOVEVHRVIgfHwgdGhpcy5wYXRjaCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgcGF0Y2ggdmVyc2lvbicpXG4gICAgfVxuXG4gICAgLy8gbnVtYmVyaWZ5IGFueSBwcmVyZWxlYXNlIG51bWVyaWMgaWRzXG4gICAgaWYgKCFtWzRdKSB7XG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBbXVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnByZXJlbGVhc2UgPSBtWzRdLnNwbGl0KCcuJykubWFwKChpZCkgPT4ge1xuICAgICAgICBpZiAoL15bMC05XSskLy50ZXN0KGlkKSkge1xuICAgICAgICAgIGNvbnN0IG51bSA9ICtpZFxuICAgICAgICAgIGlmIChudW0gPj0gMCAmJiBudW0gPCBNQVhfU0FGRV9JTlRFR0VSKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVtXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpZFxuICAgICAgfSlcbiAgICB9XG5cbiAgICB0aGlzLmJ1aWxkID0gbVs1XSA/IG1bNV0uc3BsaXQoJy4nKSA6IFtdXG4gICAgdGhpcy5mb3JtYXQoKVxuICB9XG5cbiAgZm9ybWF0ICgpIHtcbiAgICB0aGlzLnZlcnNpb24gPSBgJHt0aGlzLm1ham9yfS4ke3RoaXMubWlub3J9LiR7dGhpcy5wYXRjaH1gXG4gICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICAgIHRoaXMudmVyc2lvbiArPSBgLSR7dGhpcy5wcmVyZWxlYXNlLmpvaW4oJy4nKX1gXG4gICAgfVxuICAgIHJldHVybiB0aGlzLnZlcnNpb25cbiAgfVxuXG4gIHRvU3RyaW5nICgpIHtcbiAgICByZXR1cm4gdGhpcy52ZXJzaW9uXG4gIH1cblxuICBjb21wYXJlIChvdGhlcikge1xuICAgIGRlYnVnKCdTZW1WZXIuY29tcGFyZScsIHRoaXMudmVyc2lvbiwgdGhpcy5vcHRpb25zLCBvdGhlcilcbiAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFNlbVZlcikpIHtcbiAgICAgIGlmICh0eXBlb2Ygb3RoZXIgPT09ICdzdHJpbmcnICYmIG90aGVyID09PSB0aGlzLnZlcnNpb24pIHtcbiAgICAgICAgcmV0dXJuIDBcbiAgICAgIH1cbiAgICAgIG90aGVyID0gbmV3IFNlbVZlcihvdGhlciwgdGhpcy5vcHRpb25zKVxuICAgIH1cblxuICAgIGlmIChvdGhlci52ZXJzaW9uID09PSB0aGlzLnZlcnNpb24pIHtcbiAgICAgIHJldHVybiAwXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY29tcGFyZU1haW4ob3RoZXIpIHx8IHRoaXMuY29tcGFyZVByZShvdGhlcilcbiAgfVxuXG4gIGNvbXBhcmVNYWluIChvdGhlcikge1xuICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgU2VtVmVyKSkge1xuICAgICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLm9wdGlvbnMpXG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLm1ham9yLCBvdGhlci5tYWpvcikgfHxcbiAgICAgIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLm1pbm9yLCBvdGhlci5taW5vcikgfHxcbiAgICAgIGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLnBhdGNoLCBvdGhlci5wYXRjaClcbiAgICApXG4gIH1cblxuICBjb21wYXJlUHJlIChvdGhlcikge1xuICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgU2VtVmVyKSkge1xuICAgICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLm9wdGlvbnMpXG4gICAgfVxuXG4gICAgLy8gTk9UIGhhdmluZyBhIHByZXJlbGVhc2UgaXMgPiBoYXZpbmcgb25lXG4gICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgIW90aGVyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9IGVsc2UgaWYgKCF0aGlzLnByZXJlbGVhc2UubGVuZ3RoICYmIG90aGVyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gMVxuICAgIH0gZWxzZSBpZiAoIXRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgIW90aGVyLnByZXJlbGVhc2UubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gMFxuICAgIH1cblxuICAgIGxldCBpID0gMFxuICAgIGRvIHtcbiAgICAgIGNvbnN0IGEgPSB0aGlzLnByZXJlbGVhc2VbaV1cbiAgICAgIGNvbnN0IGIgPSBvdGhlci5wcmVyZWxlYXNlW2ldXG4gICAgICBkZWJ1ZygncHJlcmVsZWFzZSBjb21wYXJlJywgaSwgYSwgYilcbiAgICAgIGlmIChhID09PSB1bmRlZmluZWQgJiYgYiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiAwXG4gICAgICB9IGVsc2UgaWYgKGIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gMVxuICAgICAgfSBlbHNlIGlmIChhID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9IGVsc2UgaWYgKGEgPT09IGIpIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBjb21wYXJlSWRlbnRpZmllcnMoYSwgYilcbiAgICAgIH1cbiAgICB9IHdoaWxlICgrK2kpXG4gIH1cblxuICBjb21wYXJlQnVpbGQgKG90aGVyKSB7XG4gICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKSB7XG4gICAgICBvdGhlciA9IG5ldyBTZW1WZXIob3RoZXIsIHRoaXMub3B0aW9ucylcbiAgICB9XG5cbiAgICBsZXQgaSA9IDBcbiAgICBkbyB7XG4gICAgICBjb25zdCBhID0gdGhpcy5idWlsZFtpXVxuICAgICAgY29uc3QgYiA9IG90aGVyLmJ1aWxkW2ldXG4gICAgICBkZWJ1ZygncHJlcmVsZWFzZSBjb21wYXJlJywgaSwgYSwgYilcbiAgICAgIGlmIChhID09PSB1bmRlZmluZWQgJiYgYiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiAwXG4gICAgICB9IGVsc2UgaWYgKGIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gMVxuICAgICAgfSBlbHNlIGlmIChhID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIC0xXG4gICAgICB9IGVsc2UgaWYgKGEgPT09IGIpIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBjb21wYXJlSWRlbnRpZmllcnMoYSwgYilcbiAgICAgIH1cbiAgICB9IHdoaWxlICgrK2kpXG4gIH1cblxuICAvLyBwcmVtaW5vciB3aWxsIGJ1bXAgdGhlIHZlcnNpb24gdXAgdG8gdGhlIG5leHQgbWlub3IgcmVsZWFzZSwgYW5kIGltbWVkaWF0ZWx5XG4gIC8vIGRvd24gdG8gcHJlLXJlbGVhc2UuIHByZW1ham9yIGFuZCBwcmVwYXRjaCB3b3JrIHRoZSBzYW1lIHdheS5cbiAgaW5jIChyZWxlYXNlLCBpZGVudGlmaWVyKSB7XG4gICAgc3dpdGNoIChyZWxlYXNlKSB7XG4gICAgICBjYXNlICdwcmVtYWpvcic6XG4gICAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwXG4gICAgICAgIHRoaXMucGF0Y2ggPSAwXG4gICAgICAgIHRoaXMubWlub3IgPSAwXG4gICAgICAgIHRoaXMubWFqb3IrK1xuICAgICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcilcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ3ByZW1pbm9yJzpcbiAgICAgICAgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9IDBcbiAgICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgICAgdGhpcy5taW5vcisrXG4gICAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAncHJlcGF0Y2gnOlxuICAgICAgICAvLyBJZiB0aGlzIGlzIGFscmVhZHkgYSBwcmVyZWxlYXNlLCBpdCB3aWxsIGJ1bXAgdG8gdGhlIG5leHQgdmVyc2lvblxuICAgICAgICAvLyBkcm9wIGFueSBwcmVyZWxlYXNlcyB0aGF0IG1pZ2h0IGFscmVhZHkgZXhpc3QsIHNpbmNlIHRoZXkgYXJlIG5vdFxuICAgICAgICAvLyByZWxldmFudCBhdCB0aGlzIHBvaW50LlxuICAgICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID0gMFxuICAgICAgICB0aGlzLmluYygncGF0Y2gnLCBpZGVudGlmaWVyKVxuICAgICAgICB0aGlzLmluYygncHJlJywgaWRlbnRpZmllcilcbiAgICAgICAgYnJlYWtcbiAgICAgIC8vIElmIHRoZSBpbnB1dCBpcyBhIG5vbi1wcmVyZWxlYXNlIHZlcnNpb24sIHRoaXMgYWN0cyB0aGUgc2FtZSBhc1xuICAgICAgLy8gcHJlcGF0Y2guXG4gICAgICBjYXNlICdwcmVyZWxlYXNlJzpcbiAgICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLmluYygncGF0Y2gnLCBpZGVudGlmaWVyKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKVxuICAgICAgICBicmVha1xuXG4gICAgICBjYXNlICdtYWpvcic6XG4gICAgICAgIC8vIElmIHRoaXMgaXMgYSBwcmUtbWFqb3IgdmVyc2lvbiwgYnVtcCB1cCB0byB0aGUgc2FtZSBtYWpvciB2ZXJzaW9uLlxuICAgICAgICAvLyBPdGhlcndpc2UgaW5jcmVtZW50IG1ham9yLlxuICAgICAgICAvLyAxLjAuMC01IGJ1bXBzIHRvIDEuMC4wXG4gICAgICAgIC8vIDEuMS4wIGJ1bXBzIHRvIDIuMC4wXG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLm1pbm9yICE9PSAwIHx8XG4gICAgICAgICAgdGhpcy5wYXRjaCAhPT0gMCB8fFxuICAgICAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDBcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5tYWpvcisrXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5taW5vciA9IDBcbiAgICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW11cbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ21pbm9yJzpcbiAgICAgICAgLy8gSWYgdGhpcyBpcyBhIHByZS1taW5vciB2ZXJzaW9uLCBidW1wIHVwIHRvIHRoZSBzYW1lIG1pbm9yIHZlcnNpb24uXG4gICAgICAgIC8vIE90aGVyd2lzZSBpbmNyZW1lbnQgbWlub3IuXG4gICAgICAgIC8vIDEuMi4wLTUgYnVtcHMgdG8gMS4yLjBcbiAgICAgICAgLy8gMS4yLjEgYnVtcHMgdG8gMS4zLjBcbiAgICAgICAgaWYgKHRoaXMucGF0Y2ggIT09IDAgfHwgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMubWlub3IrK1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGF0Y2ggPSAwXG4gICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdwYXRjaCc6XG4gICAgICAgIC8vIElmIHRoaXMgaXMgbm90IGEgcHJlLXJlbGVhc2UgdmVyc2lvbiwgaXQgd2lsbCBpbmNyZW1lbnQgdGhlIHBhdGNoLlxuICAgICAgICAvLyBJZiBpdCBpcyBhIHByZS1yZWxlYXNlIGl0IHdpbGwgYnVtcCB1cCB0byB0aGUgc2FtZSBwYXRjaCB2ZXJzaW9uLlxuICAgICAgICAvLyAxLjIuMC01IHBhdGNoZXMgdG8gMS4yLjBcbiAgICAgICAgLy8gMS4yLjAgcGF0Y2hlcyB0byAxLjIuMVxuICAgICAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMucGF0Y2grK1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdXG4gICAgICAgIGJyZWFrXG4gICAgICAvLyBUaGlzIHByb2JhYmx5IHNob3VsZG4ndCBiZSB1c2VkIHB1YmxpY2x5LlxuICAgICAgLy8gMS4wLjAgJ3ByZScgd291bGQgYmVjb21lIDEuMC4wLTAgd2hpY2ggaXMgdGhlIHdyb25nIGRpcmVjdGlvbi5cbiAgICAgIGNhc2UgJ3ByZSc6XG4gICAgICAgIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gWzBdXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGV0IGkgPSB0aGlzLnByZXJlbGVhc2UubGVuZ3RoXG4gICAgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMucHJlcmVsZWFzZVtpXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlW2ldKytcbiAgICAgICAgICAgICAgaSA9IC0yXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChpID09PSAtMSkge1xuICAgICAgICAgICAgLy8gZGlkbid0IGluY3JlbWVudCBhbnl0aGluZ1xuICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlLnB1c2goMClcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlkZW50aWZpZXIpIHtcbiAgICAgICAgICAvLyAxLjIuMC1iZXRhLjEgYnVtcHMgdG8gMS4yLjAtYmV0YS4yLFxuICAgICAgICAgIC8vIDEuMi4wLWJldGEuZm9vYmx6IG9yIDEuMi4wLWJldGEgYnVtcHMgdG8gMS4yLjAtYmV0YS4wXG4gICAgICAgICAgaWYgKGNvbXBhcmVJZGVudGlmaWVycyh0aGlzLnByZXJlbGVhc2VbMF0sIGlkZW50aWZpZXIpID09PSAwKSB7XG4gICAgICAgICAgICBpZiAoaXNOYU4odGhpcy5wcmVyZWxlYXNlWzFdKSkge1xuICAgICAgICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbaWRlbnRpZmllciwgMF1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW2lkZW50aWZpZXIsIDBdXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBpbmNyZW1lbnQgYXJndW1lbnQ6ICR7cmVsZWFzZX1gKVxuICAgIH1cbiAgICB0aGlzLmZvcm1hdCgpXG4gICAgdGhpcy5yYXcgPSB0aGlzLnZlcnNpb25cbiAgICByZXR1cm4gdGhpc1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gU2VtVmVyXG4iLCJjb25zdCBTZW1WZXIgPSByZXF1aXJlKCcuLi9jbGFzc2VzL3NlbXZlcicpXG5jb25zdCBtYWpvciA9IChhLCBsb29zZSkgPT4gbmV3IFNlbVZlcihhLCBsb29zZSkubWFqb3Jcbm1vZHVsZS5leHBvcnRzID0gbWFqb3JcbiIsImNvbnN0IFNlbVZlciA9IHJlcXVpcmUoJy4uL2NsYXNzZXMvc2VtdmVyJylcbmNvbnN0IG1pbm9yID0gKGEsIGxvb3NlKSA9PiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5taW5vclxubW9kdWxlLmV4cG9ydHMgPSBtaW5vclxuIiwiLy8gTm90ZTogdGhpcyBpcyB0aGUgc2VtdmVyLm9yZyB2ZXJzaW9uIG9mIHRoZSBzcGVjIHRoYXQgaXQgaW1wbGVtZW50c1xuLy8gTm90IG5lY2Vzc2FyaWx5IHRoZSBwYWNrYWdlIHZlcnNpb24gb2YgdGhpcyBjb2RlLlxuY29uc3QgU0VNVkVSX1NQRUNfVkVSU0lPTiA9ICcyLjAuMCdcblxuY29uc3QgTUFYX0xFTkdUSCA9IDI1NlxuY29uc3QgTUFYX1NBRkVfSU5URUdFUiA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8XG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyA5MDA3MTk5MjU0NzQwOTkxXG5cbi8vIE1heCBzYWZlIHNlZ21lbnQgbGVuZ3RoIGZvciBjb2VyY2lvbi5cbmNvbnN0IE1BWF9TQUZFX0NPTVBPTkVOVF9MRU5HVEggPSAxNlxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgU0VNVkVSX1NQRUNfVkVSU0lPTixcbiAgTUFYX0xFTkdUSCxcbiAgTUFYX1NBRkVfSU5URUdFUixcbiAgTUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSCxcbn1cbiIsImNvbnN0IGRlYnVnID0gKFxuICB0eXBlb2YgcHJvY2VzcyA9PT0gJ29iamVjdCcgJiZcbiAgcHJvY2Vzcy5lbnYgJiZcbiAgcHJvY2Vzcy5lbnYuTk9ERV9ERUJVRyAmJlxuICAvXFxic2VtdmVyXFxiL2kudGVzdChwcm9jZXNzLmVudi5OT0RFX0RFQlVHKVxuKSA/ICguLi5hcmdzKSA9PiBjb25zb2xlLmVycm9yKCdTRU1WRVInLCAuLi5hcmdzKVxuICA6ICgpID0+IHt9XG5cbm1vZHVsZS5leHBvcnRzID0gZGVidWdcbiIsImNvbnN0IG51bWVyaWMgPSAvXlswLTldKyQvXG5jb25zdCBjb21wYXJlSWRlbnRpZmllcnMgPSAoYSwgYikgPT4ge1xuICBjb25zdCBhbnVtID0gbnVtZXJpYy50ZXN0KGEpXG4gIGNvbnN0IGJudW0gPSBudW1lcmljLnRlc3QoYilcblxuICBpZiAoYW51bSAmJiBibnVtKSB7XG4gICAgYSA9ICthXG4gICAgYiA9ICtiXG4gIH1cblxuICByZXR1cm4gYSA9PT0gYiA/IDBcbiAgICA6IChhbnVtICYmICFibnVtKSA/IC0xXG4gICAgOiAoYm51bSAmJiAhYW51bSkgPyAxXG4gICAgOiBhIDwgYiA/IC0xXG4gICAgOiAxXG59XG5cbmNvbnN0IHJjb21wYXJlSWRlbnRpZmllcnMgPSAoYSwgYikgPT4gY29tcGFyZUlkZW50aWZpZXJzKGIsIGEpXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBjb21wYXJlSWRlbnRpZmllcnMsXG4gIHJjb21wYXJlSWRlbnRpZmllcnMsXG59XG4iLCIvLyBwYXJzZSBvdXQganVzdCB0aGUgb3B0aW9ucyB3ZSBjYXJlIGFib3V0IHNvIHdlIGFsd2F5cyBnZXQgYSBjb25zaXN0ZW50XG4vLyBvYmogd2l0aCBrZXlzIGluIGEgY29uc2lzdGVudCBvcmRlci5cbmNvbnN0IG9wdHMgPSBbJ2luY2x1ZGVQcmVyZWxlYXNlJywgJ2xvb3NlJywgJ3J0bCddXG5jb25zdCBwYXJzZU9wdGlvbnMgPSBvcHRpb25zID0+XG4gICFvcHRpb25zID8ge31cbiAgOiB0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcgPyB7IGxvb3NlOiB0cnVlIH1cbiAgOiBvcHRzLmZpbHRlcihrID0+IG9wdGlvbnNba10pLnJlZHVjZSgobywgaykgPT4ge1xuICAgIG9ba10gPSB0cnVlXG4gICAgcmV0dXJuIG9cbiAgfSwge30pXG5tb2R1bGUuZXhwb3J0cyA9IHBhcnNlT3B0aW9uc1xuIiwiY29uc3QgeyBNQVhfU0FGRV9DT01QT05FTlRfTEVOR1RIIH0gPSByZXF1aXJlKCcuL2NvbnN0YW50cycpXG5jb25zdCBkZWJ1ZyA9IHJlcXVpcmUoJy4vZGVidWcnKVxuZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0ge31cblxuLy8gVGhlIGFjdHVhbCByZWdleHBzIGdvIG9uIGV4cG9ydHMucmVcbmNvbnN0IHJlID0gZXhwb3J0cy5yZSA9IFtdXG5jb25zdCBzcmMgPSBleHBvcnRzLnNyYyA9IFtdXG5jb25zdCB0ID0gZXhwb3J0cy50ID0ge31cbmxldCBSID0gMFxuXG5jb25zdCBjcmVhdGVUb2tlbiA9IChuYW1lLCB2YWx1ZSwgaXNHbG9iYWwpID0+IHtcbiAgY29uc3QgaW5kZXggPSBSKytcbiAgZGVidWcobmFtZSwgaW5kZXgsIHZhbHVlKVxuICB0W25hbWVdID0gaW5kZXhcbiAgc3JjW2luZGV4XSA9IHZhbHVlXG4gIHJlW2luZGV4XSA9IG5ldyBSZWdFeHAodmFsdWUsIGlzR2xvYmFsID8gJ2cnIDogdW5kZWZpbmVkKVxufVxuXG4vLyBUaGUgZm9sbG93aW5nIFJlZ3VsYXIgRXhwcmVzc2lvbnMgY2FuIGJlIHVzZWQgZm9yIHRva2VuaXppbmcsXG4vLyB2YWxpZGF0aW5nLCBhbmQgcGFyc2luZyBTZW1WZXIgdmVyc2lvbiBzdHJpbmdzLlxuXG4vLyAjIyBOdW1lcmljIElkZW50aWZpZXJcbi8vIEEgc2luZ2xlIGAwYCwgb3IgYSBub24temVybyBkaWdpdCBmb2xsb3dlZCBieSB6ZXJvIG9yIG1vcmUgZGlnaXRzLlxuXG5jcmVhdGVUb2tlbignTlVNRVJJQ0lERU5USUZJRVInLCAnMHxbMS05XVxcXFxkKicpXG5jcmVhdGVUb2tlbignTlVNRVJJQ0lERU5USUZJRVJMT09TRScsICdbMC05XSsnKVxuXG4vLyAjIyBOb24tbnVtZXJpYyBJZGVudGlmaWVyXG4vLyBaZXJvIG9yIG1vcmUgZGlnaXRzLCBmb2xsb3dlZCBieSBhIGxldHRlciBvciBoeXBoZW4sIGFuZCB0aGVuIHplcm8gb3Jcbi8vIG1vcmUgbGV0dGVycywgZGlnaXRzLCBvciBoeXBoZW5zLlxuXG5jcmVhdGVUb2tlbignTk9OTlVNRVJJQ0lERU5USUZJRVInLCAnXFxcXGQqW2EtekEtWi1dW2EtekEtWjAtOS1dKicpXG5cbi8vICMjIE1haW4gVmVyc2lvblxuLy8gVGhyZWUgZG90LXNlcGFyYXRlZCBudW1lcmljIGlkZW50aWZpZXJzLlxuXG5jcmVhdGVUb2tlbignTUFJTlZFUlNJT04nLCBgKCR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJdfSlcXFxcLmAgK1xuICAgICAgICAgICAgICAgICAgIGAoJHtzcmNbdC5OVU1FUklDSURFTlRJRklFUl19KVxcXFwuYCArXG4gICAgICAgICAgICAgICAgICAgYCgke3NyY1t0Lk5VTUVSSUNJREVOVElGSUVSXX0pYClcblxuY3JlYXRlVG9rZW4oJ01BSU5WRVJTSU9OTE9PU0UnLCBgKCR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJMT09TRV19KVxcXFwuYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgKCR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJMT09TRV19KVxcXFwuYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgKCR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJMT09TRV19KWApXG5cbi8vICMjIFByZS1yZWxlYXNlIFZlcnNpb24gSWRlbnRpZmllclxuLy8gQSBudW1lcmljIGlkZW50aWZpZXIsIG9yIGEgbm9uLW51bWVyaWMgaWRlbnRpZmllci5cblxuY3JlYXRlVG9rZW4oJ1BSRVJFTEVBU0VJREVOVElGSUVSJywgYCg/OiR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJdXG59fCR7c3JjW3QuTk9OTlVNRVJJQ0lERU5USUZJRVJdfSlgKVxuXG5jcmVhdGVUb2tlbignUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRScsIGAoPzoke3NyY1t0Lk5VTUVSSUNJREVOVElGSUVSTE9PU0VdXG59fCR7c3JjW3QuTk9OTlVNRVJJQ0lERU5USUZJRVJdfSlgKVxuXG4vLyAjIyBQcmUtcmVsZWFzZSBWZXJzaW9uXG4vLyBIeXBoZW4sIGZvbGxvd2VkIGJ5IG9uZSBvciBtb3JlIGRvdC1zZXBhcmF0ZWQgcHJlLXJlbGVhc2UgdmVyc2lvblxuLy8gaWRlbnRpZmllcnMuXG5cbmNyZWF0ZVRva2VuKCdQUkVSRUxFQVNFJywgYCg/Oi0oJHtzcmNbdC5QUkVSRUxFQVNFSURFTlRJRklFUl1cbn0oPzpcXFxcLiR7c3JjW3QuUFJFUkVMRUFTRUlERU5USUZJRVJdfSkqKSlgKVxuXG5jcmVhdGVUb2tlbignUFJFUkVMRUFTRUxPT1NFJywgYCg/Oi0/KCR7c3JjW3QuUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRV1cbn0oPzpcXFxcLiR7c3JjW3QuUFJFUkVMRUFTRUlERU5USUZJRVJMT09TRV19KSopKWApXG5cbi8vICMjIEJ1aWxkIE1ldGFkYXRhIElkZW50aWZpZXJcbi8vIEFueSBjb21iaW5hdGlvbiBvZiBkaWdpdHMsIGxldHRlcnMsIG9yIGh5cGhlbnMuXG5cbmNyZWF0ZVRva2VuKCdCVUlMRElERU5USUZJRVInLCAnWzAtOUEtWmEtei1dKycpXG5cbi8vICMjIEJ1aWxkIE1ldGFkYXRhXG4vLyBQbHVzIHNpZ24sIGZvbGxvd2VkIGJ5IG9uZSBvciBtb3JlIHBlcmlvZC1zZXBhcmF0ZWQgYnVpbGQgbWV0YWRhdGFcbi8vIGlkZW50aWZpZXJzLlxuXG5jcmVhdGVUb2tlbignQlVJTEQnLCBgKD86XFxcXCsoJHtzcmNbdC5CVUlMRElERU5USUZJRVJdXG59KD86XFxcXC4ke3NyY1t0LkJVSUxESURFTlRJRklFUl19KSopKWApXG5cbi8vICMjIEZ1bGwgVmVyc2lvbiBTdHJpbmdcbi8vIEEgbWFpbiB2ZXJzaW9uLCBmb2xsb3dlZCBvcHRpb25hbGx5IGJ5IGEgcHJlLXJlbGVhc2UgdmVyc2lvbiBhbmRcbi8vIGJ1aWxkIG1ldGFkYXRhLlxuXG4vLyBOb3RlIHRoYXQgdGhlIG9ubHkgbWFqb3IsIG1pbm9yLCBwYXRjaCwgYW5kIHByZS1yZWxlYXNlIHNlY3Rpb25zIG9mXG4vLyB0aGUgdmVyc2lvbiBzdHJpbmcgYXJlIGNhcHR1cmluZyBncm91cHMuICBUaGUgYnVpbGQgbWV0YWRhdGEgaXMgbm90IGFcbi8vIGNhcHR1cmluZyBncm91cCwgYmVjYXVzZSBpdCBzaG91bGQgbm90IGV2ZXIgYmUgdXNlZCBpbiB2ZXJzaW9uXG4vLyBjb21wYXJpc29uLlxuXG5jcmVhdGVUb2tlbignRlVMTFBMQUlOJywgYHY/JHtzcmNbdC5NQUlOVkVSU0lPTl1cbn0ke3NyY1t0LlBSRVJFTEVBU0VdfT8ke1xuICBzcmNbdC5CVUlMRF19P2ApXG5cbmNyZWF0ZVRva2VuKCdGVUxMJywgYF4ke3NyY1t0LkZVTExQTEFJTl19JGApXG5cbi8vIGxpa2UgZnVsbCwgYnV0IGFsbG93cyB2MS4yLjMgYW5kID0xLjIuMywgd2hpY2ggcGVvcGxlIGRvIHNvbWV0aW1lcy5cbi8vIGFsc28sIDEuMC4wYWxwaGExIChwcmVyZWxlYXNlIHdpdGhvdXQgdGhlIGh5cGhlbikgd2hpY2ggaXMgcHJldHR5XG4vLyBjb21tb24gaW4gdGhlIG5wbSByZWdpc3RyeS5cbmNyZWF0ZVRva2VuKCdMT09TRVBMQUlOJywgYFt2PVxcXFxzXSoke3NyY1t0Lk1BSU5WRVJTSU9OTE9PU0VdXG59JHtzcmNbdC5QUkVSRUxFQVNFTE9PU0VdfT8ke1xuICBzcmNbdC5CVUlMRF19P2ApXG5cbmNyZWF0ZVRva2VuKCdMT09TRScsIGBeJHtzcmNbdC5MT09TRVBMQUlOXX0kYClcblxuY3JlYXRlVG9rZW4oJ0dUTFQnLCAnKCg/Ojx8Pik/PT8pJylcblxuLy8gU29tZXRoaW5nIGxpa2UgXCIyLipcIiBvciBcIjEuMi54XCIuXG4vLyBOb3RlIHRoYXQgXCJ4LnhcIiBpcyBhIHZhbGlkIHhSYW5nZSBpZGVudGlmZXIsIG1lYW5pbmcgXCJhbnkgdmVyc2lvblwiXG4vLyBPbmx5IHRoZSBmaXJzdCBpdGVtIGlzIHN0cmljdGx5IHJlcXVpcmVkLlxuY3JlYXRlVG9rZW4oJ1hSQU5HRUlERU5USUZJRVJMT09TRScsIGAke3NyY1t0Lk5VTUVSSUNJREVOVElGSUVSTE9PU0VdfXx4fFh8XFxcXCpgKVxuY3JlYXRlVG9rZW4oJ1hSQU5HRUlERU5USUZJRVInLCBgJHtzcmNbdC5OVU1FUklDSURFTlRJRklFUl19fHh8WHxcXFxcKmApXG5cbmNyZWF0ZVRva2VuKCdYUkFOR0VQTEFJTicsIGBbdj1cXFxcc10qKCR7c3JjW3QuWFJBTkdFSURFTlRJRklFUl19KWAgK1xuICAgICAgICAgICAgICAgICAgIGAoPzpcXFxcLigke3NyY1t0LlhSQU5HRUlERU5USUZJRVJdfSlgICtcbiAgICAgICAgICAgICAgICAgICBgKD86XFxcXC4oJHtzcmNbdC5YUkFOR0VJREVOVElGSUVSXX0pYCArXG4gICAgICAgICAgICAgICAgICAgYCg/OiR7c3JjW3QuUFJFUkVMRUFTRV19KT8ke1xuICAgICAgICAgICAgICAgICAgICAgc3JjW3QuQlVJTERdfT9gICtcbiAgICAgICAgICAgICAgICAgICBgKT8pP2ApXG5cbmNyZWF0ZVRva2VuKCdYUkFOR0VQTEFJTkxPT1NFJywgYFt2PVxcXFxzXSooJHtzcmNbdC5YUkFOR0VJREVOVElGSUVSTE9PU0VdfSlgICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGAoPzpcXFxcLigke3NyY1t0LlhSQU5HRUlERU5USUZJRVJMT09TRV19KWAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYCg/OlxcXFwuKCR7c3JjW3QuWFJBTkdFSURFTlRJRklFUkxPT1NFXX0pYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgKD86JHtzcmNbdC5QUkVSRUxFQVNFTE9PU0VdfSk/JHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjW3QuQlVJTERdfT9gICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGApPyk/YClcblxuY3JlYXRlVG9rZW4oJ1hSQU5HRScsIGBeJHtzcmNbdC5HVExUXX1cXFxccyoke3NyY1t0LlhSQU5HRVBMQUlOXX0kYClcbmNyZWF0ZVRva2VuKCdYUkFOR0VMT09TRScsIGBeJHtzcmNbdC5HVExUXX1cXFxccyoke3NyY1t0LlhSQU5HRVBMQUlOTE9PU0VdfSRgKVxuXG4vLyBDb2VyY2lvbi5cbi8vIEV4dHJhY3QgYW55dGhpbmcgdGhhdCBjb3VsZCBjb25jZWl2YWJseSBiZSBhIHBhcnQgb2YgYSB2YWxpZCBzZW12ZXJcbmNyZWF0ZVRva2VuKCdDT0VSQ0UnLCBgJHsnKF58W15cXFxcZF0pJyArXG4gICAgICAgICAgICAgICcoXFxcXGR7MSwnfSR7TUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSH19KWAgK1xuICAgICAgICAgICAgICBgKD86XFxcXC4oXFxcXGR7MSwke01BWF9TQUZFX0NPTVBPTkVOVF9MRU5HVEh9fSkpP2AgK1xuICAgICAgICAgICAgICBgKD86XFxcXC4oXFxcXGR7MSwke01BWF9TQUZFX0NPTVBPTkVOVF9MRU5HVEh9fSkpP2AgK1xuICAgICAgICAgICAgICBgKD86JHxbXlxcXFxkXSlgKVxuY3JlYXRlVG9rZW4oJ0NPRVJDRVJUTCcsIHNyY1t0LkNPRVJDRV0sIHRydWUpXG5cbi8vIFRpbGRlIHJhbmdlcy5cbi8vIE1lYW5pbmcgaXMgXCJyZWFzb25hYmx5IGF0IG9yIGdyZWF0ZXIgdGhhblwiXG5jcmVhdGVUb2tlbignTE9ORVRJTERFJywgJyg/On4+PyknKVxuXG5jcmVhdGVUb2tlbignVElMREVUUklNJywgYChcXFxccyopJHtzcmNbdC5MT05FVElMREVdfVxcXFxzK2AsIHRydWUpXG5leHBvcnRzLnRpbGRlVHJpbVJlcGxhY2UgPSAnJDF+J1xuXG5jcmVhdGVUb2tlbignVElMREUnLCBgXiR7c3JjW3QuTE9ORVRJTERFXX0ke3NyY1t0LlhSQU5HRVBMQUlOXX0kYClcbmNyZWF0ZVRva2VuKCdUSUxERUxPT1NFJywgYF4ke3NyY1t0LkxPTkVUSUxERV19JHtzcmNbdC5YUkFOR0VQTEFJTkxPT1NFXX0kYClcblxuLy8gQ2FyZXQgcmFuZ2VzLlxuLy8gTWVhbmluZyBpcyBcImF0IGxlYXN0IGFuZCBiYWNrd2FyZHMgY29tcGF0aWJsZSB3aXRoXCJcbmNyZWF0ZVRva2VuKCdMT05FQ0FSRVQnLCAnKD86XFxcXF4pJylcblxuY3JlYXRlVG9rZW4oJ0NBUkVUVFJJTScsIGAoXFxcXHMqKSR7c3JjW3QuTE9ORUNBUkVUXX1cXFxccytgLCB0cnVlKVxuZXhwb3J0cy5jYXJldFRyaW1SZXBsYWNlID0gJyQxXidcblxuY3JlYXRlVG9rZW4oJ0NBUkVUJywgYF4ke3NyY1t0LkxPTkVDQVJFVF19JHtzcmNbdC5YUkFOR0VQTEFJTl19JGApXG5jcmVhdGVUb2tlbignQ0FSRVRMT09TRScsIGBeJHtzcmNbdC5MT05FQ0FSRVRdfSR7c3JjW3QuWFJBTkdFUExBSU5MT09TRV19JGApXG5cbi8vIEEgc2ltcGxlIGd0L2x0L2VxIHRoaW5nLCBvciBqdXN0IFwiXCIgdG8gaW5kaWNhdGUgXCJhbnkgdmVyc2lvblwiXG5jcmVhdGVUb2tlbignQ09NUEFSQVRPUkxPT1NFJywgYF4ke3NyY1t0LkdUTFRdfVxcXFxzKigke3NyY1t0LkxPT1NFUExBSU5dfSkkfF4kYClcbmNyZWF0ZVRva2VuKCdDT01QQVJBVE9SJywgYF4ke3NyY1t0LkdUTFRdfVxcXFxzKigke3NyY1t0LkZVTExQTEFJTl19KSR8XiRgKVxuXG4vLyBBbiBleHByZXNzaW9uIHRvIHN0cmlwIGFueSB3aGl0ZXNwYWNlIGJldHdlZW4gdGhlIGd0bHQgYW5kIHRoZSB0aGluZ1xuLy8gaXQgbW9kaWZpZXMsIHNvIHRoYXQgYD4gMS4yLjNgID09PiBgPjEuMi4zYFxuY3JlYXRlVG9rZW4oJ0NPTVBBUkFUT1JUUklNJywgYChcXFxccyopJHtzcmNbdC5HVExUXVxufVxcXFxzKigke3NyY1t0LkxPT1NFUExBSU5dfXwke3NyY1t0LlhSQU5HRVBMQUlOXX0pYCwgdHJ1ZSlcbmV4cG9ydHMuY29tcGFyYXRvclRyaW1SZXBsYWNlID0gJyQxJDIkMydcblxuLy8gU29tZXRoaW5nIGxpa2UgYDEuMi4zIC0gMS4yLjRgXG4vLyBOb3RlIHRoYXQgdGhlc2UgYWxsIHVzZSB0aGUgbG9vc2UgZm9ybSwgYmVjYXVzZSB0aGV5J2xsIGJlXG4vLyBjaGVja2VkIGFnYWluc3QgZWl0aGVyIHRoZSBzdHJpY3Qgb3IgbG9vc2UgY29tcGFyYXRvciBmb3JtXG4vLyBsYXRlci5cbmNyZWF0ZVRva2VuKCdIWVBIRU5SQU5HRScsIGBeXFxcXHMqKCR7c3JjW3QuWFJBTkdFUExBSU5dfSlgICtcbiAgICAgICAgICAgICAgICAgICBgXFxcXHMrLVxcXFxzK2AgK1xuICAgICAgICAgICAgICAgICAgIGAoJHtzcmNbdC5YUkFOR0VQTEFJTl19KWAgK1xuICAgICAgICAgICAgICAgICAgIGBcXFxccyokYClcblxuY3JlYXRlVG9rZW4oJ0hZUEhFTlJBTkdFTE9PU0UnLCBgXlxcXFxzKigke3NyY1t0LlhSQU5HRVBMQUlOTE9PU0VdfSlgICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGBcXFxccystXFxcXHMrYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgKCR7c3JjW3QuWFJBTkdFUExBSU5MT09TRV19KWAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYFxcXFxzKiRgKVxuXG4vLyBTdGFyIHJhbmdlcyBiYXNpY2FsbHkganVzdCBhbGxvdyBhbnl0aGluZyBhdCBhbGwuXG5jcmVhdGVUb2tlbignU1RBUicsICcoPHw+KT89P1xcXFxzKlxcXFwqJylcbi8vID49MC4wLjAgaXMgbGlrZSBhIHN0YXJcbmNyZWF0ZVRva2VuKCdHVEUwJywgJ15cXFxccyo+PVxcXFxzKjBcXFxcLjBcXFxcLjBcXFxccyokJylcbmNyZWF0ZVRva2VuKCdHVEUwUFJFJywgJ15cXFxccyo+PVxcXFxzKjBcXFxcLjBcXFxcLjAtMFxcXFxzKiQnKVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJOSUxcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX25pbC5kZWZhdWx0O1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInBhcnNlXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9wYXJzZS5kZWZhdWx0O1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInN0cmluZ2lmeVwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfc3RyaW5naWZ5LmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjFcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3YuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ2M1wiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdjIuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ2NFwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdjMuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ2NVwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdjQuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ2YWxpZGF0ZVwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdmFsaWRhdGUuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ2ZXJzaW9uXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF92ZXJzaW9uLmRlZmF1bHQ7XG4gIH1cbn0pO1xuXG52YXIgX3YgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3YxLmpzXCIpKTtcblxudmFyIF92MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdjMuanNcIikpO1xuXG52YXIgX3YzID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92NC5qc1wiKSk7XG5cbnZhciBfdjQgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3Y1LmpzXCIpKTtcblxudmFyIF9uaWwgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL25pbC5qc1wiKSk7XG5cbnZhciBfdmVyc2lvbiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdmVyc2lvbi5qc1wiKSk7XG5cbnZhciBfdmFsaWRhdGUgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZhbGlkYXRlLmpzXCIpKTtcblxudmFyIF9zdHJpbmdpZnkgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3N0cmluZ2lmeS5qc1wiKSk7XG5cbnZhciBfcGFyc2UgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3BhcnNlLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxuLypcbiAqIEJyb3dzZXItY29tcGF0aWJsZSBKYXZhU2NyaXB0IE1ENVxuICpcbiAqIE1vZGlmaWNhdGlvbiBvZiBKYXZhU2NyaXB0IE1ENVxuICogaHR0cHM6Ly9naXRodWIuY29tL2JsdWVpbXAvSmF2YVNjcmlwdC1NRDVcbiAqXG4gKiBDb3B5cmlnaHQgMjAxMSwgU2ViYXN0aWFuIFRzY2hhblxuICogaHR0cHM6Ly9ibHVlaW1wLm5ldFxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZTpcbiAqIGh0dHBzOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUXG4gKlxuICogQmFzZWQgb25cbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgUlNBIERhdGEgU2VjdXJpdHksIEluYy4gTUQ1IE1lc3NhZ2VcbiAqIERpZ2VzdCBBbGdvcml0aG0sIGFzIGRlZmluZWQgaW4gUkZDIDEzMjEuXG4gKiBWZXJzaW9uIDIuMiBDb3B5cmlnaHQgKEMpIFBhdWwgSm9obnN0b24gMTk5OSAtIDIwMDlcbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCU0QgTGljZW5zZVxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIG1vcmUgaW5mby5cbiAqL1xuZnVuY3Rpb24gbWQ1KGJ5dGVzKSB7XG4gIGlmICh0eXBlb2YgYnl0ZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uc3QgbXNnID0gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KGJ5dGVzKSk7IC8vIFVURjggZXNjYXBlXG5cbiAgICBieXRlcyA9IG5ldyBVaW50OEFycmF5KG1zZy5sZW5ndGgpO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyArK2kpIHtcbiAgICAgIGJ5dGVzW2ldID0gbXNnLmNoYXJDb2RlQXQoaSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1kNVRvSGV4RW5jb2RlZEFycmF5KHdvcmRzVG9NZDUoYnl0ZXNUb1dvcmRzKGJ5dGVzKSwgYnl0ZXMubGVuZ3RoICogOCkpO1xufVxuLypcbiAqIENvbnZlcnQgYW4gYXJyYXkgb2YgbGl0dGxlLWVuZGlhbiB3b3JkcyB0byBhbiBhcnJheSBvZiBieXRlc1xuICovXG5cblxuZnVuY3Rpb24gbWQ1VG9IZXhFbmNvZGVkQXJyYXkoaW5wdXQpIHtcbiAgY29uc3Qgb3V0cHV0ID0gW107XG4gIGNvbnN0IGxlbmd0aDMyID0gaW5wdXQubGVuZ3RoICogMzI7XG4gIGNvbnN0IGhleFRhYiA9ICcwMTIzNDU2Nzg5YWJjZGVmJztcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDMyOyBpICs9IDgpIHtcbiAgICBjb25zdCB4ID0gaW5wdXRbaSA+PiA1XSA+Pj4gaSAlIDMyICYgMHhmZjtcbiAgICBjb25zdCBoZXggPSBwYXJzZUludChoZXhUYWIuY2hhckF0KHggPj4+IDQgJiAweDBmKSArIGhleFRhYi5jaGFyQXQoeCAmIDB4MGYpLCAxNik7XG4gICAgb3V0cHV0LnB1c2goaGV4KTtcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQ7XG59XG4vKipcbiAqIENhbGN1bGF0ZSBvdXRwdXQgbGVuZ3RoIHdpdGggcGFkZGluZyBhbmQgYml0IGxlbmd0aFxuICovXG5cblxuZnVuY3Rpb24gZ2V0T3V0cHV0TGVuZ3RoKGlucHV0TGVuZ3RoOCkge1xuICByZXR1cm4gKGlucHV0TGVuZ3RoOCArIDY0ID4+PiA5IDw8IDQpICsgMTQgKyAxO1xufVxuLypcbiAqIENhbGN1bGF0ZSB0aGUgTUQ1IG9mIGFuIGFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHMsIGFuZCBhIGJpdCBsZW5ndGguXG4gKi9cblxuXG5mdW5jdGlvbiB3b3Jkc1RvTWQ1KHgsIGxlbikge1xuICAvKiBhcHBlbmQgcGFkZGluZyAqL1xuICB4W2xlbiA+PiA1XSB8PSAweDgwIDw8IGxlbiAlIDMyO1xuICB4W2dldE91dHB1dExlbmd0aChsZW4pIC0gMV0gPSBsZW47XG4gIGxldCBhID0gMTczMjU4NDE5MztcbiAgbGV0IGIgPSAtMjcxNzMzODc5O1xuICBsZXQgYyA9IC0xNzMyNTg0MTk0O1xuICBsZXQgZCA9IDI3MTczMzg3ODtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHgubGVuZ3RoOyBpICs9IDE2KSB7XG4gICAgY29uc3Qgb2xkYSA9IGE7XG4gICAgY29uc3Qgb2xkYiA9IGI7XG4gICAgY29uc3Qgb2xkYyA9IGM7XG4gICAgY29uc3Qgb2xkZCA9IGQ7XG4gICAgYSA9IG1kNWZmKGEsIGIsIGMsIGQsIHhbaV0sIDcsIC02ODA4NzY5MzYpO1xuICAgIGQgPSBtZDVmZihkLCBhLCBiLCBjLCB4W2kgKyAxXSwgMTIsIC0zODk1NjQ1ODYpO1xuICAgIGMgPSBtZDVmZihjLCBkLCBhLCBiLCB4W2kgKyAyXSwgMTcsIDYwNjEwNTgxOSk7XG4gICAgYiA9IG1kNWZmKGIsIGMsIGQsIGEsIHhbaSArIDNdLCAyMiwgLTEwNDQ1MjUzMzApO1xuICAgIGEgPSBtZDVmZihhLCBiLCBjLCBkLCB4W2kgKyA0XSwgNywgLTE3NjQxODg5Nyk7XG4gICAgZCA9IG1kNWZmKGQsIGEsIGIsIGMsIHhbaSArIDVdLCAxMiwgMTIwMDA4MDQyNik7XG4gICAgYyA9IG1kNWZmKGMsIGQsIGEsIGIsIHhbaSArIDZdLCAxNywgLTE0NzMyMzEzNDEpO1xuICAgIGIgPSBtZDVmZihiLCBjLCBkLCBhLCB4W2kgKyA3XSwgMjIsIC00NTcwNTk4Myk7XG4gICAgYSA9IG1kNWZmKGEsIGIsIGMsIGQsIHhbaSArIDhdLCA3LCAxNzcwMDM1NDE2KTtcbiAgICBkID0gbWQ1ZmYoZCwgYSwgYiwgYywgeFtpICsgOV0sIDEyLCAtMTk1ODQxNDQxNyk7XG4gICAgYyA9IG1kNWZmKGMsIGQsIGEsIGIsIHhbaSArIDEwXSwgMTcsIC00MjA2Myk7XG4gICAgYiA9IG1kNWZmKGIsIGMsIGQsIGEsIHhbaSArIDExXSwgMjIsIC0xOTkwNDA0MTYyKTtcbiAgICBhID0gbWQ1ZmYoYSwgYiwgYywgZCwgeFtpICsgMTJdLCA3LCAxODA0NjAzNjgyKTtcbiAgICBkID0gbWQ1ZmYoZCwgYSwgYiwgYywgeFtpICsgMTNdLCAxMiwgLTQwMzQxMTAxKTtcbiAgICBjID0gbWQ1ZmYoYywgZCwgYSwgYiwgeFtpICsgMTRdLCAxNywgLTE1MDIwMDIyOTApO1xuICAgIGIgPSBtZDVmZihiLCBjLCBkLCBhLCB4W2kgKyAxNV0sIDIyLCAxMjM2NTM1MzI5KTtcbiAgICBhID0gbWQ1Z2coYSwgYiwgYywgZCwgeFtpICsgMV0sIDUsIC0xNjU3OTY1MTApO1xuICAgIGQgPSBtZDVnZyhkLCBhLCBiLCBjLCB4W2kgKyA2XSwgOSwgLTEwNjk1MDE2MzIpO1xuICAgIGMgPSBtZDVnZyhjLCBkLCBhLCBiLCB4W2kgKyAxMV0sIDE0LCA2NDM3MTc3MTMpO1xuICAgIGIgPSBtZDVnZyhiLCBjLCBkLCBhLCB4W2ldLCAyMCwgLTM3Mzg5NzMwMik7XG4gICAgYSA9IG1kNWdnKGEsIGIsIGMsIGQsIHhbaSArIDVdLCA1LCAtNzAxNTU4NjkxKTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgMTBdLCA5LCAzODAxNjA4Myk7XG4gICAgYyA9IG1kNWdnKGMsIGQsIGEsIGIsIHhbaSArIDE1XSwgMTQsIC02NjA0NzgzMzUpO1xuICAgIGIgPSBtZDVnZyhiLCBjLCBkLCBhLCB4W2kgKyA0XSwgMjAsIC00MDU1Mzc4NDgpO1xuICAgIGEgPSBtZDVnZyhhLCBiLCBjLCBkLCB4W2kgKyA5XSwgNSwgNTY4NDQ2NDM4KTtcbiAgICBkID0gbWQ1Z2coZCwgYSwgYiwgYywgeFtpICsgMTRdLCA5LCAtMTAxOTgwMzY5MCk7XG4gICAgYyA9IG1kNWdnKGMsIGQsIGEsIGIsIHhbaSArIDNdLCAxNCwgLTE4NzM2Mzk2MSk7XG4gICAgYiA9IG1kNWdnKGIsIGMsIGQsIGEsIHhbaSArIDhdLCAyMCwgMTE2MzUzMTUwMSk7XG4gICAgYSA9IG1kNWdnKGEsIGIsIGMsIGQsIHhbaSArIDEzXSwgNSwgLTE0NDQ2ODE0NjcpO1xuICAgIGQgPSBtZDVnZyhkLCBhLCBiLCBjLCB4W2kgKyAyXSwgOSwgLTUxNDAzNzg0KTtcbiAgICBjID0gbWQ1Z2coYywgZCwgYSwgYiwgeFtpICsgN10sIDE0LCAxNzM1MzI4NDczKTtcbiAgICBiID0gbWQ1Z2coYiwgYywgZCwgYSwgeFtpICsgMTJdLCAyMCwgLTE5MjY2MDc3MzQpO1xuICAgIGEgPSBtZDVoaChhLCBiLCBjLCBkLCB4W2kgKyA1XSwgNCwgLTM3ODU1OCk7XG4gICAgZCA9IG1kNWhoKGQsIGEsIGIsIGMsIHhbaSArIDhdLCAxMSwgLTIwMjI1NzQ0NjMpO1xuICAgIGMgPSBtZDVoaChjLCBkLCBhLCBiLCB4W2kgKyAxMV0sIDE2LCAxODM5MDMwNTYyKTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgMTRdLCAyMywgLTM1MzA5NTU2KTtcbiAgICBhID0gbWQ1aGgoYSwgYiwgYywgZCwgeFtpICsgMV0sIDQsIC0xNTMwOTkyMDYwKTtcbiAgICBkID0gbWQ1aGgoZCwgYSwgYiwgYywgeFtpICsgNF0sIDExLCAxMjcyODkzMzUzKTtcbiAgICBjID0gbWQ1aGgoYywgZCwgYSwgYiwgeFtpICsgN10sIDE2LCAtMTU1NDk3NjMyKTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgMTBdLCAyMywgLTEwOTQ3MzA2NDApO1xuICAgIGEgPSBtZDVoaChhLCBiLCBjLCBkLCB4W2kgKyAxM10sIDQsIDY4MTI3OTE3NCk7XG4gICAgZCA9IG1kNWhoKGQsIGEsIGIsIGMsIHhbaV0sIDExLCAtMzU4NTM3MjIyKTtcbiAgICBjID0gbWQ1aGgoYywgZCwgYSwgYiwgeFtpICsgM10sIDE2LCAtNzIyNTIxOTc5KTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgNl0sIDIzLCA3NjAyOTE4OSk7XG4gICAgYSA9IG1kNWhoKGEsIGIsIGMsIGQsIHhbaSArIDldLCA0LCAtNjQwMzY0NDg3KTtcbiAgICBkID0gbWQ1aGgoZCwgYSwgYiwgYywgeFtpICsgMTJdLCAxMSwgLTQyMTgxNTgzNSk7XG4gICAgYyA9IG1kNWhoKGMsIGQsIGEsIGIsIHhbaSArIDE1XSwgMTYsIDUzMDc0MjUyMCk7XG4gICAgYiA9IG1kNWhoKGIsIGMsIGQsIGEsIHhbaSArIDJdLCAyMywgLTk5NTMzODY1MSk7XG4gICAgYSA9IG1kNWlpKGEsIGIsIGMsIGQsIHhbaV0sIDYsIC0xOTg2MzA4NDQpO1xuICAgIGQgPSBtZDVpaShkLCBhLCBiLCBjLCB4W2kgKyA3XSwgMTAsIDExMjY4OTE0MTUpO1xuICAgIGMgPSBtZDVpaShjLCBkLCBhLCBiLCB4W2kgKyAxNF0sIDE1LCAtMTQxNjM1NDkwNSk7XG4gICAgYiA9IG1kNWlpKGIsIGMsIGQsIGEsIHhbaSArIDVdLCAyMSwgLTU3NDM0MDU1KTtcbiAgICBhID0gbWQ1aWkoYSwgYiwgYywgZCwgeFtpICsgMTJdLCA2LCAxNzAwNDg1NTcxKTtcbiAgICBkID0gbWQ1aWkoZCwgYSwgYiwgYywgeFtpICsgM10sIDEwLCAtMTg5NDk4NjYwNik7XG4gICAgYyA9IG1kNWlpKGMsIGQsIGEsIGIsIHhbaSArIDEwXSwgMTUsIC0xMDUxNTIzKTtcbiAgICBiID0gbWQ1aWkoYiwgYywgZCwgYSwgeFtpICsgMV0sIDIxLCAtMjA1NDkyMjc5OSk7XG4gICAgYSA9IG1kNWlpKGEsIGIsIGMsIGQsIHhbaSArIDhdLCA2LCAxODczMzEzMzU5KTtcbiAgICBkID0gbWQ1aWkoZCwgYSwgYiwgYywgeFtpICsgMTVdLCAxMCwgLTMwNjExNzQ0KTtcbiAgICBjID0gbWQ1aWkoYywgZCwgYSwgYiwgeFtpICsgNl0sIDE1LCAtMTU2MDE5ODM4MCk7XG4gICAgYiA9IG1kNWlpKGIsIGMsIGQsIGEsIHhbaSArIDEzXSwgMjEsIDEzMDkxNTE2NDkpO1xuICAgIGEgPSBtZDVpaShhLCBiLCBjLCBkLCB4W2kgKyA0XSwgNiwgLTE0NTUyMzA3MCk7XG4gICAgZCA9IG1kNWlpKGQsIGEsIGIsIGMsIHhbaSArIDExXSwgMTAsIC0xMTIwMjEwMzc5KTtcbiAgICBjID0gbWQ1aWkoYywgZCwgYSwgYiwgeFtpICsgMl0sIDE1LCA3MTg3ODcyNTkpO1xuICAgIGIgPSBtZDVpaShiLCBjLCBkLCBhLCB4W2kgKyA5XSwgMjEsIC0zNDM0ODU1NTEpO1xuICAgIGEgPSBzYWZlQWRkKGEsIG9sZGEpO1xuICAgIGIgPSBzYWZlQWRkKGIsIG9sZGIpO1xuICAgIGMgPSBzYWZlQWRkKGMsIG9sZGMpO1xuICAgIGQgPSBzYWZlQWRkKGQsIG9sZGQpO1xuICB9XG5cbiAgcmV0dXJuIFthLCBiLCBjLCBkXTtcbn1cbi8qXG4gKiBDb252ZXJ0IGFuIGFycmF5IGJ5dGVzIHRvIGFuIGFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHNcbiAqIENoYXJhY3RlcnMgPjI1NSBoYXZlIHRoZWlyIGhpZ2gtYnl0ZSBzaWxlbnRseSBpZ25vcmVkLlxuICovXG5cblxuZnVuY3Rpb24gYnl0ZXNUb1dvcmRzKGlucHV0KSB7XG4gIGlmIChpbnB1dC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBsZW5ndGg4ID0gaW5wdXQubGVuZ3RoICogODtcbiAgY29uc3Qgb3V0cHV0ID0gbmV3IFVpbnQzMkFycmF5KGdldE91dHB1dExlbmd0aChsZW5ndGg4KSk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg4OyBpICs9IDgpIHtcbiAgICBvdXRwdXRbaSA+PiA1XSB8PSAoaW5wdXRbaSAvIDhdICYgMHhmZikgPDwgaSAlIDMyO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cbi8qXG4gKiBBZGQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9ucyBpbnRlcm5hbGx5XG4gKiB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICovXG5cblxuZnVuY3Rpb24gc2FmZUFkZCh4LCB5KSB7XG4gIGNvbnN0IGxzdyA9ICh4ICYgMHhmZmZmKSArICh5ICYgMHhmZmZmKTtcbiAgY29uc3QgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG4gIHJldHVybiBtc3cgPDwgMTYgfCBsc3cgJiAweGZmZmY7XG59XG4vKlxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxuICovXG5cblxuZnVuY3Rpb24gYml0Um90YXRlTGVmdChudW0sIGNudCkge1xuICByZXR1cm4gbnVtIDw8IGNudCB8IG51bSA+Pj4gMzIgLSBjbnQ7XG59XG4vKlxuICogVGhlc2UgZnVuY3Rpb25zIGltcGxlbWVudCB0aGUgZm91ciBiYXNpYyBvcGVyYXRpb25zIHRoZSBhbGdvcml0aG0gdXNlcy5cbiAqL1xuXG5cbmZ1bmN0aW9uIG1kNWNtbihxLCBhLCBiLCB4LCBzLCB0KSB7XG4gIHJldHVybiBzYWZlQWRkKGJpdFJvdGF0ZUxlZnQoc2FmZUFkZChzYWZlQWRkKGEsIHEpLCBzYWZlQWRkKHgsIHQpKSwgcyksIGIpO1xufVxuXG5mdW5jdGlvbiBtZDVmZihhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBtZDVjbW4oYiAmIGMgfCB+YiAmIGQsIGEsIGIsIHgsIHMsIHQpO1xufVxuXG5mdW5jdGlvbiBtZDVnZyhhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBtZDVjbW4oYiAmIGQgfCBjICYgfmQsIGEsIGIsIHgsIHMsIHQpO1xufVxuXG5mdW5jdGlvbiBtZDVoaChhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBtZDVjbW4oYiBeIGMgXiBkLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxuZnVuY3Rpb24gbWQ1aWkoYSwgYiwgYywgZCwgeCwgcywgdCkge1xuICByZXR1cm4gbWQ1Y21uKGMgXiAoYiB8IH5kKSwgYSwgYiwgeCwgcywgdCk7XG59XG5cbnZhciBfZGVmYXVsdCA9IG1kNTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuY29uc3QgcmFuZG9tVVVJRCA9IHR5cGVvZiBjcnlwdG8gIT09ICd1bmRlZmluZWQnICYmIGNyeXB0by5yYW5kb21VVUlEICYmIGNyeXB0by5yYW5kb21VVUlELmJpbmQoY3J5cHRvKTtcbnZhciBfZGVmYXVsdCA9IHtcbiAgcmFuZG9tVVVJRFxufTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xudmFyIF9kZWZhdWx0ID0gJzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMCc7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF92YWxpZGF0ZSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdmFsaWRhdGUuanNcIikpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBwYXJzZSh1dWlkKSB7XG4gIGlmICghKDAsIF92YWxpZGF0ZS5kZWZhdWx0KSh1dWlkKSkge1xuICAgIHRocm93IFR5cGVFcnJvcignSW52YWxpZCBVVUlEJyk7XG4gIH1cblxuICBsZXQgdjtcbiAgY29uc3QgYXJyID0gbmV3IFVpbnQ4QXJyYXkoMTYpOyAvLyBQYXJzZSAjIyMjIyMjIy0uLi4uLS4uLi4tLi4uLi0uLi4uLi4uLi4uLi5cblxuICBhcnJbMF0gPSAodiA9IHBhcnNlSW50KHV1aWQuc2xpY2UoMCwgOCksIDE2KSkgPj4+IDI0O1xuICBhcnJbMV0gPSB2ID4+PiAxNiAmIDB4ZmY7XG4gIGFyclsyXSA9IHYgPj4+IDggJiAweGZmO1xuICBhcnJbM10gPSB2ICYgMHhmZjsgLy8gUGFyc2UgLi4uLi4uLi4tIyMjIy0uLi4uLS4uLi4tLi4uLi4uLi4uLi4uXG5cbiAgYXJyWzRdID0gKHYgPSBwYXJzZUludCh1dWlkLnNsaWNlKDksIDEzKSwgMTYpKSA+Pj4gODtcbiAgYXJyWzVdID0gdiAmIDB4ZmY7IC8vIFBhcnNlIC4uLi4uLi4uLS4uLi4tIyMjIy0uLi4uLS4uLi4uLi4uLi4uLlxuXG4gIGFycls2XSA9ICh2ID0gcGFyc2VJbnQodXVpZC5zbGljZSgxNCwgMTgpLCAxNikpID4+PiA4O1xuICBhcnJbN10gPSB2ICYgMHhmZjsgLy8gUGFyc2UgLi4uLi4uLi4tLi4uLi0uLi4uLSMjIyMtLi4uLi4uLi4uLi4uXG5cbiAgYXJyWzhdID0gKHYgPSBwYXJzZUludCh1dWlkLnNsaWNlKDE5LCAyMyksIDE2KSkgPj4+IDg7XG4gIGFycls5XSA9IHYgJiAweGZmOyAvLyBQYXJzZSAuLi4uLi4uLi0uLi4uLS4uLi4tLi4uLi0jIyMjIyMjIyMjIyNcbiAgLy8gKFVzZSBcIi9cIiB0byBhdm9pZCAzMi1iaXQgdHJ1bmNhdGlvbiB3aGVuIGJpdC1zaGlmdGluZyBoaWdoLW9yZGVyIGJ5dGVzKVxuXG4gIGFyclsxMF0gPSAodiA9IHBhcnNlSW50KHV1aWQuc2xpY2UoMjQsIDM2KSwgMTYpKSAvIDB4MTAwMDAwMDAwMDAgJiAweGZmO1xuICBhcnJbMTFdID0gdiAvIDB4MTAwMDAwMDAwICYgMHhmZjtcbiAgYXJyWzEyXSA9IHYgPj4+IDI0ICYgMHhmZjtcbiAgYXJyWzEzXSA9IHYgPj4+IDE2ICYgMHhmZjtcbiAgYXJyWzE0XSA9IHYgPj4+IDggJiAweGZmO1xuICBhcnJbMTVdID0gdiAmIDB4ZmY7XG4gIHJldHVybiBhcnI7XG59XG5cbnZhciBfZGVmYXVsdCA9IHBhcnNlO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG52YXIgX2RlZmF1bHQgPSAvXig/OlswLTlhLWZdezh9LVswLTlhLWZdezR9LVsxLTVdWzAtOWEtZl17M30tWzg5YWJdWzAtOWEtZl17M30tWzAtOWEtZl17MTJ9fDAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMCkkL2k7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHJuZztcbi8vIFVuaXF1ZSBJRCBjcmVhdGlvbiByZXF1aXJlcyBhIGhpZ2ggcXVhbGl0eSByYW5kb20gIyBnZW5lcmF0b3IuIEluIHRoZSBicm93c2VyIHdlIHRoZXJlZm9yZVxuLy8gcmVxdWlyZSB0aGUgY3J5cHRvIEFQSSBhbmQgZG8gbm90IHN1cHBvcnQgYnVpbHQtaW4gZmFsbGJhY2sgdG8gbG93ZXIgcXVhbGl0eSByYW5kb20gbnVtYmVyXG4vLyBnZW5lcmF0b3JzIChsaWtlIE1hdGgucmFuZG9tKCkpLlxubGV0IGdldFJhbmRvbVZhbHVlcztcbmNvbnN0IHJuZHM4ID0gbmV3IFVpbnQ4QXJyYXkoMTYpO1xuXG5mdW5jdGlvbiBybmcoKSB7XG4gIC8vIGxhenkgbG9hZCBzbyB0aGF0IGVudmlyb25tZW50cyB0aGF0IG5lZWQgdG8gcG9seWZpbGwgaGF2ZSBhIGNoYW5jZSB0byBkbyBzb1xuICBpZiAoIWdldFJhbmRvbVZhbHVlcykge1xuICAgIC8vIGdldFJhbmRvbVZhbHVlcyBuZWVkcyB0byBiZSBpbnZva2VkIGluIGEgY29udGV4dCB3aGVyZSBcInRoaXNcIiBpcyBhIENyeXB0byBpbXBsZW1lbnRhdGlvbi5cbiAgICBnZXRSYW5kb21WYWx1ZXMgPSB0eXBlb2YgY3J5cHRvICE9PSAndW5kZWZpbmVkJyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzICYmIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMuYmluZChjcnlwdG8pO1xuXG4gICAgaWYgKCFnZXRSYW5kb21WYWx1ZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY3J5cHRvLmdldFJhbmRvbVZhbHVlcygpIG5vdCBzdXBwb3J0ZWQuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vdXVpZGpzL3V1aWQjZ2V0cmFuZG9tdmFsdWVzLW5vdC1zdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZ2V0UmFuZG9tVmFsdWVzKHJuZHM4KTtcbn0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxuLy8gQWRhcHRlZCBmcm9tIENocmlzIFZlbmVzcycgU0hBMSBjb2RlIGF0XG4vLyBodHRwOi8vd3d3Lm1vdmFibGUtdHlwZS5jby51ay9zY3JpcHRzL3NoYTEuaHRtbFxuZnVuY3Rpb24gZihzLCB4LCB5LCB6KSB7XG4gIHN3aXRjaCAocykge1xuICAgIGNhc2UgMDpcbiAgICAgIHJldHVybiB4ICYgeSBeIH54ICYgejtcblxuICAgIGNhc2UgMTpcbiAgICAgIHJldHVybiB4IF4geSBeIHo7XG5cbiAgICBjYXNlIDI6XG4gICAgICByZXR1cm4geCAmIHkgXiB4ICYgeiBeIHkgJiB6O1xuXG4gICAgY2FzZSAzOlxuICAgICAgcmV0dXJuIHggXiB5IF4gejtcbiAgfVxufVxuXG5mdW5jdGlvbiBST1RMKHgsIG4pIHtcbiAgcmV0dXJuIHggPDwgbiB8IHggPj4+IDMyIC0gbjtcbn1cblxuZnVuY3Rpb24gc2hhMShieXRlcykge1xuICBjb25zdCBLID0gWzB4NWE4Mjc5OTksIDB4NmVkOWViYTEsIDB4OGYxYmJjZGMsIDB4Y2E2MmMxZDZdO1xuICBjb25zdCBIID0gWzB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjBdO1xuXG4gIGlmICh0eXBlb2YgYnl0ZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uc3QgbXNnID0gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KGJ5dGVzKSk7IC8vIFVURjggZXNjYXBlXG5cbiAgICBieXRlcyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyArK2kpIHtcbiAgICAgIGJ5dGVzLnB1c2gobXNnLmNoYXJDb2RlQXQoaSkpO1xuICAgIH1cbiAgfSBlbHNlIGlmICghQXJyYXkuaXNBcnJheShieXRlcykpIHtcbiAgICAvLyBDb252ZXJ0IEFycmF5LWxpa2UgdG8gQXJyYXlcbiAgICBieXRlcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGJ5dGVzKTtcbiAgfVxuXG4gIGJ5dGVzLnB1c2goMHg4MCk7XG4gIGNvbnN0IGwgPSBieXRlcy5sZW5ndGggLyA0ICsgMjtcbiAgY29uc3QgTiA9IE1hdGguY2VpbChsIC8gMTYpO1xuICBjb25zdCBNID0gbmV3IEFycmF5KE4pO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgTjsgKytpKSB7XG4gICAgY29uc3QgYXJyID0gbmV3IFVpbnQzMkFycmF5KDE2KTtcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgMTY7ICsraikge1xuICAgICAgYXJyW2pdID0gYnl0ZXNbaSAqIDY0ICsgaiAqIDRdIDw8IDI0IHwgYnl0ZXNbaSAqIDY0ICsgaiAqIDQgKyAxXSA8PCAxNiB8IGJ5dGVzW2kgKiA2NCArIGogKiA0ICsgMl0gPDwgOCB8IGJ5dGVzW2kgKiA2NCArIGogKiA0ICsgM107XG4gICAgfVxuXG4gICAgTVtpXSA9IGFycjtcbiAgfVxuXG4gIE1bTiAtIDFdWzE0XSA9IChieXRlcy5sZW5ndGggLSAxKSAqIDggLyBNYXRoLnBvdygyLCAzMik7XG4gIE1bTiAtIDFdWzE0XSA9IE1hdGguZmxvb3IoTVtOIC0gMV1bMTRdKTtcbiAgTVtOIC0gMV1bMTVdID0gKGJ5dGVzLmxlbmd0aCAtIDEpICogOCAmIDB4ZmZmZmZmZmY7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBOOyArK2kpIHtcbiAgICBjb25zdCBXID0gbmV3IFVpbnQzMkFycmF5KDgwKTtcblxuICAgIGZvciAobGV0IHQgPSAwOyB0IDwgMTY7ICsrdCkge1xuICAgICAgV1t0XSA9IE1baV1bdF07XG4gICAgfVxuXG4gICAgZm9yIChsZXQgdCA9IDE2OyB0IDwgODA7ICsrdCkge1xuICAgICAgV1t0XSA9IFJPVEwoV1t0IC0gM10gXiBXW3QgLSA4XSBeIFdbdCAtIDE0XSBeIFdbdCAtIDE2XSwgMSk7XG4gICAgfVxuXG4gICAgbGV0IGEgPSBIWzBdO1xuICAgIGxldCBiID0gSFsxXTtcbiAgICBsZXQgYyA9IEhbMl07XG4gICAgbGV0IGQgPSBIWzNdO1xuICAgIGxldCBlID0gSFs0XTtcblxuICAgIGZvciAobGV0IHQgPSAwOyB0IDwgODA7ICsrdCkge1xuICAgICAgY29uc3QgcyA9IE1hdGguZmxvb3IodCAvIDIwKTtcbiAgICAgIGNvbnN0IFQgPSBST1RMKGEsIDUpICsgZihzLCBiLCBjLCBkKSArIGUgKyBLW3NdICsgV1t0XSA+Pj4gMDtcbiAgICAgIGUgPSBkO1xuICAgICAgZCA9IGM7XG4gICAgICBjID0gUk9UTChiLCAzMCkgPj4+IDA7XG4gICAgICBiID0gYTtcbiAgICAgIGEgPSBUO1xuICAgIH1cblxuICAgIEhbMF0gPSBIWzBdICsgYSA+Pj4gMDtcbiAgICBIWzFdID0gSFsxXSArIGIgPj4+IDA7XG4gICAgSFsyXSA9IEhbMl0gKyBjID4+PiAwO1xuICAgIEhbM10gPSBIWzNdICsgZCA+Pj4gMDtcbiAgICBIWzRdID0gSFs0XSArIGUgPj4+IDA7XG4gIH1cblxuICByZXR1cm4gW0hbMF0gPj4gMjQgJiAweGZmLCBIWzBdID4+IDE2ICYgMHhmZiwgSFswXSA+PiA4ICYgMHhmZiwgSFswXSAmIDB4ZmYsIEhbMV0gPj4gMjQgJiAweGZmLCBIWzFdID4+IDE2ICYgMHhmZiwgSFsxXSA+PiA4ICYgMHhmZiwgSFsxXSAmIDB4ZmYsIEhbMl0gPj4gMjQgJiAweGZmLCBIWzJdID4+IDE2ICYgMHhmZiwgSFsyXSA+PiA4ICYgMHhmZiwgSFsyXSAmIDB4ZmYsIEhbM10gPj4gMjQgJiAweGZmLCBIWzNdID4+IDE2ICYgMHhmZiwgSFszXSA+PiA4ICYgMHhmZiwgSFszXSAmIDB4ZmYsIEhbNF0gPj4gMjQgJiAweGZmLCBIWzRdID4+IDE2ICYgMHhmZiwgSFs0XSA+PiA4ICYgMHhmZiwgSFs0XSAmIDB4ZmZdO1xufVxuXG52YXIgX2RlZmF1bHQgPSBzaGExO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5leHBvcnRzLnVuc2FmZVN0cmluZ2lmeSA9IHVuc2FmZVN0cmluZ2lmeTtcblxudmFyIF92YWxpZGF0ZSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdmFsaWRhdGUuanNcIikpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG4vKipcbiAqIENvbnZlcnQgYXJyYXkgb2YgMTYgYnl0ZSB2YWx1ZXMgdG8gVVVJRCBzdHJpbmcgZm9ybWF0IG9mIHRoZSBmb3JtOlxuICogWFhYWFhYWFgtWFhYWC1YWFhYLVhYWFgtWFhYWFhYWFhYWFhYXG4gKi9cbmNvbnN0IGJ5dGVUb0hleCA9IFtdO1xuXG5mb3IgKGxldCBpID0gMDsgaSA8IDI1NjsgKytpKSB7XG4gIGJ5dGVUb0hleC5wdXNoKChpICsgMHgxMDApLnRvU3RyaW5nKDE2KS5zbGljZSgxKSk7XG59XG5cbmZ1bmN0aW9uIHVuc2FmZVN0cmluZ2lmeShhcnIsIG9mZnNldCA9IDApIHtcbiAgLy8gTm90ZTogQmUgY2FyZWZ1bCBlZGl0aW5nIHRoaXMgY29kZSEgIEl0J3MgYmVlbiB0dW5lZCBmb3IgcGVyZm9ybWFuY2VcbiAgLy8gYW5kIHdvcmtzIGluIHdheXMgeW91IG1heSBub3QgZXhwZWN0LiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3V1aWRqcy91dWlkL3B1bGwvNDM0XG4gIHJldHVybiAoYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAwXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDFdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgMl1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAzXV0gKyAnLScgKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDRdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgNV1dICsgJy0nICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyA2XV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDddXSArICctJyArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgOF1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyA5XV0gKyAnLScgKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDEwXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDExXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDEyXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDEzXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDE0XV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDE1XV0pLnRvTG93ZXJDYXNlKCk7XG59XG5cbmZ1bmN0aW9uIHN0cmluZ2lmeShhcnIsIG9mZnNldCA9IDApIHtcbiAgY29uc3QgdXVpZCA9IHVuc2FmZVN0cmluZ2lmeShhcnIsIG9mZnNldCk7IC8vIENvbnNpc3RlbmN5IGNoZWNrIGZvciB2YWxpZCBVVUlELiAgSWYgdGhpcyB0aHJvd3MsIGl0J3MgbGlrZWx5IGR1ZSB0byBvbmVcbiAgLy8gb2YgdGhlIGZvbGxvd2luZzpcbiAgLy8gLSBPbmUgb3IgbW9yZSBpbnB1dCBhcnJheSB2YWx1ZXMgZG9uJ3QgbWFwIHRvIGEgaGV4IG9jdGV0IChsZWFkaW5nIHRvXG4gIC8vIFwidW5kZWZpbmVkXCIgaW4gdGhlIHV1aWQpXG4gIC8vIC0gSW52YWxpZCBpbnB1dCB2YWx1ZXMgZm9yIHRoZSBSRkMgYHZlcnNpb25gIG9yIGB2YXJpYW50YCBmaWVsZHNcblxuICBpZiAoISgwLCBfdmFsaWRhdGUuZGVmYXVsdCkodXVpZCkpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ1N0cmluZ2lmaWVkIFVVSUQgaXMgaW52YWxpZCcpO1xuICB9XG5cbiAgcmV0dXJuIHV1aWQ7XG59XG5cbnZhciBfZGVmYXVsdCA9IHN0cmluZ2lmeTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3JuZyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vcm5nLmpzXCIpKTtcblxudmFyIF9zdHJpbmdpZnkgPSByZXF1aXJlKFwiLi9zdHJpbmdpZnkuanNcIik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbi8vICoqYHYxKClgIC0gR2VuZXJhdGUgdGltZS1iYXNlZCBVVUlEKipcbi8vXG4vLyBJbnNwaXJlZCBieSBodHRwczovL2dpdGh1Yi5jb20vTGlvc0svVVVJRC5qc1xuLy8gYW5kIGh0dHA6Ly9kb2NzLnB5dGhvbi5vcmcvbGlicmFyeS91dWlkLmh0bWxcbmxldCBfbm9kZUlkO1xuXG5sZXQgX2Nsb2Nrc2VxOyAvLyBQcmV2aW91cyB1dWlkIGNyZWF0aW9uIHRpbWVcblxuXG5sZXQgX2xhc3RNU2VjcyA9IDA7XG5sZXQgX2xhc3ROU2VjcyA9IDA7IC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vdXVpZGpzL3V1aWQgZm9yIEFQSSBkZXRhaWxzXG5cbmZ1bmN0aW9uIHYxKG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIGxldCBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuICBjb25zdCBiID0gYnVmIHx8IG5ldyBBcnJheSgxNik7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBsZXQgbm9kZSA9IG9wdGlvbnMubm9kZSB8fCBfbm9kZUlkO1xuICBsZXQgY2xvY2tzZXEgPSBvcHRpb25zLmNsb2Nrc2VxICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsb2Nrc2VxIDogX2Nsb2Nrc2VxOyAvLyBub2RlIGFuZCBjbG9ja3NlcSBuZWVkIHRvIGJlIGluaXRpYWxpemVkIHRvIHJhbmRvbSB2YWx1ZXMgaWYgdGhleSdyZSBub3RcbiAgLy8gc3BlY2lmaWVkLiAgV2UgZG8gdGhpcyBsYXppbHkgdG8gbWluaW1pemUgaXNzdWVzIHJlbGF0ZWQgdG8gaW5zdWZmaWNpZW50XG4gIC8vIHN5c3RlbSBlbnRyb3B5LiAgU2VlICMxODlcblxuICBpZiAobm9kZSA9PSBudWxsIHx8IGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICBjb25zdCBzZWVkQnl0ZXMgPSBvcHRpb25zLnJhbmRvbSB8fCAob3B0aW9ucy5ybmcgfHwgX3JuZy5kZWZhdWx0KSgpO1xuXG4gICAgaWYgKG5vZGUgPT0gbnVsbCkge1xuICAgICAgLy8gUGVyIDQuNSwgY3JlYXRlIGFuZCA0OC1iaXQgbm9kZSBpZCwgKDQ3IHJhbmRvbSBiaXRzICsgbXVsdGljYXN0IGJpdCA9IDEpXG4gICAgICBub2RlID0gX25vZGVJZCA9IFtzZWVkQnl0ZXNbMF0gfCAweDAxLCBzZWVkQnl0ZXNbMV0sIHNlZWRCeXRlc1syXSwgc2VlZEJ5dGVzWzNdLCBzZWVkQnl0ZXNbNF0sIHNlZWRCeXRlc1s1XV07XG4gICAgfVxuXG4gICAgaWYgKGNsb2Nrc2VxID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjIuMiwgcmFuZG9taXplICgxNCBiaXQpIGNsb2Nrc2VxXG4gICAgICBjbG9ja3NlcSA9IF9jbG9ja3NlcSA9IChzZWVkQnl0ZXNbNl0gPDwgOCB8IHNlZWRCeXRlc1s3XSkgJiAweDNmZmY7XG4gICAgfVxuICB9IC8vIFVVSUQgdGltZXN0YW1wcyBhcmUgMTAwIG5hbm8tc2Vjb25kIHVuaXRzIHNpbmNlIHRoZSBHcmVnb3JpYW4gZXBvY2gsXG4gIC8vICgxNTgyLTEwLTE1IDAwOjAwKS4gIEpTTnVtYmVycyBhcmVuJ3QgcHJlY2lzZSBlbm91Z2ggZm9yIHRoaXMsIHNvXG4gIC8vIHRpbWUgaXMgaGFuZGxlZCBpbnRlcm5hbGx5IGFzICdtc2VjcycgKGludGVnZXIgbWlsbGlzZWNvbmRzKSBhbmQgJ25zZWNzJ1xuICAvLyAoMTAwLW5hbm9zZWNvbmRzIG9mZnNldCBmcm9tIG1zZWNzKSBzaW5jZSB1bml4IGVwb2NoLCAxOTcwLTAxLTAxIDAwOjAwLlxuXG5cbiAgbGV0IG1zZWNzID0gb3B0aW9ucy5tc2VjcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5tc2VjcyA6IERhdGUubm93KCk7IC8vIFBlciA0LjIuMS4yLCB1c2UgY291bnQgb2YgdXVpZCdzIGdlbmVyYXRlZCBkdXJpbmcgdGhlIGN1cnJlbnQgY2xvY2tcbiAgLy8gY3ljbGUgdG8gc2ltdWxhdGUgaGlnaGVyIHJlc29sdXRpb24gY2xvY2tcblxuICBsZXQgbnNlY3MgPSBvcHRpb25zLm5zZWNzICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm5zZWNzIDogX2xhc3ROU2VjcyArIDE7IC8vIFRpbWUgc2luY2UgbGFzdCB1dWlkIGNyZWF0aW9uIChpbiBtc2VjcylcblxuICBjb25zdCBkdCA9IG1zZWNzIC0gX2xhc3RNU2VjcyArIChuc2VjcyAtIF9sYXN0TlNlY3MpIC8gMTAwMDA7IC8vIFBlciA0LjIuMS4yLCBCdW1wIGNsb2Nrc2VxIG9uIGNsb2NrIHJlZ3Jlc3Npb25cblxuICBpZiAoZHQgPCAwICYmIG9wdGlvbnMuY2xvY2tzZXEgPT09IHVuZGVmaW5lZCkge1xuICAgIGNsb2Nrc2VxID0gY2xvY2tzZXEgKyAxICYgMHgzZmZmO1xuICB9IC8vIFJlc2V0IG5zZWNzIGlmIGNsb2NrIHJlZ3Jlc3NlcyAobmV3IGNsb2Nrc2VxKSBvciB3ZSd2ZSBtb3ZlZCBvbnRvIGEgbmV3XG4gIC8vIHRpbWUgaW50ZXJ2YWxcblxuXG4gIGlmICgoZHQgPCAwIHx8IG1zZWNzID4gX2xhc3RNU2VjcykgJiYgb3B0aW9ucy5uc2VjcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbnNlY3MgPSAwO1xuICB9IC8vIFBlciA0LjIuMS4yIFRocm93IGVycm9yIGlmIHRvbyBtYW55IHV1aWRzIGFyZSByZXF1ZXN0ZWRcblxuXG4gIGlmIChuc2VjcyA+PSAxMDAwMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcInV1aWQudjEoKTogQ2FuJ3QgY3JlYXRlIG1vcmUgdGhhbiAxME0gdXVpZHMvc2VjXCIpO1xuICB9XG5cbiAgX2xhc3RNU2VjcyA9IG1zZWNzO1xuICBfbGFzdE5TZWNzID0gbnNlY3M7XG4gIF9jbG9ja3NlcSA9IGNsb2Nrc2VxOyAvLyBQZXIgNC4xLjQgLSBDb252ZXJ0IGZyb20gdW5peCBlcG9jaCB0byBHcmVnb3JpYW4gZXBvY2hcblxuICBtc2VjcyArPSAxMjIxOTI5MjgwMDAwMDsgLy8gYHRpbWVfbG93YFxuXG4gIGNvbnN0IHRsID0gKChtc2VjcyAmIDB4ZmZmZmZmZikgKiAxMDAwMCArIG5zZWNzKSAlIDB4MTAwMDAwMDAwO1xuICBiW2krK10gPSB0bCA+Pj4gMjQgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gMTYgJiAweGZmO1xuICBiW2krK10gPSB0bCA+Pj4gOCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsICYgMHhmZjsgLy8gYHRpbWVfbWlkYFxuXG4gIGNvbnN0IHRtaCA9IG1zZWNzIC8gMHgxMDAwMDAwMDAgKiAxMDAwMCAmIDB4ZmZmZmZmZjtcbiAgYltpKytdID0gdG1oID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdG1oICYgMHhmZjsgLy8gYHRpbWVfaGlnaF9hbmRfdmVyc2lvbmBcblxuICBiW2krK10gPSB0bWggPj4+IDI0ICYgMHhmIHwgMHgxMDsgLy8gaW5jbHVkZSB2ZXJzaW9uXG5cbiAgYltpKytdID0gdG1oID4+PiAxNiAmIDB4ZmY7IC8vIGBjbG9ja19zZXFfaGlfYW5kX3Jlc2VydmVkYCAoUGVyIDQuMi4yIC0gaW5jbHVkZSB2YXJpYW50KVxuXG4gIGJbaSsrXSA9IGNsb2Nrc2VxID4+PiA4IHwgMHg4MDsgLy8gYGNsb2NrX3NlcV9sb3dgXG5cbiAgYltpKytdID0gY2xvY2tzZXEgJiAweGZmOyAvLyBgbm9kZWBcblxuICBmb3IgKGxldCBuID0gMDsgbiA8IDY7ICsrbikge1xuICAgIGJbaSArIG5dID0gbm9kZVtuXTtcbiAgfVxuXG4gIHJldHVybiBidWYgfHwgKDAsIF9zdHJpbmdpZnkudW5zYWZlU3RyaW5naWZ5KShiKTtcbn1cblxudmFyIF9kZWZhdWx0ID0gdjE7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF92ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92MzUuanNcIikpO1xuXG52YXIgX21kID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9tZDUuanNcIikpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5jb25zdCB2MyA9ICgwLCBfdi5kZWZhdWx0KSgndjMnLCAweDMwLCBfbWQuZGVmYXVsdCk7XG52YXIgX2RlZmF1bHQgPSB2MztcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5VUkwgPSBleHBvcnRzLkROUyA9IHZvaWQgMDtcbmV4cG9ydHMuZGVmYXVsdCA9IHYzNTtcblxudmFyIF9zdHJpbmdpZnkgPSByZXF1aXJlKFwiLi9zdHJpbmdpZnkuanNcIik7XG5cbnZhciBfcGFyc2UgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3BhcnNlLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gc3RyaW5nVG9CeXRlcyhzdHIpIHtcbiAgc3RyID0gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHN0cikpOyAvLyBVVEY4IGVzY2FwZVxuXG4gIGNvbnN0IGJ5dGVzID0gW107XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICBieXRlcy5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpKTtcbiAgfVxuXG4gIHJldHVybiBieXRlcztcbn1cblxuY29uc3QgRE5TID0gJzZiYTdiODEwLTlkYWQtMTFkMS04MGI0LTAwYzA0ZmQ0MzBjOCc7XG5leHBvcnRzLkROUyA9IEROUztcbmNvbnN0IFVSTCA9ICc2YmE3YjgxMS05ZGFkLTExZDEtODBiNC0wMGMwNGZkNDMwYzgnO1xuZXhwb3J0cy5VUkwgPSBVUkw7XG5cbmZ1bmN0aW9uIHYzNShuYW1lLCB2ZXJzaW9uLCBoYXNoZnVuYykge1xuICBmdW5jdGlvbiBnZW5lcmF0ZVVVSUQodmFsdWUsIG5hbWVzcGFjZSwgYnVmLCBvZmZzZXQpIHtcbiAgICB2YXIgX25hbWVzcGFjZTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YWx1ZSA9IHN0cmluZ1RvQnl0ZXModmFsdWUpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbmFtZXNwYWNlID09PSAnc3RyaW5nJykge1xuICAgICAgbmFtZXNwYWNlID0gKDAsIF9wYXJzZS5kZWZhdWx0KShuYW1lc3BhY2UpO1xuICAgIH1cblxuICAgIGlmICgoKF9uYW1lc3BhY2UgPSBuYW1lc3BhY2UpID09PSBudWxsIHx8IF9uYW1lc3BhY2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9uYW1lc3BhY2UubGVuZ3RoKSAhPT0gMTYpIHtcbiAgICAgIHRocm93IFR5cGVFcnJvcignTmFtZXNwYWNlIG11c3QgYmUgYXJyYXktbGlrZSAoMTYgaXRlcmFibGUgaW50ZWdlciB2YWx1ZXMsIDAtMjU1KScpO1xuICAgIH0gLy8gQ29tcHV0ZSBoYXNoIG9mIG5hbWVzcGFjZSBhbmQgdmFsdWUsIFBlciA0LjNcbiAgICAvLyBGdXR1cmU6IFVzZSBzcHJlYWQgc3ludGF4IHdoZW4gc3VwcG9ydGVkIG9uIGFsbCBwbGF0Zm9ybXMsIGUuZy4gYGJ5dGVzID1cbiAgICAvLyBoYXNoZnVuYyhbLi4ubmFtZXNwYWNlLCAuLi4gdmFsdWVdKWBcblxuXG4gICAgbGV0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoMTYgKyB2YWx1ZS5sZW5ndGgpO1xuICAgIGJ5dGVzLnNldChuYW1lc3BhY2UpO1xuICAgIGJ5dGVzLnNldCh2YWx1ZSwgbmFtZXNwYWNlLmxlbmd0aCk7XG4gICAgYnl0ZXMgPSBoYXNoZnVuYyhieXRlcyk7XG4gICAgYnl0ZXNbNl0gPSBieXRlc1s2XSAmIDB4MGYgfCB2ZXJzaW9uO1xuICAgIGJ5dGVzWzhdID0gYnl0ZXNbOF0gJiAweDNmIHwgMHg4MDtcblxuICAgIGlmIChidWYpIHtcbiAgICAgIG9mZnNldCA9IG9mZnNldCB8fCAwO1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDE2OyArK2kpIHtcbiAgICAgICAgYnVmW29mZnNldCArIGldID0gYnl0ZXNbaV07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBidWY7XG4gICAgfVxuXG4gICAgcmV0dXJuICgwLCBfc3RyaW5naWZ5LnVuc2FmZVN0cmluZ2lmeSkoYnl0ZXMpO1xuICB9IC8vIEZ1bmN0aW9uI25hbWUgaXMgbm90IHNldHRhYmxlIG9uIHNvbWUgcGxhdGZvcm1zICgjMjcwKVxuXG5cbiAgdHJ5IHtcbiAgICBnZW5lcmF0ZVVVSUQubmFtZSA9IG5hbWU7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1lbXB0eVxuICB9IGNhdGNoIChlcnIpIHt9IC8vIEZvciBDb21tb25KUyBkZWZhdWx0IGV4cG9ydCBzdXBwb3J0XG5cblxuICBnZW5lcmF0ZVVVSUQuRE5TID0gRE5TO1xuICBnZW5lcmF0ZVVVSUQuVVJMID0gVVJMO1xuICByZXR1cm4gZ2VuZXJhdGVVVUlEO1xufSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX25hdGl2ZSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vbmF0aXZlLmpzXCIpKTtcblxudmFyIF9ybmcgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3JuZy5qc1wiKSk7XG5cbnZhciBfc3RyaW5naWZ5ID0gcmVxdWlyZShcIi4vc3RyaW5naWZ5LmpzXCIpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiB2NChvcHRpb25zLCBidWYsIG9mZnNldCkge1xuICBpZiAoX25hdGl2ZS5kZWZhdWx0LnJhbmRvbVVVSUQgJiYgIWJ1ZiAmJiAhb3B0aW9ucykge1xuICAgIHJldHVybiBfbmF0aXZlLmRlZmF1bHQucmFuZG9tVVVJRCgpO1xuICB9XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgY29uc3Qgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBfcm5nLmRlZmF1bHQpKCk7IC8vIFBlciA0LjQsIHNldCBiaXRzIGZvciB2ZXJzaW9uIGFuZCBgY2xvY2tfc2VxX2hpX2FuZF9yZXNlcnZlZGBcblxuXG4gIHJuZHNbNl0gPSBybmRzWzZdICYgMHgwZiB8IDB4NDA7XG4gIHJuZHNbOF0gPSBybmRzWzhdICYgMHgzZiB8IDB4ODA7IC8vIENvcHkgYnl0ZXMgdG8gYnVmZmVyLCBpZiBwcm92aWRlZFxuXG4gIGlmIChidWYpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfHwgMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMTY7ICsraSkge1xuICAgICAgYnVmW29mZnNldCArIGldID0gcm5kc1tpXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnVmO1xuICB9XG5cbiAgcmV0dXJuICgwLCBfc3RyaW5naWZ5LnVuc2FmZVN0cmluZ2lmeSkocm5kcyk7XG59XG5cbnZhciBfZGVmYXVsdCA9IHY0O1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfdiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdjM1LmpzXCIpKTtcblxudmFyIF9zaGEgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3NoYTEuanNcIikpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5jb25zdCB2NSA9ICgwLCBfdi5kZWZhdWx0KSgndjUnLCAweDUwLCBfc2hhLmRlZmF1bHQpO1xudmFyIF9kZWZhdWx0ID0gdjU7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF9yZWdleCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vcmVnZXguanNcIikpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiB2YWxpZGF0ZSh1dWlkKSB7XG4gIHJldHVybiB0eXBlb2YgdXVpZCA9PT0gJ3N0cmluZycgJiYgX3JlZ2V4LmRlZmF1bHQudGVzdCh1dWlkKTtcbn1cblxudmFyIF9kZWZhdWx0ID0gdmFsaWRhdGU7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF92YWxpZGF0ZSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdmFsaWRhdGUuanNcIikpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiB2ZXJzaW9uKHV1aWQpIHtcbiAgaWYgKCEoMCwgX3ZhbGlkYXRlLmRlZmF1bHQpKHV1aWQpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKCdJbnZhbGlkIFVVSUQnKTtcbiAgfVxuXG4gIHJldHVybiBwYXJzZUludCh1dWlkLnNsaWNlKDE0LCAxNSksIDE2KTtcbn1cblxudmFyIF9kZWZhdWx0ID0gdmVyc2lvbjtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIi8qXG5XaWxkRW1pdHRlci5qcyBpcyBhIHNsaW0gbGl0dGxlIGV2ZW50IGVtaXR0ZXIgYnkgQGhlbnJpa2pvcmV0ZWcgbGFyZ2VseSBiYXNlZFxub24gQHZpc2lvbm1lZGlhJ3MgRW1pdHRlciBmcm9tIFVJIEtpdC5cblxuV2h5PyBJIHdhbnRlZCBpdCBzdGFuZGFsb25lLlxuXG5JIGFsc28gd2FudGVkIHN1cHBvcnQgZm9yIHdpbGRjYXJkIGVtaXR0ZXJzIGxpa2UgdGhpczpcblxuZW1pdHRlci5vbignKicsIGZ1bmN0aW9uIChldmVudE5hbWUsIG90aGVyLCBldmVudCwgcGF5bG9hZHMpIHtcblxufSk7XG5cbmVtaXR0ZXIub24oJ3NvbWVuYW1lc3BhY2UqJywgZnVuY3Rpb24gKGV2ZW50TmFtZSwgcGF5bG9hZHMpIHtcblxufSk7XG5cblBsZWFzZSBub3RlIHRoYXQgY2FsbGJhY2tzIHRyaWdnZXJlZCBieSB3aWxkY2FyZCByZWdpc3RlcmVkIGV2ZW50cyBhbHNvIGdldFxudGhlIGV2ZW50IG5hbWUgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxuKi9cblxubW9kdWxlLmV4cG9ydHMgPSBXaWxkRW1pdHRlcjtcblxuZnVuY3Rpb24gV2lsZEVtaXR0ZXIoKSB7IH1cblxuV2lsZEVtaXR0ZXIubWl4aW4gPSBmdW5jdGlvbiAoY29uc3RydWN0b3IpIHtcbiAgICB2YXIgcHJvdG90eXBlID0gY29uc3RydWN0b3IucHJvdG90eXBlIHx8IGNvbnN0cnVjdG9yO1xuXG4gICAgcHJvdG90eXBlLmlzV2lsZEVtaXR0ZXI9IHRydWU7XG5cbiAgICAvLyBMaXN0ZW4gb24gdGhlIGdpdmVuIGBldmVudGAgd2l0aCBgZm5gLiBTdG9yZSBhIGdyb3VwIG5hbWUgaWYgcHJlc2VudC5cbiAgICBwcm90b3R5cGUub24gPSBmdW5jdGlvbiAoZXZlbnQsIGdyb3VwTmFtZSwgZm4pIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxuICAgICAgICAgICAgZ3JvdXAgPSBoYXNHcm91cCA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGZ1bmMgPSBoYXNHcm91cCA/IGFyZ3VtZW50c1syXSA6IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgZnVuYy5fZ3JvdXBOYW1lID0gZ3JvdXA7XG4gICAgICAgICh0aGlzLmNhbGxiYWNrc1tldmVudF0gPSB0aGlzLmNhbGxiYWNrc1tldmVudF0gfHwgW10pLnB1c2goZnVuYyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLyBBZGRzIGFuIGBldmVudGAgbGlzdGVuZXIgdGhhdCB3aWxsIGJlIGludm9rZWQgYSBzaW5nbGVcbiAgICAvLyB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxuICAgIHByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24gKGV2ZW50LCBncm91cE5hbWUsIGZuKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcyxcbiAgICAgICAgICAgIGhhc0dyb3VwID0gKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpLFxuICAgICAgICAgICAgZ3JvdXAgPSBoYXNHcm91cCA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGZ1bmMgPSBoYXNHcm91cCA/IGFyZ3VtZW50c1syXSA6IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgZnVuY3Rpb24gb24oKSB7XG4gICAgICAgICAgICBzZWxmLm9mZihldmVudCwgb24pO1xuICAgICAgICAgICAgZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub24oZXZlbnQsIGdyb3VwLCBvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLyBVbmJpbmRzIGFuIGVudGlyZSBncm91cFxuICAgIHByb3RvdHlwZS5yZWxlYXNlR3JvdXAgPSBmdW5jdGlvbiAoZ3JvdXBOYW1lKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XG4gICAgICAgIHZhciBpdGVtLCBpLCBsZW4sIGhhbmRsZXJzO1xuICAgICAgICBmb3IgKGl0ZW0gaW4gdGhpcy5jYWxsYmFja3MpIHtcbiAgICAgICAgICAgIGhhbmRsZXJzID0gdGhpcy5jYWxsYmFja3NbaXRlbV07XG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBoYW5kbGVycy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChoYW5kbGVyc1tpXS5fZ3JvdXBOYW1lID09PSBncm91cE5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZygncmVtb3ZpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIGl0IGFuZCBzaG9ydGVuIHRoZSBhcnJheSB3ZSdyZSBsb29waW5nIHRocm91Z2hcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICBpLS07XG4gICAgICAgICAgICAgICAgICAgIGxlbi0tO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLy8gUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcbiAgICAvLyByZWdpc3RlcmVkIGNhbGxiYWNrcy5cbiAgICBwcm90b3R5cGUub2ZmID0gZnVuY3Rpb24gKGV2ZW50LCBmbikge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3NbZXZlbnRdLFxuICAgICAgICAgICAgaTtcblxuICAgICAgICBpZiAoIWNhbGxiYWNrcykgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgLy8gcmVtb3ZlIGFsbCBoYW5kbGVyc1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2V2ZW50XTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcbiAgICAgICAgaSA9IGNhbGxiYWNrcy5pbmRleE9mKGZuKTtcbiAgICAgICAgaWYgKGkgIT09IC0xKSB7XG4gICAgICAgICAgICBjYWxsYmFja3Muc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5jYWxsYmFja3NbZXZlbnRdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLy8gRW1pdCBgZXZlbnRgIHdpdGggdGhlIGdpdmVuIGFyZ3MuXG4gICAgLy8gYWxzbyBjYWxscyBhbnkgYCpgIGhhbmRsZXJzXG4gICAgcHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSksXG4gICAgICAgICAgICBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF0sXG4gICAgICAgICAgICBzcGVjaWFsQ2FsbGJhY2tzID0gdGhpcy5nZXRXaWxkY2FyZENhbGxiYWNrcyhldmVudCksXG4gICAgICAgICAgICBpLFxuICAgICAgICAgICAgbGVuLFxuICAgICAgICAgICAgaXRlbSxcbiAgICAgICAgICAgIGxpc3RlbmVycztcblxuICAgICAgICBpZiAoY2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBsaXN0ZW5lcnMgPSBjYWxsYmFja3Muc2xpY2UoKTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgICAgIGlmICghbGlzdGVuZXJzW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3BlY2lhbENhbGxiYWNrcykge1xuICAgICAgICAgICAgbGVuID0gc3BlY2lhbENhbGxiYWNrcy5sZW5ndGg7XG4gICAgICAgICAgICBsaXN0ZW5lcnMgPSBzcGVjaWFsQ2FsbGJhY2tzLnNsaWNlKCk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWxpc3RlbmVyc1tpXSkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIFtldmVudF0uY29uY2F0KGFyZ3MpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvLyBIZWxwZXIgZm9yIGZvciBmaW5kaW5nIHNwZWNpYWwgd2lsZGNhcmQgZXZlbnQgaGFuZGxlcnMgdGhhdCBtYXRjaCB0aGUgZXZlbnRcbiAgICBwcm90b3R5cGUuZ2V0V2lsZGNhcmRDYWxsYmFja3MgPSBmdW5jdGlvbiAoZXZlbnROYW1lKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XG4gICAgICAgIHZhciBpdGVtLFxuICAgICAgICAgICAgc3BsaXQsXG4gICAgICAgICAgICByZXN1bHQgPSBbXTtcblxuICAgICAgICBmb3IgKGl0ZW0gaW4gdGhpcy5jYWxsYmFja3MpIHtcbiAgICAgICAgICAgIHNwbGl0ID0gaXRlbS5zcGxpdCgnKicpO1xuICAgICAgICAgICAgaWYgKGl0ZW0gPT09ICcqJyB8fCAoc3BsaXQubGVuZ3RoID09PSAyICYmIGV2ZW50TmFtZS5zbGljZSgwLCBzcGxpdFswXS5sZW5ndGgpID09PSBzcGxpdFswXSkpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQuY29uY2F0KHRoaXMuY2FsbGJhY2tzW2l0ZW1dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbn07XG5cbldpbGRFbWl0dGVyLm1peGluKFdpbGRFbWl0dGVyKTtcbiIsIi8qIVxuICogRXZlbnRFbWl0dGVyIHY1LjIuOSAtIGdpdC5pby9lZVxuICogVW5saWNlbnNlIC0gaHR0cDovL3VubGljZW5zZS5vcmcvXG4gKiBPbGl2ZXIgQ2FsZHdlbGwgLSBodHRwczovL29saS5tZS51ay9cbiAqIEBwcmVzZXJ2ZVxuICovXG5cbjsoZnVuY3Rpb24gKGV4cG9ydHMpIHtcbiAgICAndXNlIHN0cmljdCc7XG5cbiAgICAvKipcbiAgICAgKiBDbGFzcyBmb3IgbWFuYWdpbmcgZXZlbnRzLlxuICAgICAqIENhbiBiZSBleHRlbmRlZCB0byBwcm92aWRlIGV2ZW50IGZ1bmN0aW9uYWxpdHkgaW4gb3RoZXIgY2xhc3Nlcy5cbiAgICAgKlxuICAgICAqIEBjbGFzcyBFdmVudEVtaXR0ZXIgTWFuYWdlcyBldmVudCByZWdpc3RlcmluZyBhbmQgZW1pdHRpbmcuXG4gICAgICovXG4gICAgZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge31cblxuICAgIC8vIFNob3J0Y3V0cyB0byBpbXByb3ZlIHNwZWVkIGFuZCBzaXplXG4gICAgdmFyIHByb3RvID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZTtcbiAgICB2YXIgb3JpZ2luYWxHbG9iYWxWYWx1ZSA9IGV4cG9ydHMuRXZlbnRFbWl0dGVyO1xuXG4gICAgLyoqXG4gICAgICogRmluZHMgdGhlIGluZGV4IG9mIHRoZSBsaXN0ZW5lciBmb3IgdGhlIGV2ZW50IGluIGl0cyBzdG9yYWdlIGFycmF5LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBsaXN0ZW5lcnMgQXJyYXkgb2YgbGlzdGVuZXJzIHRvIHNlYXJjaCB0aHJvdWdoLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byBsb29rIGZvci5cbiAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9IEluZGV4IG9mIHRoZSBzcGVjaWZpZWQgbGlzdGVuZXIsIC0xIGlmIG5vdCBmb3VuZFxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluZGV4T2ZMaXN0ZW5lcihsaXN0ZW5lcnMsIGxpc3RlbmVyKSB7XG4gICAgICAgIHZhciBpID0gbGlzdGVuZXJzLmxlbmd0aDtcbiAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVyc1tpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBhIG1ldGhvZCB3aGlsZSBrZWVwaW5nIHRoZSBjb250ZXh0IGNvcnJlY3QsIHRvIGFsbG93IGZvciBvdmVyd3JpdGluZyBvZiB0YXJnZXQgbWV0aG9kLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgVGhlIG5hbWUgb2YgdGhlIHRhcmdldCBtZXRob2QuXG4gICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBhbGlhc2VkIG1ldGhvZFxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFsaWFzKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIGFsaWFzQ2xvc3VyZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW25hbWVdLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgbGlzdGVuZXIgYXJyYXkgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogV2lsbCBpbml0aWFsaXNlIHRoZSBldmVudCBvYmplY3QgYW5kIGxpc3RlbmVyIGFycmF5cyBpZiByZXF1aXJlZC5cbiAgICAgKiBXaWxsIHJldHVybiBhbiBvYmplY3QgaWYgeW91IHVzZSBhIHJlZ2V4IHNlYXJjaC4gVGhlIG9iamVjdCBjb250YWlucyBrZXlzIGZvciBlYWNoIG1hdGNoZWQgZXZlbnQuIFNvIC9iYVtyel0vIG1pZ2h0IHJldHVybiBhbiBvYmplY3QgY29udGFpbmluZyBiYXIgYW5kIGJhei4gQnV0IG9ubHkgaWYgeW91IGhhdmUgZWl0aGVyIGRlZmluZWQgdGhlbSB3aXRoIGRlZmluZUV2ZW50IG9yIGFkZGVkIHNvbWUgbGlzdGVuZXJzIHRvIHRoZW0uXG4gICAgICogRWFjaCBwcm9wZXJ0eSBpbiB0aGUgb2JqZWN0IHJlc3BvbnNlIGlzIGFuIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJldHVybiB0aGUgbGlzdGVuZXJzIGZyb20uXG4gICAgICogQHJldHVybiB7RnVuY3Rpb25bXXxPYmplY3R9IEFsbCBsaXN0ZW5lciBmdW5jdGlvbnMgZm9yIHRoZSBldmVudC5cbiAgICAgKi9cbiAgICBwcm90by5nZXRMaXN0ZW5lcnMgPSBmdW5jdGlvbiBnZXRMaXN0ZW5lcnMoZXZ0KSB7XG4gICAgICAgIHZhciBldmVudHMgPSB0aGlzLl9nZXRFdmVudHMoKTtcbiAgICAgICAgdmFyIHJlc3BvbnNlO1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIC8vIFJldHVybiBhIGNvbmNhdGVuYXRlZCBhcnJheSBvZiBhbGwgbWF0Y2hpbmcgZXZlbnRzIGlmXG4gICAgICAgIC8vIHRoZSBzZWxlY3RvciBpcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAgICAgICAgaWYgKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSB7fTtcbiAgICAgICAgICAgIGZvciAoa2V5IGluIGV2ZW50cykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBldnQudGVzdChrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlW2tleV0gPSBldmVudHNba2V5XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IGV2ZW50c1tldnRdIHx8IChldmVudHNbZXZ0XSA9IFtdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVGFrZXMgYSBsaXN0IG9mIGxpc3RlbmVyIG9iamVjdHMgYW5kIGZsYXR0ZW5zIGl0IGludG8gYSBsaXN0IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0W119IGxpc3RlbmVycyBSYXcgbGlzdGVuZXIgb2JqZWN0cy5cbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbltdfSBKdXN0IHRoZSBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICovXG4gICAgcHJvdG8uZmxhdHRlbkxpc3RlbmVycyA9IGZ1bmN0aW9uIGZsYXR0ZW5MaXN0ZW5lcnMobGlzdGVuZXJzKSB7XG4gICAgICAgIHZhciBmbGF0TGlzdGVuZXJzID0gW107XG4gICAgICAgIHZhciBpO1xuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsaXN0ZW5lcnMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGZsYXRMaXN0ZW5lcnMucHVzaChsaXN0ZW5lcnNbaV0ubGlzdGVuZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZsYXRMaXN0ZW5lcnM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIHJlcXVlc3RlZCBsaXN0ZW5lcnMgdmlhIGdldExpc3RlbmVycyBidXQgd2lsbCBhbHdheXMgcmV0dXJuIHRoZSByZXN1bHRzIGluc2lkZSBhbiBvYmplY3QuIFRoaXMgaXMgbWFpbmx5IGZvciBpbnRlcm5hbCB1c2UgYnV0IG90aGVycyBtYXkgZmluZCBpdCB1c2VmdWwuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZXR1cm4gdGhlIGxpc3RlbmVycyBmcm9tLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQWxsIGxpc3RlbmVyIGZ1bmN0aW9ucyBmb3IgYW4gZXZlbnQgaW4gYW4gb2JqZWN0LlxuICAgICAqL1xuICAgIHByb3RvLmdldExpc3RlbmVyc0FzT2JqZWN0ID0gZnVuY3Rpb24gZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVycyhldnQpO1xuICAgICAgICB2YXIgcmVzcG9uc2U7XG5cbiAgICAgICAgaWYgKGxpc3RlbmVycyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgICByZXNwb25zZSA9IHt9O1xuICAgICAgICAgICAgcmVzcG9uc2VbZXZ0XSA9IGxpc3RlbmVycztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXNwb25zZSB8fCBsaXN0ZW5lcnM7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIGlzVmFsaWRMaXN0ZW5lciAobGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJyB8fCBsaXN0ZW5lciBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lciAmJiB0eXBlb2YgbGlzdGVuZXIgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNWYWxpZExpc3RlbmVyKGxpc3RlbmVyLmxpc3RlbmVyKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgbGlzdGVuZXIgZnVuY3Rpb24gdG8gdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICAgKiBUaGUgbGlzdGVuZXIgd2lsbCBub3QgYmUgYWRkZWQgaWYgaXQgaXMgYSBkdXBsaWNhdGUuXG4gICAgICogSWYgdGhlIGxpc3RlbmVyIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBpdCBpcyBjYWxsZWQuXG4gICAgICogSWYgeW91IHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gYXMgdGhlIGV2ZW50IG5hbWUgdGhlbiB0aGUgbGlzdGVuZXIgd2lsbCBiZSBhZGRlZCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBhdHRhY2ggdGhlIGxpc3RlbmVyIHRvLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIE1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiB0aGUgZXZlbnQgaXMgZW1pdHRlZC4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSB0aGVuIGl0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBjYWxsaW5nLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gYWRkTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoIWlzVmFsaWRMaXN0ZW5lcihsaXN0ZW5lcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KTtcbiAgICAgICAgdmFyIGxpc3RlbmVySXNXcmFwcGVkID0gdHlwZW9mIGxpc3RlbmVyID09PSAnb2JqZWN0JztcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMuaGFzT3duUHJvcGVydHkoa2V5KSAmJiBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzW2tleV0sIGxpc3RlbmVyKSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcnNba2V5XS5wdXNoKGxpc3RlbmVySXNXcmFwcGVkID8gbGlzdGVuZXIgOiB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyOiBsaXN0ZW5lcixcbiAgICAgICAgICAgICAgICAgICAgb25jZTogZmFsc2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBhZGRMaXN0ZW5lclxuICAgICAqL1xuICAgIHByb3RvLm9uID0gYWxpYXMoJ2FkZExpc3RlbmVyJyk7XG5cbiAgICAvKipcbiAgICAgKiBTZW1pLWFsaWFzIG9mIGFkZExpc3RlbmVyLiBJdCB3aWxsIGFkZCBhIGxpc3RlbmVyIHRoYXQgd2lsbCBiZVxuICAgICAqIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZCBhZnRlciBpdHMgZmlyc3QgZXhlY3V0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRPbmNlTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRPbmNlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lcikge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRMaXN0ZW5lcihldnQsIHtcbiAgICAgICAgICAgIGxpc3RlbmVyOiBsaXN0ZW5lcixcbiAgICAgICAgICAgIG9uY2U6IHRydWVcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEFsaWFzIG9mIGFkZE9uY2VMaXN0ZW5lci5cbiAgICAgKi9cbiAgICBwcm90by5vbmNlID0gYWxpYXMoJ2FkZE9uY2VMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogRGVmaW5lcyBhbiBldmVudCBuYW1lLiBUaGlzIGlzIHJlcXVpcmVkIGlmIHlvdSB3YW50IHRvIHVzZSBhIHJlZ2V4IHRvIGFkZCBhIGxpc3RlbmVyIHRvIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBJZiB5b3UgZG9uJ3QgZG8gdGhpcyB0aGVuIGhvdyBkbyB5b3UgZXhwZWN0IGl0IHRvIGtub3cgd2hhdCBldmVudCB0byBhZGQgdG8/IFNob3VsZCBpdCBqdXN0IGFkZCB0byBldmVyeSBwb3NzaWJsZSBtYXRjaCBmb3IgYSByZWdleD8gTm8uIFRoYXQgaXMgc2NhcnkgYW5kIGJhZC5cbiAgICAgKiBZb3UgbmVlZCB0byB0ZWxsIGl0IHdoYXQgZXZlbnQgbmFtZXMgc2hvdWxkIGJlIG1hdGNoZWQgYnkgYSByZWdleC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gY3JlYXRlLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmRlZmluZUV2ZW50ID0gZnVuY3Rpb24gZGVmaW5lRXZlbnQoZXZ0KSB7XG4gICAgICAgIHRoaXMuZ2V0TGlzdGVuZXJzKGV2dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBVc2VzIGRlZmluZUV2ZW50IHRvIGRlZmluZSBtdWx0aXBsZSBldmVudHMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ1tdfSBldnRzIEFuIGFycmF5IG9mIGV2ZW50IG5hbWVzIHRvIGRlZmluZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5kZWZpbmVFdmVudHMgPSBmdW5jdGlvbiBkZWZpbmVFdmVudHMoZXZ0cykge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGV2dHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHRoaXMuZGVmaW5lRXZlbnQoZXZ0c1tpXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYSBsaXN0ZW5lciBmdW5jdGlvbiBmcm9tIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogV2hlbiBwYXNzZWQgYSByZWd1bGFyIGV4cHJlc3Npb24gYXMgdGhlIGV2ZW50IG5hbWUsIGl0IHdpbGwgcmVtb3ZlIHRoZSBsaXN0ZW5lciBmcm9tIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gcmVtb3ZlIGZyb20gdGhlIGV2ZW50LlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnNBc09iamVjdChldnQpO1xuICAgICAgICB2YXIgaW5kZXg7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBpbmRleCA9IGluZGV4T2ZMaXN0ZW5lcihsaXN0ZW5lcnNba2V5XSwgbGlzdGVuZXIpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnNba2V5XS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiByZW1vdmVMaXN0ZW5lclxuICAgICAqL1xuICAgIHByb3RvLm9mZiA9IGFsaWFzKCdyZW1vdmVMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogQWRkcyBsaXN0ZW5lcnMgaW4gYnVsayB1c2luZyB0aGUgbWFuaXB1bGF0ZUxpc3RlbmVycyBtZXRob2QuXG4gICAgICogSWYgeW91IHBhc3MgYW4gb2JqZWN0IGFzIHRoZSBmaXJzdCBhcmd1bWVudCB5b3UgY2FuIGFkZCB0byBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gVGhlIG9iamVjdCBzaG91bGQgY29udGFpbiBrZXkgdmFsdWUgcGFpcnMgb2YgZXZlbnRzIGFuZCBsaXN0ZW5lcnMgb3IgbGlzdGVuZXIgYXJyYXlzLiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgYWRkZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gYWRkIHRoZSBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqIFllYWgsIHRoaXMgZnVuY3Rpb24gZG9lcyBxdWl0ZSBhIGJpdC4gVGhhdCdzIHByb2JhYmx5IGEgYmFkIHRoaW5nLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIGFkZCB0byBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byBhZGQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkTGlzdGVuZXJzID0gZnVuY3Rpb24gYWRkTGlzdGVuZXJzKGV2dCwgbGlzdGVuZXJzKSB7XG4gICAgICAgIC8vIFBhc3MgdGhyb3VnaCB0byBtYW5pcHVsYXRlTGlzdGVuZXJzXG4gICAgICAgIHJldHVybiB0aGlzLm1hbmlwdWxhdGVMaXN0ZW5lcnMoZmFsc2UsIGV2dCwgbGlzdGVuZXJzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBsaXN0ZW5lcnMgaW4gYnVsayB1c2luZyB0aGUgbWFuaXB1bGF0ZUxpc3RlbmVycyBtZXRob2QuXG4gICAgICogSWYgeW91IHBhc3MgYW4gb2JqZWN0IGFzIHRoZSBmaXJzdCBhcmd1bWVudCB5b3UgY2FuIHJlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLiBUaGUgb2JqZWN0IHNob3VsZCBjb250YWluIGtleSB2YWx1ZSBwYWlycyBvZiBldmVudHMgYW5kIGxpc3RlbmVycyBvciBsaXN0ZW5lciBhcnJheXMuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIHJlbW92ZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgaXQgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gcmVtb3ZlIHRoZSBsaXN0ZW5lcnMgZnJvbSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R8UmVnRXhwfSBldnQgQW4gZXZlbnQgbmFtZSBpZiB5b3Ugd2lsbCBwYXNzIGFuIGFycmF5IG9mIGxpc3RlbmVycyBuZXh0LiBBbiBvYmplY3QgaWYgeW91IHdpc2ggdG8gcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gcmVtb3ZlLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUxpc3RlbmVycyA9IGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVycyhldnQsIGxpc3RlbmVycykge1xuICAgICAgICAvLyBQYXNzIHRocm91Z2ggdG8gbWFuaXB1bGF0ZUxpc3RlbmVyc1xuICAgICAgICByZXR1cm4gdGhpcy5tYW5pcHVsYXRlTGlzdGVuZXJzKHRydWUsIGV2dCwgbGlzdGVuZXJzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRWRpdHMgbGlzdGVuZXJzIGluIGJ1bGsuIFRoZSBhZGRMaXN0ZW5lcnMgYW5kIHJlbW92ZUxpc3RlbmVycyBtZXRob2RzIGJvdGggdXNlIHRoaXMgdG8gZG8gdGhlaXIgam9iLiBZb3Ugc2hvdWxkIHJlYWxseSB1c2UgdGhvc2UgaW5zdGVhZCwgdGhpcyBpcyBhIGxpdHRsZSBsb3dlciBsZXZlbC5cbiAgICAgKiBUaGUgZmlyc3QgYXJndW1lbnQgd2lsbCBkZXRlcm1pbmUgaWYgdGhlIGxpc3RlbmVycyBhcmUgcmVtb3ZlZCAodHJ1ZSkgb3IgYWRkZWQgKGZhbHNlKS5cbiAgICAgKiBJZiB5b3UgcGFzcyBhbiBvYmplY3QgYXMgdGhlIHNlY29uZCBhcmd1bWVudCB5b3UgY2FuIGFkZC9yZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gVGhlIG9iamVjdCBzaG91bGQgY29udGFpbiBrZXkgdmFsdWUgcGFpcnMgb2YgZXZlbnRzIGFuZCBsaXN0ZW5lcnMgb3IgbGlzdGVuZXIgYXJyYXlzLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSBhZGRlZC9yZW1vdmVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIG1hbmlwdWxhdGUgdGhlIGxpc3RlbmVycyBvZiBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlbW92ZSBUcnVlIGlmIHlvdSB3YW50IHRvIHJlbW92ZSBsaXN0ZW5lcnMsIGZhbHNlIGlmIHlvdSB3YW50IHRvIGFkZC5cbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R8UmVnRXhwfSBldnQgQW4gZXZlbnQgbmFtZSBpZiB5b3Ugd2lsbCBwYXNzIGFuIGFycmF5IG9mIGxpc3RlbmVycyBuZXh0LiBBbiBvYmplY3QgaWYgeW91IHdpc2ggdG8gYWRkL3JlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIGFkZC9yZW1vdmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ubWFuaXB1bGF0ZUxpc3RlbmVycyA9IGZ1bmN0aW9uIG1hbmlwdWxhdGVMaXN0ZW5lcnMocmVtb3ZlLCBldnQsIGxpc3RlbmVycykge1xuICAgICAgICB2YXIgaTtcbiAgICAgICAgdmFyIHZhbHVlO1xuICAgICAgICB2YXIgc2luZ2xlID0gcmVtb3ZlID8gdGhpcy5yZW1vdmVMaXN0ZW5lciA6IHRoaXMuYWRkTGlzdGVuZXI7XG4gICAgICAgIHZhciBtdWx0aXBsZSA9IHJlbW92ZSA/IHRoaXMucmVtb3ZlTGlzdGVuZXJzIDogdGhpcy5hZGRMaXN0ZW5lcnM7XG5cbiAgICAgICAgLy8gSWYgZXZ0IGlzIGFuIG9iamVjdCB0aGVuIHBhc3MgZWFjaCBvZiBpdHMgcHJvcGVydGllcyB0byB0aGlzIG1ldGhvZFxuICAgICAgICBpZiAodHlwZW9mIGV2dCA9PT0gJ29iamVjdCcgJiYgIShldnQgaW5zdGFuY2VvZiBSZWdFeHApKSB7XG4gICAgICAgICAgICBmb3IgKGkgaW4gZXZ0KSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2dC5oYXNPd25Qcm9wZXJ0eShpKSAmJiAodmFsdWUgPSBldnRbaV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFBhc3MgdGhlIHNpbmdsZSBsaXN0ZW5lciBzdHJhaWdodCB0aHJvdWdoIHRvIHRoZSBzaW5ndWxhciBtZXRob2RcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2luZ2xlLmNhbGwodGhpcywgaSwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlIHBhc3MgYmFjayB0byB0aGUgbXVsdGlwbGUgZnVuY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIG11bHRpcGxlLmNhbGwodGhpcywgaSwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gU28gZXZ0IG11c3QgYmUgYSBzdHJpbmdcbiAgICAgICAgICAgIC8vIEFuZCBsaXN0ZW5lcnMgbXVzdCBiZSBhbiBhcnJheSBvZiBsaXN0ZW5lcnNcbiAgICAgICAgICAgIC8vIExvb3Agb3ZlciBpdCBhbmQgcGFzcyBlYWNoIG9uZSB0byB0aGUgbXVsdGlwbGUgbWV0aG9kXG4gICAgICAgICAgICBpID0gbGlzdGVuZXJzLmxlbmd0aDtcbiAgICAgICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgICAgICBzaW5nbGUuY2FsbCh0aGlzLCBldnQsIGxpc3RlbmVyc1tpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbGwgbGlzdGVuZXJzIGZyb20gYSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogSWYgeW91IGRvIG5vdCBzcGVjaWZ5IGFuIGV2ZW50IHRoZW4gYWxsIGxpc3RlbmVycyB3aWxsIGJlIHJlbW92ZWQuXG4gICAgICogVGhhdCBtZWFucyBldmVyeSBldmVudCB3aWxsIGJlIGVtcHRpZWQuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgYSByZWdleCB0byByZW1vdmUgYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBbZXZ0XSBPcHRpb25hbCBuYW1lIG9mIHRoZSBldmVudCB0byByZW1vdmUgYWxsIGxpc3RlbmVycyBmb3IuIFdpbGwgcmVtb3ZlIGZyb20gZXZlcnkgZXZlbnQgaWYgbm90IHBhc3NlZC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVFdmVudCA9IGZ1bmN0aW9uIHJlbW92ZUV2ZW50KGV2dCkge1xuICAgICAgICB2YXIgdHlwZSA9IHR5cGVvZiBldnQ7XG4gICAgICAgIHZhciBldmVudHMgPSB0aGlzLl9nZXRFdmVudHMoKTtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICAvLyBSZW1vdmUgZGlmZmVyZW50IHRoaW5ncyBkZXBlbmRpbmcgb24gdGhlIHN0YXRlIG9mIGV2dFxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50XG4gICAgICAgICAgICBkZWxldGUgZXZlbnRzW2V2dF07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGV2ZW50cyBtYXRjaGluZyB0aGUgcmVnZXguXG4gICAgICAgICAgICBmb3IgKGtleSBpbiBldmVudHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnRzLmhhc093blByb3BlcnR5KGtleSkgJiYgZXZ0LnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgZXZlbnRzW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBsaXN0ZW5lcnMgaW4gYWxsIGV2ZW50c1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50cztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiByZW1vdmVFdmVudC5cbiAgICAgKlxuICAgICAqIEFkZGVkIHRvIG1pcnJvciB0aGUgbm9kZSBBUEkuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlQWxsTGlzdGVuZXJzID0gYWxpYXMoJ3JlbW92ZUV2ZW50Jyk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBhbiBldmVudCBvZiB5b3VyIGNob2ljZS5cbiAgICAgKiBXaGVuIGVtaXR0ZWQsIGV2ZXJ5IGxpc3RlbmVyIGF0dGFjaGVkIHRvIHRoYXQgZXZlbnQgd2lsbCBiZSBleGVjdXRlZC5cbiAgICAgKiBJZiB5b3UgcGFzcyB0aGUgb3B0aW9uYWwgYXJndW1lbnQgYXJyYXkgdGhlbiB0aG9zZSBhcmd1bWVudHMgd2lsbCBiZSBwYXNzZWQgdG8gZXZlcnkgbGlzdGVuZXIgdXBvbiBleGVjdXRpb24uXG4gICAgICogQmVjYXVzZSBpdCB1c2VzIGBhcHBseWAsIHlvdXIgYXJyYXkgb2YgYXJndW1lbnRzIHdpbGwgYmUgcGFzc2VkIGFzIGlmIHlvdSB3cm90ZSB0aGVtIG91dCBzZXBhcmF0ZWx5LlxuICAgICAqIFNvIHRoZXkgd2lsbCBub3QgYXJyaXZlIHdpdGhpbiB0aGUgYXJyYXkgb24gdGhlIG90aGVyIHNpZGUsIHRoZXkgd2lsbCBiZSBzZXBhcmF0ZS5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBlbWl0IHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGVtaXQgYW5kIGV4ZWN1dGUgbGlzdGVuZXJzIGZvci5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBbYXJnc10gT3B0aW9uYWwgYXJyYXkgb2YgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byBlYWNoIGxpc3RlbmVyLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmVtaXRFdmVudCA9IGZ1bmN0aW9uIGVtaXRFdmVudChldnQsIGFyZ3MpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVyc01hcCA9IHRoaXMuZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KTtcbiAgICAgICAgdmFyIGxpc3RlbmVycztcbiAgICAgICAgdmFyIGxpc3RlbmVyO1xuICAgICAgICB2YXIgaTtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgdmFyIHJlc3BvbnNlO1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVyc01hcCkge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVyc01hcC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzID0gbGlzdGVuZXJzTWFwW2tleV0uc2xpY2UoMCk7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBsaXN0ZW5lciByZXR1cm5zIHRydWUgdGhlbiBpdCBzaGFsbCBiZSByZW1vdmVkIGZyb20gdGhlIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSBmdW5jdGlvbiBpcyBleGVjdXRlZCBlaXRoZXIgd2l0aCBhIGJhc2ljIGNhbGwgb3IgYW4gYXBwbHkgaWYgdGhlcmUgaXMgYW4gYXJncyBhcnJheVxuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lciA9IGxpc3RlbmVyc1tpXTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAobGlzdGVuZXIub25jZSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyLmxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlID0gbGlzdGVuZXIubGlzdGVuZXIuYXBwbHkodGhpcywgYXJncyB8fCBbXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlID09PSB0aGlzLl9nZXRPbmNlUmV0dXJuVmFsdWUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcihldnQsIGxpc3RlbmVyLmxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBlbWl0RXZlbnRcbiAgICAgKi9cbiAgICBwcm90by50cmlnZ2VyID0gYWxpYXMoJ2VtaXRFdmVudCcpO1xuXG4gICAgLyoqXG4gICAgICogU3VidGx5IGRpZmZlcmVudCBmcm9tIGVtaXRFdmVudCBpbiB0aGF0IGl0IHdpbGwgcGFzcyBpdHMgYXJndW1lbnRzIG9uIHRvIHRoZSBsaXN0ZW5lcnMsIGFzIG9wcG9zZWQgdG8gdGFraW5nIGEgc2luZ2xlIGFycmF5IG9mIGFyZ3VtZW50cyB0byBwYXNzIG9uLlxuICAgICAqIEFzIHdpdGggZW1pdEV2ZW50LCB5b3UgY2FuIHBhc3MgYSByZWdleCBpbiBwbGFjZSBvZiB0aGUgZXZlbnQgbmFtZSB0byBlbWl0IHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGVtaXQgYW5kIGV4ZWN1dGUgbGlzdGVuZXJzIGZvci5cbiAgICAgKiBAcGFyYW0gey4uLip9IE9wdGlvbmFsIGFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byBlYWNoIGxpc3RlbmVyLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmVtaXQgPSBmdW5jdGlvbiBlbWl0KGV2dCkge1xuICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVtaXRFdmVudChldnQsIGFyZ3MpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGFnYWluc3Qgd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLiBJZiBhXG4gICAgICogbGlzdGVuZXJzIHJldHVybiB2YWx1ZSBtYXRjaGVzIHRoZSBvbmUgc2V0IGhlcmUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWRcbiAgICAgKiBhZnRlciBleGVjdXRpb24uIFRoaXMgdmFsdWUgZGVmYXVsdHMgdG8gdHJ1ZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIG5ldyB2YWx1ZSB0byBjaGVjayBmb3Igd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLnNldE9uY2VSZXR1cm5WYWx1ZSA9IGZ1bmN0aW9uIHNldE9uY2VSZXR1cm5WYWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLl9vbmNlUmV0dXJuVmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZldGNoZXMgdGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgYWdhaW5zdCB3aGVuIGV4ZWN1dGluZyBsaXN0ZW5lcnMuIElmXG4gICAgICogdGhlIGxpc3RlbmVycyByZXR1cm4gdmFsdWUgbWF0Y2hlcyB0aGlzIG9uZSB0aGVuIGl0IHNob3VsZCBiZSByZW1vdmVkXG4gICAgICogYXV0b21hdGljYWxseS4gSXQgd2lsbCByZXR1cm4gdHJ1ZSBieSBkZWZhdWx0LlxuICAgICAqXG4gICAgICogQHJldHVybiB7KnxCb29sZWFufSBUaGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBmb3Igb3IgdGhlIGRlZmF1bHQsIHRydWUuXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgcHJvdG8uX2dldE9uY2VSZXR1cm5WYWx1ZSA9IGZ1bmN0aW9uIF9nZXRPbmNlUmV0dXJuVmFsdWUoKSB7XG4gICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KCdfb25jZVJldHVyblZhbHVlJykpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbmNlUmV0dXJuVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSBldmVudHMgb2JqZWN0IGFuZCBjcmVhdGVzIG9uZSBpZiByZXF1aXJlZC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gVGhlIGV2ZW50cyBzdG9yYWdlIG9iamVjdC5cbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBwcm90by5fZ2V0RXZlbnRzID0gZnVuY3Rpb24gX2dldEV2ZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50cyB8fCAodGhpcy5fZXZlbnRzID0ge30pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZXZlcnRzIHRoZSBnbG9iYWwge0BsaW5rIEV2ZW50RW1pdHRlcn0gdG8gaXRzIHByZXZpb3VzIHZhbHVlIGFuZCByZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoaXMgdmVyc2lvbi5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBOb24gY29uZmxpY3RpbmcgRXZlbnRFbWl0dGVyIGNsYXNzLlxuICAgICAqL1xuICAgIEV2ZW50RW1pdHRlci5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gbm9Db25mbGljdCgpIHtcbiAgICAgICAgZXhwb3J0cy5FdmVudEVtaXR0ZXIgPSBvcmlnaW5hbEdsb2JhbFZhbHVlO1xuICAgICAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuICAgIH07XG5cbiAgICAvLyBFeHBvc2UgdGhlIGNsYXNzIGVpdGhlciB2aWEgQU1ELCBDb21tb25KUyBvciB0aGUgZ2xvYmFsIG9iamVjdFxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBFdmVudEVtaXR0ZXI7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cyl7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZXhwb3J0cy5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG4gICAgfVxufSh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHRoaXMgfHwge30pKTtcbiIsIm1vZHVsZS5leHBvcnRzPXtcbiAgICBcImF1dGhvclwiOiBcIk9wZW5WaWR1XCIsIFxuICAgIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICAgICAgXCJmcmVlaWNlXCI6IFwiMi4yLjJcIiwgXG4gICAgICAgIFwiaGFya1wiOiBcIjEuMi4zXCIsIFxuICAgICAgICBcImpzbmxvZ1wiOiBcIjIuMzAuMFwiLCBcbiAgICAgICAgXCJtaW1lXCI6IFwiMy4wLjBcIiwgXG4gICAgICAgIFwicGxhdGZvcm1cIjogXCIxLjMuNlwiLCBcbiAgICAgICAgXCJzZW12ZXJcIjogXCI3LjMuOFwiLCBcbiAgICAgICAgXCJ1dWlkXCI6IFwiOS4wLjBcIiwgXG4gICAgICAgIFwid29sZnk4Ny1ldmVudGVtaXR0ZXJcIjogXCI1LjIuOVwiLCBcbiAgICAgICAgXCJldmVudHNcIjogXCIzLjMuMFwiLCBcbiAgICAgICAgXCJpbmhlcml0c1wiOiBcIjIuMC40XCJcbiAgICB9LCBcbiAgICBcImRlc2NyaXB0aW9uXCI6IFwiT3BlblZpZHUgQnJvd3NlclwiLCBcbiAgICBcImRldkRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiQHR5cGVzL25vZGVcIjogXCIxOC4xMS45XCIsIFxuICAgICAgICBcIkB0eXBlcy9wbGF0Zm9ybVwiOiBcIjEuMy40XCIsIFxuICAgICAgICBcImJyb3dzZXJpZnlcIjogXCIxNy4wLjBcIiwgXG4gICAgICAgIFwiZ3J1bnRcIjogXCIxLjUuM1wiLCBcbiAgICAgICAgXCJncnVudC1jbGlcIjogXCIxLjQuM1wiLCBcbiAgICAgICAgXCJncnVudC1jb250cmliLWNvcHlcIjogXCIxLjAuMFwiLCBcbiAgICAgICAgXCJncnVudC1jb250cmliLXNhc3NcIjogXCIyLjAuMFwiLCBcbiAgICAgICAgXCJncnVudC1jb250cmliLXVnbGlmeVwiOiBcIjUuMi4yXCIsIFxuICAgICAgICBcImdydW50LWNvbnRyaWItd2F0Y2hcIjogXCIxLjEuMFwiLCBcbiAgICAgICAgXCJncnVudC1wb3N0Y3NzXCI6IFwiMC45LjBcIiwgXG4gICAgICAgIFwiZ3J1bnQtc3RyaW5nLXJlcGxhY2VcIjogXCIxLjMuM1wiLCBcbiAgICAgICAgXCJncnVudC10c1wiOiBcIjYuMC4wLWJldGEuMjJcIiwgXG4gICAgICAgIFwidGVyc2VyXCI6IFwiNS4xNS4xXCIsIFxuICAgICAgICBcInRzaWZ5XCI6IFwiNS4wLjRcIiwgXG4gICAgICAgIFwidHNsaW50XCI6IFwiNi4xLjNcIiwgXG4gICAgICAgIFwidHlwZWRvY1wiOiBcIjAuMjMuMjFcIiwgXG4gICAgICAgIFwidHlwZXNjcmlwdFwiOiBcIjQuOS4zXCJcbiAgICB9LCBcbiAgICBcImxpY2Vuc2VcIjogXCJBcGFjaGUtMi4wXCIsIFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLCBcbiAgICBcIm5hbWVcIjogXCJvcGVudmlkdS1icm93c2VyXCIsIFxuICAgIFwicmVwb3NpdG9yeVwiOiB7XG4gICAgICAgIFwidHlwZVwiOiBcImdpdFwiLCBcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LCBcbiAgICBcInNjcmlwdHNcIjoge1xuICAgICAgICBcImJyb3dzZXJpZnlcIjogXCJWRVJTSU9OPSR7VkVSU0lPTjotZGV2fTsgbWtkaXIgLXAgc3RhdGljL2pzLyAmJiBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLCBcbiAgICAgICAgXCJicm93c2VyaWZ5LXByb2RcIjogXCJWRVJTSU9OPSR7VkVSU0lPTjotZGV2fTsgbWtkaXIgLXAgc3RhdGljL2pzLyAmJiBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy90ZXJzZXIvYmluL3RlcnNlciAtLXNvdXJjZS1tYXAgY29udGVudD1pbmxpbmUgLS1vdXRwdXQgLi4vc3RhdGljL2pzL29wZW52aWR1LWJyb3dzZXItJFZFUlNJT04ubWluLmpzXCIsIFxuICAgICAgICBcImJ1aWxkXCI6IFwiY2Qgc3JjL09wZW5WaWR1ICYmIC4vLi4vLi4vbm9kZV9tb2R1bGVzL3R5cGVzY3JpcHQvYmluL3RzYyAmJiBjZCAuLi8uLiAmJiAuL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgLS1kZWNsYXJhdGlvbiBzcmMvaW5kZXgudHMgLS1vdXREaXIgLi9saWIgLS1zb3VyY2VNYXAgLS10YXJnZXQgZXM1IC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdCAmJiBybSAtcmYgLi90czQuNCAmJiBta2RpciAtcCAuL3RzNC40L2xpYiAmJiBjcCAtciAuL2xpYiAuL3RzNC40ICYmIGZpbmQgLi90czQuNC9saWIgLXR5cGUgZiAhIC1pbmFtZSAnKi5kLnRzJyAtZGVsZXRlICYmIC4vY29uZmlnL3JlcGxhY2VfZm9yX3RzNDQuc2hcIiwgXG4gICAgICAgIFwiZG9jc1wiOiBcIi4vZ2VuZXJhdGUtZG9jcy5zaFwiXG4gICAgfSwgXG4gICAgXCJ0eXBlc1wiOiBcImxpYi9pbmRleC5kLnRzXCIsIFxuICAgIFwidHlwZXNWZXJzaW9uc1wiOiB7XG4gICAgICAgIFwiPDQuNFwiOiB7XG4gICAgICAgICAgICBcIipcIjogW1xuICAgICAgICAgICAgICAgIFwidHM0LjQvKlwiXG4gICAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICB9LCBcbiAgICBcInZlcnNpb25cIjogXCIyLjI1LjBcIlxufSIsImltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdS9PcGVuVmlkdSc7XG5pbXBvcnQgeyBKTCB9IGZyb20gJ2pzbmxvZyc7XG5cbmlmICh0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBnbG9iYWxUaGlzWydPcGVuVmlkdSddID0gT3BlblZpZHU7XG59XG5cbi8vIERpc2FibGUganNubG9nIHdoZW4gbGlicmFyeSBpcyBsb2FkZWRcbkpMLnNldE9wdGlvbnMoeyBlbmFibGVkOiBmYWxzZSB9KTtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IExvY2FsQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Mb2NhbENvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IFJlbW90ZUNvbm5lY3Rpb25PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvUmVtb3RlQ29ubmVjdGlvbk9wdGlvbnMnO1xuaW1wb3J0IHsgSW5ib3VuZFN0cmVhbU9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9JbmJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBTdHJlYW1PcHRpb25zU2VydmVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvU3RyZWFtT3B0aW9uc1NlcnZlcic7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IEV4Y2VwdGlvbkV2ZW50LCBFeGNlcHRpb25FdmVudE5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FeGNlcHRpb25FdmVudCc7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSB1c2VyJ3MgY29ubmVjdGlvbiB0byB0aGUgc2Vzc2lvbiAodGhlIGxvY2FsIG9uZSBhbmQgb3RoZXIgdXNlcidzIGNvbm5lY3Rpb25zKS5cbiAqIFRoZXJlZm9yZSBlYWNoIHtAbGluayBTZXNzaW9ufSBhbmQge0BsaW5rIFN0cmVhbX0gb2JqZWN0IGhhcyBhbiBhdHRyaWJ1dGUgb2YgdHlwZSBDb25uZWN0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25uZWN0aW9uIHtcbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgY29ubmVjdGlvblxuICAgICAqL1xuICAgIGNvbm5lY3Rpb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGltZSB3aGVuIHRoaXMgY29ubmVjdGlvbiB3YXMgY3JlYXRlZCBpbiBPcGVuVmlkdSBTZXJ2ZXIgKFVUQyBtaWxsaXNlY29uZHMpXG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBEYXRhIGFzc29jaWF0ZWQgdG8gdGhpcyBjb25uZWN0aW9uIChhbmQgdGhlcmVmb3JlIHRvIGNlcnRhaW4gdXNlcikuIFRoaXMgaXMgYW4gaW1wb3J0YW50IGZpZWxkOlxuICAgICAqIGl0IGFsbG93cyB5b3UgdG8gYnJvYWRjYXN0IGFsbCB0aGUgaW5mb3JtYXRpb24geW91IHdhbnQgZm9yIGVhY2ggdXNlciAoYSB1c2VybmFtZSwgZm9yIGV4YW1wbGUpXG4gICAgICovXG4gICAgZGF0YTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogUm9sZSBvZiB0aGUgY29ubmVjdGlvbi5cbiAgICAgKiAtIGBTVUJTQ1JJQkVSYDogY2FuIHN1YnNjcmliZSB0byBwdWJsaXNoZWQgU3RyZWFtcyBvZiBvdGhlciB1c2VycyBieSBjYWxsaW5nIHtAbGluayBTZXNzaW9uLnN1YnNjcmliZX1cbiAgICAgKiAtIGBQVUJMSVNIRVJgOiBTVUJTQ1JJQkVSIHBlcm1pc3Npb25zICsgY2FuIHB1Ymxpc2ggdGhlaXIgb3duIFN0cmVhbXMgYnkgY2FsbGluZyB7QGxpbmsgU2Vzc2lvbi5wdWJsaXNofVxuICAgICAqIC0gYE1PREVSQVRPUmA6IFNVQlNDUklCRVIgKyBQVUJMSVNIRVIgcGVybWlzc2lvbnMgKyBjYW4gZm9yY2UgdGhlIHVucHVibGlzaGluZyBvciBkaXNjb25uZWN0aW9uIG92ZXIgYSB0aGlyZC1wYXJ0eSBTdHJlYW0gb3IgQ29ubmVjdGlvbiBieSBjYWxsIHtAbGluayBTZXNzaW9uLmZvcmNlVW5wdWJsaXNofSBhbmQge0BsaW5rIFNlc3Npb24uZm9yY2VEaXNjb25uZWN0fVxuICAgICAqXG4gICAgICogKipPbmx5IGRlZmluZWQgZm9yIHRoZSBsb2NhbCBjb25uZWN0aW9uLiBJbiByZW1vdGUgY29ubmVjdGlvbnMgd2lsbCBiZSBgdW5kZWZpbmVkYCoqXG4gICAgICovXG4gICAgcm9sZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtcyBwdWJsaXNoZWQgYnkgdGhpcyBDb25uZWN0aW9uIHdpbGwgYmUgcmVjb3JkZWQgb3Igbm90LiBUaGlzIG9ubHkgYWZmZWN0cyBbSU5ESVZJRFVBTCByZWNvcmRpbmddKC9lbi9zdGFibGUvYWR2YW5jZWQtZmVhdHVyZXMvcmVjb3JkaW5nLyNpbmRpdmlkdWFsLXJlY29yZGluZy1zZWxlY3Rpb24pIDxhIGhyZWY9XCJodHRwczovL2RvY3Mub3BlbnZpZHUuaW8vZW4vc3RhYmxlL29wZW52aWR1LXByby9cIiBzdHlsZT1cImRpc3BsYXk6IGlubGluZS1ibG9jazsgYmFja2dyb3VuZC1jb2xvcjogcmdiKDAsIDEzNiwgMTcwKTsgY29sb3I6IHdoaXRlOyBmb250LXdlaWdodDogYm9sZDsgcGFkZGluZzogMHB4IDVweDsgbWFyZ2luLXJpZ2h0OiA1cHg7IGJvcmRlci1yYWRpdXM6IDNweDsgZm9udC1zaXplOiAxM3B4OyBsaW5lLWhlaWdodDoyMXB4OyBmb250LWZhbWlseTogTW9udHNlcnJhdCwgc2Fucy1zZXJpZlwiPlBSTzwvYT5cbiAgICAgKlxuICAgICAqICoqT25seSBkZWZpbmVkIGZvciB0aGUgbG9jYWwgY29ubmVjdGlvbi4gSW4gcmVtb3RlIGNvbm5lY3Rpb25zIHdpbGwgYmUgYHVuZGVmaW5lZGAqKlxuICAgICAqL1xuICAgIHJlY29yZDogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW0/OiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbG9jYWxPcHRpb25zOiBMb2NhbENvbm5lY3Rpb25PcHRpb25zIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZU9wdGlvbnM6IFJlbW90ZUNvbm5lY3Rpb25PcHRpb25zIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VkID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcnBjU2Vzc2lvbklkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzZXNzaW9uOiBTZXNzaW9uLCBjb25uZWN0aW9uT3B0aW9uczogTG9jYWxDb25uZWN0aW9uT3B0aW9ucyB8IFJlbW90ZUNvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISEoPExvY2FsQ29ubmVjdGlvbk9wdGlvbnM+Y29ubmVjdGlvbk9wdGlvbnMpLnJvbGUpIHtcbiAgICAgICAgICAgIC8vIENvbm5lY3Rpb24gaXMgbG9jYWxcbiAgICAgICAgICAgIHRoaXMubG9jYWxPcHRpb25zID0gPExvY2FsQ29ubmVjdGlvbk9wdGlvbnM+Y29ubmVjdGlvbk9wdGlvbnM7XG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9IHRoaXMubG9jYWxPcHRpb25zLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmxvY2FsT3B0aW9ucy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICB0aGlzLmRhdGEgPSB0aGlzLmxvY2FsT3B0aW9ucy5tZXRhZGF0YTtcbiAgICAgICAgICAgIHRoaXMucnBjU2Vzc2lvbklkID0gdGhpcy5sb2NhbE9wdGlvbnMuc2Vzc2lvbklkO1xuICAgICAgICAgICAgdGhpcy5yb2xlID0gdGhpcy5sb2NhbE9wdGlvbnMucm9sZTtcbiAgICAgICAgICAgIHRoaXMucmVjb3JkID0gdGhpcy5sb2NhbE9wdGlvbnMucmVjb3JkO1xuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIENvbm5lY3Rpb24gaXMgcmVtb3RlXG4gICAgICAgICAgICB0aGlzLnJlbW90ZU9wdGlvbnMgPSA8UmVtb3RlQ29ubmVjdGlvbk9wdGlvbnM+Y29ubmVjdGlvbk9wdGlvbnM7XG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9IHRoaXMucmVtb3RlT3B0aW9ucy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gdGhpcy5yZW1vdGVPcHRpb25zLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIGlmICh0aGlzLnJlbW90ZU9wdGlvbnMubWV0YWRhdGEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEgPSB0aGlzLnJlbW90ZU9wdGlvbnMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5yZW1vdGVPcHRpb25zLnN0cmVhbXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRSZW1vdGVTdHJlYW1zKHRoaXMucmVtb3RlT3B0aW9ucy5zdHJlYW1zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1zZyArPSBcIihyZW1vdGUpIHdpdGggJ2Nvbm5lY3Rpb25JZCcgW1wiICsgdGhpcy5yZW1vdGVPcHRpb25zLmlkICsgJ10nO1xuICAgICAgICB9XG4gICAgICAgIGxvZ2dlci5pbmZvKG1zZyk7XG4gICAgfVxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZW5kSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlKTogdm9pZCB7XG5cbiAgICAgICAgaWYgKCF0aGlzLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoKCEhdGhpcy5zdHJlYW0hLm91dGJvdW5kU3RyZWFtT3B0cyA/ICdMb2NhbCcgOiAnUmVtb3RlJykgKyAnY2FuZGlkYXRlIGZvcicgKyB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdvbkljZUNhbmRpZGF0ZScsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBlbmRwb2ludE5hbWU6IHRoaXMuY29ubmVjdGlvbklkLFxuICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGU6IGNhbmRpZGF0ZS5jYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogY2FuZGlkYXRlLnNkcE1MaW5lSW5kZXhcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdleGNlcHRpb24nLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEV4Y2VwdGlvbkV2ZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VwdGlvbkV2ZW50TmFtZS5JQ0VfQ0FORElEQVRFX0VSUk9SLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUaGVyZSB3YXMgYW4gdW5leHBlY3RlZCBlcnJvciBvbiB0aGUgc2VydmVyLXNpZGUgcHJvY2Vzc2luZyBhbiBJQ0UgY2FuZGlkYXRlIGdlbmVyYXRlZCBhbmQgc2VudCBieSB0aGUgY2xpZW50LXNpZGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKGBDb25uZWN0aW9uICR7dGhpcy5jb25uZWN0aW9uSWR9IGRpc3Bvc2VkIHdoZW4gdHJ5aW5nIHRvIHNlbmQgYW4gSUNFIGNhbmRpZGF0ZS4gSUNFIGNhbmRpZGF0ZSBub3Qgc2VudGApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRSZW1vdGVTdHJlYW1zKG9wdGlvbnM6IFN0cmVhbU9wdGlvbnNTZXJ2ZXJbXSk6IHZvaWQge1xuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKChvcHRzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdHJlYW1PcHRpb25zOiBJbmJvdW5kU3RyZWFtT3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBpZDogb3B0cy5pZCxcbiAgICAgICAgICAgICAgICBjcmVhdGVkQXQ6IG9wdHMuY3JlYXRlZEF0LFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb246IHRoaXMsXG4gICAgICAgICAgICAgICAgaGFzQXVkaW86IG9wdHMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgaGFzVmlkZW86IG9wdHMuaGFzVmlkZW8sXG4gICAgICAgICAgICAgICAgYXVkaW9BY3RpdmU6IG9wdHMuYXVkaW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IG9wdHMudmlkZW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgdHlwZU9mVmlkZW86IG9wdHMudHlwZU9mVmlkZW8sXG4gICAgICAgICAgICAgICAgZnJhbWVSYXRlOiBvcHRzLmZyYW1lUmF0ZSxcbiAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnM6ICEhb3B0cy52aWRlb0RpbWVuc2lvbnMgPyBKU09OLnBhcnNlKG9wdHMudmlkZW9EaW1lbnNpb25zKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBmaWx0ZXI6ICEhb3B0cy5maWx0ZXIgPyBvcHRzLmZpbHRlciA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IG5ldyBTdHJlYW0odGhpcy5zZXNzaW9uLCBzdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgdGhpcy5hZGRTdHJlYW0oc3RyZWFtKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICBcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsXG4gICAgICAgICAgICB0aGlzLnN0cmVhbSEuaW5ib3VuZFN0cmVhbU9wdHNcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbSgpOiB2b2lkIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW0oKTtcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBFdmVudE1hcCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50TWFwL0V2ZW50TWFwJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9Mb2dnZXIvT3BlblZpZHVMb2dnZXInO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRXZlbnREaXNwYXRjaGVyIHtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXNlckhhbmRsZXJBcnJvd0hhbmRsZXI6IFdlYWtNYXA8KGV2ZW50OiBFdmVudCkgPT4gdm9pZCwgKGV2ZW50OiBFdmVudCkgPT4gdm9pZD4gPSBuZXcgV2Vha01hcCgpO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgZnVuY3Rpb24gYGhhbmRsZXJgIHRvIGhhbmRsZSBldmVudCBgdHlwZWBcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBFdmVudERpc3BhdGNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYWJzdHJhY3Qgb248SyBleHRlbmRzIGtleW9mIEV2ZW50TWFwPih0eXBlOiBLLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcztcblxuICAgIC8qKlxuICAgICAqIEFkZHMgZnVuY3Rpb24gYGhhbmRsZXJgIHRvIGhhbmRsZSBldmVudCBgdHlwZWAganVzdCBvbmNlLiBUaGUgaGFuZGxlciB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZCBhZnRlciBmaXJzdCBleGVjdXRpb25cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBvYmplY3QgdGhhdCBkaXNwYXRjaGVkIHRoZSBldmVudFxuICAgICAqL1xuICAgIGFic3RyYWN0IG9uY2U8SyBleHRlbmRzIGtleW9mIEV2ZW50TWFwPih0eXBlOiBLLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcztcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYSBgaGFuZGxlcmAgZnJvbSBldmVudCBgdHlwZWAuIElmIG5vIGhhbmRsZXIgaXMgcHJvdmlkZWQsIGFsbCBoYW5kbGVycyB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnRcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBvYmplY3QgdGhhdCBkaXNwYXRjaGVkIHRoZSBldmVudFxuICAgICAqL1xuICAgIGFic3RyYWN0IG9mZjxLIGV4dGVuZHMga2V5b2YgRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI/OiAoZXZlbnQ6IEV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbkF1eCh0eXBlOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIGNvbnN0IGFycm93SGFuZGxlciA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKG1lc3NhZ2UsIGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKG1lc3NhZ2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFuZGxlcihldmVudCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMudXNlckhhbmRsZXJBcnJvd0hhbmRsZXIuc2V0KGhhbmRsZXIsIGFycm93SGFuZGxlcik7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgYXJyb3dIYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uY2VBdXgodHlwZTogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBjb25zdCBhcnJvd0hhbmRsZXIgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhtZXNzYWdlLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhtZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGhhbmRsZXIgZnJvbSBtYXAgYWZ0ZXIgZmlyc3QgYW5kIG9ubHkgZXhlY3V0aW9uXG4gICAgICAgICAgICB0aGlzLnVzZXJIYW5kbGVyQXJyb3dIYW5kbGVyLmRlbGV0ZShoYW5kbGVyKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy51c2VySGFuZGxlckFycm93SGFuZGxlci5zZXQoaGFuZGxlciwgYXJyb3dIYW5kbGVyKTtcbiAgICAgICAgdGhpcy5lZS5vbmNlKHR5cGUsIGFycm93SGFuZGxlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvZmZBdXgodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIGlmICghaGFuZGxlcikge1xuICAgICAgICAgICAgdGhpcy5lZS5yZW1vdmVBbGxMaXN0ZW5lcnModHlwZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBNdXN0IHJlbW92ZSBpbnRlcm5hbCBhcnJvdyBmdW5jdGlvbiBoYW5kbGVyIHBhaXJlZCB3aXRoIHVzZXIgaGFuZGxlclxuICAgICAgICAgICAgY29uc3QgYXJyb3dIYW5kbGVyID0gdGhpcy51c2VySGFuZGxlckFycm93SGFuZGxlci5nZXQoaGFuZGxlcik7XG4gICAgICAgICAgICBpZiAoISFhcnJvd0hhbmRsZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9mZih0eXBlLCBhcnJvd0hhbmRsZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy51c2VySGFuZGxlckFycm93SGFuZGxlci5kZWxldGUoaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqICoqV0FSTklORyoqOiBleHBlcmltZW50YWwgb3B0aW9uLiBUaGlzIGludGVyZmFjZSBtYXkgY2hhbmdlIGluIHRoZSBuZWFyIGZ1dHVyZVxuICpcbiAqIFZpZGVvL2F1ZGlvIGZpbHRlciBhcHBsaWVkIHRvIGEgU3RyZWFtLiBTZWUge0BsaW5rIFN0cmVhbS5hcHBseUZpbHRlcn1cbiAqL1xuZXhwb3J0IGNsYXNzIEZpbHRlciB7XG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBmaWx0ZXIgYXBwbGllZC4gVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgcmVtb3RlIGNsYXNzIGlkZW50aWZ5aW5nIHRoZSBmaWx0ZXIgdG8gYXBwbHkgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIuXG4gICAgICogRm9yIGV4YW1wbGU6IGBcIkZhY2VPdmVybGF5RmlsdGVyXCJgLCBgXCJHU3RyZWFtZXJGaWx0ZXJcImAuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIHByb3BlcnR5IGluIGAqLmttZC5qc29uYCBmaWxlcyBkZWZpbmluZyB0aGUgS3VyZW50byBmaWx0ZXJzLiBGb3IgZXhhbXBsZSwgZm9yIEdTdHJlYW1lckZpbHRlciB0aGF0J3NcbiAgICAgKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL0t1cmVudG8va21zLWZpbHRlcnMvYmxvYi81M2E0NTJmYWM3MWQ2MTc5NTk1MmUzZDIyMDIxNTZjNmIwMGY2ZDY1L3NyYy9zZXJ2ZXIvaW50ZXJmYWNlL2ZpbHRlcnMuR1N0cmVhbWVyRmlsdGVyLmttZC5qc29uI0w0KVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuXG4gICAgICogVGhlc2UgY29ycmVzcG9uZCB0byB0aGUgY29uc3RydWN0b3IgcGFyYW1ldGVycyB1c2VkIGluIHRoZSBmaWx0ZXIgaW4gS3VyZW50byBNZWRpYSBTZXJ2ZXIgKGV4Y2VwdCBmb3IgYG1lZGlhUGlwZWxpbmVgIHBhcmFtZXRlciwgd2hpY2ggaXMgbmV2ZXIgbmVlZGVkKS5cbiAgICAgKlxuICAgICAqIEZvciBleGFtcGxlOiBmb3IgYGZpbHRlci50eXBlID0gXCJHU3RyZWFtZXJGaWx0ZXJcImAgY291bGQgYmUgYGZpbHRlci5vcHRpb25zID0ge1wiY29tbWFuZFwiOiBcInZpZGVvYmFsYW5jZSBzYXR1cmF0aW9uPTAuMFwifWBcbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDEzLUwzMSlcbiAgICAgKi9cbiAgICBvcHRpb25zOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBWYWx1ZSBwYXNzZWQgdGhlIGxhc3QgdGltZSB7QGxpbmsgRmlsdGVyLmV4ZWNNZXRob2R9IHdhcyBjYWxsZWQuIElmIGB1bmRlZmluZWRgIHRoaXMgbWV0aG9kIGhhcyBub3QgYmVlbiBjYWxsZWQgeWV0LlxuICAgICAqXG4gICAgICogWW91IGNhbiB1c2UgdGhpcyB2YWx1ZSB0byBrbm93IHRoZSBjdXJyZW50IHN0YXR1cyBvZiBhbnkgYXBwbGllZCBmaWx0ZXJcbiAgICAgKi9cbiAgICBsYXN0RXhlY01ldGhvZD86IHtcbiAgICAgICAgbWV0aG9kOiBzdHJpbmc7XG4gICAgICAgIHBhcmFtczogT2JqZWN0O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFuZGxlcnM6IE1hcDxzdHJpbmcsIChldmVudDogRmlsdGVyRXZlbnQpID0+IHZvaWQ+ID0gbmV3IE1hcCgpO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuICAgIHByaXZhdGUgbG9nZ2VyOiBPcGVuVmlkdUxvZ2dlcjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0eXBlOiBzdHJpbmcsIG9wdGlvbnM6IE9iamVjdCkge1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4ZWN1dGVzIGEgZmlsdGVyIG1ldGhvZC4gQXZhaWxhYmxlIG1ldGhvZHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIG1ldGhvZCBOYW1lIG9mIHRoZSBtZXRob2RcbiAgICAgKiBAcGFyYW0gcGFyYW1zIFBhcmFtZXRlcnMgb2YgdGhlIG1ldGhvZFxuICAgICAqL1xuICAgIGV4ZWNNZXRob2QobWV0aG9kOiBzdHJpbmcsIHBhcmFtczogT2JqZWN0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbygnRXhlY3V0aW5nIGZpbHRlciBtZXRob2QgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG5cbiAgICAgICAgICAgIGxldCBmaW5hbFBhcmFtcztcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0V4ZWNNZXRob2QgPSAodHJpZ2dlckV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ0ZpbHRlciBtZXRob2Qgc3VjY2Vzc2Z1bGx5IGV4ZWN1dGVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gKDxhbnk+T2JqZWN0KS5hc3NpZ24oe30sIHRoaXMuc3RyZWFtLmZpbHRlcik7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyIS5sYXN0RXhlY01ldGhvZCA9IHsgbWV0aG9kLCBwYXJhbXM6IGZpbmFsUGFyYW1zIH07XG4gICAgICAgICAgICAgICAgaWYgKHRyaWdnZXJFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZpbHRlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyISxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlY0ZpbHRlck1ldGhvZCdcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZmlsdGVyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5maWx0ZXIhLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdleGVjRmlsdGVyTWV0aG9kJ1xuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnR5cGUuc3RhcnRzV2l0aCgnVkI6JykpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHBhcmFtcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IEpTT04ucGFyc2UocGFyYW1zKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SLCAnV3JvbmcgcGFyYW1zIHN5bnRheDogJyArIGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBmaW5hbFBhcmFtcyA9IHBhcmFtcztcblxuICAgICAgICAgICAgICAgIGlmIChtZXRob2QgPT09ICd1cGRhdGUnKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0udmlydHVhbEJhY2tncm91bmRTaW5rRWxlbWVudHM/LlZCKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUiwgJ1RoZXJlIGlzIG5vIFZpcnR1YWwgQmFja2dyb3VuZCBmaWx0ZXIgYXBwbGllZCcpXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlydHVhbEJhY2tncm91bmRTaW5rRWxlbWVudHMuVkIudXBkYXRlVmFsdWVzKHBhcmFtcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiBzdWNjZXNzRXhlY01ldGhvZChmYWxzZSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKGVycm9yLm5hbWUsIGVycm9yLm1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0Vycm9yIHVwZGF0aW5nIHZhbHVlcyBvbiBWaXJ0dWFsIEJhY2tncm91bmQgZmlsdGVyOiAnICsgZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SLCBgVW5rbm93biBWaXJ0dWFsIEJhY2tncm91bmQgbWV0aG9kIFwiJHttZXRob2R9XCJgKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0cmluZ1BhcmFtcztcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHBhcmFtcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IEpTT04uc3RyaW5naWZ5KHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvck1zZyA9IFwiJ3BhcmFtcycgcHJvcGVydHkgbXVzdCBiZSBhIEpTT04gZm9ybWF0dGVkIG9iamVjdFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycm9yTXNnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3JNc2cpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyaW5nUGFyYW1zID0gPHN0cmluZz5wYXJhbXM7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZmluYWxQYXJhbXMgPSBzdHJpbmdQYXJhbXM7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICAnZXhlY0ZpbHRlck1ldGhvZCcsXG4gICAgICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBtZXRob2QsIHBhcmFtczogc3RyaW5nUGFyYW1zIH0sXG4gICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgZXhlY3V0aW5nIGZpbHRlciBtZXRob2QgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGV4ZWN1dGUgYSBmaWx0ZXIgbWV0aG9kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdWNjZXNzRXhlY01ldGhvZCh0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSB0byBjZXJ0YWluIGZpbHRlciBldmVudC4gQXZhaWxhYmxlIGV2ZW50cyBhcmUgc3BlY2lmaWMgZm9yIGVhY2ggZmlsdGVyXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZXZlbnRUeXBlIEV2ZW50IHRvIHdoaWNoIHN1YnNjcmliZSB0by5cbiAgICAgKiBAcGFyYW0gaGFuZGxlciBGdW5jdGlvbiB0byBleGVjdXRlIHVwb24gZXZlbnQgZGlzcGF0Y2hlZC4gSXQgcmVjZWl2ZXMgYXMgcGFyYW1ldGVyIGEge0BsaW5rIEZpbHRlckV2ZW50fSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdFcnJvciBhZGRpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gYWRkIGEgZmlsdGVyIGV2ZW50IGxpc3RlbmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVycy5zZXQoZXZlbnRUeXBlLCBoYW5kbGVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZFxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGNlcnRhaW4gZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHByZXZpb3VzbHkgc2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB1bnN1YnNjcmliZSBmcm9tLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSBldmVudCBsaXN0ZW5lciB3YXMgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQgZnJvbSB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpbiBvdGhlciBjYXNlXG4gICAgICovXG4gICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudFR5cGU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ1JlbW92aW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ3JlbW92ZUZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzLmRlbGV0ZShldmVudFR5cGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0ZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IFBsYXRmb3JtVXRpbHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1V0aWxzL1BsYXRmb3JtJztcbmltcG9ydCBNaW1lID0gcmVxdWlyZSgnbWltZS9saXRlJyk7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmxldCBwbGF0Zm9ybTogUGxhdGZvcm1VdGlscztcblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiB7QGxpbmsgU3RyZWFtfSBvYmplY3RzIHN0cmFpZ2h0YXdheSBmcm9tIHRoZSBicm93c2VyLiBJbml0aWFsaXplZCB3aXRoIHtAbGluayBPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcn0gbWV0aG9kXG4gKi9cbmV4cG9ydCBjbGFzcyBMb2NhbFJlY29yZGVyIHtcbiAgICBzdGF0ZTogTG9jYWxSZWNvcmRlclN0YXRlO1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICBwcml2YXRlIG1lZGlhUmVjb3JkZXI6IE1lZGlhUmVjb3JkZXI7XG4gICAgcHJpdmF0ZSBjaHVua3M6IGFueVtdID0gW107XG4gICAgcHJpdmF0ZSBibG9iPzogQmxvYjtcbiAgICBwcml2YXRlIGlkOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXdTcmM6IHN0cmluZztcbiAgICBwcml2YXRlIHZpZGVvUHJldmlldzogSFRNTFZpZGVvRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHN0cmVhbTogU3RyZWFtKSB7XG4gICAgICAgIHBsYXRmb3JtID0gUGxhdGZvcm1VdGlscy5nZXRJbnN0YW5jZSgpO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9ICEhdGhpcy5zdHJlYW0uY29ubmVjdGlvbiA/IHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIDogJ2RlZmF1bHQtY29ubmVjdGlvbic7XG4gICAgICAgIHRoaXMuaWQgPSB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICdfJyArIHRoaXMuY29ubmVjdGlvbklkICsgJ19sb2NhbHJlY29yZCc7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3RhcnRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4ge0BsaW5rIHN0YXRlfSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKlxuICAgICAqIEBwYXJhbSBvcHRpb25zIFRoZSBbTWVkaWFSZWNvcmRlci5vcHRpb25zXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTWVkaWFSZWNvcmRlci9NZWRpYVJlY29yZGVyI3BhcmFtZXRlcnMpIHRvIGJlIHVzZWQgdG8gcmVjb3JkIHRoaXMgU3RyZWFtLlxuICAgICAqIEZvciBleGFtcGxlOlxuICAgICAqXG4gICAgICogYGBgamF2YXNjcmlwdFxuICAgICAqIHZhciBPViA9IG5ldyBPcGVuVmlkdSgpO1xuICAgICAqIHZhciBwdWJsaXNoZXIgPSBhd2FpdCBPVi5pbml0UHVibGlzaGVyQXN5bmMoKTtcbiAgICAgKiB2YXIgbG9jYWxSZWNvcmRlciA9IE9WLmluaXRMb2NhbFJlY29yZGVyKHB1Ymxpc2hlci5zdHJlYW0pO1xuICAgICAqIHZhciBvcHRpb25zID0ge1xuICAgICAqICAgICAgbWltZVR5cGU6ICd2aWRlby93ZWJtO2NvZGVjcz12cDgnLFxuICAgICAqICAgICAgYXVkaW9CaXRzUGVyU2Vjb25kOjEyODAwMCxcbiAgICAgKiAgICAgIHZpZGVvQml0c1BlclNlY29uZDoyNTAwMDAwXG4gICAgICogfTtcbiAgICAgKiBsb2NhbFJlY29yZGVyLnJlY29yZChvcHRpb25zKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIElmIG5vdCBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IG9wdGlvbnMgcHJlZmVycmVkIGJ5IHRoZSBwbGF0Zm9ybSB3aWxsIGJlIHVzZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJyB8fCBvcHRpb25zIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgICAgICBgV2hlbiBjYWxsaW5nIExvY2FsUmVjb3JkZXIucmVjb3JkKG9wdGlvbnMpIHBhcmFtZXRlciAnb3B0aW9ucycgY2Fubm90IGJlIGEgc3RyaW5nLiBNdXN0IGJlIGFuIG9iamVjdCBsaWtlIHsgbWltZVR5cGU6IFwiJHtvcHRpb25zfVwiIH1gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGRldmljZS4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGRldmljZS4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBcIidMb2NhbFJlY29yZC5yZWNvcmQoKScgbmVlZHMgJ0xvY2FsUmVjb3JkLnN0YXRlJyB0byBiZSAnUkVBRFknIChjdXJyZW50IHZhbHVlOiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiJykuIENhbGwgJ0xvY2FsUmVjb3JkZXIuY2xlYW4oKScgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZVwiXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cbiAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IHsgbWltZVR5cGU6ICd2aWRlby93ZWJtJyB9O1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIW9wdGlvbnMubWltZVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5taW1lVHlwZSA9ICd2aWRlby93ZWJtJztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIgPSBuZXcgTWVkaWFSZWNvcmRlcih0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhcnQoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uZGF0YWF2YWlsYWJsZSA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGUuZGF0YS5zaXplID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uZXJyb3IgPSAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIubG9nKCdNZWRpYVJlY29yZGVyIHN0YXJ0ZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLm9uU3RvcERlZmF1bHQoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnBhdXNlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coJ01lZGlhUmVjb3JkZXIgcGF1c2VkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnJlc3VtZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4ge0BsaW5rIHN0YXRlfSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgIG9yIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBGSU5JU0hFRGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RvcHBlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgc3RvcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWSB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBcIidMb2NhbFJlY29yZC5zdG9wKCknIG5lZWRzICdMb2NhbFJlY29yZC5zdGF0ZScgdG8gYmUgJ1JFQ09SRElORycgb3IgJ1BBVVNFRCcgKGN1cnJlbnQgdmFsdWU6ICdcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInKS4gQ2FsbCAnTG9jYWxSZWNvcmRlci5zdGFydCgpJyBiZWZvcmVcIlxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdG9wID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uU3RvcERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGF1c2VzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4ge0BsaW5rIHN0YXRlfSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUNPUkRJTkdgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBQQVVTRURgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSBwYXVzZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHBhdXNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInTG9jYWxSZWNvcmQucGF1c2UoKScgbmVlZHMgJ0xvY2FsUmVjb3JkLnN0YXRlJyB0byBiZSAnUkVDT1JESU5HJyAoY3VycmVudCB2YWx1ZTogJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiJykuIENhbGwgJ0xvY2FsUmVjb3JkZXIuc3RhcnQoKScgb3IgJ0xvY2FsUmVjb3JkZXIucmVzdW1lKCknIGJlZm9yZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5wYXVzZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXN1bWVzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4ge0BsaW5rIHN0YXRlfSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgXCInTG9jYWxSZWNvcmQucmVzdW1lKCknIG5lZWRzICdMb2NhbFJlY29yZC5zdGF0ZScgdG8gYmUgJ1BBVVNFRCcgKGN1cnJlbnQgdmFsdWU6ICdcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInKS4gQ2FsbCAnTG9jYWxSZWNvcmRlci5wYXVzZSgpJyBiZWZvcmVcIlxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucmVzdW1lKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiB7QGxpbmsgc3RhdGV9IHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYFxuICAgICAqL1xuICAgIHByZXZpZXcocGFyZW50RWxlbWVudCk6IEhUTUxWaWRlb0VsZW1lbnQge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgICAgICAgICBcIidMb2NhbFJlY29yZC5wcmV2aWV3KCknIG5lZWRzICdMb2NhbFJlY29yZC5zdGF0ZScgdG8gYmUgJ0ZJTklTSEVEJyAoY3VycmVudCB2YWx1ZTogJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSArXG4gICAgICAgICAgICAgICAgICAgIFwiJykuIENhbGwgJ0xvY2FsUmVjb3JkZXIuc3RvcCgpJyBiZWZvcmVcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndmlkZW8nKTtcblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlldy5pZCA9IHRoaXMuaWQ7XG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmF1dG9wbGF5ID0gdHJ1ZTtcblxuICAgICAgICBpZiAocGxhdGZvcm0uaXNTYWZhcmlCcm93c2VyKCkpIHtcbiAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LnBsYXlzSW5saW5lID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgcGFyZW50RWxlbWVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudEVsZW1lbnREb20gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChwYXJlbnRFbGVtZW50KTtcbiAgICAgICAgICAgIGlmIChwYXJlbnRFbGVtZW50RG9tKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBwYXJlbnRFbGVtZW50RG9tLmFwcGVuZENoaWxkKHRoaXMudmlkZW9QcmV2aWV3KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmlkZW9QcmV2aWV3ID0gcGFyZW50RWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLnZpZGVvUHJldmlldyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpZGVvUHJldmlldy5zcmMgPSB0aGlzLnZpZGVvUHJldmlld1NyYztcblxuICAgICAgICByZXR1cm4gdGhpcy52aWRlb1ByZXZpZXc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR3JhY2VmdWxseSBzdG9wcyBhbmQgY2xlYW5zIHRoZSBjdXJyZW50IHJlY29yZGluZyAoV0FSTklORzogaXQgaXMgY29tcGxldGVseSBkaXNtaXNzZWQpLiBTZXRzIHtAbGluayBzdGF0ZX0gdG8gYFJFQURZYCBzbyB0aGUgcmVjb3JkaW5nIGNhbiBzdGFydCBhZ2FpblxuICAgICAqL1xuICAgIGNsZWFuKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBmID0gKCkgPT4ge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuYmxvYjtcbiAgICAgICAgICAgIHRoaXMuY2h1bmtzID0gW107XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQ09SRElORyB8fCB0aGlzLnN0YXRlID09PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IGYoKSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKCkgPT4gZigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGYoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERvd25sb2FkcyB0aGUgcmVjb3JkZWQgdmlkZW8gdGhyb3VnaCB0aGUgYnJvd3Nlci4ge0BsaW5rIHN0YXRlfSBwcm9wZXJ0eSBtdXN0IGJlIGBGSU5JU0hFRGBcbiAgICAgKi9cbiAgICBkb3dubG9hZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCInTG9jYWxSZWNvcmQuZG93bmxvYWQoKScgbmVlZHMgJ0xvY2FsUmVjb3JkLnN0YXRlJyB0byBiZSAnRklOSVNIRUQnIChjdXJyZW50IHZhbHVlOiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlICtcbiAgICAgICAgICAgICAgICAgICAgXCInKS4gQ2FsbCAnTG9jYWxSZWNvcmRlci5zdG9wKCknIGJlZm9yZVwiXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYTogSFRNTEFuY2hvckVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgICAgICAgICBhLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGEpO1xuXG4gICAgICAgICAgICBjb25zdCB1cmwgPSBnbG9iYWxUaGlzLlVSTC5jcmVhdGVPYmplY3RVUkwoPGFueT50aGlzLmJsb2IpO1xuICAgICAgICAgICAgYS5ocmVmID0gdXJsO1xuICAgICAgICAgICAgYS5kb3dubG9hZCA9IHRoaXMuaWQgKyAnLicgKyBNaW1lLmdldEV4dGVuc2lvbih0aGlzLmJsb2IhLnR5cGUpO1xuICAgICAgICAgICAgYS5jbGljaygpO1xuICAgICAgICAgICAgZ2xvYmFsVGhpcy5VUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG5cbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoYSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSByYXcgQmxvYiBmaWxlLiBNZXRob2RzIHByZXZpZXcsIGRvd25sb2FkLCB1cGxvYWRBc0JpbmFyeSBhbmQgdXBsb2FkQXNNdWx0aXBhcnRmaWxlIHVzZSB0aGlzIHNhbWUgZmlsZSB0byBwZXJmb3JtIHRoZWlyIHNwZWNpZmljIGFjdGlvbnMuIHtAbGluayBzdGF0ZX0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgZ2V0QmxvYigpOiBCbG9iIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXCJDYWxsICdMb2NhbFJlY29yZC5zdG9wKCknIGJlZm9yZSBnZXR0aW5nIEJsb2IgZmlsZVwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmJsb2IhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBsb2FkcyB0aGUgcmVjb3JkZWQgdmlkZW8gYXMgYSBiaW5hcnkgZmlsZSBwZXJmb3JtaW5nIGFuIEhUVFAvUE9TVCBvcGVyYXRpb24gdG8gVVJMIGBlbmRwb2ludGAuIHtAbGluayBzdGF0ZX0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgLiBPcHRpb25hbCBIVFRQIGhlYWRlcnMgY2FuIGJlIHBhc3NlZCBhcyBzZWNvbmQgcGFyYW1ldGVyLiBGb3IgZXhhbXBsZTpcbiAgICAgKiBgYGBcbiAgICAgKiB2YXIgaGVhZGVycyA9IHtcbiAgICAgKiAgXCJDb29raWVcIjogXCIkVmVyc2lvbj0xOyBTa2luPW5ldztcIixcbiAgICAgKiAgXCJBdXRob3JpemF0aW9uXCI6XCJCYXNpYyBRV3hoWkdwYmpwdUlITmxjdFpRPT1cIlxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgYGh0dHAucmVzcG9uc2VUZXh0YCBmcm9tIHNlcnZlciBpZiB0aGUgb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIHRoZSBmYWlsZWQgYGh0dHAuc3RhdHVzYCBpZiBub3RcbiAgICAgKi9cbiAgICB1cGxvYWRBc0JpbmFyeShlbmRwb2ludDogc3RyaW5nLCBoZWFkZXJzPzogYW55KTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICBFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiJ0xvY2FsUmVjb3JkLnVwbG9hZEFzQmluYXJ5KCknIG5lZWRzICdMb2NhbFJlY29yZC5zdGF0ZScgdG8gYmUgJ0ZJTklTSEVEJyAoY3VycmVudCB2YWx1ZTogJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIicpLiBDYWxsICdMb2NhbFJlY29yZGVyLnN0b3AoKScgYmVmb3JlXCJcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGh0dHAgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgICAgICBodHRwLm9wZW4oJ1BPU1QnLCBlbmRwb2ludCwgdHJ1ZSk7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGhlYWRlcnMgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGhlYWRlcnMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBodHRwLnNldFJlcXVlc3RIZWFkZXIoa2V5LCBoZWFkZXJzW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaHR0cC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChodHRwLnJlYWR5U3RhdGUgPT09IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChodHRwLnN0YXR1cy50b1N0cmluZygpLmNoYXJBdCgwKSA9PT0gJzInKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3VjY2VzcyByZXNwb25zZSBmcm9tIHNlcnZlciAoSFRUUCBzdGF0dXMgc3RhbmRhcmQ6IDJYWCBpcyBzdWNjZXNzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGh0dHAucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChodHRwLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGh0dHAuc2VuZCh0aGlzLmJsb2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIG11bHRpcGFydCBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4ge0BsaW5rIHN0YXRlfSBwcm9wZXJ0eSBtdXN0IGJlIGBGSU5JU0hFRGAuIE9wdGlvbmFsIEhUVFAgaGVhZGVycyBjYW4gYmUgcGFzc2VkIGFzIHNlY29uZCBwYXJhbWV0ZXIuIEZvciBleGFtcGxlOlxuICAgICAqIGBgYFxuICAgICAqIHZhciBoZWFkZXJzID0ge1xuICAgICAqICBcIkNvb2tpZVwiOiBcIiRWZXJzaW9uPTE7IFNraW49bmV3O1wiLFxuICAgICAqICBcIkF1dGhvcml6YXRpb25cIjpcIkJhc2ljIFFXeGhaR3BianB1SUhObGN0WlE9PVwiXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB3aXRoIHRoZSBgaHR0cC5yZXNwb25zZVRleHRgIGZyb20gc2VydmVyIGlmIHRoZSBvcGVyYXRpb24gd2FzIHN1Y2Nlc3NmdWwgYW5kIHJlamVjdGVkIHdpdGggdGhlIGZhaWxlZCBgaHR0cC5zdGF0dXNgIGlmIG5vdDpcbiAgICAgKi9cbiAgICB1cGxvYWRBc011bHRpcGFydGZpbGUoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBcIidMb2NhbFJlY29yZC51cGxvYWRBc011bHRpcGFydGZpbGUoKScgbmVlZHMgJ0xvY2FsUmVjb3JkLnN0YXRlJyB0byBiZSAnRklOSVNIRUQnIChjdXJyZW50IHZhbHVlOiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiJykuIENhbGwgJ0xvY2FsUmVjb3JkZXIuc3RvcCgpJyBiZWZvcmVcIlxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzZW5kYWJsZSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgICAgICAgICAgICAgIHNlbmRhYmxlLmFwcGVuZCgnZmlsZScsIHRoaXMuYmxvYiEsIHRoaXMuaWQgKyAnLicgKyBNaW1lLmdldEV4dGVuc2lvbih0aGlzLmJsb2IhLnR5cGUpKTtcblxuICAgICAgICAgICAgICAgIGh0dHAub25yZWFkeXN0YXRlY2hhbmdlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaHR0cC5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaHR0cC5zdGF0dXMudG9TdHJpbmcoKS5jaGFyQXQoMCkgPT09ICcyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN1Y2Nlc3MgcmVzcG9uc2UgZnJvbSBzZXJ2ZXIgKEhUVFAgc3RhdHVzIHN0YW5kYXJkOiAyWFggaXMgc3VjY2VzcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoaHR0cC5zdGF0dXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGh0dHAuc2VuZChzZW5kYWJsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBvblN0b3BEZWZhdWx0KCk6IHZvaWQge1xuICAgICAgICBsb2dnZXIubG9nKCdNZWRpYVJlY29yZGVyIHN0b3BwZWQgIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcblxuICAgICAgICB0aGlzLmJsb2IgPSBuZXcgQmxvYih0aGlzLmNodW5rcywgeyB0eXBlOiB0aGlzLm1lZGlhUmVjb3JkZXIubWltZVR5cGUgfSk7XG4gICAgICAgIHRoaXMuY2h1bmtzID0gW107XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXdTcmMgPSBnbG9iYWxUaGlzLlVSTC5jcmVhdGVPYmplY3RVUkwodGhpcy5ibG9iKTtcblxuICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyIH0gZnJvbSAnLi9Mb2NhbFJlY29yZGVyJztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4vUHVibGlzaGVyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgRGV2aWNlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9EZXZpY2UnO1xuaW1wb3J0IHsgT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFB1Ymxpc2hlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1B1Ymxpc2hlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ3VzdG9tTWVkaWFTdHJlYW1Db25zdHJhaW50cyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0N1c3RvbU1lZGlhU3RyZWFtQ29uc3RyYWludHMnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5pbXBvcnQgeyBQbGF0Zm9ybVV0aWxzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9VdGlscy9QbGF0Zm9ybSc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudFJlYXNvbiwgQ2hhbmdlZFByb3BlcnR5VHlwZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1R5cGVzL1R5cGVzJztcblxuaW1wb3J0ICogYXMgc2NyZWVuU2hhcmluZ0F1dG8gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TY3JlZW5TaGFyaW5nL1NjcmVlbi1DYXB0dXJpbmctQXV0byc7XG5pbXBvcnQgKiBhcyBzY3JlZW5TaGFyaW5nIGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbic7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuaW1wb3J0IFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi9PcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMnKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHBhY2thZ2VKc29uID0gcmVxdWlyZSgnLi4vLi4vcGFja2FnZS5qc29uJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuZGVjbGFyZSB2YXIgY29yZG92YTogYW55O1xuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqL1xubGV0IHBsYXRmb3JtOiBQbGF0Zm9ybVV0aWxzO1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIHtAbGluayBTZXNzaW9ufSwge0BsaW5rIFB1Ymxpc2hlcn0gYW5kIHtAbGluayBMb2NhbFJlY29yZGVyfVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuICAgIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuICAgIHByaXZhdGUgbWFzdGVyTm9kZUhhc0NyYXNoZWQgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZXJzOiBQdWJsaXNoZXJbXSA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB3c1VyaTogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBodHRwVXJpOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlY3JldCA9ICcnO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZWNvcmRlciA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaWNlU2VydmVyczogUlRDSWNlU2VydmVyW107XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJvbGU6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZmluYWxVc2VySWQ6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbWVkaWFTZXJ2ZXI6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9TaW11bGNhc3Q6IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxpZmU6IG51bWJlciA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhZHZhbmNlZENvbmZpZ3VyYXRpb246IE9wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uID0ge307XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZW5kQnJvd3NlckxvZ3M6IE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbiA9IE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbi5kaXNhYmxlZDtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNBdExlYXN0UHJvOiBib29sZWFuID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzRW50ZXJwcmlzZTogYm9vbGVhbiA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBwbGF0Zm9ybSA9IFBsYXRmb3JtVXRpbHMuZ2V0SW5zdGFuY2UoKTtcbiAgICAgICAgdGhpcy5saWJyYXJ5VmVyc2lvbiA9IHBhY2thZ2VKc29uLnZlcnNpb247XG4gICAgICAgIGxvZ2dlci5pbmZvKCdPcGVuVmlkdSBpbml0aWFsaXplZCcpO1xuICAgICAgICBsb2dnZXIuaW5mbygnUGxhdGZvcm0gZGV0ZWN0ZWQ6ICcgKyBwbGF0Zm9ybS5nZXREZXNjcmlwdGlvbigpKTtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ29wZW52aWR1LWJyb3dzZXIgdmVyc2lvbjogJyArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5pc01vYmlsZURldmljZSgpIHx8IHBsYXRmb3JtLmlzUmVhY3ROYXRpdmUoKSkge1xuICAgICAgICAgICAgLy8gTGlzdGVuIHRvIG9yaWVudGF0aW9uY2hhbmdlIG9ubHkgb24gbW9iaWxlIGRldmljZXNcbiAgICAgICAgICAgIHRoaXMub25PcmllbnRhdGlvbkNoYW5nZWQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucHVibGlzaGVycy5mb3JFYWNoKChwdWJsaXNoZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHB1Ymxpc2hlci5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJiAhIXB1Ymxpc2hlci5zdHJlYW0gJiYgISFwdWJsaXNoZXIuc3RyZWFtLmhhc1ZpZGVvKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmROZXdWaWRlb0RpbWVuc2lvbnNJZlJlcXVpcmVkKHB1Ymxpc2hlciwgJ2RldmljZVJvdGF0ZWQnLCA3NSwgMTApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgbmV3IHNlc3Npb25cbiAgICAgKi9cbiAgICBpbml0U2Vzc2lvbigpOiBTZXNzaW9uIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uID0gbmV3IFNlc3Npb24odGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzLnNlc3Npb247XG4gICAgfVxuXG4gICAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCk6IFB1Ymxpc2hlcjtcbiAgICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHVibGlzaGVyO1xuICAgIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQsIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKTogUHVibGlzaGVyO1xuICAgIGluaXRQdWJsaXNoZXIoXG4gICAgICAgIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLFxuICAgICAgICBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLFxuICAgICAgICBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZFxuICAgICk6IFB1Ymxpc2hlcjtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBuZXcgcHVibGlzaGVyXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUge0BsaW5rIFB1Ymxpc2hlcn0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0RpYWxvZ09wZW5lZGAgZXZlbnQsIG9ubHkgaWYgdGhlIHBvcC11cCBzaG93biBieSB0aGUgYnJvd3NlciB0byByZXF1ZXN0IHBlcm1pc3Npb25zIGZvciB0aGUgY2FtZXJhIGlzIG9wZW5lZC4gWW91IGNhbiB1c2UgdGhpcyBldmVudCB0byBhbGVydCB0aGUgdXNlciBhYm91dCBncmFudGluZyBwZXJtaXNzaW9uc1xuICAgICAqIGZvciB5b3VyIHdlYnNpdGUuIEFuIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIGV2ZW50IHdpbGwgYWxzbyBiZSBkaXNwYXRjaGVkIGFmdGVyIHVzZXIgY2xpY2tzIG9uIFwiQWxsb3dcIiBvciBcIkJsb2NrXCIgaW4gdGhlIHBvcC11cC5cbiAgICAgKlxuICAgICAqIFRoZSB7QGxpbmsgUHVibGlzaGVyfSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhbiBgYWNjZXNzQWxsb3dlZGAgb3IgYGFjY2Vzc0RlbmllZGAgZXZlbnQgb25jZSBpdCBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90LlxuICAgICAqXG4gICAgICogVGhlIHtAbGluayBQdWJsaXNoZXJ9IG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgYSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZW4vc3RhYmxlL2NoZWF0c2hlZXQvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLiBTZWUge0BsaW5rIFZpZGVvRWxlbWVudEV2ZW50fSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIHtAbGluayBQdWJsaXNoZXJ9IG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IG9uY2UgdGhlIGxvY2FsIHN0cmVhbXMgc3RhcnRzIHBsYXlpbmcuIFNlZSB7QGxpbmsgU3RyZWFtTWFuYWdlckV2ZW50fSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgIEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlciB3aWxsIGJlIGluc2VydGVkIChzZWUge0BsaW5rIFB1Ymxpc2hlclByb3BlcnRpZXMuaW5zZXJ0TW9kZX0pLiBJZiAqbnVsbCogb3IgKnVuZGVmaW5lZCogbm8gZGVmYXVsdCB2aWRlbyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgUHVibGlzaGVyLlxuICAgICAqIFlvdSBjYW4gYWx3YXlzIGNhbGwgbWV0aG9kIHtAbGluayBQdWJsaXNoZXIuYWRkVmlkZW9FbGVtZW50fSBvciB7QGxpbmsgUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudH0gdG8gbWFuYWdlIHRoZSB2aWRlbyBlbGVtZW50cyBvbiB5b3VyIG93biAoc2VlIFtNYW5hZ2UgdmlkZW8gcGxheWVyc10oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MpIHNlY3Rpb24pXG4gICAgICogQHBhcmFtIGNvbXBsZXRpb25IYW5kbGVyIGBlcnJvcmAgcGFyYW1ldGVyIGlzIG51bGwgaWYgYGluaXRQdWJsaXNoZXJgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYGNvbXBsZXRpb25IYW5kbGVyYCBmdW5jdGlvbiBpcyBjYWxsZWQgYmVmb3JlIHRoZSBQdWJsaXNoZXIgZGlzcGF0Y2hlcyBhbiBgYWNjZXNzQWxsb3dlZGAgb3IgYW4gYGFjY2Vzc0RlbmllZGAgZXZlbnRcbiAgICAgKi9cbiAgICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLCBwYXJhbTI/LCBwYXJhbTM/KTogUHVibGlzaGVyIHtcbiAgICAgICAgbGV0IHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG5cbiAgICAgICAgaWYgKCEhcGFyYW0yICYmIHR5cGVvZiBwYXJhbTIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIC8vIE1hdGNoZXMgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcyknIG9yICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNvbXBsZXRpb25IYW5kbGVyKSdcblxuICAgICAgICAgICAgcHJvcGVydGllcyA9IDxQdWJsaXNoZXJQcm9wZXJ0aWVzPnBhcmFtMjtcblxuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpb1NvdXJjZTogdHlwZW9mIHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnID8gcHJvcGVydGllcy5hdWRpb1NvdXJjZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBmcmFtZVJhdGU6XG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFja1xuICAgICAgICAgICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwZW9mIHByb3BlcnRpZXMuZnJhbWVSYXRlICE9PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gcHJvcGVydGllcy5mcmFtZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOlxuICAgICAgICAgICAgICAgICAgICB0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgPyB0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gVmlkZW9JbnNlcnRNb2RlW3Byb3BlcnRpZXMuaW5zZXJ0TW9kZV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIG1pcnJvcjogdHlwZW9mIHByb3BlcnRpZXMubWlycm9yICE9PSAndW5kZWZpbmVkJyA/IHByb3BlcnRpZXMubWlycm9yIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwdWJsaXNoQXVkaW86IHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyAhPT0gJ3VuZGVmaW5lZCcgPyBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyA6IHRydWUsXG4gICAgICAgICAgICAgICAgcHVibGlzaFZpZGVvOiB0eXBlb2YgcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gIT09ICd1bmRlZmluZWQnID8gcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gOiB0cnVlLFxuICAgICAgICAgICAgICAgIHJlc29sdXRpb246XG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFja1xuICAgICAgICAgICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwZW9mIHByb3BlcnRpZXMucmVzb2x1dGlvbiAhPT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHByb3BlcnRpZXMucmVzb2x1dGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJzY0MHg0ODAnLFxuICAgICAgICAgICAgICAgIHZpZGVvU291cmNlOiB0eXBlb2YgcHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gJ3VuZGVmaW5lZCcgPyBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIHZpZGVvU2ltdWxjYXN0OiBwcm9wZXJ0aWVzLnZpZGVvU2ltdWxjYXN0LFxuICAgICAgICAgICAgICAgIGZpbHRlcjogcHJvcGVydGllcy5maWx0ZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBNYXRjaGVzICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQpJyBvciAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlciknXG5cbiAgICAgICAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgICAgICAgICAgaW5zZXJ0TW9kZTogVmlkZW9JbnNlcnRNb2RlLkFQUEVORCxcbiAgICAgICAgICAgICAgICBtaXJyb3I6IHRydWUsXG4gICAgICAgICAgICAgICAgcHVibGlzaEF1ZGlvOiB0cnVlLFxuICAgICAgICAgICAgICAgIHB1Ymxpc2hWaWRlbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICByZXNvbHV0aW9uOiAnNjQweDQ4MCdcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwdWJsaXNoZXI6IFB1Ymxpc2hlciA9IG5ldyBQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgdGhpcyk7XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTIgJiYgdHlwZW9mIHBhcmFtMiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTI7XG4gICAgICAgIH0gZWxzZSBpZiAoISFwYXJhbTMpIHtcbiAgICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0zO1xuICAgICAgICB9XG5cbiAgICAgICAgcHVibGlzaGVyXG4gICAgICAgICAgICAuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcsIFtdKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnLCBbZXJyb3JdKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucHVibGlzaGVycy5wdXNoKHB1Ymxpc2hlcik7XG4gICAgICAgIHJldHVybiBwdWJsaXNoZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvbWlzaWZpZWQgdmVyc2lvbiBvZiB7QGxpbmsgT3BlblZpZHUuaW5pdFB1Ymxpc2hlcn1cbiAgICAgKlxuICAgICAqID4gV0FSTklORzogZXZlbnRzIGBhY2Nlc3NEaWFsb2dPcGVuZWRgIGFuZCBgYWNjZXNzRGlhbG9nQ2xvc2VkYCB3aWxsIG5vdCBiZSBkaXNwYXRjaGVkIGlmIHVzaW5nIHRoaXMgbWV0aG9kIGluc3RlYWQgb2Yge0BsaW5rIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJ9XG4gICAgICovXG4gICAgaW5pdFB1Ymxpc2hlckFzeW5jKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkKTogUHJvbWlzZTxQdWJsaXNoZXI+O1xuICAgIGluaXRQdWJsaXNoZXJBc3luYyh0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8UHVibGlzaGVyPjtcblxuICAgIGluaXRQdWJsaXNoZXJBc3luYyh0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCwgcHJvcGVydGllcz86IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQcm9taXNlPFB1Ymxpc2hlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8UHVibGlzaGVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsZXQgcHVibGlzaGVyOiBQdWJsaXNoZXI7XG5cbiAgICAgICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHB1Ymxpc2hlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhcHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzLCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHB1Ymxpc2hlciA9IHRoaXMuaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBuZXcgbG9jYWwgcmVjb3JkZXIgZm9yIHJlY29yZGluZyBzdHJlYW1zIHN0cmFpZ2h0IGF3YXkgZnJvbSB0aGUgYnJvd3NlclxuICAgICAqIEBwYXJhbSBzdHJlYW0gIFN0cmVhbSB0byByZWNvcmRcbiAgICAgKi9cbiAgICBpbml0TG9jYWxSZWNvcmRlcihzdHJlYW06IFN0cmVhbSk6IExvY2FsUmVjb3JkZXIge1xuICAgICAgICByZXR1cm4gbmV3IExvY2FsUmVjb3JkZXIoc3RyZWFtKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgT3BlblZpZHVcbiAgICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIE9wZW5WaWR1LCAwIG90aGVyd2lzZVxuICAgICAqL1xuICAgIGNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBTcGVjaWZpYyBpT1MgcGxhdGZvcm0gc3VwcG9ydCAoaVBob25lLCBpUGFkKVxuICAgICAgICBpZiAocGxhdGZvcm0uaXNJUGhvbmVPcklQYWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0lPU1dpdGhTYWZhcmkoKSB8fFxuICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzQ2hyb21lTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNGaXJlZm94TW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNPcGVyYU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzRWRnZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzSW9uaWNJb3MoKSAvLyBJb25pYyBhcHBzIGZvciBpT1NcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZW5lcmFsIHBsYXRmb3JtIHN1cHBvcnQgZm9yIHdlYiBjbGllbnRzIChEZXNrdG9wLCBNb2JpbGUpXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0Nocm9tZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNDaHJvbWVNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzRmlyZWZveEJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNGaXJlZm94TW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc09wZXJhQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc09wZXJhTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0VkZ2VCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzRWRnZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNTYW1zdW5nQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc1NhZmFyaUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNBbmRyb2lkQnJvd3NlcigpIHx8IC8vIEFuZHJvaWQgV2ViVmlldyAmIElvbmljIGFwcHMgZm9yIEFuZHJvaWRcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzRWxlY3Ryb24oKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNOb2RlSnMoKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBzY3JlZW4tc2hhcmluZy4gRGVza3RvcCBDaHJvbWUsIEZpcmVmb3ggYW5kIE9wZXJhIHN1cHBvcnQgc2NyZWVuLXNoYXJpbmdcbiAgICAgKiBAcmV0dXJucyAxIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIHNjcmVlbi1zaGFyaW5nLCAwIG90aGVyd2lzZVxuICAgICAqL1xuICAgIGNoZWNrU2NyZWVuU2hhcmluZ0NhcGFiaWxpdGllcygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLmNhblNjcmVlblNoYXJlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29sbGVjdHMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG1lZGlhIGlucHV0IGRldmljZXMgYXZhaWxhYmxlIG9uIHRoZSBzeXN0ZW0uIFlvdSBjYW4gcGFzcyBwcm9wZXJ0eSBgZGV2aWNlSWRgIG9mIGEge0BsaW5rIERldmljZX0gb2JqZWN0IGFzIHZhbHVlIG9mIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIHtAbGluayBpbml0UHVibGlzaGVyfSBtZXRob2RcbiAgICAgKi9cbiAgICBnZXREZXZpY2VzKCk6IFByb21pc2U8RGV2aWNlW10+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPERldmljZVtdPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzXG4gICAgICAgICAgICAgICAgLmVudW1lcmF0ZURldmljZXMoKVxuICAgICAgICAgICAgICAgIC50aGVuKChkZXZpY2VJbmZvcykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIElvbmljIEFuZHJvaWQgIGRldmljZXNcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBsYXRmb3JtLmlzSW9uaWNBbmRyb2lkKCkgJiYgdHlwZW9mIGNvcmRvdmEgIT0gJ3VuZGVmaW5lZCcgJiYgY29yZG92YT8ucGx1Z2lucz8uRW51bWVyYXRlRGV2aWNlc1BsdWdpbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29yZG92YS5wbHVnaW5zLkVudW1lcmF0ZURldmljZXNQbHVnaW4uZ2V0RW51bWVyYXRlRGV2aWNlcygpLnRoZW4oKHBsdWdpbkRldmljZXM6IERldmljZVtdKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHBsdWdpbkF1ZGlvRGV2aWNlczogRGV2aWNlW10gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgdmlkZW9EZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBhdWRpb0RldmljZXM6IERldmljZVtdID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2luQXVkaW9EZXZpY2VzID0gcGx1Z2luRGV2aWNlcy5maWx0ZXIoKGRldmljZTogRGV2aWNlKSA9PiBkZXZpY2Uua2luZCA9PT0gJ2F1ZGlvaW5wdXQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RldmljZXMgPSBkZXZpY2VJbmZvcy5maWx0ZXIoKGRldmljZTogTWVkaWFEZXZpY2VJbmZvKSA9PiBkZXZpY2Uua2luZCA9PT0gJ3ZpZGVvaW5wdXQnKSBhcyBhbnk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9EZXZpY2VzID0gZGV2aWNlSW5mb3MuZmlsdGVyKChkZXZpY2U6IE1lZGlhRGV2aWNlSW5mbykgPT4gZGV2aWNlLmtpbmQgPT09ICdhdWRpb2lucHV0JykgYXMgYW55O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvRGV2aWNlcy5mb3JFYWNoKChkZXZpY2VJbmZvLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWRldmljZUluZm8ubGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBsYWJlbCA9ICcnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnRnJvbnQgQ2FtZXJhJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaW5kZXggPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdCYWNrIENhbWVyYSc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gJ1Vua25vd24gQ2FtZXJhJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogZGV2aWNlSW5mby5sYWJlbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpb0RldmljZXMuZm9yRWFjaCgoZGV2aWNlSW5mbywgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFkZXZpY2VJbmZvLmxhYmVsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbGFiZWwgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDA6IC8vIERlZmF1bHQgTWljcm9waG9uZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdEZWZhdWx0JztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOiAvLyBNaWNyb3Bob25lICsgU3BlYWtlcnBob25lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRNYXRjaCA9IHBsdWdpbkF1ZGlvRGV2aWNlcy5maWx0ZXIoKGQpID0+IGQubGFiZWwuaW5jbHVkZXMoJ0J1aWx0JykpWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IGRlZmF1bHRNYXRjaCA/IGRlZmF1bHRNYXRjaC5sYWJlbCA6ICdCdWlsdC1pbiBNaWNyb3Bob25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOiAvLyBIZWFkc2V0IE1pY3JvcGhvbmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2lyZWRNYXRjaCA9IHBsdWdpbkF1ZGlvRGV2aWNlcy5maWx0ZXIoKGQpID0+IGQubGFiZWwuaW5jbHVkZXMoJ1dpcmVkJykpWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAod2lyZWRNYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSB3aXJlZE1hdGNoLmxhYmVsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnSGVhZHNldCBlYXJwaWVjZSc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB3aXJlbGVzc01hdGNoID0gcGx1Z2luQXVkaW9EZXZpY2VzLmZpbHRlcigoZCkgPT4gZC5sYWJlbC5pbmNsdWRlcygnQmx1ZXRvb3RoJykpWzBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHdpcmVsZXNzTWF0Y2ggPyB3aXJlbGVzc01hdGNoLmxhYmVsIDogJ1dpcmVsZXNzJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnVW5rbm93biBNaWNyb3Bob25lJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogbGFiZWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSWQ6IGRldmljZUluZm8uZGV2aWNlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2YgcGxhdGZvcm1zXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VJbmZvcy5mb3JFYWNoKChkZXZpY2VJbmZvKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRldmljZUluZm8ua2luZCA9PT0gJ2F1ZGlvaW5wdXQnIHx8IGRldmljZUluZm8ua2luZCA9PT0gJ3ZpZGVvaW5wdXQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBkZXZpY2VJbmZvLmxhYmVsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoZGV2aWNlcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBnZXR0aW5nIGRldmljZXMnLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgYSBNZWRpYVN0cmVhbSBvYmplY3QgdGhhdCB5b3UgY2FuIGN1c3RvbWl6ZSBiZWZvcmUgY2FsbGluZyB7QGxpbmsgaW5pdFB1Ymxpc2hlcn0gKHBhc3MgX01lZGlhU3RyZWFtVHJhY2tfIHByb3BlcnR5IG9mIHRoZSBfTWVkaWFTdHJlYW1fIHZhbHVlIHJlc29sdmVkIGJ5IHRoZSBQcm9taXNlIGFzIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIHtAbGluayBpbml0UHVibGlzaGVyfSlcbiAgICAgKlxuICAgICAqIFBhcmFtZXRlciBgb3B0aW9uc2AgaXMgdGhlIHNhbWUgYXMgaW4ge0BsaW5rIGluaXRQdWJsaXNoZXJ9IHNlY29uZCBwYXJhbWV0ZXIgKG9mIHR5cGUge0BsaW5rIFB1Ymxpc2hlclByb3BlcnRpZXN9KSwgYnV0IG9ubHkgdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzIHdpbGwgYmUgYXBwbGllZDogYGF1ZGlvU291cmNlYCwgYHZpZGVvU291cmNlYCwgYGZyYW1lUmF0ZWAsIGByZXNvbHV0aW9uYFxuICAgICAqXG4gICAgICogVG8gY3VzdG9taXplIHRoZSBQdWJsaXNoZXIncyB2aWRlbywgdGhlIEFQSSBmb3IgSFRNTENhbnZhc0VsZW1lbnQgaXMgdmVyeSB1c2VmdWwuIEZvciBleGFtcGxlLCB0byBnZXQgYSBibGFjay1hbmQtd2hpdGUgdmlkZW8gYXQgMTAgZnBzIGFuZCBIRCByZXNvbHV0aW9uIHdpdGggbm8gc291bmQ6XG4gICAgICogYGBgXG4gICAgICogdmFyIE9WID0gbmV3IE9wZW5WaWR1KCk7XG4gICAgICogdmFyIEZSQU1FX1JBVEUgPSAxMDtcbiAgICAgKlxuICAgICAqIE9WLmdldFVzZXJNZWRpYSh7XG4gICAgICogICAgYXVkaW9Tb3VyY2U6IGZhbHNlLFxuICAgICAqICAgIHZpZGVvU291cmNlOiB1bmRlZmluZWQsXG4gICAgICogICAgcmVzb2x1dGlvbjogJzEyODB4NzIwJyxcbiAgICAgKiAgICBmcmFtZVJhdGU6IEZSQU1FX1JBVEVcbiAgICAgKiB9KVxuICAgICAqIC50aGVuKG1lZGlhU3RyZWFtID0+IHtcbiAgICAgKlxuICAgICAqICAgIHZhciB2aWRlb1RyYWNrID0gbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXTtcbiAgICAgKiAgICB2YXIgdmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgICAqICAgIHZpZGVvLnNyY09iamVjdCA9IG5ldyBNZWRpYVN0cmVhbShbdmlkZW9UcmFja10pO1xuICAgICAqXG4gICAgICogICAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAqICAgIHZhciBjdHggPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgKiAgICBjdHguZmlsdGVyID0gJ2dyYXlzY2FsZSgxMDAlKSc7XG4gICAgICpcbiAgICAgKiAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCdwbGF5JywgKCkgPT4ge1xuICAgICAqICAgICAgdmFyIGxvb3AgPSAoKSA9PiB7XG4gICAgICogICAgICAgIGlmICghdmlkZW8ucGF1c2VkICYmICF2aWRlby5lbmRlZCkge1xuICAgICAqICAgICAgICAgIGN0eC5kcmF3SW1hZ2UodmlkZW8sIDAsIDAsIDMwMCwgMTcwKTtcbiAgICAgKiAgICAgICAgICBzZXRUaW1lb3V0KGxvb3AsIDEwMDAvIEZSQU1FX1JBVEUpOyAvLyBEcmF3aW5nIGF0IDEwIGZwc1xuICAgICAqICAgICAgICB9XG4gICAgICogICAgICB9O1xuICAgICAqICAgICAgbG9vcCgpO1xuICAgICAqICAgIH0pO1xuICAgICAqICAgIHZpZGVvLnBsYXkoKTtcbiAgICAgKlxuICAgICAqICAgIHZhciBncmF5VmlkZW9UcmFjayA9IGNhbnZhcy5jYXB0dXJlU3RyZWFtKEZSQU1FX1JBVEUpLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAgICogICAgdmFyIHB1Ymxpc2hlciA9IHRoaXMuT1YuaW5pdFB1Ymxpc2hlcihcbiAgICAgKiAgICAgIG15SHRtbFRhcmdldCxcbiAgICAgKiAgICAgIHtcbiAgICAgKiAgICAgICAgYXVkaW9Tb3VyY2U6IGZhbHNlLFxuICAgICAqICAgICAgICB2aWRlb1NvdXJjZTogZ3JheVZpZGVvVHJhY2tcbiAgICAgKiAgICAgIH0pO1xuICAgICAqIH0pO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGdldFVzZXJNZWRpYShvcHRpb25zOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxNZWRpYVN0cmVhbT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8TWVkaWFTdHJlYW0+KGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFza0ZvckF1ZGlvU3RyZWFtT25seSA9IGFzeW5jIChwcmV2aW91c01lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSwgY29uc3RyYWludHM6IE1lZGlhU3RyZWFtQ29uc3RyYWludHMpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gY29uc3RyYWludHMuYXVkaW8gPT09IHVuZGVmaW5lZCA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbztcbiAgICAgICAgICAgICAgICBjb25zdCBjb25zdHJhaW50c0F1eDogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHsgYXVkaW86IGRlZmluZWRBdWRpb0NvbnN0cmFpbnQsIHZpZGVvOiBmYWxzZSB9O1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvT25seVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzQXV4KTtcbiAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNNZWRpYVN0cmVhbS5hZGRUcmFjayhhdWRpb09ubHlTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHByZXZpb3VzTWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXZpb3VzTWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNNZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KHRoaXMuZ2VuZXJhdGVBdWRpb0RldmljZUVycm9yKGVycm9yLCBjb25zdHJhaW50c0F1eCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbXlDb25zdHJhaW50cyA9IGF3YWl0IHRoaXMuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgKCEhbXlDb25zdHJhaW50cy52aWRlb1RyYWNrICYmICEhbXlDb25zdHJhaW50cy5hdWRpb1RyYWNrKSB8fFxuICAgICAgICAgICAgICAgICAgICAoISFteUNvbnN0cmFpbnRzLmF1ZGlvVHJhY2sgJiYgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cz8udmlkZW8gPT09IGZhbHNlKSB8fFxuICAgICAgICAgICAgICAgICAgICAoISFteUNvbnN0cmFpbnRzLnZpZGVvVHJhY2sgJiYgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cz8uYXVkaW8gPT09IGZhbHNlKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAvLyBObyBuZWVkIHRvIGNhbGwgZ2V0VXNlck1lZGlhIGF0IGFsbC4gQm90aCB0cmFja3MgcHJvdmlkZWQsIG9yIG9ubHkgQVVESU8gdHJhY2sgcHJvdmlkZWQgb3Igb25seSBWSURFTyB0cmFjayBwcm92aWRlZFxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSh0aGlzLmFkZEFscmVhZHlQcm92aWRlZFRyYWNrcyhteUNvbnN0cmFpbnRzLCBuZXcgTWVkaWFTdHJlYW0oKSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldFVzZXJNZWRpYSBtdXN0IGJlIGNhbGxlZC4gQVVESU8gb3IgVklERU8gYXJlIHJlcXVlc3RpbmcgYSBuZXcgdHJhY2tcblxuICAgICAgICAgICAgICAgICAgICAvLyBEZWxldGUgYWxyZWFkeSBwcm92aWRlZCBjb25zdHJhaW50cyBmb3IgYXVkaW8gb3IgdmlkZW9cbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhbXlDb25zdHJhaW50cy52aWRlb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW87XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhbXlDb25zdHJhaW50cy5hdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEuYXVkaW87XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBsZXQgbXVzdEFza0ZvckF1ZGlvVHJhY2tMYXRlciA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBWaWRlbyBpcyBkZXZpY2VJZCBvciBzY3JlZW4gc2hhcmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy52aWRlb1NvdXJjZSA9PT0gJ3dpbmRvdycgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAocGxhdGZvcm0uaXNFbGVjdHJvbigpICYmIG9wdGlvbnMudmlkZW9Tb3VyY2Uuc3RhcnRzV2l0aCgnc2NyZWVuOicpKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmlkZW8gaXMgc2NyZWVuIHNoYXJpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXN0QXNrRm9yQXVkaW9UcmFja0xhdGVyID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIW15Q29uc3RyYWludHMuYXVkaW9UcmFjayAmJiBvcHRpb25zLmF1ZGlvU291cmNlICE9PSBudWxsICYmIG9wdGlvbnMuYXVkaW9Tb3VyY2UgIT09IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChuYXZpZ2F0b3IubWVkaWFEZXZpY2VzWydnZXREaXNwbGF5TWVkaWEnXSAmJiAhcGxhdGZvcm0uaXNFbGVjdHJvbigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBzdXBwb3J0ZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10oeyB2aWRlbzogdHJ1ZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkQWxyZWFkeVByb3ZpZGVkVHJhY2tzKG15Q29uc3RyYWludHMsIG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtdXN0QXNrRm9yQXVkaW9UcmFja0xhdGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgYXNrRm9yQXVkaW9TdHJlYW1Pbmx5KG1lZGlhU3RyZWFtLCA8TWVkaWFTdHJlYW1Db25zdHJhaW50cz5teUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX0NBUFRVUkVfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldERpc3BsYXlNZWRpYSBOT1Qgc3VwcG9ydGVkLiBDYW4gcGVyZm9ybSBnZXRVc2VyTWVkaWEgYmVsb3cgd2l0aCBhbHJlYWR5IGNhbGN1bGF0ZWQgY29uc3RyYWludHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFZpZGVvIGlzIGRldmljZUlkLiBDYW4gcGVyZm9ybSBnZXRVc2VyTWVkaWEgYmVsb3cgd2l0aCBhbHJlYWR5IGNhbGN1bGF0ZWQgY29uc3RyYWludHNcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBVc2UgYWxyZWFkeSBjYWxjdWxhdGVkIGNvbnN0cmFpbnRzXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0cmFpbnRzQXV4ID0gbXVzdEFza0ZvckF1ZGlvVHJhY2tMYXRlclxuICAgICAgICAgICAgICAgICAgICAgICAgPyB7IHZpZGVvOiBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS52aWRlbyB9XG4gICAgICAgICAgICAgICAgICAgICAgICA6IG15Q29uc3RyYWludHMuY29uc3RyYWludHM7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZWRpYVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzQXV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkQWxyZWFkeVByb3ZpZGVkVHJhY2tzKG15Q29uc3RyYWludHMsIG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtdXN0QXNrRm9yQXVkaW9UcmFja0xhdGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgYXNrRm9yQXVkaW9TdHJlYW1Pbmx5KG1lZGlhU3RyZWFtLCA8TWVkaWFTdHJlYW1Db25zdHJhaW50cz5teUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGVycm9yTmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEob3B0aW9ucy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbicpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FDQ0VTU19ERU5JRUQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tZW1wdHkgKi9cbiAgICAvKipcbiAgICAgKiBEaXNhYmxlIGFsbCBsb2dnaW5nIGV4Y2VwdCBlcnJvciBsZXZlbFxuICAgICAqL1xuICAgIGVuYWJsZVByb2RNb2RlKCk6IHZvaWQge1xuICAgICAgICBsb2dnZXIuZW5hYmxlUHJvZE1vZGUoKTtcbiAgICB9XG4gICAgLyogdHNsaW50OmVuYWJsZTpuby1lbXB0eSAqL1xuXG4gICAgLyoqXG4gICAgICogU2V0IE9wZW5WaWR1IGFkdmFuY2VkIGNvbmZpZ3VyYXRpb24gb3B0aW9ucy4gYGNvbmZpZ3VyYXRpb25gIGlzIGFuIG9iamVjdCBvZiB0eXBlIHtAbGluayBPcGVuVmlkdUFkdmFuY2VkQ29uZmlndXJhdGlvbn0uIENhbGwgdGhpcyBtZXRob2QgdG8gb3ZlcnJpZGUgcHJldmlvdXMgdmFsdWVzIGF0IGFueSBtb21lbnQuXG4gICAgICovXG4gICAgc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uKGNvbmZpZ3VyYXRpb246IE9wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uKTogdm9pZCB7XG4gICAgICAgIHRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvbjtcbiAgICB9XG5cbiAgICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uT3JpZW50YXRpb25DaGFuZ2VkKGhhbmRsZXIpOiB2b2lkIHtcbiAgICAgICAgKGdsb2JhbFRoaXMgYXMgYW55KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsIGhhbmRsZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZW5kTmV3VmlkZW9EaW1lbnNpb25zSWZSZXF1aXJlZChwdWJsaXNoZXI6IFB1Ymxpc2hlciwgcmVhc29uOiBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudFJlYXNvbiwgV0FJVF9JTlRFUlZBTDogbnVtYmVyLCBNQVhfQVRURU1QVFM6IG51bWJlcikge1xuICAgICAgICBsZXQgYXR0ZW1wdHMgPSAwO1xuICAgICAgICBjb25zdCBvbGRXaWR0aCA9IHB1Ymxpc2hlcj8uc3RyZWFtPy52aWRlb0RpbWVuc2lvbnM/LndpZHRoIHx8IDA7XG4gICAgICAgIGNvbnN0IG9sZEhlaWdodCA9IHB1Ymxpc2hlcj8uc3RyZWFtPy52aWRlb0RpbWVuc2lvbnM/LmhlaWdodCB8fCAwO1xuXG4gICAgICAgIGNvbnN0IHJlcGVhdFVudGlsQ2hhbmdlT3JNYXhBdHRlbXB0czogTm9kZUpTLlRpbWVvdXQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICBhdHRlbXB0cysrO1xuICAgICAgICAgICAgaWYgKGF0dGVtcHRzID4gTUFYX0FUVEVNUFRTKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlcGVhdFVudGlsQ2hhbmdlT3JNYXhBdHRlbXB0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaXNoZXIuZ2V0VmlkZW9EaW1lbnNpb25zKCkudGhlbigobmV3RGltZW5zaW9ucykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChuZXdEaW1lbnNpb25zLndpZHRoICE9PSBvbGRXaWR0aCB8fCBuZXdEaW1lbnNpb25zLmhlaWdodCAhPT0gb2xkSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZU9yTWF4QXR0ZW1wdHMpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmRWaWRlb0RpbWVuc2lvbnNDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCByZWFzb24sIG9sZFdpZHRoLCBvbGRIZWlnaHQsIG5ld0RpbWVuc2lvbnMud2lkdGgsIG5ld0RpbWVuc2lvbnMuaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgV0FJVF9JTlRFUlZBTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlbmRWaWRlb0RpbWVuc2lvbnNDaGFuZ2VkRXZlbnQoXG4gICAgICAgIHB1Ymxpc2hlcjogUHVibGlzaGVyLFxuICAgICAgICByZWFzb246IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50UmVhc29uLFxuICAgICAgICBvbGRXaWR0aDogbnVtYmVyLFxuICAgICAgICBvbGRIZWlnaHQ6IG51bWJlcixcbiAgICAgICAgbmV3V2lkdGg6IG51bWJlcixcbiAgICAgICAgbmV3SGVpZ2h0OiBudW1iZXJcbiAgICApIHtcbiAgICAgICAgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICB3aWR0aDogbmV3V2lkdGggfHwgMCxcbiAgICAgICAgICAgIGhlaWdodDogbmV3SGVpZ2h0IHx8IDBcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHN0cmVhbUlkOiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgIHByb3BlcnR5OiAndmlkZW9EaW1lbnNpb25zJyxcbiAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkocHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMpLFxuICAgICAgICAgICAgICAgIHJlYXNvblxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuc3RyZWFtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgd2lkdGg6IG9sZFdpZHRoLCBoZWlnaHQ6IG9sZEhlaWdodCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvblxuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuc3RyZWFtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgd2lkdGg6IG9sZFdpZHRoLCBoZWlnaHQ6IG9sZEhlaWdodCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvblxuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLnNlbmRWaWRlb0RhdGEocHVibGlzaGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlbmRUcmFja0NoYW5nZWRFdmVudChwdWJsaXNoZXI6IFB1Ymxpc2hlciwgb2xkTGFiZWw6IHN0cmluZywgbmV3TGFiZWw6IHN0cmluZywgcHJvcGVydHlUeXBlOiBDaGFuZ2VkUHJvcGVydHlUeXBlKSB7XG4gICAgICAgIGNvbnN0IG9sZFZhbHVlID0geyBsYWJlbDogb2xkTGFiZWwgfTtcbiAgICAgICAgY29uc3QgbmV3VmFsdWUgPSB7IGxhYmVsOiBuZXdMYWJlbCB9O1xuICAgICAgICBjb25zdCByZWFzb24gPSAndHJhY2tSZXBsYWNlZCc7XG5cbiAgICAgICAgaWYgKHB1Ymxpc2hlci5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCkge1xuICAgICAgICAgICAgdGhpcy5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogcHJvcGVydHlUeXBlLFxuICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogbmV3VmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHJlYXNvblxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHB1Ymxpc2hlci5zdHJlYW0sIHByb3BlcnR5VHlwZSwgbmV3VmFsdWUsIG9sZFZhbHVlLCByZWFzb24pXG4gICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCBwdWJsaXNoZXIuc3RyZWFtLCBwcm9wZXJ0eVR5cGUsIG5ld1ZhbHVlLCBvbGRWYWx1ZSwgcmVhc29uKVxuICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHB1Ymxpc2hlci5zdHJlYW0sIHByb3BlcnR5VHlwZSwgbmV3VmFsdWUsIG9sZFZhbHVlLCByZWFzb24pXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCBwdWJsaXNoZXIuc3RyZWFtLCBwcm9wZXJ0eVR5cGUsIG5ld1ZhbHVlLCBvbGRWYWx1ZSwgcmVhc29uKVxuICAgICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHB1Ymxpc2hlclByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQcm9taXNlPEN1c3RvbU1lZGlhU3RyZWFtQ29uc3RyYWludHM+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPEN1c3RvbU1lZGlhU3RyZWFtQ29uc3RyYWludHM+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG15Q29uc3RyYWludHM6IEN1c3RvbU1lZGlhU3RyZWFtQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW9UcmFjazogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIHZpZGVvVHJhY2s6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBjb25zdHJhaW50czoge1xuICAgICAgICAgICAgICAgICAgICBhdWRpbzogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICB2aWRlbzogdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvU291cmNlID0gcHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZTtcbiAgICAgICAgICAgIGNvbnN0IHZpZGVvU291cmNlID0gcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZTtcblxuICAgICAgICAgICAgLy8gQ0FTRSAxOiBudWxsL2ZhbHNlXG4gICAgICAgICAgICBpZiAoYXVkaW9Tb3VyY2UgPT09IG51bGwgfHwgYXVkaW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgLy8gTm8gYXVkaW8gdHJhY2tcbiAgICAgICAgICAgICAgICBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS5hdWRpbyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZpZGVvU291cmNlID09PSBudWxsIHx8IHZpZGVvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIC8vIE5vIHZpZGVvIHRyYWNrXG4gICAgICAgICAgICAgICAgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS5hdWRpbyA9PT0gZmFsc2UgJiYgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8gPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgLy8gRVJST1IhIGF1ZGlvU291cmNlIGFuZCB2aWRlb1NvdXJjZSBjYW5ub3QgYmUgYm90aCBmYWxzZSBhdCB0aGUgc2FtZSB0aW1lXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJQcm9wZXJ0aWVzICdhdWRpb1NvdXJjZScgYW5kICd2aWRlb1NvdXJjZScgY2Fubm90IGJlIHNldCB0byBmYWxzZSBvciBudWxsIGF0IHRoZSBzYW1lIHRpbWVcIlxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ0FTRSAyOiBNZWRpYVN0cmVhbVRyYWNrc1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBhdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAvLyBBbHJlYWR5IHByb3ZpZGVkIGF1ZGlvIHRyYWNrXG4gICAgICAgICAgICAgICAgbXlDb25zdHJhaW50cy5hdWRpb1RyYWNrID0gYXVkaW9Tb3VyY2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgIC8vIEFscmVhZHkgcHJvdmlkZWQgdmlkZW8gdHJhY2tcbiAgICAgICAgICAgICAgICBteUNvbnN0cmFpbnRzLnZpZGVvVHJhY2sgPSB2aWRlb1NvdXJjZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ0FTRSAzOiBEZWZhdWx0IHRyYWNrc1xuICAgICAgICAgICAgaWYgKGF1ZGlvU291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS5hdWRpbyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmlkZW9Tb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG15Q29uc3RyYWludHMuY29uc3RyYWludHMhLnZpZGVvID0ge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWRlYWw6IDY0MFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkZWFsOiA0ODBcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENBU0UgMy41OiBnaXZlIHZhbHVlcyB0byByZXNvbHV0aW9uIGFuZCBmcmFtZVJhdGUgaWYgdmlkZW8gbm90IG51bGwvZmFsc2VcbiAgICAgICAgICAgIGlmICh2aWRlb1NvdXJjZSAhPT0gbnVsbCAmJiB2aWRlb1NvdXJjZSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnJlc29sdXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2lkdGhBbmRIZWlnaHQgPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLnJlc29sdXRpb24udG9Mb3dlckNhc2UoKS5zcGxpdCgneCcpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZGVhbFdpZHRoID0gTnVtYmVyKHdpZHRoQW5kSGVpZ2h0WzBdKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaWRlYWxIZWlnaHQgPSBOdW1iZXIod2lkdGhBbmRIZWlnaHRbMV0pO1xuICAgICAgICAgICAgICAgICAgICBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS52aWRlbyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlYWw6IGlkZWFsV2lkdGhcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVhbDogaWRlYWxIZWlnaHRcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCEhcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgKDxNZWRpYVRyYWNrQ29uc3RyYWludHM+bXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8pLmZyYW1lUmF0ZSA9IHsgaWRlYWw6IHB1Ymxpc2hlclByb3BlcnRpZXMuZnJhbWVSYXRlIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDQVNFIDQ6IGRldmljZUlkIG9yIHNjcmVlbiBzaGFyaW5nXG4gICAgICAgICAgICB0aGlzLmNvbmZpZ3VyZURldmljZUlkT3JTY3JlZW5zaGFyaW5nKG15Q29uc3RyYWludHMsIHB1Ymxpc2hlclByb3BlcnRpZXMsIHJlc29sdmUsIHJlamVjdCk7XG5cbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG15Q29uc3RyYWludHMpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3RhcnRXcyhvbkNvbm5lY3RTdWNjZXM6IChlcnJvcjogRXJyb3IpID0+IHZvaWQpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0ge1xuICAgICAgICAgICAgaGVhcnRiZWF0OiA1MDAwLFxuICAgICAgICAgICAgd3M6IHtcbiAgICAgICAgICAgICAgICB1cmk6IHRoaXMud3NVcmkgKyAnP3Nlc3Npb25JZD0nICsgdGhpcy5zZXNzaW9uLnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICAgICAgICAgIG9uZGlzY29ubmVjdDogdGhpcy5kaXNjb25uZWN0Q2FsbGJhY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBvbnJlY29ubmVjdGluZzogdGhpcy5yZWNvbm5lY3RpbmdDYWxsYmFjay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIGlzbWFzdGVybm9kZWNyYXNoZWQ6IHRoaXMuaXNNYXN0ZXJOb2RlQ3Jhc2hlZC5iaW5kKHRoaXMpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcnBjOiB7XG4gICAgICAgICAgICAgICAgcmVxdWVzdFRpbWVvdXQ6IDEwMDAwLFxuICAgICAgICAgICAgICAgIGhlYXJ0YmVhdFJlcXVlc3RUaW1lb3V0OiA1MDAwLFxuICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50Sm9pbmVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEpvaW5lZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudFVucHVibGlzaGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudFVucHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudExlZnQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50TGVmdC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIHJlY29yZGluZ1N0YXJ0ZWQ6IHRoaXMuc2Vzc2lvbi5vblJlY29yZGluZ1N0YXJ0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIHJlY29yZGluZ1N0b3BwZWQ6IHRoaXMuc2Vzc2lvbi5vblJlY29yZGluZ1N0b3BwZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgICAgICAgICBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQ6IHRoaXMuc2Vzc2lvbi5vblN0cmVhbVByb3BlcnR5Q2hhbmdlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZDogdGhpcy5zZXNzaW9uLm9uQ29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgbmV0d29ya1F1YWxpdHlMZXZlbENoYW5nZWQ6IHRoaXMuc2Vzc2lvbi5vbk5ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkQ2hhbmdlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgZmlsdGVyRXZlbnREaXNwYXRjaGVkOiB0aGlzLnNlc3Npb24ub25GaWx0ZXJFdmVudERpc3BhdGNoZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIG1lZGlhRXJyb3I6IHRoaXMuc2Vzc2lvbi5vbk1lZGlhRXJyb3IuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIG1hc3Rlck5vZGVDcmFzaGVkTm90aWZpY2F0aW9uOiB0aGlzLm9uTWFzdGVyTm9kZUNyYXNoZWROb3RpZmljYXRpb24uYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBmb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXI6IHRoaXMuc2Vzc2lvbi5vbkZvcmNpYmx5UmVjb25uZWN0U3Vic2NyaWJlci5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgc3BlZWNoVG9UZXh0TWVzc2FnZTogdGhpcy5zZXNzaW9uLm9uU3BlZWNoVG9UZXh0TWVzc2FnZS5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgc3BlZWNoVG9UZXh0RGlzY29ubmVjdGVkOiB0aGlzLnNlc3Npb24ub25TcGVlY2hUb1RleHREaXNjb25uZWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuanNvblJwY0NsaWVudCA9IG5ldyBScGNCdWlsZGVyLmNsaWVudHMuSnNvblJwY0NsaWVudChjb25maWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbk1hc3Rlck5vZGVDcmFzaGVkTm90aWZpY2F0aW9uKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01hc3RlciBOb2RlIGhhcyBjcmFzaGVkJyk7XG4gICAgICAgIHRoaXMubWFzdGVyTm9kZUhhc0NyYXNoZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbignbm9kZUNyYXNoZWQnKTtcbiAgICAgICAgdGhpcy5qc29uUnBjQ2xpZW50LmNsb3NlKDQxMDMsICdNYXN0ZXIgTm9kZSBoYXMgY3Jhc2hlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRXc1JlYWR5U3RhdGUoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuanNvblJwY0NsaWVudC5nZXRSZWFkeVN0YXRlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNsb3NlV3MoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAyLCAnQ29ubmVjdGlvbiBjbG9zZWQgYnkgY2xpZW50Jyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlbmRSZXF1ZXN0KG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IGFueSwgY2FsbGJhY2s/KTogdm9pZCB7XG4gICAgICAgIGlmIChwYXJhbXMgJiYgcGFyYW1zIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gcGFyYW1zO1xuICAgICAgICAgICAgcGFyYW1zID0ge307XG4gICAgICAgIH1cbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICAgICAgdGhpcy5qc29uUnBjQ2xpZW50Py5zZW5kKG1ldGhvZCwgcGFyYW1zLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLndzVXJpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRTZWNyZXQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRSZWNvcmRlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVjb3JkZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFN0dCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3R0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZW5lcmF0ZUF1ZGlvRGV2aWNlRXJyb3IoZXJyb3IsIGNvbnN0cmFpbnRzOiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzKTogT3BlblZpZHVFcnJvciB7XG4gICAgICAgIGlmIChlcnJvci5uYW1lID09PSAnRXJyb3InKSB7XG4gICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICB9XG4gICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTogc3RyaW5nO1xuICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSk7XG4gICAgICAgICAgICBjYXNlICdub3RhbGxvd2VkZXJyb3InOlxuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgICAgIGNhc2UgJ292ZXJjb25zdHJhaW5lZGVycm9yJzpcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29uc3RyYWludC50b0xvd2VyQ2FzZSgpID09PSAnZGV2aWNlaWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMuYXVkaW8pLmRldmljZUlkISEpLmV4YWN0ICtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiJyBub3QgZm91bmRcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2UgZG9lc24ndCBzdXBwb3J0IHRoZSB2YWx1ZSBwYXNzZWQgZm9yIGNvbnN0cmFpbnQgJ1wiICsgZXJyb3IuY29uc3RyYWludCArIFwiJ1wiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpO1xuICAgICAgICAgICAgY2FzZSAnbm90cmVhZGFibGVlcnJvcic6XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9HRU5FUklDX0VSUk9SLCBlcnJvci50b1N0cmluZygpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhZGRBbHJlYWR5UHJvdmlkZWRUcmFja3MobXlDb25zdHJhaW50czogQ3VzdG9tTWVkaWFTdHJlYW1Db25zdHJhaW50cywgbWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtLCBzdHJlYW0/OiBTdHJlYW0pIHtcbiAgICAgICAgaWYgKCEhbXlDb25zdHJhaW50cy52aWRlb1RyYWNrKSB7XG4gICAgICAgICAgICBtZWRpYVN0cmVhbS5hZGRUcmFjayhteUNvbnN0cmFpbnRzLnZpZGVvVHJhY2spO1xuICAgICAgICAgICAgaWYgKCEhc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhbXlDb25zdHJhaW50cy5jb25zdHJhaW50cy52aWRlbykge1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW0ubGFzdFZpZGVvVHJhY2tDb25zdHJhaW50cyA9IG15Q29uc3RyYWludHMuY29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmxhc3RWaWRlb1RyYWNrQ29uc3RyYWludHMgPSBteUNvbnN0cmFpbnRzLnZpZGVvVHJhY2suZ2V0Q29uc3RyYWludHMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhbXlDb25zdHJhaW50cy5hdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICBtZWRpYVN0cmVhbS5hZGRUcmFjayhteUNvbnN0cmFpbnRzLmF1ZGlvVHJhY2spO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGNvbmZpZ3VyZURldmljZUlkT3JTY3JlZW5zaGFyaW5nKFxuICAgICAgICBteUNvbnN0cmFpbnRzOiBDdXN0b21NZWRpYVN0cmVhbUNvbnN0cmFpbnRzLFxuICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLFxuICAgICAgICByZXNvbHZlLFxuICAgICAgICByZWplY3RcbiAgICApIHtcbiAgICAgICAgY29uc3QgYXVkaW9Tb3VyY2UgPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlO1xuICAgICAgICBjb25zdCB2aWRlb1NvdXJjZSA9IHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2U7XG4gICAgICAgIGlmICh0eXBlb2YgYXVkaW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS5hdWRpbyA9IHsgZGV2aWNlSWQ6IHsgZXhhY3Q6IGF1ZGlvU291cmNlIH0gfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNTY3JlZW5TaGFyZSh2aWRlb1NvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFZpZGVvU291cmNlKG15Q29uc3RyYWludHMsIHZpZGVvU291cmNlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gU2NyZWVuIHNoYXJpbmdcblxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5jaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICdZb3UgY2FuIG9ubHkgc2NyZWVuIHNoYXJlIGluIGRlc2t0b3AgQ2hyb21lLCBGaXJlZm94LCBPcGVyYSwgU2FmYXJpICg+PTEzLjApLCBFZGdlICg+PSA4MCkgb3IgRWxlY3Ryb24uIERldGVjdGVkIGNsaWVudDogJyArXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5nZXROYW1lKCkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmdldFZlcnNpb24oKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm0uaXNFbGVjdHJvbigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXggPSAnc2NyZWVuOic7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2aWRlb1NvdXJjZVN0cmluZzogc3RyaW5nID0gdmlkZW9Tb3VyY2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbGVjdHJvblNjcmVlbklkID0gdmlkZW9Tb3VyY2VTdHJpbmcuc3Vic3RyKHZpZGVvU291cmNlU3RyaW5nLmluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgKDxhbnk+bXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8pID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hbmRhdG9yeToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogJ2Rlc2t0b3AnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZUlkOiBlbGVjdHJvblNjcmVlbklkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG15Q29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhKHBsYXRmb3JtLmlzRmlyZWZveEJyb3dzZXIoKSB8fCBwbGF0Zm9ybS5pc0ZpcmVmb3hNb2JpbGVCcm93c2VyKCkpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddXG4gICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDdXN0b20gc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGZvciBDaHJvbWUgKGFuZCBPcGVyYSkgYW5kIG5vIHN1cHBvcnQgZm9yIE1lZGlhRGV2aWNlcy5nZXREaXNwbGF5TWVkaWEoKVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NyZWVuU2hhcmluZy5nZXRTY3JlZW5Db25zdHJhaW50cygoZXJyb3IsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICEhZXJyb3IgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICghIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ3Blcm1pc3Npb24tZGVuaWVkJyB8fCBlcnJvciA9PT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleHRlbnNpb25JZCA9IHRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucG9wKCkhIVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudHJpbSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1lvdSBtdXN0IGVuYWJsZSB0aGUgc2NyZWVuIGV4dGVuc2lvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3RyaW5nPnRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8gPSBzY3JlZW5Db25zdHJhaW50cztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG15Q29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2V0RGlzcGxheU1lZGlhIHN1cHBvcnQgKENocm9tZSA+PSA3MiwgRmlyZWZveCA+PSA2NiwgU2FmYXJpID49IDEzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShteUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0ZpcmVmb3hCcm93c2VyKCkgfHwgcGxhdGZvcm0uaXNGaXJlZm94TW9iaWxlQnJvd3NlcigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NyZWVuU2hhcmluZ0F1dG8uZ2V0U2NyZWVuSWQoZmlyZWZveFN0cmluZywgKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuQ29uc3RyYWludHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uVXJsID0gISF0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnaHR0cHM6Ly9jaHJvbWUuZ29vZ2xlLmNvbS93ZWJzdG9yZS9kZXRhaWwvb3BlbnZpZHUtc2NyZWVuc2hhcmluZy9sZmNnZmVwYWZub2JkbG9lY2NobmZhY2xpYmVuam9sZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXJyb3IgPT09ICdwZXJtaXNzaW9uLWRlbmllZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdVbmtub3duIGVycm9yIHdoZW4gYWNjZXNzaW5nIHNjcmVlbiBzaGFyZSdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15Q29uc3RyYWludHMuY29uc3RyYWludHMhLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobXlDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByb3RlY3RlZCBzZXRWaWRlb1NvdXJjZShteUNvbnN0cmFpbnRzOiBDdXN0b21NZWRpYVN0cmVhbUNvbnN0cmFpbnRzLCB2aWRlb1NvdXJjZTogc3RyaW5nKSB7XG4gICAgICAgIGlmICghbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8pIHtcbiAgICAgICAgICAgIG15Q29uc3RyYWludHMuY29uc3RyYWludHMhLnZpZGVvID0ge307XG4gICAgICAgIH1cbiAgICAgICAgKDxNZWRpYVRyYWNrQ29uc3RyYWludHM+bXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8pWydkZXZpY2VJZCddID0geyBleGFjdDogdmlkZW9Tb3VyY2UgfTtcbiAgICB9XG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgZGlzY29ubmVjdENhbGxiYWNrKCk6IHZvaWQge1xuICAgICAgICBsb2dnZXIud2FybignV2Vic29ja2V0IGNvbm5lY3Rpb24gbG9zdCcpO1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbGVydCgnQ29ubmVjdGlvbiBlcnJvci4gUGxlYXNlIHJlbG9hZCBwYWdlLicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICAgICAgaWYgKCF0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICBhbGVydCgnQ29ubmVjdGlvbiBlcnJvci4gUGxlYXNlIHJlbG9hZCBwYWdlLicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncmVjb25uZWN0aW5nJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZWNvbm5lY3RXZWJzb2NrZXRUaHJvdWdoUnBjQ29ubmVjdE1ldGhvZChycGNTZXNzaW9uSWQpIHtcbiAgICAgICAgLy8gVGhpcyBSUEMgbWV0aG9kIGFsbG93cyBjaGVja2luZzpcbiAgICAgICAgLy8gU2luZ2xlIE1hc3RlcjogaWYgc3VjY2VzcywgY29ubmVjdGlvbiByZWNvdmVyZWRcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgaWYgZXJyb3IsIG5vIE1hc3RlciBOb2RlIGNyYXNoZWQgYW5kIGxpZmUgd2lsbCBiZSAtMS4gb25Mb3N0Q29ubmVjdGlvbiB3aXRoIHJlYXNvbiBuZXR3b3JrRGlzY29ubmVjdCB3aWxsIGJlIHRyaWdnZXJlZFxuICAgICAgICAvLyBNdWx0aSBNYXN0ZXI6IGlmIHN1Y2Nlc3MsIGNvbm5lY3Rpb24gcmVjb3ZlcmVkXG4gICAgICAgIC8vICAgICAgICAgICAgICAgaWYgZXJyb3IgYW5kIE1hc3RlciBOb2RlIGNyYXNoZWQgbm90aWZpY2F0aW9uIHdhcyBhbHJlYWR5IHJlY2VpdmVkLCBub3RoaW5nIG11c3QgYmUgZG9uZVxuICAgICAgICAvLyAgICAgICAgICAgICAgIGlmIGVycm9yIGFuZCBNYXN0ZXIgTm9kZSBOT1QgY3Jhc2hlZCwgc2Vzc2lvblN0YXR1cyBtZXRob2QgbXVzdCBiZSBzZW50OlxuICAgICAgICAvLyAgICAgICAgICAgICAgICAgaWYgbGlmZSBpcyBlcXVhbCwgbmV0d29ya0Rpc2Nvbm5lY3RcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgIGlmIGxpZmUgaXMgZ3JlYXRlciwgbm9kZUNyYXNoZWRcbiAgICAgICAgdGhpcy5zZW5kUmVxdWVzdCgnY29ubmVjdCcsIHsgc2Vzc2lvbklkOiBycGNTZXNzaW9uSWQsIHJlY29ubmVjdDogdHJ1ZSB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzTWFzdGVyTm9kZUNyYXNoZWQoKSkge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybignTWFzdGVyIE5vZGUgaGFzIGNyYXNoZWQhJyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycm9yKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBub3RpZnlMb3N0Q29ubmVjdGlvbiA9IChyZWFzb24sIGVycm9yTXNnKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihyZWFzb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5qc29uUnBjQ2xpZW50LmNsb3NlKDQxMDEsICdSZWNvbm5lY3Rpb24gZmF1bHQ6ICcgKyBlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcnBjU2Vzc2lvblN0YXR1cyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmxpZmUgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2luZ2xlIE1hc3RlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGlmeUxvc3RDb25uZWN0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbmV0d29ya0Rpc2Nvbm5lY3QnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnV1Mgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdGVkIGJ1dCB0aGUgdXNlciB3YXMgYWxyZWFkeSBldmljdGVkIGR1ZSB0byB0aW1lb3V0J1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE11bHRpIE1hc3RlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgUlBDIG1ldGhvZCBpcyBvbmx5IHJlcXVpcmVkIHRvIGZpbmQgb3V0IHRoZSByZWFzb24gb2YgdGhlIGRpc2Nvbm5lY3Rpb246XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2hldGhlciB0aGUgY2xpZW50IGxvc3QgaXRzIG5ldHdvcmsgY29ubmVjdGlvbiBvciBhIE1hc3RlciBOb2RlIGNyYXNoZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmRSZXF1ZXN0KCdzZXNzaW9uU3RhdHVzJywgeyBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbi5zZXNzaW9uSWQgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgY2hlY2tpbmcgc2Vzc2lvbiBzdGF0dXMnLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5saWZlID09PSByZXNwb25zZS5saWZlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpZmUgc3RvcmVkIGluIHRoZSBjbGllbnQgbWF0Y2hlcyB0aGUgbGlmZSBzdG9yZWQgaW4gdGhlIHNlcnZlciwgaXQgbWVhbnMgdGhhdCB0aGUgY2xpZW50IGxvc3QgaXRzIG5ldHdvcmsgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGlmeUxvc3RDb25uZWN0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbmV0d29ya0Rpc2Nvbm5lY3QnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnV1Mgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdGVkIGJ1dCB0aGUgdXNlciB3YXMgYWxyZWFkeSBldmljdGVkIGR1ZSB0byB0aW1lb3V0J1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBsaWZlIHN0b3JlZCBpbiB0aGUgY2xpZW50IGlzIGJlbG93IHRoZSBsaWZlIHN0b3JlZCBpbiB0aGUgc2VydmVyLCBpdCBtZWFucyB0aGF0IHRoZSBNYXN0ZXIgTm9kZSBoYXMgY3Jhc2hlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGlmeUxvc3RDb25uZWN0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbm9kZUNyYXNoZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnV1Mgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdGVkIHRvIE9wZW5WaWR1IFNlcnZlciBidXQgeW91ciBNYXN0ZXIgTm9kZSBjcmFzaGVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAwMDcgJiYgZXJyb3IubWVzc2FnZSA9PT0gJ3JlY29ubmVjdGlvbiBlcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEt1cmVudG8gZXJyb3I6IGludmFsaWQgUlBDIHNlc3Npb25JZC4gVGhpcyBtZWFucyB0aGF0IHRoZSBrdXJlbnRvLWpzb25ycGMtc2VydmVyIG9mIG9wZW52aWR1LXNlcnZlciB3aGVyZSBrdXJlbnRvLWpzb25ycGMtY2xpZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpcyB0cnlpbmcgdG8gcmVjb25uZWN0IGRvZXMgbm90IGtub3cgYWJvdXQgdGhpcyBzZXNzaW9uSWQuIFRoaXMgY2FuIG1lYW4gdHdvIHRoaW5nczpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIDEpIG9wZW52aWR1LWJyb3dzZXIgbWFuYWdlZCB0byByZWNvbm5lY3QgYWZ0ZXIgYSB3aGlsZSwgYnV0IG9wZW52aWR1LXNlcnZlciBhbHJlYWR5IGV2aWN0ZWQgdGhlIHVzZXIgZm9yIG5vdCByZWNlaXZpbmcgcGluZy5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIDIpIG9wZW52aWR1LXNlcnZlciBwcm9jZXNzIGlzIGEgZGlmZmVyZW50IG9uZSBiZWNhdXNlIG9mIGEgbm9kZSBjcmFzaC5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNlbmQgYSBcInNlc3Npb25TdGF0dXNcIiBtZXRob2QgdG8gY2hlY2sgdGhlIHJlYXNvblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignSW52YWxpZCBSUEMgc2Vzc2lvbklkLiBDbGllbnQgbmV0d29yayBkaXNjb25uZWN0aW9uIG9yIE1hc3RlciBOb2RlIGNyYXNoJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBycGNTZXNzaW9uU3RhdHVzKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBycGNTZXNzaW9uU3RhdHVzKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5yZXNldFBpbmcoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub25SZWNvdmVyZWRDb25uZWN0aW9uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVjb25uZWN0ZWRDYWxsYmFjaygpOiB2b2lkIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1dlYnNvY2tldCByZWNvbm5lY3RlZCcpO1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlY29ubmVjdFdlYnNvY2tldFRocm91Z2hScGNDb25uZWN0TWV0aG9kKHRoaXMuc2Vzc2lvbi5jb25uZWN0aW9uLnJwY1Nlc3Npb25JZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdUaGVyZSB3YXMgbm8gcHJldmlvdXMgY29ubmVjdGlvbiB3aGVuIHJ1bm5pbmcgcmVjb25uZWN0aW9uIGNhbGxiYWNrJyk7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBTZXNzaW9uIG9iamVjdCBkaXNwYXRjaCAnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcgZXZlbnRcbiAgICAgICAgICAgICAgICBjb25zdCBzZXNzaW9uRGlzY29ubmVjdEV2ZW50ID0gbmV3IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCh0aGlzLnNlc3Npb24sICduZXR3b3JrRGlzY29ubmVjdCcpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lZS5lbWl0RXZlbnQoJ3Nlc3Npb25EaXNjb25uZWN0ZWQnLCBbc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudF0pO1xuICAgICAgICAgICAgICAgIHNlc3Npb25EaXNjb25uZWN0RXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaXNNYXN0ZXJOb2RlQ3Jhc2hlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFzdGVyTm9kZUhhc0NyYXNoZWQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1Jvb21BdmFpbGFibGUoKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLnNlc3Npb24gIT09IHVuZGVmaW5lZCAmJiB0aGlzLnNlc3Npb24gaW5zdGFuY2VvZiBTZXNzaW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdTZXNzaW9uIGluc3RhbmNlIG5vdCBmb3VuZCcpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1NjcmVlblNoYXJlKHZpZGVvU291cmNlOiBzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIHZpZGVvU291cmNlID09PSAnc2NyZWVuJyB8fCB2aWRlb1NvdXJjZSA9PT0gJ3dpbmRvdycgfHwgKHBsYXRmb3JtLmlzRWxlY3Ryb24oKSAmJiB2aWRlb1NvdXJjZS5zdGFydHNXaXRoKCdzY3JlZW46JykpO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBPcGVuVmlkdSB9IGZyb20gJy4vT3BlblZpZHUnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFB1Ymxpc2hlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1B1Ymxpc2hlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgUHVibGlzaGVyRXZlbnRNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudE1hcC9QdWJsaXNoZXJFdmVudE1hcCc7XG5pbXBvcnQgeyBTdHJlYW1FdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbUV2ZW50JztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5pbXBvcnQgeyBQbGF0Zm9ybVV0aWxzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9VdGlscy9QbGF0Zm9ybSc7XG5pbXBvcnQgeyBUeXBlT2ZWaWRlbyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvVHlwZU9mVmlkZW8nO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnRSZWFzb24gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9UeXBlcy9UeXBlcyc7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmxldCBwbGF0Zm9ybTogUGxhdGZvcm1VdGlscztcblxuLyoqXG4gKiBQYWNrcyBsb2NhbCBtZWRpYSBzdHJlYW1zLiBQYXJ0aWNpcGFudHMgY2FuIHB1Ymxpc2ggaXQgdG8gYSBzZXNzaW9uLiBJbml0aWFsaXplZCB3aXRoIHtAbGluayBPcGVuVmlkdS5pbml0UHVibGlzaGVyfSBtZXRob2QuXG4gKlxuICogU2VlIGF2YWlsYWJsZSBldmVudCBsaXN0ZW5lcnMgYXQge0BsaW5rIFB1Ymxpc2hlckV2ZW50TWFwfS5cbiAqL1xuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlciBleHRlbmRzIFN0cmVhbU1hbmFnZXIge1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBncmFudGVkIGFjY2VzcyB0byB0aGUgcmVxdWVzdGVkIGlucHV0IGRldmljZXMgb3Igbm90XG4gICAgICovXG4gICAgYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB5b3UgaGF2ZSBjYWxsZWQge0BsaW5rIFB1Ymxpc2hlci5zdWJzY3JpYmVUb1JlbW90ZX0gd2l0aCB2YWx1ZSBgdHJ1ZWAgb3IgYGZhbHNlYCAoKmZhbHNlKiBieSBkZWZhdWx0KVxuICAgICAqL1xuICAgIGlzU3Vic2NyaWJlZFRvUmVtb3RlID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBUaGUge0BsaW5rIFNlc3Npb259IHRvIHdoaWNoIHRoZSBQdWJsaXNoZXIgYmVsb25nc1xuICAgICAqL1xuICAgIHNlc3Npb246IFNlc3Npb247IC8vIEluaXRpYWxpemVkIGJ5IFNlc3Npb24ucHVibGlzaChQdWJsaXNoZXIpXG5cbiAgICBwcml2YXRlIGFjY2Vzc0RlbmllZCA9IGZhbHNlO1xuICAgIHByb3RlY3RlZCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzO1xuICAgIHByaXZhdGUgcGVybWlzc2lvbkRpYWxvZ1RpbWVvdXQ6IE5vZGVKUy5UaW1lcjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZpZGVvUmVmZXJlbmNlOiBIVE1MVmlkZW9FbGVtZW50O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzY3JlZW5TaGFyZVJlc2l6ZUludGVydmFsOiBOb2RlSlMuVGltZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCwgcHJvcGVydGllczogUHVibGlzaGVyUHJvcGVydGllcywgb3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKFxuICAgICAgICAgICAgbmV3IFN0cmVhbSghIW9wZW52aWR1LnNlc3Npb24gPyBvcGVudmlkdS5zZXNzaW9uIDogbmV3IFNlc3Npb24ob3BlbnZpZHUpLCB7XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyUHJvcGVydGllczogcHJvcGVydGllcyxcbiAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzOiB7fVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB0YXJnRWxcbiAgICAgICAgKTtcbiAgICAgICAgcGxhdGZvcm0gPSBQbGF0Zm9ybVV0aWxzLmdldEluc3RhbmNlKCk7XG4gICAgICAgIHRoaXMucHJvcGVydGllcyA9IHByb3BlcnRpZXM7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcblxuICAgICAgICB0aGlzLnN0cmVhbS5lZS5vbignbG9jYWwtc3RyZWFtLWRlc3Ryb3llZCcsIChyZWFzb246IFN0cmVhbUV2ZW50UmVhc29uKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gZmFsc2U7XG4gICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCB0aGlzLCAnc3RyZWFtRGVzdHJveWVkJywgdGhpcy5zdHJlYW0sIHJlYXNvbik7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtRGVzdHJveWVkJywgW3N0cmVhbUV2ZW50XSk7XG4gICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFB1Ymxpc2ggb3IgdW5wdWJsaXNoIHRoZSBhdWRpbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIGBlbmFibGVkYCB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiA+IF9Pbmx5IGlmIGBTZXNzaW9uLnB1Ymxpc2goUHVibGlzaGVyKWAgaGFzIGJlZW4gY2FsbGVkIGZvciB0aGlzIFB1Ymxpc2hlcl9cbiAgICAgKlxuICAgICAqIFRoZSB7QGxpbmsgU2Vzc2lvbn0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUge0BsaW5rIFB1Ymxpc2hlcn0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGFsc28gZGlzcGF0Y2ggdGhlIGV4YWN0IHNhbWUgZXZlbnRcbiAgICAgKlxuICAgICAqIFRoZSB7QGxpbmsgU2Vzc2lvbn0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgZXZlbnQgd2l0aCBgY2hhbmdlZFByb3BlcnR5YCBzZXQgdG8gYFwiYXVkaW9BY3RpdmVcImAgYW5kIGByZWFzb25gIHNldCB0byBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiBUaGUgcmVzcGVjdGl2ZSB7QGxpbmsgU3Vic2NyaWJlcn0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IHJlY2VpdmluZyB0aGlzIFB1Ymxpc2hlcidzIHN0cmVhbSB3aWxsIGFsc28gZGlzcGF0Y2ggdGhlIGV4YWN0IHNhbWUgZXZlbnRcbiAgICAgKlxuICAgICAqIFNlZSB7QGxpbmsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnR9IHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW5hYmxlZCBgdHJ1ZWAgdG8gcHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVucHVibGlzaCBpdFxuICAgICAqL1xuICAgIHB1Ymxpc2hBdWRpbyhlbmFibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gZW5hYmxlZCkge1xuICAgICAgICAgICAgY29uc3QgYWZmZWN0ZWRNZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0gPSB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKVxuICAgICAgICAgICAgICAgID8gdGhpcy5zdHJlYW0ubG9jYWxNZWRpYVN0cmVhbVdoZW5TdWJzY3JpYmVkVG9SZW1vdGUhXG4gICAgICAgICAgICAgICAgOiB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgYWZmZWN0ZWRNZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbiAmJiAhIXRoaXMuc3RyZWFtLnN0cmVhbUlkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICdhdWRpb0FjdGl2ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogZW5hYmxlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIGVuYWJsZWQsICFlbmFibGVkLCAncHVibGlzaEF1ZGlvJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcywgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIGVuYWJsZWQsICFlbmFibGVkLCAncHVibGlzaEF1ZGlvJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uc2VuZFZpZGVvRGF0YSh0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IGVuYWJsZWQ7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhcIidQdWJsaXNoZXInIGhhcyBcIiArIChlbmFibGVkID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHVibGlzaCBvciB1bnB1Ymxpc2ggdGhlIHZpZGVvIHN0cmVhbSAoaWYgYXZhaWxhYmxlKS4gQ2FsbGluZyB0aGlzIG1ldGhvZCB0d2ljZSBpbiBhIHJvdyBwYXNzaW5nIHNhbWUgYGVuYWJsZWRgIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqID4gX09ubHkgaWYgYFNlc3Npb24ucHVibGlzaChQdWJsaXNoZXIpYCBoYXMgYmVlbiBjYWxsZWQgZm9yIHRoaXMgUHVibGlzaGVyX1xuICAgICAqXG4gICAgICogVGhlIHtAbGluayBTZXNzaW9ufSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSB7QGxpbmsgUHVibGlzaGVyfSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogVGhlIHtAbGluayBTZXNzaW9ufSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSByZXNwZWN0aXZlIHtAbGluayBTdWJzY3JpYmVyfSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgcmVjZWl2aW5nIHRoaXMgUHVibGlzaGVyJ3Mgc3RyZWFtIHdpbGwgYWxzbyBkaXNwYXRjaCB0aGUgZXhhY3Qgc2FtZSBldmVudFxuICAgICAqXG4gICAgICogU2VlIHtAbGluayBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudH0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlbmFibGVkIGB0cnVlYCB0byBwdWJsaXNoIHRoZSB2aWRlbyBzdHJlYW0sIGBmYWxzZWAgdG8gdW5wdWJsaXNoIGl0XG4gICAgICogQHBhcmFtIHJlc291cmNlXG4gICAgICogLSBJZiBwYXJhbWV0ZXIgKipgZW5hYmxlZGAqKiBpcyBgZmFsc2VgLCB0aGlzIG9wdGlvbmFsIHBhcmFtZXRlciBpcyBvZiB0eXBlIGJvb2xlYW4uIEl0IGNhbiBiZSBzZXQgdG8gYHRydWVgIHRvIGZvcmNpYmx5IGZyZWUgdGhlIGhhcmR3YXJlIHJlc291cmNlIGFzc29jaWF0ZWQgdG8gdGhlIHZpZGVvIHRyYWNrLCBvciBjYW4gYmUgc2V0IHRvIGBmYWxzZWAgdG8ga2VlcCB0aGUgYWNjZXNzIHRvIHRoZSBoYXJkd2FyZSByZXNvdXJjZS5cbiAgICAgKiBOb3QgZnJlZWluZyB0aGUgcmVzb3VyY2UgbWFrZXMgdGhlIG9wZXJhdGlvbiBtdWNoIG1vcmUgZWZmaWNpZW50LCBidXQgZGVwZW5kaW5nIG9uIHRoZSBwbGF0Zm9ybSB0d28gc2lkZS1lZmZlY3RzIGNhbiBiZSBpbnRyb2R1Y2VkOiB0aGUgdmlkZW8gZGV2aWNlIG1heSBub3QgYmUgYWNjZXNzaWJsZSBieSBvdGhlciBhcHBsaWNhdGlvbnMgYW5kIHRoZSBhY2Nlc3MgbGlnaHQgb2ZcbiAgICAgKiB3ZWJjYW1zIG1heSByZW1haW4gb24uIFRoaXMgaXMgcGxhdGZvcm0tZGVwZW5kZW50OiBzb21lIGJyb3dzZXJzIHdpbGwgbm90IHByZXNlbnQgdGhlIHNpZGUtZWZmZWN0cyBldmVuIHdoZW4gbm90IGZyZWVpbmcgdGhlIHJlc291cmNlLjwvbGk+XG4gICAgICogLSBJZiBwYXJhbWV0ZXIgKipgZW5hYmxlZGAqKiBpcyBgdHJ1ZWAsIHRoaXMgb3B0aW9uYWwgcGFyYW1ldGVyIGlzIG9mIHR5cGUgW01lZGlhU3RyZWFtVHJhY2tdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RvY3MvV2ViL0FQSS9NZWRpYVN0cmVhbVRyYWNrKS4gSXQgY2FuIGJlIHNldCB0byBmb3JjZSB0aGUgcmVzdG9yYXRpb24gb2YgdGhlIHZpZGVvIHRyYWNrIHdpdGggYSBjdXN0b20gdHJhY2suIFRoaXMgbWF5IGJlXG4gICAgICogdXNlZnVsIGlmIHRoZSBQdWJsaXNoZXIgd2FzIHVucHVibGlzaGVkIGZyZWVpbmcgdGhlIGhhcmR3YXJlIHJlc291cmNlLCBhbmQgb3BlbnZpZHUtYnJvd3NlciBpcyBub3QgYWJsZSB0byBzdWNjZXNzZnVsbHkgcmUtY3JlYXRlIHRoZSB2aWRlbyB0cmFjayBhcyBpdCB3YXMgYmVmb3JlIHVucHVibGlzaGluZy4gSW4gdGhpcyB3YXkgcHJldmlvdXMgdHJhY2sgc2V0dGluZ3Mgd2lsbCBiZSBpZ25vcmVkIGFuZCB0aGlzIE1lZGlhU3RyZWFtVHJhY2tcbiAgICAgKiB3aWxsIGJlIHVzZWQgaW5zdGVhZC5cbiAgICAgKi9cbiAgICBwdWJsaXNoVmlkZW88VCBleHRlbmRzIGJvb2xlYW4+KGVuYWJsZWQ6IFQsIHJlc291cmNlPzogVCBleHRlbmRzIGZhbHNlID8gYm9vbGVhbiA6IE1lZGlhU3RyZWFtVHJhY2spOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gZW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFmZmVjdGVkTWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtID0gdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKClcbiAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnN0cmVhbS5sb2NhbE1lZGlhU3RyZWFtV2hlblN1YnNjcmliZWRUb1JlbW90ZSFcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgICAgIGxldCBtdXN0UmVzdGFydE1lZGlhU3RyZWFtID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYWZmZWN0ZWRNZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWVuYWJsZWQgJiYgcmVzb3VyY2UgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlbmFibGVkICYmIHRyYWNrLnJlYWR5U3RhdGUgPT09ICdlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlc291cmNlIHdhcyBmcmVlZFxuICAgICAgICAgICAgICAgICAgICAgICAgbXVzdFJlc3RhcnRNZWRpYVN0cmVhbSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIC8vIFRoZXJlIGlzIGEgVmlydHVhbCBCYWNrZ3JvdW5kIGZpbHRlciBhcHBsaWVkIHRoYXQgbXVzdCBiZSByZW1vdmVkIGluIGNhc2UgdGhlIGhhcmR3YXJlIG11c3QgYmUgZnJlZWRcbiAgICAgICAgICAgICAgICBpZiAoIWVuYWJsZWQgJiYgcmVzb3VyY2UgPT09IHRydWUgJiYgISF0aGlzLnN0cmVhbS5maWx0ZXIgJiYgdGhpcy5zdHJlYW0uZmlsdGVyLnR5cGUuc3RhcnRzV2l0aCgnVkI6JykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0ubGFzdFZCRmlsdGVyID0gdGhpcy5zdHJlYW0uZmlsdGVyOyAvLyBTYXZlIHRoZSBmaWx0ZXIgdG8gYmUgcmUtYXBwbGllZCBpbiBjYXNlIG9mIHVubXV0ZVxuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnN0cmVhbS5yZW1vdmVGaWx0ZXJBdXgodHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKG11c3RSZXN0YXJ0TWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmlkZW9UcmFjayA9IGFmZmVjdGVkTWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXTtcbiAgICAgICAgICAgICAgICAgICAgYWZmZWN0ZWRNZWRpYVN0cmVhbS5yZW1vdmVUcmFjayhvbGRWaWRlb1RyYWNrKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXBsYWNlVmlkZW9UcmFjayA9IGFzeW5jICh0cjogTWVkaWFTdHJlYW1UcmFjaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgYWZmZWN0ZWRNZWRpYVN0cmVhbS5hZGRUcmFjayh0cik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVwbGFjZVRyYWNrSW5SdGNSdHBTZW5kZXIodHIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0ubGFzdFZCRmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBvcHRpb25zID0gdGhpcy5zdHJlYW0ubGFzdFZCRmlsdGVyIS5vcHRpb25zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsYXN0RXhlY01ldGhvZCA9IHRoaXMuc3RyZWFtLmxhc3RWQkZpbHRlciEubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWxhc3RFeGVjTWV0aG9kICYmIGxhc3RFeGVjTWV0aG9kLm1ldGhvZCA9PT0gJ3VwZGF0ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBvcHRpb25zLCBsYXN0RXhlY01ldGhvZC5wYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuc3RyZWFtLmFwcGx5RmlsdGVyKHRoaXMuc3RyZWFtLmxhc3RWQkZpbHRlciEudHlwZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbS5sYXN0VkJGaWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVzb3VyY2UgJiYgcmVzb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZXBsYWNlVmlkZW9UcmFjayhyZXNvdXJjZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLnN0cmVhbS5sYXN0VmlkZW9UcmFja0NvbnN0cmFpbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgcmVwbGFjZVZpZGVvVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uICYmICEhdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5OiAndmlkZW9BY3RpdmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlOiBlbmFibGVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hWaWRlbydcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFlbmFibGVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwdWJsaXNoVmlkZW8nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuc3RyZWFtLCAndmlkZW9BY3RpdmUnLCBlbmFibGVkLCAhZW5hYmxlZCwgJ3B1Ymxpc2hWaWRlbycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uc2VuZFZpZGVvRGF0YSh0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhcIidQdWJsaXNoZXInIGhhcyBcIiArIChlbmFibGVkID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIHZpZGVvIHN0cmVhbScpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGwgdGhpcyBtZXRob2QgYmVmb3JlIHtAbGluayBTZXNzaW9uLnB1Ymxpc2h9IGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9IHZhbHVlICE9PSB1bmRlZmluZWQgPyB2YWx1ZSA6IHRydWU7XG4gICAgICAgIHRoaXMuaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5zdHJlYW0uc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIHtAbGluayBFdmVudERpc3BhdGNoZXIub259XG4gICAgICovXG4gICAgb248SyBleHRlbmRzIGtleW9mIFB1Ymxpc2hlckV2ZW50TWFwPih0eXBlOiBLLCBoYW5kbGVyOiAoZXZlbnQ6IFB1Ymxpc2hlckV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9uKDxhbnk+dHlwZSwgaGFuZGxlcik7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1DcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLm9uKCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NBbGxvd2VkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NBbGxvd2VkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzRGVuaWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMuYWNjZXNzRGVuaWVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RlbmllZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUge0BsaW5rIEV2ZW50RGlzcGF0Y2hlci5vbmNlfVxuICAgICAqL1xuICAgIG9uY2U8SyBleHRlbmRzIGtleW9mIFB1Ymxpc2hlckV2ZW50TWFwPih0eXBlOiBLLCBoYW5kbGVyOiAoZXZlbnQ6IFB1Ymxpc2hlckV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9uY2UoPGFueT50eXBlLCBoYW5kbGVyKTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUNyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnN0cmVhbSAmJiB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHRoaXMuc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUub25jZSgnc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgdGhpcy5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnYWNjZXNzQWxsb3dlZCcpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFjY2Vzc0FsbG93ZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcsIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0RlbmllZCcpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFjY2Vzc0RlbmllZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIHtAbGluayBFdmVudERpc3BhdGNoZXIub2ZmfVxuICAgICAqL1xuICAgIG9mZjxLIGV4dGVuZHMga2V5b2YgUHVibGlzaGVyRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI/OiAoZXZlbnQ6IFB1Ymxpc2hlckV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9mZig8YW55PnR5cGUsIGhhbmRsZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXBsYWNlcyB0aGUgY3VycmVudCB2aWRlbyBvciBhdWRpbyB0cmFjayB3aXRoIGEgZGlmZmVyZW50IG9uZS4gVGhpcyBhbGxvd3MgeW91IHRvIHJlcGxhY2UgYW4gb25nb2luZyB0cmFjayB3aXRoIGEgZGlmZmVyZW50IG9uZVxuICAgICAqIHdpdGhvdXQgaGF2aW5nIHRvIHJlbmVnb3RpYXRlIHRoZSB3aG9sZSBXZWJSVEMgY29ubmVjdGlvbiAodGhhdCBpcywgaW5pdGlhbGl6aW5nIGEgbmV3IFB1Ymxpc2hlciwgdW5wdWJsaXNoaW5nIHRoZSBwcmV2aW91cyBvbmVcbiAgICAgKiBhbmQgcHVibGlzaGluZyB0aGUgbmV3IG9uZSkuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIG5ldyBNZWRpYVN0cmVhbVRyYWNrIGJ5IHVzaW5nIHRoZSBuYXRpdmUgV2ViIEFQSSBvciBzaW1wbHkgd2l0aCB7QGxpbmsgT3BlblZpZHUuZ2V0VXNlck1lZGlhfSBtZXRob2QuXG4gICAgICpcbiAgICAgKiAqKldBUk5JTkc6IHRoaXMgbWV0aG9kIGhhcyBiZWVuIHByb3ZlbiB0byB3b3JrIGluIHRoZSBtYWpvcml0eSBvZiBjYXNlcywgYnV0IHRoZXJlIG1heSBiZSBzb21lIGNvbWJpbmF0aW9ucyBvZiBwdWJsaXNoZWQvcmVwbGFjZWQgdHJhY2tzIHRoYXQgbWF5IGJlIGluY29tcGF0aWJsZVxuICAgICAqIGJldHdlZW4gdGhlbSBhbmQgYnJlYWsgdGhlIGNvbm5lY3Rpb24gaW4gT3BlblZpZHUgU2VydmVyLiBBIGNvbXBsZXRlIHJlbmVnb3RpYXRpb24gbWF5IGJlIHRoZSBvbmx5IHNvbHV0aW9uIGluIHRoaXMgY2FzZS5cbiAgICAgKiBWaXNpdCBbUlRDUnRwU2VuZGVyLnJlcGxhY2VUcmFja10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1JUQ1J0cFNlbmRlci9yZXBsYWNlVHJhY2spIGRvY3VtZW50YXRpb24gZm9yIGZ1cnRoZXIgZGV0YWlscy4qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHRyYWNrIFRoZSBbTWVkaWFTdHJlYW1UcmFja10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL01lZGlhU3RyZWFtVHJhY2spIG9iamVjdCB0byByZXBsYWNlIHRoZSBjdXJyZW50IG9uZS5cbiAgICAgKiBJZiBpdCBpcyBhbiBhdWRpbyB0cmFjaywgdGhlIGN1cnJlbnQgYXVkaW8gdHJhY2sgd2lsbCBiZSB0aGUgcmVwbGFjZWQgb25lLiBJZiBpdCBpcyBhIHZpZGVvIHRyYWNrLCB0aGUgY3VycmVudCB2aWRlbyB0cmFjayB3aWxsIGJlIHRoZSByZXBsYWNlZCBvbmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHRyYWNrIHdhcyBzdWNjZXNzZnVsbHkgcmVwbGFjZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICBhc3luYyByZXBsYWNlVHJhY2sodHJhY2s6IE1lZGlhU3RyZWFtVHJhY2spOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZVRyYWNrQXV4KHRyYWNrLCB0cnVlKTtcbiAgICB9XG5cbiAgICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRpYWxpemUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsZXQgY29uc3RyYWludHM6IE1lZGlhU3RyZWFtQ29uc3RyYWludHMgPSB7fTtcbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50c0F1eDogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgY29uc3QgdGltZUZvckRpYWxvZ0V2ZW50ID0gMjAwMDtcbiAgICAgICAgICAgIGxldCBzdGFydFRpbWU7XG5cbiAgICAgICAgICAgIGNvbnN0IGVycm9yQ2FsbGJhY2sgPSAob3BlblZpZHVFcnJvcjogT3BlblZpZHVFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYFB1Ymxpc2hlciBpbml0aWFsaXphdGlvbiBmYWlsZWQuICR7b3BlblZpZHVFcnJvci5uYW1lfTogJHtvcGVuVmlkdUVycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NDYWxsYmFjayA9IChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFjY2Vzc0FsbG93ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzRGVuaWVkID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKDxNZWRpYVN0cmVhbVRyYWNrPnRoaXMucHJvcGVydGllcy5hdWRpb1NvdXJjZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLnJlbW92ZVRyYWNrKG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5hZGRUcmFjayg8TWVkaWFTdHJlYW1UcmFjaz50aGlzLnByb3BlcnRpZXMudmlkZW9Tb3VyY2UpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEFwcGx5IFB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaEF1ZGlvIGFuZCBQdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hWaWRlb1xuICAgICAgICAgICAgICAgIGlmICghIW1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuc3RyZWFtLmF1ZGlvQWN0aXZlICE9PSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogISF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW87XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIW1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlICE9PSBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogISF0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW87XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gU2V0IENvbnRlbnQgSGludCBvbiBhbGwgTWVkaWFTdHJlYW1UcmFja3NcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIG1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0cmFjay5jb250ZW50SGludD8ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb250ZW50SGludCBmb3IgYXVkaW86IFwiXCIsIFwic3BlZWNoXCIsIFwic3BlZWNoLXJlY29nbml0aW9uXCIsIFwibXVzaWNcIi5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGh0dHBzOi8vdzNjLmdpdGh1Yi5pby9tc3QtY29udGVudC1oaW50LyNhdWRpby1jb250ZW50LWhpbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFjay5jb250ZW50SGludCA9ICcnO1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYEF1ZGlvIHRyYWNrIENvbnRlbnQgSGludCBzZXQ6ICcke3RyYWNrLmNvbnRlbnRIaW50fSdgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0cmFjay5jb250ZW50SGludD8ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb250ZW50SGludCBmb3IgdmlkZW86IFwiXCIsIFwibW90aW9uXCIsIFwiZGV0YWlsXCIsIFwidGV4dFwiLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly93M2MuZ2l0aHViLmlvL21zdC1jb250ZW50LWhpbnQvI3ZpZGVvLWNvbnRlbnQtaGludHNcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodGhpcy5zdHJlYW0udHlwZU9mVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFR5cGVPZlZpZGVvLlNDUkVFTjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suY29udGVudEhpbnQgPSAnZGV0YWlsJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBUeXBlT2ZWaWRlby5DVVNUT006XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdDVVNUT00gdHlwZSB2aWRlbyB0cmFjayB3YXMgcHJvdmlkZWQgd2l0aG91dCBDb250ZW50IEhpbnQhJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLmNvbnRlbnRIaW50ID0gJ21vdGlvbic7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVHlwZU9mVmlkZW8uQ0FNRVJBOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVHlwZU9mVmlkZW8uSVBDQU06XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suY29udGVudEhpbnQgPSAnbW90aW9uJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhgVmlkZW8gdHJhY2sgQ29udGVudCBIaW50IHNldDogJyR7dHJhY2suY29udGVudEhpbnR9J2ApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplVmlkZW9SZWZlcmVuY2UobWVkaWFTdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBzdWJzY3JpYmVkIHRvIG91ciByZW1vdGUgd2UgZG9uJ3Qgc3RpbGwgc2V0IHRoZSBNZWRpYVN0cmVhbSBvYmplY3QgaW4gdGhlIHZpZGVvIGVsZW1lbnRzIHRvXG4gICAgICAgICAgICAgICAgICAgIC8vIGF2b2lkIGVhcmx5ICdzdHJlYW1QbGF5aW5nJyBldmVudFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS51cGRhdGVNZWRpYVN0cmVhbUluVmlkZW9zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmZpcnN0VmlkZW9FbGVtZW50O1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzU2VuZFZpZGVvKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSGFzIHZpZGVvIHRyYWNrXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0VmlkZW9EaW1lbnNpb25zKCkudGhlbigoZGltZW5zaW9ucykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBkaW1lbnNpb25zLndpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogZGltZW5zaW9ucy5oZWlnaHRcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBpbnRlcnZhbCB0byBsaXN0ZW4gZm9yIHNjcmVlbiByZXNpemUgZXZlbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zY3JlZW5TaGFyZVJlc2l6ZUludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXR0aW5nczogTWVkaWFUcmFja1NldHRpbmdzID0gbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXS5nZXRTZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdXaWR0aCA9IHNldHRpbmdzLndpZHRoO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdIZWlnaHQgPSBzZXR0aW5ncy5oZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpZHRoQ2hhbmdlZCA9IG5ld1dpZHRoICE9IG51bGwgJiYgbmV3V2lkdGggIT09IHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaGVpZ2h0Q2hhbmdlZCA9IG5ld0hlaWdodCAhPSBudWxsICYmIG5ld0hlaWdodCAhPT0gdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zLmhlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgJiYgKHdpZHRoQ2hhbmdlZCB8fCBoZWlnaHRDaGFuZ2VkKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kVmlkZW9EaW1lbnNpb25zQ2hhbmdlZEV2ZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NjcmVlblJlc2l6ZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy53aWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1dpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SGVpZ2h0IHx8IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCA2NTApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUuZW1pdEV2ZW50KCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gT25seSBhdWRpbyB0cmFjayAobm8gdmlkZW9EaW1lbnNpb25zKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2ggPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgW10pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBnZXRNZWRpYVN1Y2Nlc3MgPSBhc3luYyAobWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtLCBkZWZpbmVkQXVkaW9Db25zdHJhaW50KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpICYmIHRoaXMuc3RyZWFtLmlzU2VuZEF1ZGlvKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiBnZXR0aW5nIGRlc2t0b3AgYXMgdXNlciBtZWRpYSBhdWRpbyBjb25zdHJhaW50IG11c3QgYmUgZmFsc2UuIE5vdyB3ZSBjYW4gYXNrIGZvciBpdCBpZiByZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50c0F1eC5hdWRpbyA9IGRlZmluZWRBdWRpb0NvbnN0cmFpbnQ7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LnZpZGVvID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0UGVybWlzc2lvbkRpYWxvZ1RpbWVyKHRpbWVGb3JEaWFsb2dFdmVudCk7XG5cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvT25seVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzQXV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJQZXJtaXNzaW9uRGlhbG9nVGltZXIoc3RhcnRUaW1lLCB0aW1lRm9yRGlhbG9nRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJQZXJtaXNzaW9uRGlhbG9nVGltZXIoc3RhcnRUaW1lLCB0aW1lRm9yRGlhbG9nRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayh0aGlzLm9wZW52aWR1LmdlbmVyYXRlQXVkaW9EZXZpY2VFcnJvcihlcnJvciwgY29uc3RyYWludHMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgZ2V0TWVkaWFFcnJvciA9IGFzeW5jIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgZ2V0TWVkaWFFcnJvcjogJHtlcnJvci50b1N0cmluZygpfWApO1xuICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJQZXJtaXNzaW9uRGlhbG9nVGltZXIoc3RhcnRUaW1lLCB0aW1lRm9yRGlhbG9nRXZlbnQpO1xuICAgICAgICAgICAgICAgIGlmIChlcnJvci5uYW1lID09PSAnRXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBPdmVyQ29uc3RyYWluZWRFcnJvciBoYXMgYXMgbmFtZSBwcm9wZXJ0eSAnRXJyb3InIGluc3RlYWQgb2YgJ092ZXJDb25zdHJhaW5lZEVycm9yJ1xuICAgICAgICAgICAgICAgICAgICBlcnJvci5uYW1lID0gZXJyb3IuY29uc3RydWN0b3IubmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoZXJyb3IubmFtZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ25vdGZvdW5kZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZWRpYVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlbzogY29uc3RyYWludHMudmlkZW9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5JTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5JTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90YWxsb3dlZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRURcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdvdmVyY29uc3RyYWluZWRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiQXVkaW8gaW5wdXQgZGV2aWNlIHdpdGggZGV2aWNlSWQgJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy5hdWRpbykuZGV2aWNlSWQhISkuZXhhY3QgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlBVQkxJU0hFUl9QUk9QRVJUSUVTX0VSUk9SO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJBdWRpbyBpbnB1dCBkZXZpY2UgZG9lc24ndCBzdXBwb3J0IHRoZSB2YWx1ZSBwYXNzZWQgZm9yIGNvbnN0cmFpbnQgJ1wiICsgZXJyb3IuY29uc3RyYWludCArIFwiJ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb25zdHJhaW50LnRvTG93ZXJDYXNlKCkgPT09ICdkZXZpY2VpZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiVmlkZW8gaW5wdXQgZGV2aWNlIHdpdGggZGV2aWNlSWQgJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICg8Q29uc3RyYWluRE9NU3RyaW5nUGFyYW1ldGVycz4oPE1lZGlhVHJhY2tDb25zdHJhaW50cz5jb25zdHJhaW50cy52aWRlbykuZGV2aWNlSWQhISkuZXhhY3QgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInIG5vdCBmb3VuZFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlBVQkxJU0hFUl9QUk9QRVJUSUVTX0VSUk9SO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJWaWRlbyBpbnB1dCBkZXZpY2UgZG9lc24ndCBzdXBwb3J0IHRoZSB2YWx1ZSBwYXNzZWQgZm9yIGNvbnN0cmFpbnQgJ1wiICsgZXJyb3IuY29uc3RyYWludCArIFwiJ1wiO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdhYm9ydGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90cmVhZGFibGVlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5ERVZJQ0VfQUxSRUFEWV9JTl9VU0U7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5HRU5FUklDX0VSUk9SO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbXlDb25zdHJhaW50cyA9IGF3YWl0IHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHRoaXMucHJvcGVydGllcyk7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAoISFteUNvbnN0cmFpbnRzLnZpZGVvVHJhY2sgJiYgISFteUNvbnN0cmFpbnRzLmF1ZGlvVHJhY2spIHx8XG4gICAgICAgICAgICAgICAgICAgICghIW15Q29uc3RyYWludHMuYXVkaW9UcmFjayAmJiBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzPy52aWRlbyA9PT0gZmFsc2UpIHx8XG4gICAgICAgICAgICAgICAgICAgICghIW15Q29uc3RyYWludHMudmlkZW9UcmFjayAmJiBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzPy5hdWRpbyA9PT0gZmFsc2UpXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE5vIG5lZWQgdG8gY2FsbCBnZXRVc2VyTWVkaWEgYXQgYWxsLiBNZWRpYVN0cmVhbVRyYWNrcyBhbHJlYWR5IHByb3ZpZGVkXG4gICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayh0aGlzLm9wZW52aWR1LmFkZEFscmVhZHlQcm92aWRlZFRyYWNrcyhteUNvbnN0cmFpbnRzLCBuZXcgTWVkaWFTdHJlYW0oKSwgdGhpcy5zdHJlYW0pKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50cyA9IG15Q29uc3RyYWludHMuY29uc3RyYWludHM7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0Ym91bmRTdHJlYW1PcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFDb25zdHJhaW50czogY29uc3RyYWludHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2V0T3V0Ym91bmRTdHJlYW1PcHRpb25zKG91dGJvdW5kU3RyZWFtT3B0aW9ucyk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCA9IGNvbnN0cmFpbnRzLmF1ZGlvID09PSB1bmRlZmluZWQgPyB0cnVlIDogY29uc3RyYWludHMuYXVkaW87XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gdGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgPyBmYWxzZSA6IGRlZmluZWRBdWRpb0NvbnN0cmFpbnQ7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LnZpZGVvID0gY29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0UGVybWlzc2lvbkRpYWxvZ1RpbWVyKHRpbWVGb3JEaWFsb2dFdmVudCk7XG5cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSAmJiBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzWydnZXREaXNwbGF5TWVkaWEnXSAmJiAhcGxhdGZvcm0uaXNFbGVjdHJvbigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW0gPSBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzWydnZXREaXNwbGF5TWVkaWEnXSh7IHZpZGVvOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuYWRkQWxyZWFkeVByb3ZpZGVkVHJhY2tzKG15Q29uc3RyYWludHMsIG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5sYXN0VmlkZW9UcmFja0NvbnN0cmFpbnRzID0gY29uc3RyYWludHNBdXgudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW0gPSBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5hZGRBbHJlYWR5UHJvdmlkZWRUcmFja3MobXlDb25zdHJhaW50cywgbWVkaWFTdHJlYW0sIHRoaXMuc3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBnZXRNZWRpYVN1Y2Nlc3MobWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgZ2V0TWVkaWFFcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYXN5bmMgcmVwbGFjZVRyYWNrQXV4KHRyYWNrOiBNZWRpYVN0cmVhbVRyYWNrLCB1cGRhdGVMYXN0Q29uc3RyYWludHM6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgLy8gU2V0IGZpZWxkIFwiZW5hYmxlZFwiIG9mIHRoZSBuZXcgdHJhY2sgdG8gdGhlIHByZXZpb3VzIHZhbHVlXG4gICAgICAgIGNvbnN0IHRyYWNrT3JpZ2luYWxFbmFibGVkVmFsdWU6IGJvb2xlYW4gPSB0cmFjay5lbmFibGVkO1xuICAgICAgICBpZiAodHJhY2sua2luZCA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlO1xuICAgICAgICB9IGVsc2UgaWYgKHRyYWNrLmtpbmQgPT09ICdhdWRpbycpIHtcbiAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBPbmx5IGlmIHRoZSBQdWJsaXNoZXIgaGFzIGJlZW4gcHVibGlzaGVkIGlzIG5lY2Vzc2FyeSB0byBjYWxsIG5hdGl2ZSBXZWIgQVBJIFJUQ1J0cFNlbmRlci5yZXBsYWNlVHJhY2tcbiAgICAgICAgICAgICAgICAvLyBJZiBpdCBoYXMgbm90IGJlZW4gcHVibGlzaGVkIHlldCwgcmVwbGFjaW5nIGl0IG9uIHRoZSBNZWRpYVN0cmVhbSBvYmplY3QgaXMgZW5vdWdoXG4gICAgICAgICAgICAgICAgdGhpcy5yZXBsYWNlVHJhY2tJbk1lZGlhU3RyZWFtKHRyYWNrLCB1cGRhdGVMYXN0Q29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlcGxhY2VUcmFja0luUnRjUnRwU2VuZGVyKHRyYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUHVibGlzaGVyIG5vdCBwdWJsaXNoZWQuIFNpbXBseSByZXBsYWNlIHRoZSB0cmFjayBvbiB0aGUgbG9jYWwgTWVkaWFTdHJlYW1cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZXBsYWNlVHJhY2tJbk1lZGlhU3RyZWFtKHRyYWNrLCB1cGRhdGVMYXN0Q29uc3RyYWludHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHRyYWNrT3JpZ2luYWxFbmFibGVkVmFsdWU7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKlxuICAgICAqIFRvIG9idGFpbiB0aGUgdmlkZW9EaW1lbnNpb25zIHdlIHdhaXQgZm9yIHRoZSB2aWRlbyByZWZlcmVuY2UgdG8gaGF2ZSBlbm91Z2ggbWV0YWRhdGFcbiAgICAgKiBhbmQgdGhlbiB0cnkgdG8gdXNlIE1lZGlhU3RyZWFtVHJhY2suZ2V0U2V0dGluZ3NNZXRob2QoKS4gSWYgbm90IGF2YWlsYWJsZSwgdGhlbiB3ZVxuICAgICAqIHVzZSB0aGUgSFRNTFZpZGVvRWxlbWVudCBwcm9wZXJ0aWVzIHZpZGVvV2lkdGggYW5kIHZpZGVvSGVpZ2h0XG4gICAgICovXG4gICAgZ2V0VmlkZW9EaW1lbnNpb25zKCk6IFByb21pc2U8eyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IG51bWJlciB9PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAvLyBJb25pYyBpT1MgYW5kIFNhZmFyaSBpT1Mgc3VwcG9zZWRseSByZXF1aXJlIHRoZSB2aWRlbyBlbGVtZW50IHRvIGFjdHVhbGx5IGV4aXN0IGluc2lkZSB0aGUgRE9NXG4gICAgICAgICAgICBjb25zdCByZXF1aXJlc0RvbUluc2VydGlvbjogYm9vbGVhbiA9IHBsYXRmb3JtLmlzSW9uaWNJb3MoKSB8fCBwbGF0Zm9ybS5pc0lPU1dpdGhTYWZhcmkoKTtcblxuICAgICAgICAgICAgbGV0IGxvYWRlZG1ldGFkYXRhTGlzdGVuZXI7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlRGltZW5zaW9ucyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgd2lkdGg6IG51bWJlcjtcbiAgICAgICAgICAgICAgICBsZXQgaGVpZ2h0OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2V0dGluZ3MgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGggPSBzZXR0aW5ncy53aWR0aCB8fCB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIGhlaWdodCA9IHNldHRpbmdzLmhlaWdodCB8fCB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvSGVpZ2h0O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdNZWRpYVN0cmVhbVRyYWNrIGRvZXMgbm90IGhhdmUgZ2V0U2V0dGluZ3MgbWV0aG9kIG9uICcgKyBwbGF0Zm9ybS5nZXREZXNjcmlwdGlvbigpKTtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGggPSB0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIGhlaWdodCA9IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGxvYWRlZG1ldGFkYXRhTGlzdGVuZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgbG9hZGVkbWV0YWRhdGFMaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZXF1aXJlc0RvbUluc2VydGlvbikge1xuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHsgd2lkdGgsIGhlaWdodCB9KTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvUmVmZXJlbmNlLnJlYWR5U3RhdGUgPj0gMSkge1xuICAgICAgICAgICAgICAgIC8vIFRoZSB2aWRlbyBhbHJlYWR5IGhhcyBtZXRhZGF0YSBhdmFpbGFibGVcbiAgICAgICAgICAgICAgICAvLyBObyBuZWVkIG9mIGxvYWRlZG1ldGFkYXRhIGV2ZW50XG4gICAgICAgICAgICAgICAgcmVzb2x2ZURpbWVuc2lvbnMoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIHZpZGVvIGRvZXMgbm90IGhhdmUgbWV0YWRhdGEgYXZhaWxhYmxlIHlldFxuICAgICAgICAgICAgICAgIC8vIE11c3QgbGlzdGVuIHRvIGxvYWRlZG1ldGFkYXRhIGV2ZW50XG4gICAgICAgICAgICAgICAgbG9hZGVkbWV0YWRhdGFMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISF0aGlzLnZpZGVvUmVmZXJlbmNlLnZpZGVvV2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVEaW1lbnNpb25zKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSwgNDApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZURpbWVuc2lvbnMoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZS5hZGRFdmVudExpc3RlbmVyKCdsb2FkZWRtZXRhZGF0YScsIGxvYWRlZG1ldGFkYXRhTGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIGlmIChyZXF1aXJlc0RvbUluc2VydGlvbikge1xuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMudmlkZW9SZWZlcmVuY2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlZXN0YWJsaXNoU3RyZWFtUGxheWluZ0V2ZW50KCkge1xuICAgICAgICBpZiAodGhpcy5lZS5nZXRMaXN0ZW5lcnMoJ3N0cmVhbVBsYXlpbmcnKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRpYWxpemVWaWRlb1JlZmVyZW5jZShtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0pIHtcbiAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZS5tdXRlZCA9IHRydWU7XG4gICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UuYXV0b3BsYXkgPSB0cnVlO1xuICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmNvbnRyb2xzID0gZmFsc2U7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzU2FmYXJpQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAocGxhdGZvcm0uaXNJUGhvbmVPcklQYWQoKSAmJlxuICAgICAgICAgICAgICAgIChwbGF0Zm9ybS5pc0Nocm9tZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0VkZ2VNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNPcGVyYU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0ZpcmVmb3hNb2JpbGVCcm93c2VyKCkpKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UucGxheXNJbmxpbmUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RyZWFtLnNldE1lZGlhU3RyZWFtKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgaWYgKCEhdGhpcy5maXJzdFZpZGVvRWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVWaWRlb0VsZW1lbnQodGhpcy5maXJzdFZpZGVvRWxlbWVudC50YXJnZXRFbGVtZW50LCA8VmlkZW9JbnNlcnRNb2RlPnRoaXMucHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLnNyY09iamVjdCA9IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlcGxhY2VUcmFja0luTWVkaWFTdHJlYW0odHJhY2s6IE1lZGlhU3RyZWFtVHJhY2ssIHVwZGF0ZUxhc3RDb25zdHJhaW50czogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBjb25zdCBtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0gPSB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKVxuICAgICAgICAgICAgPyB0aGlzLnN0cmVhbS5sb2NhbE1lZGlhU3RyZWFtV2hlblN1YnNjcmliZWRUb1JlbW90ZSFcbiAgICAgICAgICAgIDogdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgbGV0IHJlbW92ZWRUcmFjazogTWVkaWFTdHJlYW1UcmFjaztcbiAgICAgICAgaWYgKHRyYWNrLmtpbmQgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgIHJlbW92ZWRUcmFjayA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAgICAgICAgICBpZiAodXBkYXRlTGFzdENvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0ubGFzdFZpZGVvVHJhY2tDb25zdHJhaW50cyA9IHRyYWNrLmdldENvbnN0cmFpbnRzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZW1vdmVkVHJhY2sgPSBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdO1xuICAgICAgICB9XG4gICAgICAgIHJlbW92ZWRUcmFjay5lbmFibGVkID0gZmFsc2U7XG4gICAgICAgIHJlbW92ZWRUcmFjay5zdG9wKCk7XG4gICAgICAgIG1lZGlhU3RyZWFtLnJlbW92ZVRyYWNrKHJlbW92ZWRUcmFjayk7XG4gICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKHRyYWNrKTtcbiAgICAgICAgY29uc3QgdHJhY2tJbmZvID0ge1xuICAgICAgICAgICAgb2xkTGFiZWw6IHJlbW92ZWRUcmFjaz8ubGFiZWwgfHwgJycsXG4gICAgICAgICAgICBuZXdMYWJlbDogdHJhY2s/LmxhYmVsIHx8ICcnXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0cmFjay5raW5kID09PSAndmlkZW8nICYmIHVwZGF0ZUxhc3RDb25zdHJhaW50cykge1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kTmV3VmlkZW9EaW1lbnNpb25zSWZSZXF1aXJlZCh0aGlzLCAndHJhY2tSZXBsYWNlZCcsIDUwLCAzMCk7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRUcmFja0NoYW5nZWRFdmVudCh0aGlzLCB0cmFja0luZm8ub2xkTGFiZWwsIHRyYWNrSW5mby5uZXdMYWJlbCwgJ3ZpZGVvVHJhY2snKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLnNlbmRWaWRlb0RhdGEodGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlciwgNSwgdHJ1ZSwgNSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodHJhY2sua2luZCA9PT0gJ2F1ZGlvJyAmJiB1cGRhdGVMYXN0Q29uc3RyYWludHMpIHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFRyYWNrQ2hhbmdlZEV2ZW50KHRoaXMsIHRyYWNrSW5mby5vbGRMYWJlbCwgdHJhY2tJbmZvLm5ld0xhYmVsLCAnYXVkaW9UcmFjaycpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0cmFjay5raW5kID09PSAnYXVkaW8nKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNhYmxlSGFya1NwZWFraW5nRXZlbnQoZmFsc2UpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzYWJsZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudChmYWxzZSk7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNhYmxlSGFya1ZvbHVtZUNoYW5nZUV2ZW50KGZhbHNlKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmluaXRIYXJrRXZlbnRzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgc2V0UGVybWlzc2lvbkRpYWxvZ1RpbWVyKHdhaXRUaW1lOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RpYWxvZ09wZW5lZCcsIFtdKTtcbiAgICAgICAgfSwgd2FpdFRpbWUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgY2xlYXJQZXJtaXNzaW9uRGlhbG9nVGltZXIoc3RhcnRUaW1lOiBudW1iZXIsIHdhaXRUaW1lOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucGVybWlzc2lvbkRpYWxvZ1RpbWVvdXQpO1xuICAgICAgICBpZiAoRGF0ZS5ub3coKSAtIHN0YXJ0VGltZSA+IHdhaXRUaW1lKSB7XG4gICAgICAgICAgICAvLyBQZXJtaXNzaW9uIGRpYWxvZyB3YXMgc2hvd24gYW5kIG5vdyBpcyBjbG9zZWRcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdhY2Nlc3NEaWFsb2dDbG9zZWQnLCBbXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlcGxhY2VUcmFja0luUnRjUnRwU2VuZGVyKHRyYWNrOiBNZWRpYVN0cmVhbVRyYWNrKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHNlbmRlcnM6IFJUQ1J0cFNlbmRlcltdID0gdGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKS5nZXRTZW5kZXJzKCk7XG4gICAgICAgIGxldCBzZW5kZXI6IFJUQ1J0cFNlbmRlciB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHRyYWNrLmtpbmQgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgIHNlbmRlciA9IHNlbmRlcnMuZmluZCgocykgPT4gISFzLnRyYWNrICYmIHMudHJhY2sua2luZCA9PT0gJ3ZpZGVvJyk7XG4gICAgICAgICAgICBpZiAoIXNlbmRlcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZXJlJ3Mgbm8gcmVwbGFjZWFibGUgdHJhY2sgZm9yIHRoYXQga2luZCBvZiBNZWRpYVN0cmVhbVRyYWNrIGluIHRoaXMgUHVibGlzaGVyIG9iamVjdFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0cmFjay5raW5kID09PSAnYXVkaW8nKSB7XG4gICAgICAgICAgICBzZW5kZXIgPSBzZW5kZXJzLmZpbmQoKHMpID0+ICEhcy50cmFjayAmJiBzLnRyYWNrLmtpbmQgPT09ICdhdWRpbycpO1xuICAgICAgICAgICAgaWYgKCFzZW5kZXIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGVyZSdzIG5vIHJlcGxhY2VhYmxlIHRyYWNrIGZvciB0aGF0IGtpbmQgb2YgTWVkaWFTdHJlYW1UcmFjayBpbiB0aGlzIFB1Ymxpc2hlciBvYmplY3RcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gdHJhY2sga2luZCAnICsgdHJhY2sua2luZCk7XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgKHNlbmRlciBhcyBSVENSdHBTZW5kZXIpLnJlcGxhY2VUcmFjayh0cmFjayk7XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSAnLi9GaWx0ZXInO1xuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuL09wZW5WaWR1JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4vUHVibGlzaGVyJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuL1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBDYXBhYmlsaXRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL0NhcGFiaWxpdGllcyc7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBTaWduYWxPcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TaWduYWxPcHRpb25zJztcbmltcG9ydCB7IFN1YnNjcmliZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdWJzY3JpYmVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBSZW1vdGVDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL1JlbW90ZUNvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IExvY2FsQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Mb2NhbENvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IFNlc3Npb25PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvU2Vzc2lvbk9wdGlvbnMnO1xuaW1wb3J0IHsgU2Vzc2lvbkV2ZW50TWFwIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnRNYXAvU2Vzc2lvbkV2ZW50TWFwJztcbmltcG9ydCB7IENvbm5lY3Rpb25FdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0Nvbm5lY3Rpb25FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0ZpbHRlckV2ZW50JztcbmltcG9ydCB7IFJlY29yZGluZ0V2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUmVjb3JkaW5nRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50JztcbmltcG9ydCB7IFNpZ25hbEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQnO1xuaW1wb3J0IHsgU3BlZWNoVG9UZXh0RXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TcGVlY2hUb1RleHRFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1FdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbUV2ZW50JztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvQ29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE5ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9OZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcbmltcG9ydCB7IFZpZGVvSW5zZXJ0TW9kZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvVmlkZW9JbnNlcnRNb2RlJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9Mb2dnZXIvT3BlblZpZHVMb2dnZXInO1xuaW1wb3J0IHsgUGxhdGZvcm1VdGlscyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvVXRpbHMvUGxhdGZvcm0nO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRSZWFzb24sIENoYW5nZWRQcm9wZXJ0eVR5cGUsIFJlY29yZGluZ0V2ZW50UmVhc29uLCBDb25uZWN0aW9uRXZlbnRSZWFzb24sIFN0cmVhbUV2ZW50UmVhc29uIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVHlwZXMvVHlwZXMnO1xuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmltcG9ydCBzZW12ZXJNYWpvciA9IHJlcXVpcmUoJ3NlbXZlci9mdW5jdGlvbnMvbWFqb3InKTtcbi8qKlxuICogQGhpZGRlblxuICovXG5pbXBvcnQgc2VtdmVyTWlub3IgPSByZXF1aXJlKCdzZW12ZXIvZnVuY3Rpb25zL21pbm9yJyk7XG5pbXBvcnQgeyBFeGNlcHRpb25FdmVudCwgRXhjZXB0aW9uRXZlbnROYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXhjZXB0aW9uRXZlbnQnO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuY29uc3QgbG9nZ2VyOiBPcGVuVmlkdUxvZ2dlciA9IE9wZW5WaWR1TG9nZ2VyLmdldEluc3RhbmNlKCk7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5sZXQgcGxhdGZvcm06IFBsYXRmb3JtVXRpbHM7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHZpZGVvIGNhbGwuIEl0IGNhbiBhbHNvIGJlIHNlZW4gYXMgYSB2aWRlb2NvbmZlcmVuY2Ugcm9vbSB3aGVyZSBtdWx0aXBsZSB1c2VycyBjYW4gY29ubmVjdC5cbiAqIFBhcnRpY2lwYW50cyB3aG8gcHVibGlzaCB0aGVpciB2aWRlb3MgdG8gYSBzZXNzaW9uIGNhbiBiZSBzZWVuIGJ5IHRoZSByZXN0IG9mIHVzZXJzIGNvbm5lY3RlZCB0byB0aGF0IHNwZWNpZmljIHNlc3Npb24uXG4gKiBJbml0aWFsaXplZCB3aXRoIHtAbGluayBPcGVuVmlkdS5pbml0U2Vzc2lvbn0gbWV0aG9kLlxuICpcbiAqIFNlZSBhdmFpbGFibGUgZXZlbnQgbGlzdGVuZXJzIGF0IHtAbGluayBTZXNzaW9uRXZlbnRNYXB9LlxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBleHRlbmRzIEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgLyoqXG4gICAgICogTG9jYWwgY29ubmVjdGlvbiB0byB0aGUgU2Vzc2lvbi4gVGhpcyBvYmplY3QgaXMgZGVmaW5lZCBvbmx5IGFmdGVyIHtAbGluayBTZXNzaW9uLmNvbm5lY3R9IGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBleGVjdXRlZCwgYW5kIGNhbiBiZSByZXRyaWV2ZWQgc3Vic2NyaWJpbmcgdG8gYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudFxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgU2Vzc2lvblxuICAgICAqL1xuICAgIHNlc3Npb25JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQ29sbGVjdGlvbiBvZiBhbGwgU3RyZWFtTWFuYWdlcnMgb2YgdGhpcyBTZXNzaW9uICh7QGxpbmsgUHVibGlzaGVyfSBhbmQge0BsaW5rIFN1YnNjcmliZXJ9KVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXJzOiBTdHJlYW1NYW5hZ2VyW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIE9iamVjdCBkZWZpbmluZyB0aGUgbWV0aG9kcyB0aGF0IHRoZSBjbGllbnQgaXMgYWJsZSB0byBjYWxsLiBUaGVzZSBhcmUgZGVmaW5lZCBieSB0aGUge0BsaW5rIENvbm5lY3Rpb24ucm9sZX0uXG4gICAgICogVGhpcyBvYmplY3QgaXMgb25seSBkZWZpbmVkIGFmdGVyIHtAbGluayBTZXNzaW9uLmNvbm5lY3R9IGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSByZXNvbHZlZFxuICAgICAqL1xuICAgIGNhcGFiaWxpdGllczogQ2FwYWJpbGl0aWVzO1xuXG4gICAgLy8gVGhpcyBtYXAgaXMgb25seSB1c2VkIHRvIGF2b2lkIHJhY2UgY29uZGl0aW9uIGJldHdlZW4gJ2pvaW5Sb29tJyByZXNwb25zZSBhbmQgJ29uUGFydGljaXBhbnRQdWJsaXNoZWQnIG5vdGlmaWNhdGlvblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdGVTdHJlYW1zQ3JlYXRlZDogTWFwPHN0cmluZywgYm9vbGVhbj4gPSBuZXcgTWFwKCk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlQ29ubmVjdGlvbnM6IE1hcDxzdHJpbmcsIENvbm5lY3Rpb24+ID0gbmV3IE1hcCgpO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcGVudmlkdTogT3BlblZpZHU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wdGlvbnM6IFNlc3Npb25PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB0b2tlbjogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcml2YXRlIHZpZGVvRGF0YUludGVydmFsOiBOb2RlSlMuVGltZW91dDtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJpdmF0ZSB2aWRlb0RhdGFUaW1lb3V0OiBOb2RlSlMuVGltZW91dDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihvcGVudmlkdTogT3BlblZpZHUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgcGxhdGZvcm0gPSBQbGF0Zm9ybVV0aWxzLmdldEluc3RhbmNlKCk7XG4gICAgICAgIHRoaXMub3BlbnZpZHUgPSBvcGVudmlkdTtcbiAgICB9XG5cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YTogYW55KTogUHJvbWlzZTxhbnk+O1xuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdHMgdG8gdGhlIHNlc3Npb24gdXNpbmcgYHRva2VuYC4gUGFyYW1ldGVyIGBtZXRhZGF0YWAgYWxsb3dzIHlvdSB0byBwYXNzIGV4dHJhIGRhdGEgdG8gc2hhcmUgd2l0aCBvdGhlciB1c2VycyB3aGVuXG4gICAgICogdGhleSByZWNlaXZlIGBzdHJlYW1DcmVhdGVkYCBldmVudC4gVGhlIHN0cnVjdHVyZSBvZiBgbWV0YWRhdGFgIHN0cmluZyBpcyB1cCB0byB5b3UgKG1heWJlIHNvbWUgc3RhbmRhcmRpemVkIGZvcm1hdFxuICAgICAqIGFzIEpTT04gb3IgWE1MIGlzIGEgZ29vZCBpZGVhKS5cbiAgICAgKlxuICAgICAqIFRoaXMgbWV0YWRhdGEgaXMgbm90IGNvbnNpZGVyZWQgc2VjdXJlLCBhcyBpdCBpcyBnZW5lcmF0ZWQgaW4gdGhlIGNsaWVudCBzaWRlLiBUbyBwYXNzIHNlY3VyZSBkYXRhLCBhZGQgaXQgYXMgYSBwYXJhbWV0ZXIgaW4gdGhlXG4gICAgICogdG9rZW4gZ2VuZXJhdGlvbiBvcGVyYXRpb24gKHRocm91Z2ggdGhlIEFQSSBSRVNULCBvcGVudmlkdS1qYXZhLWNsaWVudCBvciBvcGVudmlkdS1ub2RlLWNsaWVudCkuXG4gICAgICpcbiAgICAgKiBPbmx5IGFmdGVyIHRoZSByZXR1cm5lZCBQcm9taXNlIGlzIHN1Y2Nlc3NmdWxseSByZXNvbHZlZCB7QGxpbmsgU2Vzc2lvbi5jb25uZWN0aW9ufSBvYmplY3Qgd2lsbCBiZSBhdmFpbGFibGUgYW5kIHByb3Blcmx5IGRlZmluZWQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUge0BsaW5rIFNlc3Npb259IG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBmaXJzdCBkaXNwYXRjaCBvbmUgb3IgbW9yZSBgY29ubmVjdGlvbkNyZWF0ZWRgIGV2ZW50cyB1cG9uIHN1Y2Nlc3NmdWwgdGVybWluYXRpb24gb2YgdGhpcyBtZXRob2Q6XG4gICAgICogLSBGaXJzdCBvbmUgZm9yIHlvdXIgb3duIGxvY2FsIENvbm5lY3Rpb24gb2JqZWN0LCBzbyB5b3UgY2FuIHJldHJpZXZlIHtAbGluayBTZXNzaW9uLmNvbm5lY3Rpb259IHByb3BlcnR5LlxuICAgICAqIC0gVGhlbiBvbmUgZm9yIGVhY2ggcmVtb3RlIENvbm5lY3Rpb24gcHJldmlvdXNseSBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24sIGlmIGFueS4gQW55IG90aGVyIHJlbW90ZSB1c2VyIGNvbm5lY3RpbmcgdG8gdGhlIFNlc3Npb24gYWZ0ZXIgeW91IGhhdmVcbiAgICAgKiBzdWNjZXNzZnVsbHkgY29ubmVjdGVkIHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgd2hlbiB0aGV5IGRvIHNvLlxuICAgICAqXG4gICAgICogVGhlIHtAbGluayBTZXNzaW9ufSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBmb3IgZWFjaCByZW1vdGUgYWN0aXZlIHtAbGluayBQdWJsaXNoZXJ9IHRoYXQgd2FzIGFscmVhZHkgc3RyZWFtaW5nXG4gICAgICogd2hlbiBjb25uZWN0aW5nLCBqdXN0IGFmdGVyIGRpc3BhdGNoaW5nIGFsbCByZW1vdGUgYGNvbm5lY3Rpb25DcmVhdGVkYCBldmVudHMuXG4gICAgICpcbiAgICAgKiBUaGUge0BsaW5rIFNlc3Npb259IG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIENvbm5lY3Rpb25FdmVudH0gYW5kIHtAbGluayBTdHJlYW1FdmVudH0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSB0byB3aGljaCB5b3UgbXVzdCBzdWJzY3JpYmUgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgdGhlIGNvbm5lY3Rpb24gdG8gdGhlIFNlc3Npb24gd2FzIHN1Y2Nlc3NmdWwgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqXG4gICAgICovXG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nLCBtZXRhZGF0YT86IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5wcm9jZXNzVG9rZW4odG9rZW4pO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5vcGVudmlkdS5jaGVja1N5c3RlbVJlcXVpcmVtZW50cygpKSB7XG4gICAgICAgICAgICAgICAgLy8gRWFybHkgY29uZmlndXJhdGlvbiB0byBkZWFjdGl2YXRlIGF1dG9tYXRpYyBzdWJzY3JpcHRpb24gdG8gc3RyZWFtc1xuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICAgICAgcGFydGljaXBhbnRJZDogdG9rZW4sXG4gICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhOiAhIW1ldGFkYXRhID8gdGhpcy5zdHJpbmdDbGllbnRNZXRhZGF0YShtZXRhZGF0YSkgOiAnJ1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0QXV4KHRva2VuKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiByZXNvbHZlKCkpXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLkJST1dTRVJfTk9UX1NVUFBPUlRFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICdCcm93c2VyICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm0uZ2V0TmFtZSgpICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcgKHZlcnNpb24gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5nZXRWZXJzaW9uKCkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJykgZm9yICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm0uZ2V0RmFtaWx5KCkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1J1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTGVhdmVzIHRoZSBzZXNzaW9uLCBkZXN0cm95aW5nIGFsbCBzdHJlYW1zIGFuZCBkZWxldGluZyB0aGUgdXNlciBhcyBhIHBhcnRpY2lwYW50LlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIHtAbGluayBTZXNzaW9ufSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIGxlYXZpbmcgcGFydGljaXBhbnQgZnJvbSBldmVyeSBTdWJzY3JpYmVyIG9iamVjdCBvZiB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBSVENQZWVyQ29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBlYWNoIFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgZWFjaCBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGAgdG8gYXZvaWQgdGhpcyBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgYWxsIHRoZSBTdWJzY3JpYmVyIG9iamVjdHMgeW91cnNlbGYuXG4gICAgICogU2VlIHtAbGluayBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnR9IGFuZCB7QGxpbmsgVmlkZW9FbGVtZW50RXZlbnR9IHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBUaGUge0BsaW5rIFB1Ymxpc2hlcn0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlcmUgaXMgYSB7QGxpbmsgUHVibGlzaGVyfSBvYmplY3QgcHVibGlzaGluZyB0byB0aGUgc2Vzc2lvbi5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFB1Ymxpc2hlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHN0cmVhbURlc3Ryb3llZGAgaWYgeW91IHdhbnQgdG8gY2xlYW4gdGhlIFB1Ymxpc2hlciBvYmplY3Qgb24geW91ciBvd24gb3IgcmUtcHVibGlzaCBpdCBpbiBhIGRpZmZlcmVudCBTZXNzaW9uICh0byBkbyBzbyBpdCBpcyBhIG1hbmRhdG9yeSByZXF1aXJlbWVudCB0byBjYWxsIGBTZXNzaW9uLnVucHVibGlzaCgpYFxuICAgICAqIG9yL2FuZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgIGluIHRoZSBwcmV2aW91cyBzZXNzaW9uKS4gU2VlIHtAbGluayBTdHJlYW1FdmVudH0gYW5kIHtAbGluayBWaWRlb0VsZW1lbnRFdmVudH0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSB7QGxpbmsgU2Vzc2lvbn0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlIGRpc2Nvbm5lY3RlZCBwYXJ0aWNpcGFudCB3YXMgcHVibGlzaGluZy5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSB1bnN1YnNjcmliZSB0aGUgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBSVENQZWVyQ29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGF0IFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHlvdXJzZWxmLlxuICAgICAqIFNlZSB7QGxpbmsgU3RyZWFtRXZlbnR9IGFuZCB7QGxpbmsgVmlkZW9FbGVtZW50RXZlbnR9IHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBUaGUge0BsaW5rIFNlc3Npb259IG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBpbiBhbnkgY2FzZS4gU2VlIHtAbGluayBDb25uZWN0aW9uRXZlbnR9IHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sZWF2ZShmYWxzZSwgJ2Rpc2Nvbm5lY3QnKTtcbiAgICB9XG5cbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkKTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFN1YnNjcmliZXI7XG4gICAgc3Vic2NyaWJlKFxuICAgICAgICBzdHJlYW06IFN0cmVhbSxcbiAgICAgICAgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQsXG4gICAgICAgIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkXG4gICAgKTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoXG4gICAgICAgIHN0cmVhbTogU3RyZWFtLFxuICAgICAgICB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCxcbiAgICAgICAgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMsXG4gICAgICAgIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkXG4gICAgKTogU3Vic2NyaWJlcjtcblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZXMgdG8gYSBgc3RyZWFtYCwgYWRkaW5nIGEgbmV3IEhUTUwgdmlkZW8gZWxlbWVudCB0byBET00gd2l0aCBgc3Vic2NyaWJlclByb3BlcnRpZXNgIHNldHRpbmdzLiBUaGlzIG1ldGhvZCBpcyB1c3VhbGx5IGNhbGxlZCBpbiB0aGUgY2FsbGJhY2sgb2YgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50LlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIHtAbGluayBTdWJzY3JpYmVyfSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnRDcmVhdGVkYCBldmVudCBvbmNlIHRoZSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZW4vc3RhYmxlL2NoZWF0c2hlZXQvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLiBTZWUge0BsaW5rIFZpZGVvRWxlbWVudEV2ZW50fSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIHtAbGluayBTdWJzY3JpYmVyfSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSByZW1vdGUgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUge0BsaW5rIFN0cmVhbU1hbmFnZXJFdmVudH0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzdHJlYW0gU3RyZWFtIG9iamVjdCB0byBzdWJzY3JpYmUgdG9cbiAgICAgKiBAcGFyYW0gdGFyZ2V0RWxlbWVudCBIVE1MIERPTSBlbGVtZW50IChvciBpdHMgYGlkYCBhdHRyaWJ1dGUpIGluIHdoaWNoIHRoZSB2aWRlbyBlbGVtZW50IG9mIHRoZSBTdWJzY3JpYmVyIHdpbGwgYmUgaW5zZXJ0ZWQgKHNlZSB7QGxpbmsgU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZX0pLiBJZiAqbnVsbCogb3IgKnVuZGVmaW5lZCogbm8gZGVmYXVsdCB2aWRlbyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgU3Vic2NyaWJlci5cbiAgICAgKiBZb3UgY2FuIGFsd2F5cyBjYWxsIG1ldGhvZCB7QGxpbmsgU3Vic2NyaWJlci5hZGRWaWRlb0VsZW1lbnR9IG9yIHtAbGluayBTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudH0gdG8gbWFuYWdlIHRoZSB2aWRlbyBlbGVtZW50cyBvbiB5b3VyIG93biAoc2VlIFtNYW5hZ2UgdmlkZW8gcGxheWVyc10oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MpIHNlY3Rpb24pXG4gICAgICogQHBhcmFtIGNvbXBsZXRpb25IYW5kbGVyIGBlcnJvcmAgcGFyYW1ldGVyIGlzIG51bGwgaWYgYHN1YnNjcmliZWAgc3VjY2VlZHMsIGFuZCBpcyBkZWZpbmVkIGlmIGl0IGZhaWxzLlxuICAgICAqL1xuICAgIHN1YnNjcmliZShcbiAgICAgICAgc3RyZWFtOiBTdHJlYW0sXG4gICAgICAgIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLFxuICAgICAgICBwYXJhbTM/OiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCBTdWJzY3JpYmVyUHJvcGVydGllcyxcbiAgICAgICAgcGFyYW00PzogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZFxuICAgICk6IFN1YnNjcmliZXIge1xuICAgICAgICBsZXQgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMgPSB7fTtcbiAgICAgICAgaWYgKCEhcGFyYW0zICYmIHR5cGVvZiBwYXJhbTMgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgICAgICAgICAgaW5zZXJ0TW9kZTpcbiAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgPyB0eXBlb2YgcGFyYW0zLmluc2VydE1vZGUgPT09ICdzdHJpbmcnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBWaWRlb0luc2VydE1vZGVbcGFyYW0zLmluc2VydE1vZGVdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBwcm9wZXJ0aWVzLmluc2VydE1vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORCxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb0F1ZGlvOiB0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gIT09ICd1bmRlZmluZWQnID8gcGFyYW0zLnN1YnNjcmliZVRvQXVkaW8gOiB0cnVlLFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvVmlkZW86IHR5cGVvZiBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyAhPT0gJ3VuZGVmaW5lZCcgPyBwYXJhbTMuc3Vic2NyaWJlVG9WaWRlbyA6IHRydWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZCkgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICghIXBhcmFtMyAmJiB0eXBlb2YgcGFyYW0zID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlciA9IHBhcmFtMztcbiAgICAgICAgfSBlbHNlIGlmICghIXBhcmFtNCkge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuc2Vzc2lvbkNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKHRoaXMubm90Q29ubmVjdGVkRXJyb3IoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyB0aGlzLm5vdENvbm5lY3RlZEVycm9yKCk7XG4gICAgICAgIH1cblxuICAgICAgICBsb2dnZXIuaW5mbygnU3Vic2NyaWJpbmcgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG5cbiAgICAgICAgc3RyZWFtXG4gICAgICAgICAgICAuc3Vic2NyaWJlKClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnU3Vic2NyaWJlZCBjb3JyZWN0bHkgdG8gJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChjb21wbGV0aW9uSGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgc3Vic2NyaWJlciA9IG5ldyBTdWJzY3JpYmVyKHN0cmVhbSwgdGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcyk7XG4gICAgICAgIGlmICghIXN1YnNjcmliZXIudGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgc3RyZWFtLnN0cmVhbU1hbmFnZXIuY3JlYXRlVmlkZW9FbGVtZW50KHN1YnNjcmliZXIudGFyZ2V0RWxlbWVudCwgPFZpZGVvSW5zZXJ0TW9kZT5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdWJzY3JpYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByb21pc2lmaWVkIHZlcnNpb24gb2Yge0BsaW5rIFNlc3Npb24uc3Vic2NyaWJlfVxuICAgICAqL1xuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCk6IFByb21pc2U8U3Vic2NyaWJlcj47XG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFByb21pc2U8U3Vic2NyaWJlcj47XG5cbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM/OiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFByb21pc2U8U3Vic2NyaWJlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8U3Vic2NyaWJlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNlc3Npb25Db25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QodGhpcy5ub3RDb25uZWN0ZWRFcnJvcigpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHN1YnNjcmliZXI6IFN1YnNjcmliZXI7XG5cbiAgICAgICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHN1YnNjcmliZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICghIXByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyID0gdGhpcy5zdWJzY3JpYmUoc3RyZWFtLCB0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzLCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUge0BsaW5rIFN1YnNjcmliZXJ9IG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQgZm9yIGVhY2ggdmlkZW8gYXNzb2NpYXRlZCB0byBpdCB0aGF0IHdhcyByZW1vdmVkIGZyb20gRE9NLlxuICAgICAqIE9ubHkgdmlkZW9zIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9lbi9zdGFibGUvY2hlYXRzaGVldC9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IHJlbW92ZWRcbiAgICAgKlxuICAgICAqIFNlZSB7QGxpbmsgVmlkZW9FbGVtZW50RXZlbnR9IHRvIGxlYXJuIG1vcmVcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZShzdWJzY3JpYmVyOiBTdWJzY3JpYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2Vzc2lvbkNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCh0aGlzLm5vdENvbm5lY3RlZEVycm9yKCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uSWQgPSBzdWJzY3JpYmVyLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZDtcblxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdVbnN1YnNjcmliaW5nIGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tVmlkZW8nLFxuICAgICAgICAgICAgICAgICAgICB7IHNlbmRlcjogc3Vic2NyaWJlci5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciB1bnN1YnNjcmliaW5nIGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdVbnN1YnNjcmliZWQgY29ycmVjdGx5IGZyb20gJyArIGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLmRpc3Bvc2VNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQdWJsaXNoZXMgdG8gdGhlIFNlc3Npb24gdGhlIFB1Ymxpc2hlciBvYmplY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCB7QGxpbmsgUHVibGlzaGVyfSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCB1cG9uIHN1Y2Nlc3NmdWwgdGVybWluYXRpb24gb2YgdGhpcyBtZXRob2QuIFNlZSB7QGxpbmsgU3RyZWFtRXZlbnR9IHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBUaGUgbG9jYWwge0BsaW5rIFB1Ymxpc2hlcn0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUGxheWluZ2Agb25jZSB0aGUgbWVkaWEgc3RyZWFtIHN0YXJ0cyBwbGF5aW5nLiBTZWUge0BsaW5rIFN0cmVhbU1hbmFnZXJFdmVudH0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSB7QGxpbmsgU2Vzc2lvbn0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbUNyZWF0ZWRgIGV2ZW50IHNvIHRoZXkgY2FuIHN1YnNjcmliZSB0byBpdC4gU2VlIHtAbGluayBTdHJlYW1FdmVudH0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBvbmx5IGFmdGVyIHRoZSBwdWJsaXNoZXIgd2FzIHN1Y2Nlc3NmdWxseSBwdWJsaXNoZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIHB1Ymxpc2gocHVibGlzaGVyOiBQdWJsaXNoZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zZXNzaW9uQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KHRoaXMubm90Q29ubmVjdGVkRXJyb3IoKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHB1Ymxpc2hlci5zZXNzaW9uID0gdGhpcztcbiAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0uc2Vzc2lvbiA9IHRoaXM7XG5cbiAgICAgICAgICAgIGlmICghcHVibGlzaGVyLnN0cmVhbS5wdWJsaXNoZWRPbmNlKSB7XG4gICAgICAgICAgICAgICAgLy8gJ1Nlc3Npb24udW5wdWJsaXNoKFB1Ymxpc2hlciknIGhhcyBOT1QgYmVlbiBjYWxsZWRcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uYWRkU3RyZWFtKHB1Ymxpc2hlci5zdHJlYW0pO1xuICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmRWaWRlb0RhdGEocHVibGlzaGVyLCA4LCB0cnVlLCA1KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyAnU2Vzc2lvbi51bnB1Ymxpc2goUHVibGlzaGVyKScgaGFzIGJlZW4gY2FsbGVkLiBNdXN0IGluaXRpYWxpemUgYWdhaW4gUHVibGlzaGVyXG4gICAgICAgICAgICAgICAgcHVibGlzaGVyXG4gICAgICAgICAgICAgICAgICAgIC5pbml0aWFsaXplKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmFkZFN0cmVhbShwdWJsaXNoZXIuc3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5yZWVzdGFibGlzaFN0cmVhbVBsYXlpbmdFdmVudCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaGVyLnN0cmVhbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VuZFZpZGVvRGF0YShwdWJsaXNoZXIsIDgsIHRydWUsIDUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVbnB1Ymxpc2hlcyBmcm9tIHRoZSBTZXNzaW9uIHRoZSBQdWJsaXNoZXIgb2JqZWN0LlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIHtAbGluayBQdWJsaXNoZXJ9IG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGlzIFB1Ymxpc2hlclxuICAgICAqIChvbmx5IHRob3NlIHZpZGVvcyBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZW4vc3RhYmxlL2NoZWF0c2hlZXQvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUge0BsaW5rIFNlc3Npb259IG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBTdWJzY3JpYmVyIG9iamVjdCBmcm9tIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKSBhbmRcbiAgICAgKiBkZWxldGUgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGl0IChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9lbi9zdGFibGUvY2hlYXRzaGVldC9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCB0byBhdm9pZCB0aGlzIGRlZmF1bHQgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIHRoZSBTdWJzY3JpYmVyIG9iamVjdCBvbiB5b3VyIG93bi5cbiAgICAgKlxuICAgICAqIFNlZSB7QGxpbmsgU3RyZWFtRXZlbnR9IGFuZCB7QGxpbmsgVmlkZW9FbGVtZW50RXZlbnR9IHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2Vzc2lvbkNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgdGhpcy5ub3RDb25uZWN0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBwdWJsaXNoZXIuc3RyZWFtO1xuXG4gICAgICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJ1RoZSBhc3NvY2lhdGVkIENvbm5lY3Rpb24gb2JqZWN0IG9mIHRoaXMgUHVibGlzaGVyIGlzIG51bGwnKSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmVhbS5jb25uZWN0aW9uICE9PSB0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAnVGhlIGFzc29jaWF0ZWQgQ29ubmVjdGlvbiBvYmplY3Qgb2YgdGhpcyBQdWJsaXNoZXIgaXMgbm90IHlvdXIgbG9jYWwgQ29ubmVjdGlvbi4gICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCJPbmx5IG1vZGVyYXRvcnMgY2FuIGZvcmNlIHVucHVibGlzaCBvbiByZW1vdGUgU3RyZWFtcyB2aWEgJ2ZvcmNlVW5wdWJsaXNoJyBtZXRob2RcIlxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ1VucHVibGlzaGluZyBsb2NhbCBtZWRpYSAoJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCArICcpJyk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCd1bnB1Ymxpc2hWaWRlbycsIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdNZWRpYSB1bnB1Ymxpc2hlZCBjb3JyZWN0bHknKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW0uY29ubmVjdGlvbi5zdHJlYW0gPT0gc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIENvbm5lY3Rpb24uc3RyZWFtIG1heSBoYXZlIGNoYW5nZWQgaWYgU2Vzc2lvbi5wdWJsaXNoIHdhcyBjYWxsZWQgd2l0aCBvdGhlciBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgc3RyZWFtLmNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCBwdWJsaXNoZXIsICdzdHJlYW1EZXN0cm95ZWQnLCBwdWJsaXNoZXIuc3RyZWFtLCAndW5wdWJsaXNoJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIGxlYXZlIHRoZSBzZXNzaW9uXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgYmVoYXZpb3IgaXMgdGhlIHNhbWUgYXMgd2hlbiBzb21lIHVzZXIgY2FsbHMge0BsaW5rIFNlc3Npb24uZGlzY29ubmVjdH0sIGJ1dCBgcmVhc29uYCBwcm9wZXJ0eSBpbiBhbGwgZXZlbnRzIHdpbGwgYmUgYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogVGhlIHtAbGluayBTZXNzaW9ufSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZSBldmljdGVkIHVzZXIgd2FzIHB1Ymxpc2hpbmcgYSBzdHJlYW0sIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUge0BsaW5rIFNlc3Npb259IG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCBleGNlcHQgdGhlIGV2aWN0ZWQgb25lIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgZm9yIHRoZSBldmljdGVkIHVzZXIsIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIElmIGFueSwgdGhlIHtAbGluayBQdWJsaXNoZXJ9IG9iamVjdCBvZiB0aGUgZXZpY3RlZCBwYXJ0aWNpcGFudCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICogVGhlIHtAbGluayBTZXNzaW9ufSBvYmplY3Qgb2YgdGhlIGV2aWN0ZWQgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzZXNzaW9uRGlzY29ubmVjdGVkYCBldmVudCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIFN0cmVhbUV2ZW50fSwge0BsaW5rIENvbm5lY3Rpb25FdmVudH0gYW5kIHtAbGluayBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnR9IHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcGFydGljaXBhbnQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvbiBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgZm9yY2VEaXNjb25uZWN0KGNvbm5lY3Rpb246IENvbm5lY3Rpb24pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zZXNzaW9uQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KHRoaXMubm90Q29ubmVjdGVkRXJyb3IoKSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgZm9yIGNvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2ZvcmNlRGlzY29ubmVjdCcsIHsgY29ubmVjdGlvbklkOiBjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgZm9yY2luZyBkaXNjb25uZWN0IGZvciBDb25uZWN0aW9uICcgKyBjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBmb3JjZSBhIGRpc2Nvbm5lY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdGb3JjaW5nIGRpc2Nvbm5lY3QgY29ycmVjdGx5IGZvciBDb25uZWN0aW9uICcgKyBjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvcmNlcyBzb21lIHVzZXIgdG8gdW5wdWJsaXNoIGEgU3RyZWFtXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgYmVoYXZpb3IgaXMgdGhlIHNhbWUgYXMgd2hlbiBzb21lIHVzZXIgY2FsbHMge0BsaW5rIFNlc3Npb24udW5wdWJsaXNofSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIHtAbGluayBTZXNzaW9ufSBvYmplY3Qgb2YgZXZlcnkgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIHtAbGluayBQdWJsaXNoZXJ9IG9iamVjdCBvZiB0aGUgYWZmZWN0ZWQgcGFydGljaXBhbnQgd2lsbCBhbHNvIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIFN0cmVhbUV2ZW50fSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2Vzc2lvbkNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCh0aGlzLm5vdENvbm5lY3RlZEVycm9yKCkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsb2dnZXIuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2ZvcmNlVW5wdWJsaXNoJywgeyBzdHJlYW1JZDogc3RyZWFtLnN0cmVhbUlkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBmb3JjaW5nIHVucHVibGlzaCBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYW4gdW5wdWJsaXNoaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggY29ycmVjdGx5IGZvciBTdHJlYW0gJyArIHN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlbmRzIG9uZSBzaWduYWwuIGBzaWduYWxgIG9iamVjdCBoYXMgdGhlIGZvbGxvd2luZyBvcHRpb25hbCBwcm9wZXJ0aWVzOlxuICAgICAqIGBgYGpzb25cbiAgICAgKiB7ZGF0YTpzdHJpbmcsIHRvOkNvbm5lY3Rpb25bXSwgdHlwZTpzdHJpbmd9XG4gICAgICogYGBgXG4gICAgICogQWxsIHVzZXJzIHN1YnNjcmliZWQgdG8gdGhhdCBzaWduYWwgKGBzZXNzaW9uLm9uKCdzaWduYWw6dHlwZScsIC4uLilgIG9yIGBzZXNzaW9uLm9uKCdzaWduYWwnLCAuLi4pYCBmb3IgYWxsIHNpZ25hbHMpIGFuZCB3aG9zZSBDb25uZWN0aW9uIG9iamVjdHMgYXJlIGluIGB0b2AgYXJyYXkgd2lsbCByZWNlaXZlIGl0LiBUaGVpciBsb2NhbFxuICAgICAqIFNlc3Npb24gb2JqZWN0cyB3aWxsIGRpc3BhdGNoIGEgYHNpZ25hbGAgb3IgYHNpZ25hbDp0eXBlYCBldmVudC4gU2VlIHtAbGluayBTaWduYWxFdmVudH0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgbWVzc2FnZSBzdWNjZXNzZnVsbHkgcmVhY2hlZCBvcGVudmlkdS1zZXJ2ZXIgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdC4gX1RoaXMgZG9lc24ndFxuICAgICAqIG1lYW4gdGhhdCBvcGVudmlkdS1zZXJ2ZXIgY291bGQgcmVzZW5kIHRoZSBtZXNzYWdlIHRvIGFsbCB0aGUgbGlzdGVkIHJlY2VpdmVycy5fXG4gICAgICovXG4gICAgc2lnbmFsKHNpZ25hbDogU2lnbmFsT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNlc3Npb25Db25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QodGhpcy5ub3RDb25uZWN0ZWRFcnJvcigpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc2lnbmFsTWVzc2FnZSA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoc2lnbmFsLnRvICYmIHNpZ25hbC50by5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgICAgICAgICBzaWduYWwudG8uZm9yRWFjaCgoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbklkcy5wdXNoKGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBjb25uZWN0aW9uSWRzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0byddID0gW107XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ2RhdGEnXSA9IHNpZ25hbC5kYXRhID8gc2lnbmFsLmRhdGEgOiAnJztcblxuICAgICAgICAgICAgbGV0IHR5cGVBdXg6IHN0cmluZyA9IHNpZ25hbC50eXBlID8gc2lnbmFsLnR5cGUgOiAnc2lnbmFsJztcbiAgICAgICAgICAgIGlmICghIXR5cGVBdXgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZUF1eC5zdWJzdHJpbmcoMCwgNykgIT09ICdzaWduYWw6Jykge1xuICAgICAgICAgICAgICAgICAgICB0eXBlQXV4ID0gJ3NpZ25hbDonICsgdHlwZUF1eDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzaWduYWxNZXNzYWdlWyd0eXBlJ10gPSB0eXBlQXV4O1xuXG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdzZW5kTWVzc2FnZScsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBKU09OLnN0cmluZ2lmeShzaWduYWxNZXNzYWdlKVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU3Vic2NyaWJlIHRvIHRoZSBTcGVlY2gtVG8tVGV4dCBldmVudHMgZm9yIHRoaXMge0BsaW5rIFN0cmVhbX0uIFRoZSBTZXNzaW9uIG9iamVjdCB3aWxsIGVtaXQge0BsaW5rIFNwZWVjaFRvVGV4dEV2ZW50fSBmb3IgdGhlIFN0cmVhbVxuICAgICAqIHdoZW4gc3BlZWNoIGlzIGRldGVjdGVkIGluIGl0cyBhdWRpbyB0cmFjay5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzdHJlYW0gLSBUaGUgU3RyZWFtIGZvciB3aGljaCB5b3Ugd2FudCB0byBzdGFydCByZWNlaXZpbmcge0BsaW5rIFNwZWVjaFRvVGV4dEV2ZW50fS5cbiAgICAgKiBAcGFyYW0gbGFuZyAtIFRoZSBsYW5ndWFnZSBvZiB0aGUgU3RyZWFtJ3MgYXVkaW8gdHJhY2suIEl0IG11c3QgYmUgYSB2YWxpZCBbQkNQLTQ3XShodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvYmNwNDcpIGxhbmd1YWdlIHRhZyBsaWtlIFwiZW4tVVNcIiBvciBcImVzLUVTXCIuXG4gICAgICogXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSBzcGVlY2gtdG8tdGV4dCBzdWJzY3JpcHRpb25cbiAgICAgKiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90LlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvU3BlZWNoVG9UZXh0KHN0cmVhbTogU3RyZWFtLCBsYW5nOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ3N1YnNjcmliZVRvU3BlZWNoVG9UZXh0JyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25JZDogc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkLFxuICAgICAgICAgICAgICAgICAgICBsYW5nXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVbnN1YnNjcmliZSBmcm9tIHRoZSBTcGVlY2gtVG8tVGV4dCBldmVudHMgZm9yIHRoaXMge0BsaW5rIFN0cmVhbX0uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHNwZWVjaC10by10ZXh0IHN1YnNjcmlwdGlvblxuICAgICAqIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3QuXG4gICAgICovXG4gICAgdW5zdWJzY3JpYmVGcm9tU3BlZWNoVG9UZXh0KHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICd1bnN1YnNjcmliZUZyb21TcGVlY2hUb1RleHQnLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbklkOiBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWRcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSB7QGxpbmsgRXZlbnREaXNwYXRjaGVyLm9ufVxuICAgICAqL1xuICAgIG9uPEsgZXh0ZW5kcyBrZXlvZiBTZXNzaW9uRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9uQXV4KHR5cGUsIFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgJ1Nlc3Npb24nXCIsIGhhbmRsZXIpO1xuXG4gICAgICAgIGlmICh0eXBlID09PSAncHVibGlzaGVyU3RhcnRTcGVha2luZycpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBhbHJlYWR5IGF2YWlsYWJsZSByZW1vdGUgc3RyZWFtcyB3aXRoIGF1ZGlvLCBlbmFibGUgaGFyayAnc3BlYWtpbmcnIGV2ZW50IGluIGFsbCBvZiB0aGVtXG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmZvckVhY2goKHJlbW90ZUNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uLnN0cmVhbT8uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0uZW5hYmxlSGFya1NwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghIXRoaXMuY29ubmVjdGlvbj8uc3RyZWFtPy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIC8vIElmIGNvbm5lY3RlZCB0byB0aGUgU2Vzc2lvbiBhbmQgcHVibGlzaGluZyB3aXRoIGF1ZGlvLCBhbHNvIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgZm9yIHRoZSBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmVuYWJsZUhhcmtTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMgd2l0aCBhdWRpbywgZW5hYmxlIGhhcmsgJ3N0b3BwZWRfc3BlYWtpbmcnIGV2ZW50IGluIGFsbCBvZiB0aGVtXG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmZvckVhY2goKHJlbW90ZUNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uLnN0cmVhbT8uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0uZW5hYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24/LnN0cmVhbT8uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24gYW5kIHB1Ymxpc2hpbmcgd2l0aCBhdWRpbywgYWxzbyBlbmFibGUgaGFyayAnc3RvcHBlZF9zcGVha2luZycgZXZlbnQgZm9yIHRoZSBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmVuYWJsZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIHtAbGluayBFdmVudERpc3BhdGNoZXIub25jZX1cbiAgICAgKi9cbiAgICBvbmNlPEsgZXh0ZW5kcyBrZXlvZiBTZXNzaW9uRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9uY2VBdXgodHlwZSwgXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlIGJ5ICdTZXNzaW9uJ1wiLCBoYW5kbGVyKTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMgd2l0aCBhdWRpbywgZW5hYmxlIGhhcmsgJ3NwZWFraW5nJyBldmVudCAob25jZSkgaW4gYWxsIG9mIHRoZW0gb25jZVxuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9ucy5mb3JFYWNoKChyZW1vdGVDb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0/Lmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtLmVuYWJsZU9uY2VIYXJrU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uPy5zdHJlYW0/Lmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgY29ubmVjdGVkIHRvIHRoZSBTZXNzaW9uIGFuZCBwdWJsaXNoaW5nIHdpdGggYXVkaW8sIGFsc28gZW5hYmxlIGhhcmsgJ3NwZWFraW5nJyBldmVudCAob25jZSkgZm9yIHRoZSBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmVuYWJsZU9uY2VIYXJrU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAncHVibGlzaGVyU3RvcFNwZWFraW5nJykge1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIGFscmVhZHkgYXZhaWxhYmxlIHJlbW90ZSBzdHJlYW1zIHdpdGggYXVkaW8sIGVuYWJsZSBoYXJrICdzdG9wcGVkX3NwZWFraW5nJyBldmVudCAob25jZSkgaW4gYWxsIG9mIHRoZW0gb25jZVxuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9ucy5mb3JFYWNoKChyZW1vdGVDb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0/Lmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtLmVuYWJsZU9uY2VIYXJrU3RvcHBlZFNwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghIXRoaXMuY29ubmVjdGlvbj8uc3RyZWFtPy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIC8vIElmIGNvbm5lY3RlZCB0byB0aGUgU2Vzc2lvbiBhbmQgcHVibGlzaGluZyB3aXRoIGF1ZGlvLCBhbHNvIGVuYWJsZSBoYXJrICdzdG9wcGVkX3NwZWFraW5nJyBldmVudCAob25jZSkgZm9yIHRoZSBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmVuYWJsZU9uY2VIYXJrU3RvcHBlZFNwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSB7QGxpbmsgRXZlbnREaXNwYXRjaGVyLm9mZn1cbiAgICAgKi9cbiAgICBvZmY8SyBleHRlbmRzIGtleW9mIFNlc3Npb25FdmVudE1hcD4odHlwZTogSywgaGFuZGxlcj86IChldmVudDogU2Vzc2lvbkV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9mZkF1eCh0eXBlLCBoYW5kbGVyKTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAvLyBDaGVjayBpZiBTZXNzaW9uIG9iamVjdCBzdGlsbCBoYXMgc29tZSBsaXN0ZW5lciBmb3IgdGhlIGV2ZW50XG4gICAgICAgICAgICBpZiAoIXRoaXMuYW55U3BlZWNoRXZlbnRMaXN0ZW5lckVuYWJsZWQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBmYWxzZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmZvckVhY2goKHJlbW90ZUNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0/LnN0cmVhbU1hbmFnZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIFN1YnNjcmliZXIgb2JqZWN0IHN0aWxsIGhhcyBzb21lIGxpc3RlbmVyIGZvciB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5hbnlTcGVlY2hFdmVudExpc3RlbmVyRW5hYmxlZCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIGZhbHNlLCByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtLmRpc2FibGVIYXJrU3BlYWtpbmdFdmVudChmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24/LnN0cmVhbT8uc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBQdWJsaXNoZXIgb2JqZWN0IHN0aWxsIGhhcyBzb21lIGxpc3RlbmVyIGZvciB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgZmFsc2UsIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtTWFuYWdlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZGlzYWJsZUhhcmtTcGVha2luZ0V2ZW50KGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIFNlc3Npb24gb2JqZWN0IHN0aWxsIGhhcyBzb21lIGxpc3RlbmVyIGZvciB0aGUgZXZlbnRcbiAgICAgICAgICAgIGlmICghdGhpcy5hbnlTcGVlY2hFdmVudExpc3RlbmVyRW5hYmxlZCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgZmFsc2UpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9ucy5mb3JFYWNoKChyZW1vdGVDb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtPy5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBTdWJzY3JpYmVyIG9iamVjdCBzdGlsbCBoYXMgc29tZSBsaXN0ZW5lciBmb3IgdGhlIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuYW55U3BlZWNoRXZlbnRMaXN0ZW5lckVuYWJsZWQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIGZhbHNlLCByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtLmRpc2FibGVIYXJrU3RvcHBlZFNwZWFraW5nRXZlbnQoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uPy5zdHJlYW0/LnN0cmVhbU1hbmFnZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgUHVibGlzaGVyIG9iamVjdCBzdGlsbCBoYXMgc29tZSBsaXN0ZW5lciBmb3IgdGhlIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5hbnlTcGVlY2hFdmVudExpc3RlbmVyRW5hYmxlZCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgZmFsc2UsIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtTWFuYWdlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZGlzYWJsZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudChmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50Sm9pbmVkKGV2ZW50OiBSZW1vdGVDb25uZWN0aW9uT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICAvLyBDb25uZWN0aW9uIHNob3VsZG4ndCBleGlzdFxuICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24oZXZlbnQuaWQsICcnKVxuICAgICAgICAgICAgLnRoZW4oKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIud2FybignQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgKyAnIGFscmVhZHkgZXhpc3RzIGluIGNvbm5lY3Rpb25zIGxpc3QnKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKG9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgZXZlbnQpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuc2V0KGV2ZW50LmlkLCBjb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvbkNyZWF0ZWQnLCBbbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25DcmVhdGVkJywgY29ubmVjdGlvbiwgJycpXSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudExlZnQoZXZlbnQ6IHsgY29ubmVjdGlvbklkOiBzdHJpbmc7IHJlYXNvbjogQ29ubmVjdGlvbkV2ZW50UmVhc29uIH0pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKGV2ZW50LmNvbm5lY3Rpb25JZCwgJ29uUGFydGljaXBhbnRMZWZ0JylcbiAgICAgICAgICAgIC50aGVuKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbi5zdHJlYW0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtID0gY29ubmVjdGlvbi5zdHJlYW07XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgdGhpcywgJ3N0cmVhbURlc3Ryb3llZCcsIHN0cmVhbSwgZXZlbnQucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZC5kZWxldGUoc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbi5kaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9ucy5kZWxldGUoY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uRGVzdHJveWVkJywgW1xuICAgICAgICAgICAgICAgICAgICBuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkRlc3Ryb3llZCcsIGNvbm5lY3Rpb24sIGV2ZW50LnJlYXNvbilcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKG9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudFB1Ymxpc2hlZChldmVudDogUmVtb3RlQ29ubmVjdGlvbk9wdGlvbnMpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgYWZ0ZXJDb25uZWN0aW9uRm91bmQgPSAoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9ucy5zZXQoY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGNvbm5lY3Rpb24pO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQuZ2V0KGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkKSkge1xuICAgICAgICAgICAgICAgIC8vIEF2b2lkIHJhY2UgY29uZGl0aW9uIGJldHdlZW4gc3RyZWFtLnN1YnNjcmliZSgpIGluIFwib25QYXJ0aWNpcGFudFB1Ymxpc2hlZFwiIGFuZCBpbiBcImpvaW5Sb29tXCIgcnBjIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBjb25kaXRpb24gaXMgZmFsc2UgaWYgb3BlbnZpZHUtc2VydmVyIHNlbmRzIFwicGFydGljaXBhbnRQdWJsaXNoZWRcIiBldmVudCB0byBhIHN1YnNjcmliZXIgcGFydGljaXBhbnQgdGhhdCBoYXNcbiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IHN1YnNjcmliZWQgdG8gY2VydGFpbiBzdHJlYW0gaW4gdGhlIGNhbGxiYWNrIG9mIFwiam9pblJvb21cIiBtZXRob2RcblxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQuc2V0KGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkLCB0cnVlKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBHZXQgdGhlIGV4aXN0aW5nIENvbm5lY3Rpb24gY3JlYXRlZCBvbiAnb25QYXJ0aWNpcGFudEpvaW5lZCcgZm9yXG4gICAgICAgIC8vIGV4aXN0aW5nIHBhcnRpY2lwYW50cyBvciBjcmVhdGUgYSBuZXcgb25lIGZvciBuZXcgcGFydGljaXBhbnRzXG4gICAgICAgIGxldCBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24oZXZlbnQuaWQsICdvblBhcnRpY2lwYW50UHVibGlzaGVkJylcblxuICAgICAgICAgICAgLnRoZW4oKGNvbikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBleGlzdGluZyBDb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IGNvbjtcbiAgICAgICAgICAgICAgICBldmVudC5tZXRhZGF0YSA9IGNvbi5kYXRhO1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ucmVtb3RlT3B0aW9ucyA9IGV2ZW50O1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaW5pdFJlbW90ZVN0cmVhbXMoZXZlbnQuc3RyZWFtcyk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChvcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQ3JlYXRlIG5ldyBDb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbiA9IG5ldyBDb25uZWN0aW9uKHRoaXMsIGV2ZW50KTtcbiAgICAgICAgICAgICAgICBhZnRlckNvbm5lY3Rpb25Gb3VuZChjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50VW5wdWJsaXNoZWQoZXZlbnQ6IHsgY29ubmVjdGlvbklkOiBzdHJpbmc7IHJlYXNvbjogU3RyZWFtRXZlbnRSZWFzb24gfSk6IHZvaWQge1xuICAgICAgICBpZiAoZXZlbnQuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3VyIHN0cmVhbSBoYXMgYmVlbiBmb3JjZWRseSB1bnB1Ymxpc2hlZCBmcm9tIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0oZXZlbnQucmVhc29uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihldmVudC5jb25uZWN0aW9uSWQsICdvblBhcnRpY2lwYW50VW5wdWJsaXNoZWQnKVxuXG4gICAgICAgICAgICAgICAgLnRoZW4oKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXZlbnQgPSBuZXcgU3RyZWFtRXZlbnQodHJ1ZSwgdGhpcywgJ3N0cmVhbURlc3Ryb3llZCcsIGNvbm5lY3Rpb24uc3RyZWFtISwgZXZlbnQucmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbURlc3Ryb3llZCcsIFtzdHJlYW1FdmVudF0pO1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW1FdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRpbmcgdGhlIHJlbW90ZSBzdHJlYW0gaWYgaXQgZXhpc3RzXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb25uZWN0aW9uLnN0cmVhbSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1JZDogc3RyaW5nID0gY29ubmVjdGlvbi5zdHJlYW0hLnN0cmVhbUlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZC5kZWxldGUoc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbi5yZW1vdmVTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChvcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblBhcnRpY2lwYW50RXZpY3RlZChldmVudDogeyBjb25uZWN0aW9uSWQ6IHN0cmluZzsgcmVhc29uOiBDb25uZWN0aW9uRXZlbnRSZWFzb24gfSk6IHZvaWQge1xuICAgICAgICBpZiAoZXZlbnQuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgZXZlbnQucmVhc29uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbk5ld01lc3NhZ2UoZXZlbnQ6IHsgdHlwZT86IHN0cmluZzsgZGF0YT86IHN0cmluZzsgZnJvbT86IHN0cmluZyB9KTogdm9pZCB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdOZXcgc2lnbmFsOiAnICsgSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcblxuICAgICAgICBjb25zdCBzdHJpcHBlZFR5cGUgPSAhIWV2ZW50LnR5cGUgPyBldmVudC50eXBlLnJlcGxhY2UoL14oc2lnbmFsOikvLCAnJykgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKCEhZXZlbnQuZnJvbSkge1xuICAgICAgICAgICAgLy8gU2lnbmFsIHNlbnQgYnkgb3RoZXIgY2xpZW50XG4gICAgICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24oXG4gICAgICAgICAgICAgICAgZXZlbnQuZnJvbSxcbiAgICAgICAgICAgICAgICBcIkNvbm5lY3Rpb24gJ1wiICtcbiAgICAgICAgICAgICAgICBldmVudC5mcm9tICtcbiAgICAgICAgICAgICAgICBcIicgdW5rbm93biB3aGVuICdvbk5ld01lc3NhZ2UnLiBFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6IFwiICtcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmtleXMoKSkgK1xuICAgICAgICAgICAgICAgICcuIEV4aXN0aW5nIGxvY2FsIGNvbm5lY3Rpb246ICcgK1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5jb25uZWN0aW9uSWRcbiAgICAgICAgICAgIClcblxuICAgICAgICAgICAgICAgIC50aGVuKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzaWduYWwnLCBbbmV3IFNpZ25hbEV2ZW50KHRoaXMsIHN0cmlwcGVkVHlwZSwgZXZlbnQuZGF0YSwgY29ubmVjdGlvbildKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXZlbnQudHlwZSAmJiBldmVudC50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoZXZlbnQudHlwZSwgW25ldyBTaWduYWxFdmVudCh0aGlzLCBzdHJpcHBlZFR5cGUsIGV2ZW50LmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgob3BlblZpZHVFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTaWduYWwgc2VudCBieSBzZXJ2ZXJcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzaWduYWwnLCBbbmV3IFNpZ25hbEV2ZW50KHRoaXMsIHN0cmlwcGVkVHlwZSwgZXZlbnQuZGF0YSwgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgaWYgKCEhZXZlbnQudHlwZSAmJiBldmVudC50eXBlICE9PSAnc2lnbmFsJykge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KGV2ZW50LnR5cGUsIFtuZXcgU2lnbmFsRXZlbnQodGhpcywgc3RyaXBwZWRUeXBlLCBldmVudC5kYXRhLCB1bmRlZmluZWQpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQoZXZlbnQ6IHsgY29ubmVjdGlvbklkOiBzdHJpbmc7IHN0cmVhbUlkOiBzdHJpbmc7IHByb3BlcnR5OiBDaGFuZ2VkUHJvcGVydHlUeXBlOyBuZXdWYWx1ZTogYW55OyByZWFzb246IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50UmVhc29uIH0pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY2FsbGJhY2sgPSAoY29ubmVjdGlvbjogQ29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbi5zdHJlYW0gJiYgY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWQgPT09IGV2ZW50LnN0cmVhbUlkKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtID0gY29ubmVjdGlvbi5zdHJlYW07XG4gICAgICAgICAgICAgICAgbGV0IG9sZFZhbHVlO1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQucHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0uYXVkaW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5uZXdWYWx1ZSA9IGV2ZW50Lm5ld1ZhbHVlID09PSAndHJ1ZSc7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uYXVkaW9BY3RpdmUgPSBldmVudC5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb0FjdGl2ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0FjdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Lm5ld1ZhbHVlID0gZXZlbnQubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS52aWRlb0FjdGl2ZSA9IGV2ZW50Lm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvVHJhY2snOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQubmV3VmFsdWUgPSBKU09OLnBhcnNlKGV2ZW50Lm5ld1ZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdhdWRpb1RyYWNrJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Lm5ld1ZhbHVlID0gSlNPTi5wYXJzZShldmVudC5uZXdWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAndmlkZW9EaW1lbnNpb25zJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlID0gc3RyZWFtLnZpZGVvRGltZW5zaW9ucztcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Lm5ld1ZhbHVlID0gSlNPTi5wYXJzZShKU09OLnBhcnNlKGV2ZW50Lm5ld1ZhbHVlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9EaW1lbnNpb25zID0gZXZlbnQubmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnZmlsdGVyJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlID0gc3RyZWFtLmZpbHRlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Lm5ld1ZhbHVlID0gT2JqZWN0LmtleXMoZXZlbnQubmV3VmFsdWUpLmxlbmd0aCA+IDAgPyBldmVudC5uZXdWYWx1ZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudC5uZXdWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlciA9IG5ldyBGaWx0ZXIoZXZlbnQubmV3VmFsdWUudHlwZSwgZXZlbnQubmV3VmFsdWUub3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmZpbHRlci5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50Lm5ld1ZhbHVlLmxhc3RFeGVjTWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIubGFzdEV4ZWNNZXRob2QgPSBldmVudC5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQubmV3VmFsdWUgPSBzdHJlYW0uZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCBzdHJlYW0sIGV2ZW50LnByb3BlcnR5LCBldmVudC5uZXdWYWx1ZSwgb2xkVmFsdWUsIGV2ZW50LnJlYXNvbilcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICBpZiAoISFzdHJlYW0uc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW0uc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChzdHJlYW0uc3RyZWFtTWFuYWdlciwgc3RyZWFtLCBldmVudC5wcm9wZXJ0eSwgZXZlbnQubmV3VmFsdWUsIG9sZFZhbHVlLCBldmVudC5yZWFzb24pXG4gICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICBcIk5vIHN0cmVhbSB3aXRoIHN0cmVhbUlkICdcIiArXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnN0cmVhbUlkICtcbiAgICAgICAgICAgICAgICAgICAgXCInIGZvdW5kIGZvciBjb25uZWN0aW9uICdcIiArXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmNvbm5lY3Rpb25JZCArXG4gICAgICAgICAgICAgICAgICAgIFwiJyBvbiAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoZXZlbnQuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAvLyBZb3VyIHN0cmVhbSBoYXMgYmVlbiBmb3JjZWRseSBjaGFuZ2VkIChmaWx0ZXIgZmVhdHVyZSlcbiAgICAgICAgICAgIGNhbGxiYWNrKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24oZXZlbnQuY29ubmVjdGlvbklkLCAnb25TdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnKVxuICAgICAgICAgICAgICAgIC50aGVuKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChvcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbkNvbm5lY3Rpb25Qcm9wZXJ0eUNoYW5nZWQoZXZlbnQ6IHsgcHJvcGVydHk6IHN0cmluZzsgbmV3VmFsdWU6IGFueSB9KTogdm9pZCB7XG4gICAgICAgIGxldCBvbGRWYWx1ZTtcbiAgICAgICAgc3dpdGNoIChldmVudC5wcm9wZXJ0eSkge1xuICAgICAgICAgICAgY2FzZSAncm9sZSc6XG4gICAgICAgICAgICAgICAgb2xkVmFsdWUgPSB0aGlzLmNvbm5lY3Rpb24ucm9sZS5zbGljZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5yb2xlID0gZXZlbnQubmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmxvY2FsT3B0aW9ucyEucm9sZSA9IGV2ZW50Lm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncmVjb3JkJzpcbiAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHRoaXMuY29ubmVjdGlvbi5yZWNvcmQ7XG4gICAgICAgICAgICAgICAgZXZlbnQubmV3VmFsdWUgPSBldmVudC5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5yZWNvcmQgPSBldmVudC5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24ubG9jYWxPcHRpb25zIS5yZWNvcmQgPSBldmVudC5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgIG5ldyBDb25uZWN0aW9uUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcywgdGhpcy5jb25uZWN0aW9uLCBldmVudC5wcm9wZXJ0eSwgZXZlbnQubmV3VmFsdWUsIG9sZFZhbHVlKVxuICAgICAgICBdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZENoYW5nZWQoZXZlbnQ6IHsgY29ubmVjdGlvbklkOiBzdHJpbmc7IG5ld1ZhbHVlOiBudW1iZXI7IG9sZFZhbHVlOiBudW1iZXIgfSk6IHZvaWQge1xuICAgICAgICBpZiAoZXZlbnQuY29ubmVjdGlvbklkID09PSB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnbmV0d29ya1F1YWxpdHlMZXZlbENoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgbmV3IE5ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkRXZlbnQodGhpcywgZXZlbnQubmV3VmFsdWUsIGV2ZW50Lm9sZFZhbHVlLCB0aGlzLmNvbm5lY3Rpb24pXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihldmVudC5jb25uZWN0aW9uSWQsICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBldmVudC5jb25uZWN0aW9uSWQpXG4gICAgICAgICAgICAgICAgLnRoZW4oKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ25ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE5ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkRXZlbnQodGhpcywgZXZlbnQubmV3VmFsdWUsIGV2ZW50Lm9sZFZhbHVlLCBjb25uZWN0aW9uKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgob3BlblZpZHVFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVjdkljZUNhbmRpZGF0ZShldmVudDoge1xuICAgICAgICBzZW5kZXJDb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICAgICAgZW5kcG9pbnROYW1lOiBzdHJpbmc7XG4gICAgICAgIHNkcE1MaW5lSW5kZXg6IG51bWJlcjtcbiAgICAgICAgc2RwTWlkOiBzdHJpbmc7XG4gICAgICAgIGNhbmRpZGF0ZTogc3RyaW5nO1xuICAgIH0pOiB2b2lkIHtcbiAgICAgICAgLy8gVGhlIGV2ZW50IGNvbnRhaW5zIGZpZWxkcyB0aGF0IGNhbiBiZSB1c2VkIHRvIG9idGFpbiBhIHByb3BlciBjYW5kaWRhdGUsXG4gICAgICAgIC8vIHVzaW5nIHRoZSBSVENJY2VDYW5kaWRhdGUgY29uc3RydWN0b3I6XG4gICAgICAgIC8vIGh0dHBzOi8vdzNjLmdpdGh1Yi5pby93ZWJydGMtcGMvI2RvbS1ydGNpY2VjYW5kaWRhdGUtY29uc3RydWN0b3JcbiAgICAgICAgY29uc3QgY2FuZGlkYXRlSW5pdDogUlRDSWNlQ2FuZGlkYXRlSW5pdCA9IHtcbiAgICAgICAgICAgIGNhbmRpZGF0ZTogZXZlbnQuY2FuZGlkYXRlLFxuICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogZXZlbnQuc2RwTUxpbmVJbmRleCxcbiAgICAgICAgICAgIHNkcE1pZDogZXZlbnQuc2RwTWlkXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGljZUNhbmRpZGF0ZSA9IG5ldyBSVENJY2VDYW5kaWRhdGUoY2FuZGlkYXRlSW5pdCk7XG5cbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKFxuICAgICAgICAgICAgZXZlbnQuc2VuZGVyQ29ubmVjdGlvbklkLFxuICAgICAgICAgICAgJ0Nvbm5lY3Rpb24gbm90IGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArXG4gICAgICAgICAgICBldmVudC5zZW5kZXJDb25uZWN0aW9uSWQgK1xuICAgICAgICAgICAgJyBvd25pbmcgZW5kcG9pbnQgJyArXG4gICAgICAgICAgICBldmVudC5lbmRwb2ludE5hbWUgK1xuICAgICAgICAgICAgJy4gSWNlIGNhbmRpZGF0ZSB3aWxsIGJlIGlnbm9yZWQ6ICcgK1xuICAgICAgICAgICAgaWNlQ2FuZGlkYXRlXG4gICAgICAgIClcbiAgICAgICAgICAgIC50aGVuKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtOiBTdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbSE7XG4gICAgICAgICAgICAgICAgc3RyZWFtXG4gICAgICAgICAgICAgICAgICAgIC5nZXRXZWJSdGNQZWVyKClcbiAgICAgICAgICAgICAgICAgICAgLmFkZEljZUNhbmRpZGF0ZShpY2VDYW5kaWRhdGUpXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnRXJyb3IgYWRkaW5nIGNhbmRpZGF0ZSBmb3IgJyArIHN0cmVhbSEuc3RyZWFtSWQgKyAnIHN0cmVhbSBvZiBlbmRwb2ludCAnICsgZXZlbnQuZW5kcG9pbnROYW1lICsgJzogJyArIGVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKG9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25TZXNzaW9uQ2xvc2VkKG1zZyk6IHZvaWQge1xuICAgICAgICBsb2dnZXIuaW5mbygnU2Vzc2lvbiBjbG9zZWQ6ICcgKyBKU09OLnN0cmluZ2lmeShtc2cpKTtcbiAgICAgICAgY29uc3QgcyA9IG1zZy5zZXNzaW9uSWQ7XG4gICAgICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzZXNzaW9uLWNsb3NlZCcsIFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHNcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdTZXNzaW9uIHVuZGVmaW5lZCBvbiBzZXNzaW9uIGNsb3NlZCcsIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Mb3N0Q29ubmVjdGlvbihyZWFzb246IENvbm5lY3Rpb25FdmVudFJlYXNvbik6IHZvaWQge1xuICAgICAgICBsb2dnZXIud2FybignTG9zdCBjb25uZWN0aW9uIGluIFNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uSWQgJiYgISF0aGlzLmNvbm5lY3Rpb24gJiYgIXRoaXMuY29ubmVjdGlvbi5kaXNwb3NlZCkge1xuICAgICAgICAgICAgdGhpcy5sZWF2ZSh0cnVlLCByZWFzb24pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUmVjb3ZlcmVkQ29ubmVjdGlvbigpOiB2b2lkIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ1JlY292ZXJlZCBjb25uZWN0aW9uIGluIFNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgdGhpcy5yZWNvbm5lY3RCcm9rZW5TdHJlYW1zKCk7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvbm5lY3RlZCcsIFtdKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25NZWRpYUVycm9yKGV2ZW50OiB7IGVycm9yOiBzdHJpbmcgfSk6IHZvaWQge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ01lZGlhIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXZlbnQpKTtcbiAgICAgICAgY29uc3QgZXJyID0gZXZlbnQuZXJyb3I7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdlcnJvci1tZWRpYScsIFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yOiBlcnJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdSZWNlaXZlZCB1bmRlZmluZWQgbWVkaWEgZXJyb3I6JywgZXZlbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUmVjb3JkaW5nU3RhcnRlZChldmVudDogeyBpZDogc3RyaW5nOyBuYW1lOiBzdHJpbmcgfSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncmVjb3JkaW5nU3RhcnRlZCcsIFtuZXcgUmVjb3JkaW5nRXZlbnQodGhpcywgJ3JlY29yZGluZ1N0YXJ0ZWQnLCBldmVudC5pZCwgZXZlbnQubmFtZSldKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25SZWNvcmRpbmdTdG9wcGVkKGV2ZW50OiB7IGlkOiBzdHJpbmc7IG5hbWU6IHN0cmluZzsgcmVhc29uOiBSZWNvcmRpbmdFdmVudFJlYXNvbiB9KTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdG9wcGVkJywgW25ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RvcHBlZCcsIGV2ZW50LmlkLCBldmVudC5uYW1lLCBldmVudC5yZWFzb24pXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uRmlsdGVyRXZlbnREaXNwYXRjaGVkKGV2ZW50OiB7IGNvbm5lY3Rpb25JZDogc3RyaW5nOyBzdHJlYW1JZDogc3RyaW5nOyBmaWx0ZXJUeXBlOiBzdHJpbmc7IGV2ZW50VHlwZTogc3RyaW5nOyBkYXRhOiBzdHJpbmcgfSk6IHZvaWQge1xuICAgICAgICBjb25zdCBjb25uZWN0aW9uSWQ6IHN0cmluZyA9IGV2ZW50LmNvbm5lY3Rpb25JZDtcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKGNvbm5lY3Rpb25JZCwgJ05vIGNvbm5lY3Rpb24gZm91bmQgZm9yIGNvbm5lY3Rpb25JZCAnICsgY29ubmVjdGlvbklkKS50aGVuKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhgRmlsdGVyIGV2ZW50IG9mIHR5cGUgXCIke2V2ZW50LmV2ZW50VHlwZX1cIiBkaXNwYXRjaGVkYCk7XG4gICAgICAgICAgICBjb25zdCBzdHJlYW06IFN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtITtcbiAgICAgICAgICAgIGlmICghc3RyZWFtIHx8ICFzdHJlYW0uZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYEZpbHRlciBldmVudCBvZiB0eXBlIFwiJHtldmVudC5ldmVudFR5cGV9XCIgZGlzcGF0Y2hlZCBmb3Igc3RyZWFtICR7c3RyZWFtLnN0cmVhbUlkfSBidXQgdGhlcmUgaXMgbm8gJHshc3RyZWFtID8gJ3N0cmVhbScgOiAnZmlsdGVyJ1xuICAgICAgICAgICAgICAgICAgICB9IGRlZmluZWRgXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGV2ZW50SGFuZGxlciA9IHN0cmVhbS5maWx0ZXIuaGFuZGxlcnMuZ2V0KGV2ZW50LmV2ZW50VHlwZSk7XG4gICAgICAgICAgICBpZiAoIWV2ZW50SGFuZGxlciB8fCB0eXBlb2YgZXZlbnRIYW5kbGVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYWN0dWFsSGFuZGxlcnM6IHN0cmluZ1tdID0gQXJyYXkuZnJvbShzdHJlYW0uZmlsdGVyLmhhbmRsZXJzLmtleXMoKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYEZpbHRlciBldmVudCBvZiB0eXBlIFwiJHtldmVudC5ldmVudFR5cGV9XCIgbm90IGhhbmRsZWQgb3Igbm90IGEgZnVuY3Rpb24hIEFjdGl2ZSBmaWx0ZXIgZXZlbnRzOiAke2FjdHVhbEhhbmRsZXJzLmpvaW4oXG4gICAgICAgICAgICAgICAgICAgICAgICAnLCdcbiAgICAgICAgICAgICAgICAgICAgKX1gXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZXZlbnRIYW5kbGVyLmNhbGwodGhpcywgbmV3IEZpbHRlckV2ZW50KHN0cmVhbS5maWx0ZXIsIGV2ZW50LmV2ZW50VHlwZSwgZXZlbnQuZGF0YSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Gb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXIoZXZlbnQ6IHsgY29ubmVjdGlvbklkOiBzdHJpbmc7IHN0cmVhbUlkOiBzdHJpbmc7IHNkcE9mZmVyOiBzdHJpbmcgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKGV2ZW50LmNvbm5lY3Rpb25JZCwgJ29uRm9yY2libHlSZWNvbm5lY3RTdWJzY3JpYmVyJylcbiAgICAgICAgICAgICAgICAudGhlbigoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSAmJiBjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZCA9PT0gZXZlbnQuc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RyZWFtLnNldHVwUmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyKHJlc29sdmUsIHJlamVjdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmdvaW5nIHJlY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdhaXQgZm9yIHRoZSBldmVudCBlbWl0dGVyIHRvIGJlIGZyZWUgKHdpdGggc3VjY2VzcyBvciBlcnJvcikgYW5kIGNhbGwgdGhlIG1ldGhvZCBhZ2FpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW0ucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyIVsnb25Gb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXJMYXN0RXZlbnQnXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFR3byBvciBtb3JlIG9uRm9yY2libHlSZWNvbm5lY3RTdWJzY3JpYmVyIGV2ZW50cyB3ZXJlIHJlY2VpdmVkIHdoaWxlIGEgcmVjb25uZWN0aW9uIHByb2Nlc3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2YgdGhlIHN1YnNjcmliZXIgd2FzIGFscmVhZHkgdGFraW5nIHBsYWNlLiBBbHdheXMgdXNlIHRoZSBsYXN0IG9uZSB0byByZXRyeSB0aGUgcmUtc3Vic2NyaXB0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByb2Nlc3MsIGFzIHRoYXQgU0RQIG9mZmVyIHdpbGwgYmUgdGhlIG9ubHkgb25lIGF2YWlsYWJsZSBhdCB0aGUgc2VydmVyIHNpZGUuIElnbm9yZSBwcmV2aW91cyBvbmVzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIhWydvbkZvcmNpYmx5UmVjb25uZWN0U3Vic2NyaWJlckxhc3RFdmVudCddID0gZXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoJ09uZ29pbmcgZm9yY2VkIHN1YnNjcmliZXIgcmVjb25uZWN0aW9uJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25lIG9uRm9yY2libHlSZWNvbm5lY3RTdWJzY3JpYmVyIGV2ZW4gaGFzIGJlZW4gcmVjZWl2ZWQgd2hpbGUgYSByZWNvbm5lY3Rpb24gcHJvY2Vzc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBvZiB0aGUgc3Vic2NyaWJlciB3YXMgYWxyZWFkeSB0YWtpbmcgcGxhY2UuIFNldCB1cCBhIGxpc3RlbmVyIHRvIHdhaXQgZm9yIGl0IHRvIHJldHJ5IHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3JjZWQgcmVjb25uZWN0aW9uIHByb2Nlc3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlciFbJ29uRm9yY2libHlSZWNvbm5lY3RTdWJzY3JpYmVyTGFzdEV2ZW50J10gPSBldmVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBldmVudEF1eCA9IHN0cmVhbS5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIhWydvbkZvcmNpYmx5UmVjb25uZWN0U3Vic2NyaWJlckxhc3RFdmVudCddO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHN0cmVhbS5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIhWydvbkZvcmNpYmx5UmVjb25uZWN0U3Vic2NyaWJlckxhc3RFdmVudCddO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkZvcmNpYmx5UmVjb25uZWN0U3Vic2NyaWJlcihldmVudEF1eCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIhLm9uY2UoJ3N1Y2Nlc3MnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlciEub25jZSgnZXJyb3InLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29tcGxldGVXZWJSdGNQZWVyUmVjZWl2ZSh0cnVlLCB0cnVlLCBldmVudC5zZHBPZmZlcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiBzdHJlYW0uZmluYWxSZXNvbHZlRm9yU3Vic2NyaXB0aW9uKHRydWUsIHJlc29sdmUpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maW5hbFJlamVjdEZvclN1YnNjcmlwdGlvbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgRXJyb3Igd2hpbGUgZm9yY2libHkgcmVjb25uZWN0aW5nIHJlbW90ZSBzdHJlYW0gJHtldmVudC5zdHJlYW1JZH06ICR7ZXJyb3IudG9TdHJpbmcoKX1gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyTXNnID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIk5vIHN0cmVhbSB3aXRoIHN0cmVhbUlkICdcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RyZWFtSWQgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiJyBmb3VuZCBmb3IgY29ubmVjdGlvbiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LmNvbm5lY3Rpb25JZCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInIG9uICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnIGV2ZW50XCI7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyTXNnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyTXNnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChvcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChvcGVuVmlkdUVycm9yKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY29ubmVjdEJyb2tlblN0cmVhbXMoKTogdm9pZCB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdSZS1lc3RhYmxpc2hpbmcgbWVkaWEgY29ubmVjdGlvbnMuLi4nKTtcbiAgICAgICAgbGV0IHNvbWVSZWNvbm5lY3Rpb24gPSBmYWxzZTtcbiAgICAgICAgLy8gUmUtZXN0YWJsaXNoIFB1Ymxpc2hlciBzdHJlYW1cbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSAmJiB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUljZUNvbm5lY3Rpb25TdGF0ZUJyb2tlbigpKSB7XG4gICAgICAgICAgICBsb2dnZXIud2FybignUmUtZXN0YWJsaXNoaW5nIFB1Ymxpc2hlciAnICsgdGhpcy5jb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmluaXRXZWJSdGNQZWVyU2VuZCh0cnVlKTtcbiAgICAgICAgICAgIHNvbWVSZWNvbm5lY3Rpb24gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlLWVzdGFibGlzaCBTdWJzY3JpYmVyIHN0cmVhbXNcbiAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9ucy5mb3JFYWNoKChyZW1vdGVDb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uLnN0cmVhbSAmJiByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JY2VDb25uZWN0aW9uU3RhdGVCcm9rZW4oKSkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdSZS1lc3RhYmxpc2hpbmcgU3Vic2NyaWJlciAnICsgcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgIHJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtLmluaXRXZWJSdGNQZWVyUmVjZWl2ZSh0cnVlKTtcbiAgICAgICAgICAgICAgICBzb21lUmVjb25uZWN0aW9uID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghc29tZVJlY29ubmVjdGlvbikge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ1RoZXJlIHdlcmUgbm8gbWVkaWEgc3RyZWFtcyBpbiBuZWVkIG9mIGEgcmVjb25uZWN0aW9uJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYXN5bmMgb25TcGVlY2hUb1RleHRNZXNzYWdlKGV2ZW50OiB7XG4gICAgICAgIHRpbWVzdGFtcD86IERhdGU7XG4gICAgICAgIHN0cmVhbUlkOiBzdHJpbmc7XG4gICAgICAgIGNvbm5lY3Rpb25JZDogc3RyaW5nO1xuICAgICAgICBzZXNzaW9uSWQ6IHN0cmluZztcbiAgICAgICAgdGV4dDogc3RyaW5nO1xuICAgICAgICByZWFzb246IHN0cmluZztcbiAgICAgICAgcmF3OiBzdHJpbmc7XG4gICAgICAgIGxhbmc6IHN0cmluZztcbiAgICB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLmdldENvbm5lY3Rpb24oZXZlbnQuY29ubmVjdGlvbklkLCAnTm8gY29ubmVjdGlvbiBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgKyBldmVudC5jb25uZWN0aW9uSWQpO1xuICAgICAgICBjb25zdCBldiA9IG5ldyBTcGVlY2hUb1RleHRFdmVudCh0aGlzLCBjb25uZWN0aW9uLCBldmVudC50ZXh0LCA8YW55PihldmVudC5yZWFzb24pLnRvTG93ZXJDYXNlKCksIGV2ZW50LnJhdywgZXZlbnQubGFuZyk7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzcGVlY2hUb1RleHRNZXNzYWdlJywgW2V2XSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFzeW5jIG9uU3BlZWNoVG9UZXh0RGlzY29ubmVjdGVkKGV2ZW50OiB7IG1lc3NhZ2U6IHN0cmluZyB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRoaXMuZW1pdEV2ZW50KCdleGNlcHRpb24nLCBbbmV3IEV4Y2VwdGlvbkV2ZW50KHRoaXMsIEV4Y2VwdGlvbkV2ZW50TmFtZS5TUEVFQ0hfVE9fVEVYVF9ESVNDT05ORUNURUQsIHRoaXMsIGV2ZW50Lm1lc3NhZ2UpXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVtaXRFdmVudCh0eXBlOiBzdHJpbmcsIGV2ZW50QXJyYXk6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KHR5cGUsIGV2ZW50QXJyYXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBsZWF2ZShmb3JjZWQ6IGJvb2xlYW4sIHJlYXNvbjogQ29ubmVjdGlvbkV2ZW50UmVhc29uKTogdm9pZCB7XG4gICAgICAgIGZvcmNlZCA9ICEhZm9yY2VkO1xuICAgICAgICBsb2dnZXIuaW5mbygnTGVhdmluZyBTZXNzaW9uIChmb3JjZWQ9JyArIGZvcmNlZCArICcpJyk7XG4gICAgICAgIHRoaXMuc3RvcFZpZGVvRGF0YUludGVydmFscygpO1xuXG4gICAgICAgIGlmICghIXRoaXMuY29ubmVjdGlvbikge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQgJiYgIWZvcmNlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2xlYXZlUm9vbScsIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYGxlYXZlUm9vbSBlcnJvcjogJHtKU09OLnN0cmluZ2lmeShlcnJvcil9YCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5jbG9zZVdzKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFNlc3Npb24gb2JqZWN0IGRpc3BhdGNoICdzZXNzaW9uRGlzY29ubmVjdGVkJyBldmVudCAoaWYgaXQgaXMgbm90IGFscmVhZHkgZGlzcG9zZWQpXG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudCA9IG5ldyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQodGhpcywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcsIFtzZXNzaW9uRGlzY29ubmVjdEV2ZW50XSk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudC5jYWxsRGVmYXVsdEJlaGF2aW9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dnZXIud2FybignWW91IHdlcmUgbm90IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiAnICsgdGhpcy5zZXNzaW9uSWQpO1xuICAgICAgICB9XG4gICAgICAgIGxvZ2dlci5mbHVzaCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplUGFyYW1zKHRva2VuOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3Qgam9pblBhcmFtcyA9IHtcbiAgICAgICAgICAgIHRva2VuOiAhIXRva2VuID8gdG9rZW4gOiAnJyxcbiAgICAgICAgICAgIHNlc3Npb246IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgcGxhdGZvcm06ICEhcGxhdGZvcm0uZ2V0RGVzY3JpcHRpb24oKSA/IHBsYXRmb3JtLmdldERlc2NyaXB0aW9uKCkgOiAndW5rbm93bicsXG4gICAgICAgICAgICBzZGtWZXJzaW9uOiB0aGlzLm9wZW52aWR1LmxpYnJhcnlWZXJzaW9uLFxuICAgICAgICAgICAgbWV0YWRhdGE6ICEhdGhpcy5vcHRpb25zLm1ldGFkYXRhID8gdGhpcy5vcHRpb25zLm1ldGFkYXRhIDogJycsXG4gICAgICAgICAgICBzZWNyZXQ6IHRoaXMub3BlbnZpZHUuZ2V0U2VjcmV0KCksXG4gICAgICAgICAgICByZWNvcmRlcjogdGhpcy5vcGVudmlkdS5nZXRSZWNvcmRlcigpLFxuICAgICAgICAgICAgc3R0OiB0aGlzLm9wZW52aWR1LmdldFN0dCgpXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBqb2luUGFyYW1zO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZW5kVmlkZW9EYXRhKHN0cmVhbU1hbmFnZXI6IFN0cmVhbU1hbmFnZXIsIGludGVydmFsU2Vjb25kczogbnVtYmVyID0gMSwgZG9JbnRlcnZhbDogYm9vbGVhbiA9IGZhbHNlLCBtYXhMb29wczogbnVtYmVyID0gMSkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0Nocm9tZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNDaHJvbWVNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzT3BlcmFCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzT3BlcmFNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzRWRnZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNFZGdlTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0VsZWN0cm9uKCkgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5pc1NhZmFyaUJyb3dzZXIoKSAmJiAhcGxhdGZvcm0uaXNJb25pY0lvcygpKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNBbmRyb2lkQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc1NhbXN1bmdCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzSW9uaWNBbmRyb2lkKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzSU9TV2l0aFNhZmFyaSgpXG4gICAgICAgICkge1xuICAgICAgICAgICAgY29uc3Qgb2J0YWluQW5kU2VuZFZpZGVvID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBjID0gc3RyZWFtTWFuYWdlci5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKTtcbiAgICAgICAgICAgICAgICBpZiAocGMuY29ubmVjdGlvblN0YXRlID09PSAnY29ubmVjdGVkJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGF0c01hcCA9IGF3YWl0IHBjLmdldFN0YXRzKCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFycjogYW55W10gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgc3RhdHNNYXAuZm9yRWFjaCgoc3RhdHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgnZnJhbWVXaWR0aCcgaW4gc3RhdHMgJiYgJ2ZyYW1lSGVpZ2h0JyBpbiBzdGF0cyAmJiBhcnIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyLnB1c2goc3RhdHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFyci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2aWRlb0RhdGEnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBhcnJbMF0uZnJhbWVIZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiBhcnJbMF0uZnJhbWVXaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IHN0cmVhbU1hbmFnZXIuc3RyZWFtLnZpZGVvQWN0aXZlICE9IG51bGwgPyBzdHJlYW1NYW5hZ2VyLnN0cmVhbS52aWRlb0FjdGl2ZSA6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpb0FjdGl2ZTogc3RyZWFtTWFuYWdlci5zdHJlYW0uYXVkaW9BY3RpdmUgIT0gbnVsbCA/IHN0cmVhbU1hbmFnZXIuc3RyZWFtLmF1ZGlvQWN0aXZlIDogZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXCJFcnJvciBzZW5kaW5nICd2aWRlb0RhdGEnIGV2ZW50XCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGRvSW50ZXJ2YWwpIHtcbiAgICAgICAgICAgICAgICBsZXQgbG9vcHMgPSAxO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EYXRhSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChsb29wcyA8IG1heExvb3BzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb29wcysrO1xuICAgICAgICAgICAgICAgICAgICAgICAgb2J0YWluQW5kU2VuZFZpZGVvKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHRoaXMudmlkZW9EYXRhSW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSwgaW50ZXJ2YWxTZWNvbmRzICogMTAwMCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EYXRhVGltZW91dCA9IHNldFRpbWVvdXQob2J0YWluQW5kU2VuZFZpZGVvLCBpbnRlcnZhbFNlY29uZHMgKiAxMDAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChwbGF0Zm9ybS5pc0ZpcmVmb3hCcm93c2VyKCkgfHwgcGxhdGZvcm0uaXNGaXJlZm94TW9iaWxlQnJvd3NlcigpIHx8IHBsYXRmb3JtLmlzSW9uaWNJb3MoKSB8fCBwbGF0Zm9ybS5pc1JlYWN0TmF0aXZlKCkpIHtcbiAgICAgICAgICAgIC8vIEJhc2ljIHZlcnNpb24gZm9yIEZpcmVmb3ggYW5kIElvbmljIGlPUy4gVGhleSBkbyBub3Qgc3VwcG9ydCBzdGF0c1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAndmlkZW9EYXRhJyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogc3RyZWFtTWFuYWdlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zPy5oZWlnaHQgfHwgMCxcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHN0cmVhbU1hbmFnZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucz8ud2lkdGggfHwgMCxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IHN0cmVhbU1hbmFnZXIuc3RyZWFtLnZpZGVvQWN0aXZlICE9IG51bGwgPyBzdHJlYW1NYW5hZ2VyLnN0cmVhbS52aWRlb0FjdGl2ZSA6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBhdWRpb0FjdGl2ZTogc3RyZWFtTWFuYWdlci5zdHJlYW0uYXVkaW9BY3RpdmUgIT0gbnVsbCA/IHN0cmVhbU1hbmFnZXIuc3RyZWFtLmF1ZGlvQWN0aXZlIDogZmFsc2VcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXCJFcnJvciBzZW5kaW5nICd2aWRlb0RhdGEnIGV2ZW50XCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgJ0Jyb3dzZXIgJyArXG4gICAgICAgICAgICAgICAgcGxhdGZvcm0uZ2V0TmFtZSgpICtcbiAgICAgICAgICAgICAgICAnICh2ZXJzaW9uICcgK1xuICAgICAgICAgICAgICAgIHBsYXRmb3JtLmdldFZlcnNpb24oKSArXG4gICAgICAgICAgICAgICAgJykgZm9yICcgK1xuICAgICAgICAgICAgICAgIHBsYXRmb3JtLmdldEZhbWlseSgpICtcbiAgICAgICAgICAgICAgICAnIGlzIG5vdCBzdXBwb3J0ZWQgaW4gT3BlblZpZHUgZm9yIE5ldHdvcmsgUXVhbGl0eSdcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2Vzc2lvbkNvbm5lY3RlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbiAhPSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBub3RDb25uZWN0ZWRFcnJvcigpOiBPcGVuVmlkdUVycm9yIHtcbiAgICAgICAgcmV0dXJuIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCxcbiAgICAgICAgICAgIFwiVGhlcmUgaXMgbm8gY29ubmVjdGlvbiB0byB0aGUgc2Vzc2lvbi4gTWV0aG9kICdTZXNzaW9uLmNvbm5lY3QnIG11c3QgYmUgc3VjY2Vzc2Z1bGx5IGNvbXBsZXRlZCBmaXJzdFwiXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKGV2ZW50OiBzdHJpbmcsIG9ubHlPbmNlOiBib29sZWFuLCBzdHJlYW1NYW5hZ2VyPzogU3RyZWFtTWFuYWdlcik6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgaGFuZGxlcnNJblNlc3Npb24gPSB0aGlzLmVlLmdldExpc3RlbmVycyhldmVudCk7XG4gICAgICAgIGlmIChvbmx5T25jZSkge1xuICAgICAgICAgICAgaGFuZGxlcnNJblNlc3Npb24gPSBoYW5kbGVyc0luU2Vzc2lvbi5maWx0ZXIoKGgpID0+IChoIGFzIGFueSkub25jZSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGxpc3RlbmVyc0luU2Vzc2lvbiA9IGhhbmRsZXJzSW5TZXNzaW9uLmxlbmd0aDtcbiAgICAgICAgaWYgKGxpc3RlbmVyc0luU2Vzc2lvbiA+IDApIHJldHVybiB0cnVlO1xuICAgICAgICBsZXQgbGlzdGVuZXJzSW5TdHJlYW1NYW5hZ2VyID0gMDtcbiAgICAgICAgaWYgKCEhc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgbGV0IGhhbmRsZXJzSW5TdHJlYW1NYW5hZ2VyID0gc3RyZWFtTWFuYWdlci5lZS5nZXRMaXN0ZW5lcnMoZXZlbnQpO1xuICAgICAgICAgICAgaWYgKG9ubHlPbmNlKSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlcnNJblN0cmVhbU1hbmFnZXIgPSBoYW5kbGVyc0luU3RyZWFtTWFuYWdlci5maWx0ZXIoKGgpID0+IChoIGFzIGFueSkub25jZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsaXN0ZW5lcnNJblN0cmVhbU1hbmFnZXIgPSBoYW5kbGVyc0luU3RyZWFtTWFuYWdlci5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyc0luU3RyZWFtTWFuYWdlciA+IDA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFRva2VuUGFyYW1zKHRva2VuOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgbWF0Y2ggPSB0b2tlbi5tYXRjaCgvXih3c3M/KVxcOlxcL1xcLygoW146XFwvPyNdKikoPzpcXDooWzAtOV0rKSk/KShbXFwvXXswLDF9W14/I10qKShcXD9bXiNdKnwpKCMuKnwpJC8pO1xuICAgICAgICBpZiAoISFtYXRjaCkge1xuICAgICAgICAgICAgY29uc3QgdXJsID0ge1xuICAgICAgICAgICAgICAgIHByb3RvY29sOiBtYXRjaFsxXSxcbiAgICAgICAgICAgICAgICBob3N0OiBtYXRjaFsyXSxcbiAgICAgICAgICAgICAgICBob3N0bmFtZTogbWF0Y2hbM10sXG4gICAgICAgICAgICAgICAgcG9ydDogbWF0Y2hbNF0sXG4gICAgICAgICAgICAgICAgcGF0aG5hbWU6IG1hdGNoWzVdLFxuICAgICAgICAgICAgICAgIHNlYXJjaDogbWF0Y2hbNl0sXG4gICAgICAgICAgICAgICAgaGFzaDogbWF0Y2hbN11cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHRva2VuLnNwbGl0KCc/Jyk7XG4gICAgICAgICAgICBjb25zdCBxdWVyeVBhcmFtcyA9IGRlY29kZVVSSShwYXJhbXNbMV0pXG4gICAgICAgICAgICAgICAgLnNwbGl0KCcmJylcbiAgICAgICAgICAgICAgICAubWFwKChwYXJhbSkgPT4gcGFyYW0uc3BsaXQoJz0nKSlcbiAgICAgICAgICAgICAgICAucmVkdWNlKCh2YWx1ZXMsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZXNba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVzO1xuICAgICAgICAgICAgICAgIH0sIHt9KTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHF1ZXJ5UGFyYW1zWydzZXNzaW9uSWQnXSxcbiAgICAgICAgICAgICAgICBzZWNyZXQ6IHF1ZXJ5UGFyYW1zWydzZWNyZXQnXSxcbiAgICAgICAgICAgICAgICByZWNvcmRlcjogcXVlcnlQYXJhbXNbJ3JlY29yZGVyJ10sXG4gICAgICAgICAgICAgICAgc3R0OiBxdWVyeVBhcmFtc1snc3R0J10sXG4gICAgICAgICAgICAgICAgd2VicnRjU3RhdHNJbnRlcnZhbDogcXVlcnlQYXJhbXNbJ3dlYnJ0Y1N0YXRzSW50ZXJ2YWwnXSxcbiAgICAgICAgICAgICAgICBzZW5kQnJvd3NlckxvZ3M6IHF1ZXJ5UGFyYW1zWydzZW5kQnJvd3NlckxvZ3MnXSxcbiAgICAgICAgICAgICAgICBlZGl0aW9uOiBxdWVyeVBhcmFtc1snZWRpdGlvbiddLFxuICAgICAgICAgICAgICAgIHdzVXJpOiB1cmwucHJvdG9jb2wgKyAnOi8vJyArIHVybC5ob3N0ICsgJy9vcGVudmlkdScsXG4gICAgICAgICAgICAgICAgaHR0cFVyaTogJ2h0dHBzOi8vJyArIHVybC5ob3N0XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUb2tlbiBub3QgdmFsaWQ6IFwiJHt0b2tlbn1cImApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIGNvbm5lY3RBdXgodG9rZW46IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zdGFydFdzKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB0aGlzLmluaXRpYWxpemVQYXJhbXModG9rZW4pO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2pvaW5Sb29tJywgam9pblBhcmFtcywgKGVycm9yLCByZXNwb25zZTogTG9jYWxDb25uZWN0aW9uT3B0aW9ucykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUHJvY2VzcyBqb2luIHJvb20gcmVzcG9uc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NKb2luUm9vbVJlc3BvbnNlKHJlc3BvbnNlLCB0b2tlbik7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIGxvY2FsIENvbm5lY3Rpb24gb2JqZWN0IHdpdGggdmFsdWVzIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IG5ldyBDb25uZWN0aW9uKHRoaXMsIHJlc3BvbnNlKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgcmVtb3RlIENvbm5lY3Rpb25zIHdpdGggdmFsdWUgcmV0dXJuZWQgYnkgb3BlbnZpZHUtc2VydmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXZlbnRzID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uczogbmV3IEFycmF5PENvbm5lY3Rpb24+KCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbXM6IG5ldyBBcnJheTxTdHJlYW0+KClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nUGFydGljaXBhbnRzOiBSZW1vdGVDb25uZWN0aW9uT3B0aW9uc1tdID0gcmVzcG9uc2UudmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdQYXJ0aWNpcGFudHMuZm9yRWFjaCgocmVtb3RlQ29ubmVjdGlvbk9wdGlvbnM6IFJlbW90ZUNvbm5lY3Rpb25PcHRpb25zKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZW1vdGVDb25uZWN0aW9uT3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuc2V0KGNvbm5lY3Rpb24uY29ubmVjdGlvbklkLCBjb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZVN0cmVhbXNDcmVhdGVkLnNldChjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudHMuc3RyZWFtcy5wdXNoKGNvbm5lY3Rpb24uc3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3duICdjb25uZWN0aW9uQ3JlYXRlZCcgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvbkNyZWF0ZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIHRoaXMuY29ubmVjdGlvbiwgJycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgJ2Nvbm5lY3Rpb25DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBleGlzdGluZyBjb25uZWN0aW9uIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLmNvbm5lY3Rpb25zLmZvckVhY2goKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25DcmVhdGVkJywgY29ubmVjdGlvbiwgJycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25lICdzdHJlYW1DcmVhdGVkJyBldmVudCBmb3IgZWFjaCBhY3RpdmUgc3RyZWFtIGluIHRoZSBzZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMuZm9yRWFjaCgoc3RyZWFtKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCBzdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVzcG9uc2UucmVjb3JkaW5nSWQgJiYgISFyZXNwb25zZS5yZWNvcmRpbmdOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdyZWNvcmRpbmdTdGFydGVkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdGFydGVkJywgcmVzcG9uc2UucmVjb3JkaW5nSWQsIHJlc3BvbnNlLnJlY29yZGluZ05hbWUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BQdWJsaXNoZXJTdHJlYW0ocmVhc29uOiBTdHJlYW1FdmVudFJlYXNvbikge1xuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24uc3RyZWFtKSB7XG4gICAgICAgICAgICAvLyBEaXNwb3NlIFB1Ymxpc2hlcidzICBsb2NhbCBzdHJlYW1cbiAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBNYWtlIFB1Ymxpc2hlciBvYmplY3QgZGlzcGF0Y2ggJ3N0cmVhbURlc3Ryb3llZCcgZXZlbnQgaWYgdGhlIFN0cmVhbSB3YXMgcHVibGlzaGVkXG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLnN0cmVhbS5lZS5lbWl0RXZlbnQoJ2xvY2FsLXN0cmVhbS1kZXN0cm95ZWQnLCBbcmVhc29uXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BWaWRlb0RhdGFJbnRlcnZhbHMoKTogdm9pZCB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy52aWRlb0RhdGFJbnRlcnZhbCk7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnZpZGVvRGF0YVRpbWVvdXQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RyaW5nQ2xpZW50TWV0YWRhdGEobWV0YWRhdGE6IGFueSk6IHN0cmluZyB7XG4gICAgICAgIGlmICh0eXBlb2YgbWV0YWRhdGEgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkobWV0YWRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG1ldGFkYXRhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldENvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9ucy5nZXQoY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkID09PSBjb25uZWN0aW9uSWQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVzb2x2ZSBsb2NhbCBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHRoaXMuY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBub3QgZm91bmQuIFJlamVjdCB3aXRoIE9wZW5WaWR1RXJyb3JcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5HRU5FUklDX0VSUk9SLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UmVtb3RlQ29ubmVjdGlvbihjb25uZWN0aW9uSWQ6IHN0cmluZywgb3BlcmF0aW9uOiBzdHJpbmcpOiBQcm9taXNlPENvbm5lY3Rpb24+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPENvbm5lY3Rpb24+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmdldChjb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgcmVtb3RlIGNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3RlIGNvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID1cbiAgICAgICAgICAgICAgICAgICAgJ1JlbW90ZSBjb25uZWN0aW9uICcgK1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWQgK1xuICAgICAgICAgICAgICAgICAgICBcIiB1bmtub3duIHdoZW4gJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uICtcbiAgICAgICAgICAgICAgICAgICAgXCInLiBcIiArXG4gICAgICAgICAgICAgICAgICAgICdFeGlzdGluZyByZW1vdGUgY29ubmVjdGlvbnM6ICcgK1xuICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmtleXMoKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5HRU5FUklDX0VSUk9SLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwcm9jZXNzVG9rZW4odG9rZW46IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zdCB0b2tlblBhcmFtcyA9IHRoaXMuZ2V0VG9rZW5QYXJhbXModG9rZW4pO1xuICAgICAgICB0aGlzLnNlc3Npb25JZCA9IHRva2VuUGFyYW1zLnNlc3Npb25JZDtcblxuICAgICAgICBpZiAoISF0b2tlblBhcmFtcy5zZWNyZXQpIHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VjcmV0ID0gdG9rZW5QYXJhbXMuc2VjcmV0O1xuICAgICAgICB9XG4gICAgICAgIGlmICghIXRva2VuUGFyYW1zLnJlY29yZGVyKSB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnJlY29yZGVyID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISF0b2tlblBhcmFtcy5zdHQpIHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc3R0ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISF0b2tlblBhcmFtcy53ZWJydGNTdGF0c0ludGVydmFsKSB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LndlYnJ0Y1N0YXRzSW50ZXJ2YWwgPSB0b2tlblBhcmFtcy53ZWJydGNTdGF0c0ludGVydmFsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghIXRva2VuUGFyYW1zLnNlbmRCcm93c2VyTG9ncykge1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kQnJvd3NlckxvZ3MgPSB0b2tlblBhcmFtcy5zZW5kQnJvd3NlckxvZ3M7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcGVudmlkdS5pc0F0TGVhc3RQcm8gPSB0b2tlblBhcmFtcy5lZGl0aW9uID09PSAncHJvJyB8fCB0b2tlblBhcmFtcy5lZGl0aW9uID09PSAnZW50ZXJwcmlzZSc7XG4gICAgICAgIHRoaXMub3BlbnZpZHUuaXNFbnRlcnByaXNlID0gdG9rZW5QYXJhbXMuZWRpdGlvbiA9PT0gJ2VudGVycHJpc2UnO1xuXG4gICAgICAgIHRoaXMub3BlbnZpZHUud3NVcmkgPSB0b2tlblBhcmFtcy53c1VyaTtcbiAgICAgICAgdGhpcy5vcGVudmlkdS5odHRwVXJpID0gdG9rZW5QYXJhbXMuaHR0cFVyaTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NKb2luUm9vbVJlc3BvbnNlKG9wdHM6IExvY2FsQ29ubmVjdGlvbk9wdGlvbnMsIHRva2VuOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSBvcHRzLnNlc3Npb247XG4gICAgICAgIGlmIChvcHRzLmN1c3RvbUljZVNlcnZlcnMgIT0gbnVsbCAmJiBvcHRzLmN1c3RvbUljZVNlcnZlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGljZVNlcnZlciBvZiBvcHRzLmN1c3RvbUljZVNlcnZlcnMpIHtcbiAgICAgICAgICAgICAgICBsZXQgcnRjSWNlU2VydmVyOiBSVENJY2VTZXJ2ZXIgPSB7XG4gICAgICAgICAgICAgICAgICAgIHVybHM6IFtpY2VTZXJ2ZXIudXJsXVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmxvZygnU1RVTi9UVVJOIHNlcnZlciBJUDogJyArIGljZVNlcnZlci51cmwpO1xuICAgICAgICAgICAgICAgIGlmIChpY2VTZXJ2ZXIudXNlcm5hbWUgIT0gbnVsbCAmJiBpY2VTZXJ2ZXIuY3JlZGVudGlhbCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJ0Y0ljZVNlcnZlci51c2VybmFtZSA9IGljZVNlcnZlci51c2VybmFtZTtcbiAgICAgICAgICAgICAgICAgICAgcnRjSWNlU2VydmVyLmNyZWRlbnRpYWwgPSBpY2VTZXJ2ZXIuY3JlZGVudGlhbDtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZygnVFVSTiBjcmVkZW50aWFscyBbJyArIGljZVNlcnZlci51c2VybmFtZSArICc6JyArIGljZVNlcnZlci5jcmVkZW50aWFsICsgJ10nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5pY2VTZXJ2ZXJzLnB1c2gocnRjSWNlU2VydmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wZW52aWR1LnJvbGUgPSBvcHRzLnJvbGU7XG4gICAgICAgIHRoaXMub3BlbnZpZHUuZmluYWxVc2VySWQgPSBvcHRzLmZpbmFsVXNlcklkO1xuICAgICAgICB0aGlzLm9wZW52aWR1Lm1lZGlhU2VydmVyID0gb3B0cy5tZWRpYVNlcnZlcjtcbiAgICAgICAgdGhpcy5vcGVudmlkdS52aWRlb1NpbXVsY2FzdCA9IG9wdHMudmlkZW9TaW11bGNhc3Q7XG4gICAgICAgIHRoaXMuY2FwYWJpbGl0aWVzID0ge1xuICAgICAgICAgICAgc3Vic2NyaWJlOiB0cnVlLFxuICAgICAgICAgICAgcHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlICE9PSAnU1VCU0NSSUJFUicsXG4gICAgICAgICAgICBmb3JjZVVucHVibGlzaDogdGhpcy5vcGVudmlkdS5yb2xlID09PSAnTU9ERVJBVE9SJyxcbiAgICAgICAgICAgIGZvcmNlRGlzY29ubmVjdDogdGhpcy5vcGVudmlkdS5yb2xlID09PSAnTU9ERVJBVE9SJ1xuICAgICAgICB9O1xuICAgICAgICBsb2dnZXIuaW5mbygnb3BlbnZpZHUtc2VydmVyIHZlcnNpb246ICcgKyBvcHRzLnZlcnNpb24pO1xuICAgICAgICBpZiAob3B0cy5saWZlICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUubGlmZSA9IG9wdHMubGlmZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtaW5vckRpZmZlcmVuY2U6IG51bWJlciA9IHNlbXZlck1pbm9yKG9wdHMudmVyc2lvbikgLSBzZW12ZXJNaW5vcih0aGlzLm9wZW52aWR1LmxpYnJhcnlWZXJzaW9uKTtcbiAgICAgICAgaWYgKHNlbXZlck1ham9yKG9wdHMudmVyc2lvbikgIT09IHNlbXZlck1ham9yKHRoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb24pIHx8ICEobWlub3JEaWZmZXJlbmNlID09IDAgfHwgbWlub3JEaWZmZXJlbmNlID09IDEpKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgYG9wZW52aWR1LWJyb3dzZXIgKCR7dGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbn0pIGFuZCBvcGVudmlkdS1zZXJ2ZXIgKCR7b3B0cy52ZXJzaW9ufSkgdmVyc2lvbnMgYXJlIGluY29tcGF0aWJsZS4gYCArXG4gICAgICAgICAgICAgICAgJ0Vycm9ycyBhcmUgbGlrZWx5IHRvIG9jY3VyLiBvcGVudmlkdS1icm93c2VyIFNESyBpcyBvbmx5IGNvbXBhdGlibGUgd2l0aCB0aGUgc2FtZSB2ZXJzaW9uIG9yIHRoZSBpbW1lZGlhdGVseSBmb2xsb3dpbmcgbWlub3IgdmVyc2lvbiBvZiBhbiBPcGVuVmlkdSBkZXBsb3ltZW50J1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChtaW5vckRpZmZlcmVuY2UgPT0gMSkge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgICAgICAgYG9wZW52aWR1LWJyb3dzZXIgdmVyc2lvbiAke3RoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb259IGRvZXMgbm90IG1hdGNoIG9wZW52aWR1LXNlcnZlciB2ZXJzaW9uICR7b3B0cy52ZXJzaW9ufS4gYCArXG4gICAgICAgICAgICAgICAgYFRoZXNlIHZlcnNpb25zIGFyZSBzdGlsbCBjb21wYXRpYmxlIHdpdGggZWFjaCBvdGhlciwgYnV0IG9wZW52aWR1LWJyb3dzZXIgdmVyc2lvbiBtdXN0IGJlIHVwZGF0ZWQgYXMgc29vbiBhcyBwb3NzaWJsZSB0byAke3NlbXZlck1ham9yKFxuICAgICAgICAgICAgICAgICAgICBvcHRzLnZlcnNpb25cbiAgICAgICAgICAgICAgICApfS4ke3NlbXZlck1pbm9yKG9wdHMudmVyc2lvbil9LnguIGAgK1xuICAgICAgICAgICAgICAgIGBUaGlzIGNsaWVudCB1c2luZyBvcGVudmlkdS1icm93c2VyICR7dGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbn0gd2lsbCBiZWNvbWUgaW5jb21wYXRpYmxlIHdpdGggdGhlIG5leHQgcmVsZWFzZSBvZiBvcGVudmlkdS1zZXJ2ZXJgXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ29uZmlndXJlIEpTTkxvZ3NcbiAgICAgICAgT3BlblZpZHVMb2dnZXIuY29uZmlndXJlSlNOTG9nKHRoaXMub3BlbnZpZHUsIHRva2VuKTtcblxuICAgICAgICAvLyBTdG9yZSB0b2tlblxuICAgICAgICB0aGlzLnRva2VuID0gdG9rZW47XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuL0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSAnLi9GaWx0ZXInO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSAnLi9QdWJsaXNoZXInO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgSW5ib3VuZFN0cmVhbU9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9JbmJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBPdXRib3VuZFN0cmVhbU9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9PdXRib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHtcbiAgICBXZWJSdGNQZWVyLFxuICAgIFdlYlJ0Y1BlZXJTZW5kb25seSxcbiAgICBXZWJSdGNQZWVyUmVjdm9ubHksXG4gICAgV2ViUnRjUGVlclNlbmRyZWN2LFxuICAgIFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uXG59IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyJztcbmltcG9ydCB7IFdlYlJ0Y1N0YXRzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cyc7XG5pbXBvcnQgeyBFeGNlcHRpb25FdmVudCwgRXhjZXB0aW9uRXZlbnROYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXhjZXB0aW9uRXZlbnQnO1xuaW1wb3J0IHsgUHVibGlzaGVyU3BlYWtpbmdFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1B1Ymxpc2hlclNwZWFraW5nRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtTWFuYWdlckV2ZW50JztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVHlwZU9mVmlkZW8gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1R5cGVPZlZpZGVvJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9Mb2dnZXIvT3BlblZpZHVMb2dnZXInO1xuaW1wb3J0IHsgUGxhdGZvcm1VdGlscyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvVXRpbHMvUGxhdGZvcm0nO1xuXG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tICd1dWlkJztcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmltcG9ydCBoYXJrID0gcmVxdWlyZSgnaGFyaycpO1xuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmltcG9ydCBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCd3b2xmeTg3LWV2ZW50ZW1pdHRlcicpO1xuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqL1xubGV0IHBsYXRmb3JtOiBQbGF0Zm9ybVV0aWxzO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgZWFjaCBvbmUgb2YgdGhlIG1lZGlhIHN0cmVhbXMgYXZhaWxhYmxlIGluIE9wZW5WaWR1IFNlcnZlciBmb3IgY2VydGFpbiBzZXNzaW9uLlxuICogRWFjaCB7QGxpbmsgUHVibGlzaGVyfSBhbmQge0BsaW5rIFN1YnNjcmliZXJ9IGhhcyBhbiBhdHRyaWJ1dGUgb2YgdHlwZSBTdHJlYW0sIGFzIHRoZXkgZ2l2ZSBhY2Nlc3NcbiAqIHRvIG9uZSBvZiB0aGVtIChzZW5kaW5nIGFuZCByZWNlaXZpbmcgaXQsIHJlc3BlY3RpdmVseSlcbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbSB7XG4gICAgLyoqXG4gICAgICogVGhlIENvbm5lY3Rpb24gb2JqZWN0IHRoYXQgaXMgcHVibGlzaGluZyB0aGUgc3RyZWFtXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEZyYW1lIHJhdGUgb2YgdGhlIHZpZGVvIGluIGZyYW1lcyBwZXIgc2Vjb25kLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZiB0aGUge0BsaW5rIFB1Ymxpc2hlcn0gb2ZcbiAgICAgKiB0aGUgc3RyZWFtIHdhcyBpbml0aWFsaXplZCBwYXNzaW5nIGEgX2ZyYW1lUmF0ZV8gcHJvcGVydHkgb24ge0BsaW5rIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJ9IG1ldGhvZFxuICAgICAqL1xuICAgIGZyYW1lUmF0ZT86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgYSB2aWRlbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNWaWRlbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgYW4gYXVkaW8gdHJhY2sgb3Igbm90XG4gICAgICovXG4gICAgaGFzQXVkaW86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSB2aWRlbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiB7QGxpbmsgaGFzVmlkZW99IGlzIGZhbHNlLCB0aGlzIHByb3BlcnR5IGlzIHVuZGVmaW5lZC5cbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbSBjYWxscyB7QGxpbmsgUHVibGlzaGVyLnB1Ymxpc2hWaWRlb30uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIHtAbGluayBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudH0gd2lsbCBiZSBkaXNwYXRjaGVkXG4gICAgICogYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvQWN0aXZlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyB0aGUgYXVkaW8gdHJhY2sgbXV0ZWQgb3IgdW5tdXRlZC4gSWYge0BsaW5rIGhhc0F1ZGlvfSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHB1Ymxpc2hpbmcgdGhlIHN0cmVhbSBjYWxscyB7QGxpbmsgUHVibGlzaGVyLnB1Ymxpc2hBdWRpb30uIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIHtAbGluayBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudH0gd2lsbCBiZSBkaXNwYXRjaGVkXG4gICAgICogYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIGF1ZGlvQWN0aXZlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIHN0cmVhbS4gSWYgdGhlIHN0cmVhbSBiZWxvbmdzIHRvIGEuLi5cbiAgICAgKiAtIFN1YnNjcmliZXIgb2JqZWN0OiBwcm9wZXJ0eSBgc3RyZWFtSWRgIGlzIGFsd2F5cyBkZWZpbmVkXG4gICAgICogLSBQdWJsaXNoZXIgb2JqZWN0OiBwcm9wZXJ0eSBgc3RyZWFtSWRgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiB7QGxpbmsgU2Vzc2lvbi5wdWJsaXNofVxuICAgICAqL1xuICAgIHN0cmVhbUlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaW1lIHdoZW4gdGhpcyBzdHJlYW0gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKS4gRGVwZW5kaW5nIG9uIHRoZSBvd25lciBvZiB0aGlzIHN0cmVhbTpcbiAgICAgKiAtIFN1YnNjcmliZXIgb2JqZWN0OiBwcm9wZXJ0eSBgY3JlYXRpb25UaW1lYCBpcyBhbHdheXMgZGVmaW5lZFxuICAgICAqIC0gUHVibGlzaGVyIG9iamVjdDogcHJvcGVydHkgYGNyZWF0aW9uVGltZWAgaXMgb25seSBkZWZpbmVkIGFmdGVyIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIG9mIHtAbGluayBTZXNzaW9uLnB1Ymxpc2h9XG4gICAgICovXG4gICAgY3JlYXRpb25UaW1lOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBDYW4gYmU6XG4gICAgICogLSBgXCJDQU1FUkFcImA6IHdoZW4gdGhlIHZpZGVvIHNvdXJjZSBjb21lcyBmcm9tIGEgd2ViY2FtLlxuICAgICAqIC0gYFwiU0NSRUVOXCJgOiB3aGVuIHRoZSB2aWRlbyBzb3VyY2UgY29tZXMgZnJvbSBzY3JlZW4tc2hhcmluZy5cbiAgICAgKiAtIGBcIkNVU1RPTVwiYDogd2hlbiB7QGxpbmsgUHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZX0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgaW4gdGhlIFB1Ymxpc2hlciBzaWRlIHdpdGggYSBjdXN0b20gTWVkaWFTdHJlYW1UcmFjayB3aGVuIGNhbGxpbmcge0BsaW5rIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJ9KS5cbiAgICAgKiAtIGBcIklQQ0FNXCJgOiB3aGVuIHRoZSB2aWRlbyBzb3VyY2UgY29tZXMgZnJvbSBhbiBJUCBjYW1lcmEgcGFydGljaXBhbnQgaW5zdGVhZCBvZiBhIHJlZ3VsYXIgcGFydGljaXBhbnQgKHNlZSBbSVAgY2FtZXJhc10oL2VuL3N0YWJsZS9hZHZhbmNlZC1mZWF0dXJlcy9pcC1jYW1lcmFzLykpLlxuICAgICAqXG4gICAgICogSWYge0BsaW5rIGhhc1ZpZGVvfSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKi9cbiAgICB0eXBlT2ZWaWRlbz86IGtleW9mIHR5cGVvZiBUeXBlT2ZWaWRlbzsgLy8gVE9ETzogQ2hhbmdlIHRoaXMgdHlwZSB0byBlbnVtIFR5cGVPZlZpZGVvIG9uIHRoZSBuZXh0IGJyZWFraW5nLWNoYW5nZSByZWxlYXNlXG5cbiAgICAvKipcbiAgICAgKiBTdHJlYW1NYW5hZ2VyIG9iamVjdCAoe0BsaW5rIFB1Ymxpc2hlcn0gb3Ige0BsaW5rIFN1YnNjcmliZXJ9KSBpbiBjaGFyZ2Ugb2YgZGlzcGxheWluZyB0aGlzIHN0cmVhbSBpbiB0aGUgRE9NXG4gICAgICovXG4gICAgc3RyZWFtTWFuYWdlcjogU3RyZWFtTWFuYWdlcjtcblxuICAgIC8qKlxuICAgICAqIFdpZHRoIGFuZCBoZWlnaHQgaW4gcGl4ZWxzIG9mIHRoZSBlbmNvZGVkIHZpZGVvIHN0cmVhbS4gSWYge0BsaW5rIGhhc1ZpZGVvfSBpcyBmYWxzZSwgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWRcbiAgICAgKlxuICAgICAqIFRoaXMgcHJvcGVydHkgbWF5IGNoYW5nZSBpZiB0aGUgUHVibGlzaGVyIHRoYXQgaXMgcHVibGlzaGluZzpcbiAgICAgKiAtIElmIGl0IGlzIGEgbW9iaWxlIGRldmljZSwgd2hlbmV2ZXIgdGhlIHVzZXIgcm90YXRlcyB0aGUgZGV2aWNlLlxuICAgICAqIC0gSWYgaXQgaXMgc2NyZWVuLXNoYXJpbmcsIHdoZW5ldmVyIHRoZSB1c2VyIGNoYW5nZXMgdGhlIHNpemUgb2YgdGhlIGNhcHR1cmVkIHdpbmRvdy5cbiAgICAgKlxuICAgICAqIFdoZW5ldmVyIHRoaXMgaGFwcGVucyBhIHtAbGluayBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudH0gd2lsbCBiZSBkaXNwYXRjaGVkIGJ5IHRoZSBTZXNzaW9uIG9iamVjdCBhcyB3ZWxsIGFzIGJ5IHRoZSBhZmZlY3RlZCBTdWJzY3JpYmVyL1B1Ymxpc2hlciBvYmplY3RcbiAgICAgKi9cbiAgICB2aWRlb0RpbWVuc2lvbnM6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfTtcblxuICAgIC8qKlxuICAgICAqICoqV0FSTklORyoqOiBleHBlcmltZW50YWwgb3B0aW9uLiBUaGlzIGludGVyZmFjZSBtYXkgY2hhbmdlIGluIHRoZSBuZWFyIGZ1dHVyZVxuICAgICAqXG4gICAgICogRmlsdGVyIGFwcGxpZWQgdG8gdGhlIFN0cmVhbS4gWW91IGNhbiBhcHBseSBmaWx0ZXJzIGJ5IGNhbGxpbmcge0BsaW5rIFN0cmVhbS5hcHBseUZpbHRlcn0sIGV4ZWN1dGUgbWV0aG9kcyBvZiB0aGUgYXBwbGllZCBmaWx0ZXIgd2l0aFxuICAgICAqIHtAbGluayBGaWx0ZXIuZXhlY01ldGhvZH0gYW5kIHJlbW92ZSBpdCB3aXRoIHtAbGluayBTdHJlYW0ucmVtb3ZlRmlsdGVyfS4gQmUgYXdhcmUgdGhhdCB0aGUgY2xpZW50IGNhbGxpbmcgdGhpcyBtZXRob2RzIG11c3QgaGF2ZSB0aGVcbiAgICAgKiBuZWNlc3NhcnkgcGVybWlzc2lvbnM6IHRoZSB0b2tlbiBvd25lZCBieSB0aGUgY2xpZW50IG11c3QgaGF2ZSBiZWVuIGluaXRpYWxpemVkIHdpdGggdGhlIGFwcHJvcHJpYXRlZCBgYWxsb3dlZEZpbHRlcnNgIGFycmF5LlxuICAgICAqL1xuICAgIGZpbHRlcj86IEZpbHRlcjtcblxuICAgIHByb3RlY3RlZCB3ZWJSdGNQZWVyOiBXZWJSdGNQZWVyO1xuICAgIHByb3RlY3RlZCBtZWRpYVN0cmVhbT86IE1lZGlhU3RyZWFtO1xuICAgIHByaXZhdGUgd2ViUnRjU3RhdHM6IFdlYlJ0Y1N0YXRzO1xuXG4gICAgcHJpdmF0ZSBpc1N1YnNjcmliZVRvUmVtb3RlID0gZmFsc2U7XG5cbiAgICBwcml2YXRlIHZpcnR1YWxCYWNrZ3JvdW5kU291cmNlRWxlbWVudHM/OiB7IHZpZGVvQ2xvbmU6IEhUTUxWaWRlb0VsZW1lbnQ7IG1lZGlhU3RyZWFtQ2xvbmU6IE1lZGlhU3RyZWFtIH07XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZpcnR1YWxCYWNrZ3JvdW5kU2lua0VsZW1lbnRzPzogeyBWQjogYW55OyB2aWRlbzogSFRNTFZpZGVvRWxlbWVudCB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlZE9uY2UgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2Vzc2lvbjogU2Vzc2lvbjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5ib3VuZFN0cmVhbU9wdHM6IEluYm91bmRTdHJlYW1PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvdXRib3VuZFN0cmVhbU9wdHM6IE91dGJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3BlZWNoRXZlbnQ6IGFueTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFya1NwZWFraW5nRW5hYmxlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXJrU3BlYWtpbmdFbmFibGVkT25jZSA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZE9uY2UgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhcmtPcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBsb2NhbE1lZGlhU3RyZWFtV2hlblN1YnNjcmliZWRUb1JlbW90ZT86IE1lZGlhU3RyZWFtO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyOiBFdmVudEVtaXR0ZXIgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhc3RWaWRlb1RyYWNrQ29uc3RyYWludHM6IE1lZGlhVHJhY2tDb25zdHJhaW50cyB8IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhc3RWQkZpbHRlcj86IEZpbHRlcjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzZXNzaW9uOiBTZXNzaW9uLCBvcHRpb25zOiBJbmJvdW5kU3RyZWFtT3B0aW9ucyB8IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB8IHt9KSB7XG4gICAgICAgIHBsYXRmb3JtID0gUGxhdGZvcm1VdGlscy5nZXRJbnN0YW5jZSgpO1xuICAgICAgICB0aGlzLnNlc3Npb24gPSBzZXNzaW9uO1xuXG4gICAgICAgIGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KCdpZCcpKSB7XG4gICAgICAgICAgICAvLyBJbmJvdW5kU3RyZWFtT3B0aW9uczogc3RyZWFtIGJlbG9uZ3MgdG8gYSBTdWJzY3JpYmVyXG4gICAgICAgICAgICB0aGlzLmluYm91bmRTdHJlYW1PcHRzID0gPEluYm91bmRTdHJlYW1PcHRpb25zPm9wdGlvbnM7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbUlkID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICB0aGlzLmhhc0F1ZGlvID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5oYXNBdWRpbztcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc1ZpZGVvO1xuICAgICAgICAgICAgaWYgKHRoaXMuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5hdWRpb0FjdGl2ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc1ZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb0FjdGl2ZSA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudmlkZW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9ICF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvID8gdW5kZWZpbmVkIDogdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy50eXBlT2ZWaWRlbztcbiAgICAgICAgICAgICAgICB0aGlzLmZyYW1lUmF0ZSA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlID09PSAtMSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiBPYmplY3Qua2V5cyh0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlcikubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlci5sYXN0RXhlY01ldGhvZCAmJlxuICAgICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyh0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlci5sYXN0RXhlY01ldGhvZCkubGVuZ3RoID09PSAwXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlci5sYXN0RXhlY01ldGhvZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIE91dGJvdW5kU3RyZWFtT3B0aW9uczogc3RyZWFtIGJlbG9uZ3MgdG8gYSBQdWJsaXNoZXJcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gPE91dGJvdW5kU3RyZWFtT3B0aW9ucz5vcHRpb25zO1xuXG4gICAgICAgICAgICB0aGlzLmhhc0F1ZGlvID0gdGhpcy5pc1NlbmRBdWRpbygpO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaXNTZW5kVmlkZW8oKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvQWN0aXZlID0gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc1ZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZyYW1lUmF0ZTtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFja1xuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gVHlwZU9mVmlkZW8uQ1VTVE9NO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudHlwZU9mVmlkZW8gPSB0aGlzLmlzU2VuZFNjcmVlbigpID8gVHlwZU9mVmlkZW8uU0NSRUVOIDogVHlwZU9mVmlkZW8uQ0FNRVJBO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSEpO1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtPy5pZCArICddIHVwZGF0ZWQgaW4gc3RyZWFtIFsnICsgdGhpcy5zdHJlYW1JZCArICddJyk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlY3JlYXRlcyB0aGUgbWVkaWEgY29ubmVjdGlvbiB3aXRoIHRoZSBzZXJ2ZXIuIFRoaXMgZW50YWlscyB0aGUgZGlzcG9zYWwgb2YgdGhlIHByZXZpb3VzIFJUQ1BlZXJDb25uZWN0aW9uIGFuZCB0aGUgcmUtbmVnb3RpYXRpb25cbiAgICAgKiBvZiBhIG5ldyBvbmUsIHRoYXQgd2lsbCBhcHBseSB0aGUgc2FtZSBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgY2FuIGJlIHVzZWZ1bCBpbiB0aG9zZSBzaXR1YXRpb25zIHdlcmUgdGhlcmUgdGhlIG1lZGlhIGNvbm5lY3Rpb24gYnJlYWtzIGFuZCBPcGVuVmlkdSBpcyBub3QgYWJsZSB0byByZWNvdmVyIG9uIGl0cyBvd25cbiAgICAgKiBmb3IgYW55IGtpbmQgb2YgdW5hbnRpY2lwYXRlZCByZWFzb24gKHNlZSBbQXV0b21hdGljIHJlY29ubmVjdGlvbl0oL2VuL3N0YWJsZS9hZHZhbmNlZC1mZWF0dXJlcy9hdXRvbWF0aWMtcmVjb25uZWN0aW9uLykpLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvbm5lY3Rpb24gb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWNvbm5lY3RTdHJlYW0oJ0FQSScpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFwcGxpZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHRvIHRoZSBzdHJlYW0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdHlwZSBUeXBlIG9mIGZpbHRlciBhcHBsaWVkLiBTZWUge0BsaW5rIEZpbHRlci50eXBlfVxuICAgICAqIEBwYXJhbSBvcHRpb25zIFBhcmFtZXRlcnMgdXNlZCB0byBpbml0aWFsaXplIHRoZSBmaWx0ZXIuIFNlZSB7QGxpbmsgRmlsdGVyLm9wdGlvbnN9XG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgdG8gdGhlIGFwcGxpZWQgZmlsdGVyIGlmIHN1Y2Nlc3MgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGFwcGx5RmlsdGVyKHR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KTogUHJvbWlzZTxGaWx0ZXI+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUiwgJ1RoZXJlIGlzIGFscmVhZHkgYSBmaWx0ZXIgYXBwbGllZCB0byBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcmVzb2x2ZUFwcGx5RmlsdGVyID0gKGVycm9yLCB0cmlnZ2VyRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBhcHBseWluZyBmaWx0ZXIgZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIGFwcGx5IGEgZmlsdGVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnRmlsdGVyIHN1Y2Nlc3NmdWxseSBhcHBsaWVkIG9uIFN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlOiBGaWx0ZXIgPSB0aGlzLmZpbHRlciE7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyID0gbmV3IEZpbHRlcih0eXBlLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIuc3RyZWFtID0gdGhpcztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRyaWdnZXJFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXG4gICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKVxuICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUodGhpcy5maWx0ZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICh0eXBlLnN0YXJ0c1dpdGgoJ1ZCOicpKSB7XG4gICAgICAgICAgICAgICAgLy8gQ2xpZW50IGZpbHRlcnNcblxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5oYXNWaWRlbykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUaGUgVmlydHVhbCBCYWNrZ3JvdW5kIGZpbHRlciByZXF1aXJlcyBhIHZpZGVvIHRyYWNrIHRvIGJlIGFwcGxpZWQnXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5tZWRpYVN0cmVhbSB8fCB0aGlzLnN0cmVhbU1hbmFnZXIudmlkZW9zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUaGUgU3RyZWFtTWFuYWdlciByZXF1aXJlcyBzb21lIHZpZGVvIGVsZW1lbnQgdG8gYmUgYXR0YWNoZWQgdG8gaXQgaW4gb3JkZXIgdG8gYXBwbHkgYSBWaXJ0dWFsIEJhY2tncm91bmQgZmlsdGVyJ1xuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxldCBvcGVudmlkdVRva2VuOiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uLnRva2VuKSB7XG4gICAgICAgICAgICAgICAgICAgIG9wZW52aWR1VG9rZW4gPSB0aGlzLnNlc3Npb24udG9rZW47XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlbnZpZHVUb2tlbiA9IG9wdGlvbnNbJ3Rva2VuJ107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghb3BlbnZpZHVUb2tlbikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdWaXJ0dWFsIEJhY2tncm91bmQgcmVxdWlyZXMgdGhlIGNsaWVudCB0byBiZSBjb25uZWN0ZWQgdG8gYSBTZXNzaW9uIG9yIHRvIGhhdmUgYSBcInRva2VuXCIgcHJvcGVydHkgYXZhaWxhYmxlIGluIFwib3B0aW9uc1wiIHBhcmFtZXRlciB3aXRoIGEgdmFsaWQgT3BlblZpZHUgdG9rZW4nXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgdG9rZW5QYXJhbXMgPSB0aGlzLnNlc3Npb24uZ2V0VG9rZW5QYXJhbXMob3BlbnZpZHVUb2tlbik7XG4gICAgICAgICAgICAgICAgaWYgKHRva2VuUGFyYW1zLmVkaXRpb24gIT09ICdwcm8nICYmIHRva2VuUGFyYW1zLmVkaXRpb24gIT09ICdlbnRlcnByaXNlJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdPcGVuVmlkdSBWaXJ0dWFsIEJhY2tncm91bmQgQVBJIGlzIGF2YWlsYWJsZSBmcm9tIE9wZW5WaWR1IFBybyBlZGl0aW9uIG9ud2FyZHMnXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgb3BlbnZpZHVUb2tlbiA9IGVuY29kZVVSSUNvbXBvbmVudChidG9hKG9wZW52aWR1VG9rZW4pKTtcblxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdBcHBseWluZyBWaXJ0dWFsIEJhY2tncm91bmQgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGFmdGVyU2NyaXB0TG9hZGVkID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaWQgPSB0aGlzLnN0cmVhbUlkICsgJ18nICsgdXVpZHY0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZWRpYVN0cmVhbUNsb25lID0gdGhpcy5tZWRpYVN0cmVhbSEuY2xvbmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZpZGVvQ2xvbmUgPSB0aGlzLnN0cmVhbU1hbmFnZXIudmlkZW9zWzBdLnZpZGVvLmNsb25lTm9kZShmYWxzZSkgYXMgSFRNTFZpZGVvRWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvQ2xvbmUuaWQgPSBWaXJ0dWFsQmFja2dyb3VuZC5WaXJ0dWFsQmFja2dyb3VuZC5TT1VSQ0VfVklERU9fUFJFRklYICsgaWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0Nsb25lLnNyY09iamVjdCA9IG1lZGlhU3RyZWFtQ2xvbmU7XG4gICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0Nsb25lLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlydHVhbEJhY2tncm91bmRTb3VyY2VFbGVtZW50cyA9IHsgdmlkZW9DbG9uZSwgbWVkaWFTdHJlYW1DbG9uZSB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICBWaXJ0dWFsQmFja2dyb3VuZC5WaXJ0dWFsQmFja2dyb3VuZC5oaWRlSHRtbEVsZW1lbnQodmlkZW9DbG9uZSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgVmlydHVhbEJhY2tncm91bmQuVmlydHVhbEJhY2tncm91bmQuYXBwZW5kSHRtbEVsZW1lbnRUb0hpZGRlbkNvbnRhaW5lcih2aWRlb0Nsb25lLCBpZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHZpZGVvQ2xvbmUucGxheSgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBWQiA9IG5ldyBWaXJ0dWFsQmFja2dyb3VuZC5WaXJ0dWFsQmFja2dyb3VuZCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlbnZpZHVTZXJ2ZXJVcmw6IG5ldyBVUkwodG9rZW5QYXJhbXMuaHR0cFVyaSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlbnZpZHVUb2tlbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFZpZGVvOiB2aWRlb0Nsb25lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0UmVzb2x1dGlvbjogJzE2MHg5NicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0RnJhbWVyYXRlOiAyNFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmaWx0ZXJlZFZpZGVvOiBIVE1MVmlkZW9FbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnVkI6Ymx1cic6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyZWRWaWRlbyA9IGF3YWl0IFZCLmJhY2tncm91bmRCbHVyKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnVkI6aW1hZ2UnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcmVkVmlkZW8gPSBhd2FpdCBWQi5iYWNrZ3JvdW5kSW1hZ2Uob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gVmlydHVhbCBCYWNrZ3JvdW5kIGZpbHRlcjogJyArIHR5cGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpcnR1YWxCYWNrZ3JvdW5kU2lua0VsZW1lbnRzID0geyBWQiwgdmlkZW86IGZpbHRlcmVkVmlkZW8gfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW9DbG9uZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW1NYW5hZ2VyLnJlbW90ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5yZXBsYWNlVHJhY2tJbk1lZGlhU3RyZWFtKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodGhpcy52aXJ0dWFsQmFja2dyb3VuZFNpbmtFbGVtZW50cy52aWRlby5zcmNPYmplY3QgYXMgTWVkaWFTdHJlYW0pLmdldFZpZGVvVHJhY2tzKClbMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRoaXMuc3RyZWFtTWFuYWdlciBhcyBQdWJsaXNoZXIpLnJlcGxhY2VUcmFja0F1eChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRoaXMudmlydHVhbEJhY2tncm91bmRTaW5rRWxlbWVudHMudmlkZW8uc3JjT2JqZWN0IGFzIE1lZGlhU3RyZWFtKS5nZXRWaWRlb1RyYWNrcygpWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVBcHBseUZpbHRlcih1bmRlZmluZWQsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5uYW1lID09PSBPcGVuVmlkdUVycm9yTmFtZS5WSVJUVUFMX0JBQ0tHUk9VTkRfRVJST1IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlQXBwbHlGaWx0ZXIobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SLCBlcnJvci5tZXNzYWdlKSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlQXBwbHlGaWx0ZXIoZXJyb3IsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBWaXJ0dWFsQmFja2dyb3VuZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHNjcmlwdDogSFRNTFNjcmlwdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcbiAgICAgICAgICAgICAgICAgICAgc2NyaXB0LnR5cGUgPSAndGV4dC9qYXZhc2NyaXB0JztcbiAgICAgICAgICAgICAgICAgICAgc2NyaXB0LnNyYyA9IHRva2VuUGFyYW1zLmh0dHBVcmkgKyAnL29wZW52aWR1L3ZpcnR1YWwtYmFja2dyb3VuZC9vcGVudmlkdS12aXJ0dWFsLWJhY2tncm91bmQuanM/dG9rZW49JyArIG9wZW52aWR1VG9rZW47XG4gICAgICAgICAgICAgICAgICAgIHNjcmlwdC5vbmxvYWQgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IGFmdGVyU2NyaXB0TG9hZGVkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgRmlsdGVyKHR5cGUsIG9wdGlvbnMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFmdGVyU2NyaXB0TG9hZGVkKClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHJlc29sdmUobmV3IEZpbHRlcih0eXBlLCBvcHRpb25zKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFNlcnZlciBmaWx0ZXJzXG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc2Vzc2lvbi5zZXNzaW9uQ29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCh0aGlzLnNlc3Npb24ubm90Q29ubmVjdGVkRXJyb3IoKSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ0FwcGx5aW5nIHNlcnZlciBmaWx0ZXIgdG8gc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gb3B0aW9ucyAhPSBudWxsID8gb3B0aW9ucyA6IHt9O1xuICAgICAgICAgICAgICAgIGxldCBvcHRpb25zU3RyaW5nID0gb3B0aW9ucztcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnNTdHJpbmcgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnNTdHJpbmcgPSBKU09OLnN0cmluZ2lmeShvcHRpb25zU3RyaW5nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICAnYXBwbHlGaWx0ZXInLFxuICAgICAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkLCB0eXBlLCBvcHRpb25zOiBvcHRpb25zU3RyaW5nIH0sXG4gICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVBcHBseUZpbHRlcihlcnJvciwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGFuIGF1ZGlvL3ZpZGVvIGZpbHRlciBwcmV2aW91c2x5IGFwcGxpZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHByZXZpb3VzbHkgYXBwbGllZCBmaWx0ZXIgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlbW92ZWQgYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGluIG90aGVyIGNhc2VcbiAgICAgKi9cbiAgICBhc3luYyByZW1vdmVGaWx0ZXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlbW92ZUZpbHRlckF1eChmYWxzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaW50ZXJuYWwgUlRDUGVlckNvbm5lY3Rpb24gb2JqZWN0IGFzc29jaWF0ZWQgdG8gdGhpcyBzdHJlYW0gKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9SVENQZWVyQ29ubmVjdGlvbilcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIE5hdGl2ZSBSVENQZWVyQ29ubmVjdGlvbiBXZWIgQVBJIG9iamVjdFxuICAgICAqL1xuICAgIGdldFJUQ1BlZXJDb25uZWN0aW9uKCk6IFJUQ1BlZXJDb25uZWN0aW9uIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5wYztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBpbnRlcm5hbCBNZWRpYVN0cmVhbSBvYmplY3QgYXNzb2NpYXRlZCB0byB0aGlzIHN0cmVhbSAoaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL01lZGlhU3RyZWFtKVxuICAgICAqXG4gICAgICogQHJldHVybnMgTmF0aXZlIE1lZGlhU3RyZWFtIFdlYiBBUEkgb2JqZWN0XG4gICAgICovXG4gICAgZ2V0TWVkaWFTdHJlYW0oKTogTWVkaWFTdHJlYW0ge1xuICAgICAgICByZXR1cm4gdGhpcy5tZWRpYVN0cmVhbSE7XG4gICAgfVxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdmVGaWx0ZXJBdXgoaXNEaXNwb3Npbmc6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc29sdmVSZW1vdmVGaWx0ZXIgPSAoZXJyb3IsIHRyaWdnZXJFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgcmVtb3ZpbmcgZmlsdGVyIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byByZW1vdmUgYSBmaWx0ZXJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdGaWx0ZXIgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQgZnJvbSBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuZmlsdGVyITtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHJpZ2dlckV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyISwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXG4gICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIhLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJylcbiAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCEhdGhpcy5maWx0ZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBUaGVyZSBpcyBhIGZpbHRlciBhcHBsaWVkXG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5maWx0ZXI/LnR5cGUuc3RhcnRzV2l0aCgnVkI6JykpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ2xpZW50IGZpbHRlcnNcblxuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW1DbG9uZSA9IHRoaXMudmlydHVhbEJhY2tncm91bmRTb3VyY2VFbGVtZW50cyEubWVkaWFTdHJlYW1DbG9uZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghaXNEaXNwb3NpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW1NYW5hZ2VyLnJlbW90ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIucmVwbGFjZVRyYWNrSW5NZWRpYVN0cmVhbShtZWRpYVN0cmVhbUNsb25lLmdldFZpZGVvVHJhY2tzKClbMF0sIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCAodGhpcy5zdHJlYW1NYW5hZ2VyIGFzIFB1Ymxpc2hlcikucmVwbGFjZVRyYWNrQXV4KG1lZGlhU3RyZWFtQ2xvbmUuZ2V0VmlkZW9UcmFja3MoKVswXSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW1DbG9uZS5nZXRUcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4gdHJhY2suc3RvcCgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52aXJ0dWFsQmFja2dyb3VuZFNpbmtFbGVtZW50cyEuVkIuY2xlYW5VcCgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy52aXJ0dWFsQmFja2dyb3VuZFNpbmtFbGVtZW50cztcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnZpcnR1YWxCYWNrZ3JvdW5kU291cmNlRWxlbWVudHM7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlUmVtb3ZlRmlsdGVyKHVuZGVmaW5lZCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmVSZW1vdmVGaWx0ZXIoZXJyb3IsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNlcnZlciBmaWx0ZXJzXG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLnNlc3Npb24uc2Vzc2lvbkNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KHRoaXMuc2Vzc2lvbi5ub3RDb25uZWN0ZWRFcnJvcigpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdSZW1vdmluZyBmaWx0ZXIgb2Ygc3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdyZW1vdmVGaWx0ZXInLCB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbUlkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlUmVtb3ZlRmlsdGVyKGVycm9yLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBUaGVyZSBpcyBubyBmaWx0ZXIgYXBwbGllZFxuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUiwgJ1N0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCArICcgaGFzIG5vIGZpbHRlciBhcHBsaWVkJykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdlYlJ0Y1BlZXIoKTogV2ViUnRjUGVlciB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvTXlSZW1vdGUodmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5pc1N1YnNjcmliZVRvUmVtb3RlID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNldE91dGJvdW5kU3RyZWFtT3B0aW9ucyhvdXRib3VuZFN0cmVhbU9wdHM6IE91dGJvdW5kU3RyZWFtT3B0aW9ucyk6IHZvaWQge1xuICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyA9IG91dGJvdW5kU3RyZWFtT3B0cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3Vic2NyaWJlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjUGVlclJlY2VpdmUoZmFsc2UpXG4gICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGlzaCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJTZW5kKGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiByZXNvbHZlKCkpXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9uY2UoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnB1Ymxpc2goKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlV2ViUnRjUGVlcigpOiB2b2lkIHtcbiAgICAgICAgbGV0IHdlYnJ0Y0lkO1xuICAgICAgICBpZiAoISF0aGlzLndlYlJ0Y1BlZXIpIHtcbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5kaXNwb3NlKCk7XG4gICAgICAgICAgICB3ZWJydGNJZCA9IHRoaXMud2ViUnRjUGVlci5nZXRJZCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RvcFdlYlJ0Y1N0YXRzKCk7XG4gICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPyAnT3V0Ym91bmQgJyA6ICdJbmJvdW5kICcpICtcbiAgICAgICAgICAgICdSVENQZWVyQ29ubmVjdGlvbiB3aXRoIGlkIFsnICtcbiAgICAgICAgICAgIHdlYnJ0Y0lkICtcbiAgICAgICAgICAgIFwiXSBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgK1xuICAgICAgICAgICAgJ10gaXMgbm93IGNsb3NlZCdcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYXN5bmMgZGlzcG9zZU1lZGlhU3RyZWFtKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBpZiAoISF0aGlzLmZpbHRlciAmJiB0aGlzLmZpbHRlci50eXBlLnN0YXJ0c1dpdGgoJ1ZCOicpKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucmVtb3ZlRmlsdGVyQXV4KHRydWUpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZGVidWcoYFN1Y2Nlc3MgcmVtb3ZpbmcgVmlydHVhbCBCYWNrZ3JvdW5kIGZpbHRlciBmb3Igc3RyZWFtICR7dGhpcy5zdHJlYW1JZH1gKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgcmVtb3ZpbmcgVmlydHVhbCBCYWNrZ3JvdW5kIGZpbHRlciBmb3Igc3RyZWFtICR7dGhpcy5zdHJlYW1JZH1gLCBlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5tZWRpYVN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiBzdWJzY3JpYmVUb1JlbW90ZSBsb2NhbCBNZWRpYVN0cmVhbSBtdXN0IGJlIHN0b3BwZWRcbiAgICAgICAgaWYgKHRoaXMubG9jYWxNZWRpYVN0cmVhbVdoZW5TdWJzY3JpYmVkVG9SZW1vdGUpIHtcbiAgICAgICAgICAgIHRoaXMubG9jYWxNZWRpYVN0cmVhbVdoZW5TdWJzY3JpYmVkVG9SZW1vdGUuZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5sb2NhbE1lZGlhU3RyZWFtV2hlblN1YnNjcmliZWRUb1JlbW90ZS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5sb2NhbE1lZGlhU3RyZWFtV2hlblN1YnNjcmliZWRUb1JlbW90ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnNwZWVjaEV2ZW50LnN0b3ApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICB9XG4gICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgKCEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPyAnTG9jYWwgJyA6ICdSZW1vdGUgJykgKyBcIk1lZGlhU3RyZWFtIGZyb20gJ1N0cmVhbScgd2l0aCBpZCBbXCIgKyB0aGlzLnN0cmVhbUlkICsgJ10gaXMgbm93IGRpc3Bvc2VkJ1xuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwbGF5TXlSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzU3Vic2NyaWJlVG9SZW1vdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZEF1ZGlvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZSAhPT0gZmFsc2VcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kVmlkZW8oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAhIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICE9PSBudWxsICYmXG4gICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlICE9PSBmYWxzZVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRTY3JlZW4oKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBzY3JlZW4gPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlID09PSAnc2NyZWVuJztcbiAgICAgICAgaWYgKHBsYXRmb3JtLmlzRWxlY3Ryb24oKSkge1xuICAgICAgICAgICAgc2NyZWVuID1cbiAgICAgICAgICAgICAgICB0eXBlb2YgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlLnN0YXJ0c1dpdGgoJ3NjcmVlbjonKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJiBzY3JlZW47XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZUhhcmtTcGVha2luZ0V2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldEhhcmtMaXN0ZW5lcklmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5oYXJrU3BlYWtpbmdFbmFibGVkICYmICEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgdGhpcy5oYXJrU3BlYWtpbmdFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgIG5ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIFtcbiAgICAgICAgICAgICAgICAgICAgbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZClcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWRPbmNlID0gZmFsc2U7IC8vIERpc2FibGUgJ29uY2UnIHZlcnNpb24gaWYgJ29uJyB2ZXJzaW9uIHdhcyB0cmlnZ2VyZWRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZU9uY2VIYXJrU3BlYWtpbmdFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRIYXJrTGlzdGVuZXJJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMuaGFya1NwZWFraW5nRW5hYmxlZE9uY2UgJiYgISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWRPbmNlID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgnc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFya1NwZWFraW5nRW5hYmxlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpc3RlbmVyIGhhcyBiZWVuIGRpc2FibGVkIGluIHRoZSBtZWFudGltZSAoZm9yIGV4YW1wbGUgYnkgdGhlICdvbicgdmVyc2lvbikgZG8gbm90IHRyaWdnZXIgdGhlIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXG4gICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVIYXJrU3BlYWtpbmdFdmVudCh0cnVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVIYXJrU3BlYWtpbmdFdmVudChkaXNhYmxlZEJ5T25jZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWRPbmNlID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoZGlzYWJsZWRCeU9uY2UpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXJrU3BlYWtpbmdFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSAnb24nIHZlcnNpb24gb2YgdGhpcyBzYW1lIGV2ZW50IGlzIGVuYWJsZWQgdG9vLiBEbyBub3QgcmVtb3ZlIHRoZSBoYXJrIGxpc3RlbmVyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFya1NwZWFraW5nRW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gU2h1dHRpbmcgZG93biB0aGUgaGFyayBldmVudFxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkT25jZSB8fFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTdG9wcGVkU3BlYWtpbmdFbmFibGVkT25jZVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgLy8gU29tZSBvdGhlciBoYXJrIGV2ZW50IGlzIGVuYWJsZWQuIENhbm5vdCBzdG9wIHRoZSBoYXJrIHByb2Nlc3MsIGp1c3QgcmVtb3ZlIHRoZSBzcGVjaWZpYyBsaXN0ZW5lclxuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCdzcGVha2luZycpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBObyBvdGhlciBoYXJrIGV2ZW50IGlzIGVuYWJsZWQuIFdlIGNhbiBnZXQgZW50aXJlbHkgcmlkIG9mIGl0XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldEhhcmtMaXN0ZW5lcklmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZCAmJiAhIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbignc3RvcHBlZF9zcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgIG5ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc2Vzc2lvbiwgJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZClcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgIG5ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZClcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTdG9wcGVkU3BlYWtpbmdFbmFibGVkT25jZSA9IGZhbHNlOyAvLyBEaXNhYmxlICdvbmNlJyB2ZXJzaW9uIGlmICdvbicgdmVyc2lvbiB3YXMgdHJpZ2dlcmVkXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVPbmNlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNldEhhcmtMaXN0ZW5lcklmTm90RXhpc3RzKCk7XG4gICAgICAgIGlmICghdGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZE9uY2UgJiYgISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhhcmtTdG9wcGVkU3BlYWtpbmdFbmFibGVkT25jZSA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uY2UoJ3N0b3BwZWRfc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWRPbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBsaXN0ZW5lciBoYXMgYmVlbiBkaXNhYmxlZCBpbiB0aGUgbWVhbnRpbWUgKGZvciBleGFtcGxlIGJ5IHRoZSAnb24nIHZlcnNpb24pIGRvIG5vdCB0cmlnZ2VyIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXG4gICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXG4gICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVIYXJrU3RvcHBlZFNwZWFraW5nRXZlbnQodHJ1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KGRpc2FibGVkQnlPbmNlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWRPbmNlID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoZGlzYWJsZWRCeU9uY2UpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXZSBhcmUgY2FuY2VsbGluZyB0aGUgJ29uY2UnIGxpc3RlbmVyIGZvciB0aGlzIGV2ZW50LCBidXQgdGhlICdvbicgdmVyc2lvblxuICAgICAgICAgICAgICAgICAgICAvLyBvZiB0aGlzIHNhbWUgZXZlbnQgaXMgZW5hYmxlZCB0b28uIERvIG5vdCByZW1vdmUgdGhlIGhhcmsgbGlzdGVuZXJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gU2h1dHRpbmcgZG93biB0aGUgaGFyayBldmVudFxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkT25jZSB8fFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1NwZWFraW5nRW5hYmxlZCB8fFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1NwZWFraW5nRW5hYmxlZE9uY2VcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIC8vIFNvbWUgb3RoZXIgaGFyayBldmVudCBpcyBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzLCBqdXN0IHJlbW92ZSB0aGUgc3BlY2lmaWMgbGlzdGVuZXJcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9mZignc3RvcHBlZF9zcGVha2luZycpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBObyBvdGhlciBoYXJrIGV2ZW50IGlzIGVuYWJsZWQuIFdlIGNhbiBnZXQgZW50aXJlbHkgcmlkIG9mIGl0XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuc3BlZWNoRXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlSGFya1ZvbHVtZUNoYW5nZUV2ZW50KGZvcmNlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNldEhhcmtMaXN0ZW5lcklmTm90RXhpc3RzKCkpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZCB8fCBmb3JjZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3ZvbHVtZV9jaGFuZ2UnLCAoaGFya0V2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZhbHVlID0gdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB7IG5ld1ZhbHVlOiBoYXJrRXZlbnQsIG9sZFZhbHVlIH07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWUgPSBoYXJrRXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIHZhbHVlKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRoaXMgd2F5IHdoZW5ldmVyIHRoZSBNZWRpYVN0cmVhbSBvYmplY3QgaXMgYXZhaWxhYmxlLCB0aGUgZXZlbnQgbGlzdGVuZXIgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGFkZGVkXG4gICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVPbmNlSGFya1ZvbHVtZUNoYW5nZUV2ZW50KGZvcmNlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnNldEhhcmtMaXN0ZW5lcklmTm90RXhpc3RzKCkpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZE9uY2UgfHwgZm9yY2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkT25jZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCd2b2x1bWVfY2hhbmdlJywgKGhhcmtFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlID0gaGFya0V2ZW50O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc2FibGVIYXJrVm9sdW1lQ2hhbmdlRXZlbnQodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIHZhbHVlKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRoaXMgd2F5IHdoZW5ldmVyIHRoZSBNZWRpYVN0cmVhbSBvYmplY3QgaXMgYXZhaWxhYmxlLCB0aGUgZXZlbnQgbGlzdGVuZXIgd2lsbCBiZSBhdXRvbWF0aWNhbGx5IGFkZGVkXG4gICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkT25jZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzYWJsZUhhcmtWb2x1bWVDaGFuZ2VFdmVudChkaXNhYmxlZEJ5T25jZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkT25jZSA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKGRpc2FibGVkQnlPbmNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gV2UgYXJlIGNhbmNlbGxpbmcgdGhlICdvbmNlJyBsaXN0ZW5lciBmb3IgdGhpcyBldmVudCwgYnV0IHRoZSAnb24nIHZlcnNpb25cbiAgICAgICAgICAgICAgICAgICAgLy8gb2YgdGhpcyBzYW1lIGV2ZW50IGlzIGVuYWJsZWQgdG9vLiBEbyBub3QgcmVtb3ZlIHRoZSBoYXJrIGxpc3RlbmVyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFNodXR0aW5nIGRvd24gdGhlIGhhcmsgZXZlbnRcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWRPbmNlIHx8XG4gICAgICAgICAgICAgICAgdGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZCB8fFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWRPbmNlXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAvLyBTb21lIG90aGVyIGhhcmsgZXZlbnQgaXMgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2VzcywganVzdCByZW1vdmUgdGhlIHNwZWNpZmljIGxpc3RlbmVyXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3ZvbHVtZV9jaGFuZ2UnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gTm8gb3RoZXIgaGFyayBldmVudCBpcyBlbmFibGVkLiBXZSBjYW4gZ2V0IGVudGlyZWx5IHJpZCBvZiBpdFxuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWwoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGluYm91bmQgb3B0aW9ucyB1bmRlZmluZWQgYW5kIG91dGJvdW5kIG9wdGlvbnMgZGVmaW5lZFxuICAgICAgICByZXR1cm4gIXRoaXMuaW5ib3VuZFN0cmVhbU9wdHMgJiYgISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGUoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNcbiAgICAgICAgICAgICAgICAuZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGVJbmZvKClcbiAgICAgICAgICAgICAgICAudGhlbigocmVwb3J0KSA9PiByZXNvbHZlKHJlcG9ydCkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRSZW1vdGVJY2VDYW5kaWRhdGVMaXN0KCk6IFJUQ0ljZUNhbmRpZGF0ZVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2ViUnRjUGVlci5yZW1vdGVDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldExvY2FsSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIubG9jYWxDYW5kaWRhdGVzUXVldWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN0cmVhbUljZUNvbm5lY3Rpb25TdGF0ZUJyb2tlbigpIHtcbiAgICAgICAgaWYgKCF0aGlzLmdldFdlYlJ0Y1BlZXIoKSB8fCAhdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaXNMb2NhbCgpICYmICEhdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5mb3JjZU1lZGlhUmVjb25uZWN0aW9uQWZ0ZXJOZXR3b3JrRHJvcCkge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgICAgICAgYE9wZW5WaWR1IEJyb3dzZXIgYWR2YW5jZWQgY29uZmlndXJhdGlvbiBvcHRpb24gXCJmb3JjZU1lZGlhUmVjb25uZWN0aW9uQWZ0ZXJOZXR3b3JrRHJvcFwiIGlzIGVuYWJsZWQuIFN0cmVhbSAke3RoaXMuc3RyZWFtSWRcbiAgICAgICAgICAgICAgICB9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcid9KSB3aWxsIGZvcmNlIGEgcmVjb25uZWN0aW9uYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGljZUNvbm5lY3Rpb25TdGF0ZTogUlRDSWNlQ29ubmVjdGlvblN0YXRlID0gdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmljZUNvbm5lY3Rpb25TdGF0ZTtcbiAgICAgICAgcmV0dXJuIGljZUNvbm5lY3Rpb25TdGF0ZSAhPT0gJ2Nvbm5lY3RlZCcgJiYgaWNlQ29ubmVjdGlvblN0YXRlICE9PSAnY29tcGxldGVkJztcbiAgICB9XG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgc2V0SGFya0xpc3RlbmVySWZOb3RFeGlzdHMoKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhcmtPcHRpb25zID0gISF0aGlzLmhhcmtPcHRpb25zXG4gICAgICAgICAgICAgICAgICAgID8gdGhpcy5oYXJrT3B0aW9uc1xuICAgICAgICAgICAgICAgICAgICA6IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24ucHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgICAgIGhhcmtPcHRpb25zLmludGVydmFsID0gdHlwZW9mIGhhcmtPcHRpb25zLmludGVydmFsID09PSAnbnVtYmVyJyA/IGhhcmtPcHRpb25zLmludGVydmFsIDogMTAwO1xuICAgICAgICAgICAgICAgIGhhcmtPcHRpb25zLnRocmVzaG9sZCA9IHR5cGVvZiBoYXJrT3B0aW9ucy50aHJlc2hvbGQgPT09ICdudW1iZXInID8gaGFya09wdGlvbnMudGhyZXNob2xkIDogLTUwO1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQgPSBoYXJrKHRoaXMubWVkaWFTdHJlYW0sIGhhcmtPcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2V0dXBSZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIocmVzb2x2ZTogKHZhbHVlOiB2b2lkIHwgUHJvbWlzZUxpa2U8dm9pZD4pID0+IHZvaWQsIHJlamVjdDogKHJlYXNvbj86IGFueSkgPT4gdm9pZCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAodGhpcy5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIgPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAvLyBUaGVyZSBpcyBubyBvbmdvaW5nIHJlY29ubmVjdGlvblxuICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPbmdvaW5nIHJlY29ubmVjdGlvblxuICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgIGBUcnlpbmcgdG8gcmVjb25uZWN0IHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcidcbiAgICAgICAgICAgICAgICB9KSBidXQgYW4gb25nb2luZyByZWNvbm5lY3Rpb24gcHJvY2VzcyBpcyBhY3RpdmUuIFdhaXRpbmcgZm9yIHJlc3BvbnNlLi4uYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyLm9uY2UoJ3N1Y2Nlc3MnLCAoKSA9PiByZXNvbHZlKCkpO1xuICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIub25jZSgnZXJyb3InLCAoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5pdFdlYlJ0Y1BlZXJTZW5kKHJlY29ubmVjdDogYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHJlY29ubmVjdCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNldHVwUmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyKHJlc29sdmUsIHJlamVjdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gT25nb2luZyByZWNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gTWVkaWFTdHJlYW0gd2lsbCBhbHJlYWR5IGhhdmUgaGFyayBldmVudHMgZm9yIHJlY29ubmVjdGVkIHN0cmVhbXNcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRIYXJrRXZlbnRzKCk7IC8vIEluaXQgaGFyayBldmVudHMgZm9yIHRoZSBsb2NhbCBzdHJlYW1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZmluYWxSZXNvbHZlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXI/LmVtaXRFdmVudCgnc3VjY2VzcycpO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBmaW5hbFJlamVjdCA9IChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXI/LmVtaXRFdmVudCgnZXJyb3InLCBbZXJyb3JdKTtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NPZmZlckNhbGxiYWNrID0gKHNkcE9mZmVyUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1NlbmRpbmcgU0RQIG9mZmVyIHRvIHB1Ymxpc2ggYXMgJyArIHRoaXMuc3RyZWFtSWQsIHNkcE9mZmVyUGFyYW0pO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgbWV0aG9kID0gcmVjb25uZWN0ID8gJ3JlY29ubmVjdFN0cmVhbScgOiAncHVibGlzaFZpZGVvJztcbiAgICAgICAgICAgICAgICBsZXQgcGFyYW1zO1xuICAgICAgICAgICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtOiB0aGlzLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2RwU3RyaW5nOiBzZHBPZmZlclBhcmFtXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHR5cGVPZlZpZGVvO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1NlbmRWaWRlbygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlT2ZWaWRlbyA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgaW5zdGFuY2VvZiBNZWRpYVN0cmVhbVRyYWNrXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gVHlwZU9mVmlkZW8uQ1VTVE9NXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdGhpcy5pc1NlbmRTY3JlZW4oKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBUeXBlT2ZWaWRlby5TQ1JFRU5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogVHlwZU9mVmlkZW8uQ0FNRVJBO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvTG9vcGJhY2s6IHRoaXMuZGlzcGxheU15UmVtb3RlKCkgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBoYXNBdWRpbzogdGhpcy5pc1NlbmRBdWRpbygpLFxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzVmlkZW86IHRoaXMuaXNTZW5kVmlkZW8oKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvQWN0aXZlOiB0aGlzLmF1ZGlvQWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IHRoaXMudmlkZW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlT2ZWaWRlbyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lUmF0ZTogISF0aGlzLmZyYW1lUmF0ZSA/IHRoaXMuZnJhbWVSYXRlIDogLTEsXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnM6IEpTT04uc3RyaW5naWZ5KHRoaXMudmlkZW9EaW1lbnNpb25zKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcjogdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5maWx0ZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZHBPZmZlcjogc2RwT2ZmZXJQYXJhbVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChtZXRob2QsIHBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gcHVibGlzaFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVqZWN0KCdFcnJvciBvbiBwdWJsaXNoVmlkZW86ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnByb2Nlc3NSZW1vdGVBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHJlc3BvbnNlLmlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNyZWF0aW9uVGltZSA9IHJlc3BvbnNlLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoZWRPbmNlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9jYWxNZWRpYVN0cmVhbVdoZW5TdWJzY3JpYmVkVG9SZW1vdGUgPSB0aGlzLm1lZGlhU3RyZWFtO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQocmVjb25uZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlY29ubmVjdGVkLWJ5LXB1Ymxpc2hlcicsIFtdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW0tY3JlYXRlZC1ieS1wdWJsaXNoZXInLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIidQdWJsaXNoZXInIChcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbUlkICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcpIHN1Y2Nlc3NmdWxseSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZWNvbm5lY3QgPyAncmVjb25uZWN0ZWQnIDogJ3B1Ymxpc2hlZCcpICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgdG8gc2Vzc2lvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBjb25maWc6IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uID0ge1xuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmhhc1ZpZGVvXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzaW11bGNhc3Q6IHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9TaW11bGNhc3QgPz8gdGhpcy5zZXNzaW9uLm9wZW52aWR1LnZpZGVvU2ltdWxjYXN0LFxuICAgICAgICAgICAgICAgIG9uSWNlQ2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgb25JY2VDb25uZWN0aW9uU3RhdGVFeGNlcHRpb246IHRoaXMub25JY2VDb25uZWN0aW9uU3RhdGVFeGNlcHRpb25IYW5kbGVyLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtOiB0aGlzLm1lZGlhU3RyZWFtLFxuICAgICAgICAgICAgICAgIG1lZGlhU2VydmVyOiB0aGlzLnNlc3Npb24ub3BlbnZpZHUubWVkaWFTZXJ2ZXIsXG4gICAgICAgICAgICAgICAgdHlwZU9mVmlkZW86IHRoaXMudHlwZU9mVmlkZW8gPyBUeXBlT2ZWaWRlb1t0aGlzLnR5cGVPZlZpZGVvXSA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5tZWRpYVNlcnZlciAhPT0gJ21lZGlhc291cCcpIHtcbiAgICAgICAgICAgICAgICAvLyBTaW11bGNhc3QgaXMgb25seSBzdXBwb3J0ZWQgYnkgbWVkaWFzb3VwXG4gICAgICAgICAgICAgICAgY29uZmlnLnNpbXVsY2FzdCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRyZWN2KGNvbmZpZyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyU2VuZG9ubHkoY29uZmlnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5hZGRJY2VDb25uZWN0aW9uU3RhdGVDaGFuZ2VMaXN0ZW5lcigncHVibGlzaGVyIG9mICcgKyB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlclxuICAgICAgICAgICAgICAgIC5jcmVhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgLnRoZW4oKHNkcE9mZmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlclxuICAgICAgICAgICAgICAgICAgICAgICAgLnByb2Nlc3NMb2NhbE9mZmVyKHNkcE9mZmVyKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NPZmZlckNhbGxiYWNrKHNkcE9mZmVyLnNkcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVqZWN0KG5ldyBFcnJvcignKHB1Ymxpc2gpIFNEUCBwcm9jZXNzIGxvY2FsIG9mZmVyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgZmluYWxSZWplY3QobmV3IEVycm9yKCcocHVibGlzaCkgU0RQIGNyZWF0ZSBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZmluYWxSZXNvbHZlRm9yU3Vic2NyaXB0aW9uKHJlY29ubmVjdDogYm9vbGVhbiwgcmVzb2x2ZTogKHZhbHVlOiB2b2lkIHwgUHJvbWlzZUxpa2U8dm9pZD4pID0+IHZvaWQpIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oXCInU3Vic2NyaWJlcicgKFwiICsgdGhpcy5zdHJlYW1JZCArICcpIHN1Y2Nlc3NmdWxseSAnICsgKHJlY29ubmVjdCA/ICdyZWNvbm5lY3RlZCcgOiAnc3Vic2NyaWJlZCcpKTtcbiAgICAgICAgdGhpcy5yZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQocmVjb25uZWN0KTtcbiAgICAgICAgdGhpcy5pbml0V2ViUnRjU3RhdHMoKTtcbiAgICAgICAgaWYgKHJlY29ubmVjdCkge1xuICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXI/LmVtaXRFdmVudCgnc3VjY2VzcycpO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGZpbmFsUmVqZWN0Rm9yU3Vic2NyaXB0aW9uKHJlY29ubmVjdDogYm9vbGVhbiwgZXJyb3I6IGFueSwgcmVqZWN0OiAocmVhc29uPzogYW55KSA9PiB2b2lkKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgIFwiRXJyb3IgZm9yICdTdWJzY3JpYmVyJyAoXCIgK1xuICAgICAgICAgICAgdGhpcy5zdHJlYW1JZCArXG4gICAgICAgICAgICAnKSB3aGlsZSB0cnlpbmcgdG8gJyArXG4gICAgICAgICAgICAocmVjb25uZWN0ID8gJ3JlY29ubmVjdCcgOiAnc3Vic2NyaWJlJykgK1xuICAgICAgICAgICAgJzogJyArXG4gICAgICAgICAgICBlcnJvci50b1N0cmluZygpXG4gICAgICAgICk7XG4gICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyPy5lbWl0RXZlbnQoJ2Vycm9yJywgW2Vycm9yXSk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRXZWJSdGNQZWVyUmVjZWl2ZShyZWNvbm5lY3Q6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXR1cFJlY29ubmVjdGlvbkV2ZW50RW1pdHRlcihyZXNvbHZlLCByZWplY3QpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE9uZ29pbmcgcmVjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUubWVkaWFTZXJ2ZXIgPT09ICdtZWRpYXNvdXAnKSB7XG4gICAgICAgICAgICAgICAgLy8gU2VydmVyIGluaXRpYXRlcyBuZWdvdGlhdGlvblxuXG4gICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjUGVlclJlY2VpdmVGcm9tU2VydmVyKHJlY29ubmVjdClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5maW5hbFJlc29sdmVGb3JTdWJzY3JpcHRpb24ocmVjb25uZWN0LCByZXNvbHZlKSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gdGhpcy5maW5hbFJlamVjdEZvclN1YnNjcmlwdGlvbihyZWNvbm5lY3QsIGVycm9yLCByZWplY3QpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQ2xpZW50IGluaXRpYXRlcyBuZWdvdGlhdGlvblxuXG4gICAgICAgICAgICAgICAgdGhpcy5pbml0V2ViUnRjUGVlclJlY2VpdmVGcm9tQ2xpZW50KHJlY29ubmVjdClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5maW5hbFJlc29sdmVGb3JTdWJzY3JpcHRpb24ocmVjb25uZWN0LCByZXNvbHZlKSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gdGhpcy5maW5hbFJlamVjdEZvclN1YnNjcmlwdGlvbihyZWNvbm5lY3QsIGVycm9yLCByZWplY3QpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRXZWJSdGNQZWVyUmVjZWl2ZUZyb21DbGllbnQocmVjb25uZWN0OiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNvbXBsZXRlV2ViUnRjUGVlclJlY2VpdmUocmVjb25uZWN0LCBmYWxzZSlcbiAgICAgICAgICAgICAgICAudGhlbigocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyXG4gICAgICAgICAgICAgICAgICAgICAgICAucHJvY2Vzc1JlbW90ZUFuc3dlcihyZXNwb25zZS5zZHBBbnN3ZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiByZXNvbHZlKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlRnJvbVNlcnZlcihyZWNvbm5lY3Q6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIC8vIFNlcnZlciBpbml0aWF0ZXMgbmVnb3RpYXRpb25cbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdCgncHJlcGFyZVJlY2VpdmVWaWRlb0Zyb20nLCB7IHNlbmRlcjogdGhpcy5zdHJlYW1JZCwgcmVjb25uZWN0IH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJ0Vycm9yIG9uIHByZXBhcmVSZWNlaXZlVmlkZW9Gcm9tOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb21wbGV0ZVdlYlJ0Y1BlZXJSZWNlaXZlKHJlY29ubmVjdCwgZmFsc2UsIHJlc3BvbnNlLnNkcE9mZmVyKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb21wbGV0ZVdlYlJ0Y1BlZXJSZWNlaXZlKHJlY29ubmVjdDogYm9vbGVhbiwgZm9yY2libHlSZWNvbm5lY3Q6IGJvb2xlYW4sIHNkcE9mZmVyQnlTZXJ2ZXI/OiBzdHJpbmcpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKFwiJ1Nlc3Npb24uc3Vic2NyaWJlKFN0cmVhbSknIGNhbGxlZFwiKTtcblxuICAgICAgICAgICAgY29uc3Qgc2VuZFNkcFRvU2VydmVyID0gKHNkcFN0cmluZzogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBTZW5kaW5nIGxvY2FsIFNEUCAkeyEhc2RwT2ZmZXJCeVNlcnZlciA/ICdhbnN3ZXInIDogJ29mZmVyJ30gdG8gc3Vic2NyaWJlIHRvICR7dGhpcy5zdHJlYW1JZH1gLCBzZHBTdHJpbmcpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgbWV0aG9kID0gcmVjb25uZWN0ID8gJ3JlY29ubmVjdFN0cmVhbScgOiAncmVjZWl2ZVZpZGVvRnJvbSc7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyYW1zID0ge307XG4gICAgICAgICAgICAgICAgcGFyYW1zW3JlY29ubmVjdCA/ICdzdHJlYW0nIDogJ3NlbmRlciddID0gdGhpcy5zdHJlYW1JZDtcbiAgICAgICAgICAgICAgICBpZiAoISFzZHBPZmZlckJ5U2VydmVyKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmFtc1tyZWNvbm5lY3QgPyAnc2RwU3RyaW5nJyA6ICdzZHBBbnN3ZXInXSA9IHNkcFN0cmluZztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXNbJ3NkcE9mZmVyJ10gPSBzZHBTdHJpbmc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zWydmb3JjaWJseVJlY29ubmVjdCddID0gZm9yY2libHlSZWNvbm5lY3Q7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJ0Vycm9yIG9uICcgKyBtZXRob2QgKyAnIDogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBjb25maWc6IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uID0ge1xuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW86IHRoaXMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0aGlzLmhhc1ZpZGVvXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBzaW11bGNhc3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG9uSWNlQ2FuZGlkYXRlOiB0aGlzLmNvbm5lY3Rpb24uc2VuZEljZUNhbmRpZGF0ZS5iaW5kKHRoaXMuY29ubmVjdGlvbiksXG4gICAgICAgICAgICAgICAgb25JY2VDb25uZWN0aW9uU3RhdGVFeGNlcHRpb246IHRoaXMub25JY2VDb25uZWN0aW9uU3RhdGVFeGNlcHRpb25IYW5kbGVyLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgaWNlU2VydmVyczogdGhpcy5nZXRJY2VTZXJ2ZXJzQ29uZigpLFxuICAgICAgICAgICAgICAgIG1lZGlhU2VydmVyOiB0aGlzLnNlc3Npb24ub3BlbnZpZHUubWVkaWFTZXJ2ZXIsXG4gICAgICAgICAgICAgICAgdHlwZU9mVmlkZW86IHRoaXMudHlwZU9mVmlkZW8gPyBUeXBlT2ZWaWRlb1t0aGlzLnR5cGVPZlZpZGVvXSA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHJlY29ubmVjdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyID0gbmV3IFdlYlJ0Y1BlZXJSZWN2b25seShjb25maWcpO1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyLmFkZEljZUNvbm5lY3Rpb25TdGF0ZUNoYW5nZUxpc3RlbmVyKHRoaXMuc3RyZWFtSWQpO1xuXG4gICAgICAgICAgICBpZiAoISFzZHBPZmZlckJ5U2VydmVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyXG4gICAgICAgICAgICAgICAgICAgIC5wcm9jZXNzUmVtb3RlT2ZmZXIoc2RwT2ZmZXJCeVNlcnZlcilcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZUFuc3dlcigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKHNkcEFuc3dlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wcm9jZXNzTG9jYWxBbnN3ZXIoc2RwQW5zd2VyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRTZHBUb1NlcnZlcihzZHBBbnN3ZXIuc2RwISk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCcoc3Vic2NyaWJlKSBTRFAgcHJvY2VzcyBsb2NhbCBhbnN3ZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignKHN1YnNjcmliZSkgU0RQIGNyZWF0ZSBhbnN3ZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBwcm9jZXNzIHJlbW90ZSBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyXG4gICAgICAgICAgICAgICAgICAgIC5jcmVhdGVPZmZlcigpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKChzZHBPZmZlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnByb2Nlc3NMb2NhbE9mZmVyKHNkcE9mZmVyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFNkcFRvU2VydmVyKHNkcE9mZmVyLnNkcCEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignKHN1YnNjcmliZSkgU0RQIHByb2Nlc3MgbG9jYWwgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBjcmVhdGUgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdGVQZWVyU3VjY2Vzc2Z1bGx5RXN0YWJsaXNoZWQocmVjb25uZWN0OiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmIChyZWNvbm5lY3QgJiYgdGhpcy5tZWRpYVN0cmVhbSAhPSBudWxsKSB7XG4gICAgICAgICAgICAvLyBOb3cgd2UgY2FuIGRlc3Ryb3kgdGhlIGV4aXN0aW5nIE1lZGlhU3RyZWFtXG4gICAgICAgICAgICB0aGlzLmRpc3Bvc2VNZWRpYVN0cmVhbSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tZWRpYVN0cmVhbSA9IG5ldyBNZWRpYVN0cmVhbSgpO1xuICAgICAgICBsZXQgcmVjZWl2ZXI6IFJUQ1J0cFJlY2VpdmVyO1xuICAgICAgICBmb3IgKHJlY2VpdmVyIG9mIHRoaXMud2ViUnRjUGVlci5wYy5nZXRSZWNlaXZlcnMoKSkge1xuICAgICAgICAgICAgaWYgKCEhcmVjZWl2ZXIudHJhY2spIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmFkZFRyYWNrKHJlY2VpdmVyLnRyYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsb2dnZXIuZGVidWcoJ1BlZXIgcmVtb3RlIHN0cmVhbScsIHRoaXMubWVkaWFTdHJlYW0pO1xuXG4gICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbU1hbmFnZXIgaW5zdGFuY2VvZiBTdWJzY3JpYmVyKSB7XG4gICAgICAgICAgICAgICAgLy8gQXBwbHkgU3Vic2NyaWJlclByb3BlcnRpZXMuc3Vic2NyaWJlVG9BdWRpbyBhbmQgU3Vic2NyaWJlclByb3BlcnRpZXMuc3Vic2NyaWJlVG9WaWRlb1xuICAgICAgICAgICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID0gcmVjb25uZWN0ID8gdGhpcy5hdWRpb0FjdGl2ZSA6ICEhKHRoaXMuc3RyZWFtTWFuYWdlciBhcyBTdWJzY3JpYmVyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW87XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXS5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuYWJsZWQgPSByZWNvbm5lY3QgPyB0aGlzLnZpZGVvQWN0aXZlIDogISEodGhpcy5zdHJlYW1NYW5hZ2VyIGFzIFN1YnNjcmliZXIpLnByb3BlcnRpZXMuc3Vic2NyaWJlVG9WaWRlbztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51cGRhdGVNZWRpYVN0cmVhbUluVmlkZW9zKCk7XG4gICAgICAgICAgICB0aGlzLmluaXRIYXJrRXZlbnRzKCk7IC8vIEluaXQgaGFyayBldmVudHMgZm9yIHRoZSByZW1vdGUgc3RyZWFtXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5pdEhhcmtFdmVudHMoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0hLmdldEF1ZGlvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgIC8vIEhhcmsgZXZlbnRzIGNhbiBvbmx5IGJlIHNldCBpZiBhdWRpbyB0cmFjayBpcyBhdmFpbGFibGVcbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uYW55U3BlZWNoRXZlbnRMaXN0ZW5lckVuYWJsZWQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0cnVlLCB0aGlzLnN0cmVhbU1hbmFnZXIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVPbmNlSGFya1NwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uYW55U3BlZWNoRXZlbnRMaXN0ZW5lckVuYWJsZWQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBmYWxzZSwgdGhpcy5zdHJlYW1NYW5hZ2VyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlSGFya1NwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uYW55U3BlZWNoRXZlbnRMaXN0ZW5lckVuYWJsZWQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIHRydWUsIHRoaXMuc3RyZWFtTWFuYWdlcikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZU9uY2VIYXJrU3RvcHBlZFNwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uYW55U3BlZWNoRXZlbnRMaXN0ZW5lckVuYWJsZWQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIGZhbHNlLCB0aGlzLnN0cmVhbU1hbmFnZXIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVIYXJrU3RvcHBlZFNwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkT25jZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlT25jZUhhcmtWb2x1bWVDaGFuZ2VFdmVudCh0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVIYXJrVm9sdW1lQ2hhbmdlRXZlbnQodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uSWNlQ29ubmVjdGlvblN0YXRlRXhjZXB0aW9uSGFuZGxlcihleGNlcHRpb25OYW1lOiBFeGNlcHRpb25FdmVudE5hbWUsIG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IGFueSk6IHZvaWQge1xuICAgICAgICBzd2l0Y2ggKGV4Y2VwdGlvbk5hbWUpIHtcbiAgICAgICAgICAgIGNhc2UgRXhjZXB0aW9uRXZlbnROYW1lLklDRV9DT05ORUNUSU9OX0ZBSUxFRDpcbiAgICAgICAgICAgICAgICB0aGlzLm9uSWNlQ29ubmVjdGlvbkZhaWxlZCgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBFeGNlcHRpb25FdmVudE5hbWUuSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVEOlxuICAgICAgICAgICAgICAgIHRoaXMub25JY2VDb25uZWN0aW9uRGlzY29ubmVjdGVkKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnZXhjZXB0aW9uJywgW25ldyBFeGNlcHRpb25FdmVudCh0aGlzLnNlc3Npb24sIGV4Y2VwdGlvbk5hbWUsIHRoaXMsIG1lc3NhZ2UsIGRhdGEpXSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkljZUNvbm5lY3Rpb25GYWlsZWQoKSB7XG4gICAgICAgIC8vIEltbWVkaWF0ZWx5IHJlY29ubmVjdCwgYXMgdGhpcyBpcyBhIHRlcm1pbmFsIGVycm9yXG4gICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICBgW0lDRV9DT05ORUNUSU9OX0ZBSUxFRF0gSGFuZGxpbmcgSUNFX0NPTk5FQ1RJT05fRkFJTEVEIGV2ZW50LiBSZWNvbm5lY3Rpbmcgc3RyZWFtICR7dGhpcy5zdHJlYW1JZH0gKCR7dGhpcy5pc0xvY2FsKCkgPyAnUHVibGlzaGVyJyA6ICdTdWJzY3JpYmVyJ1xuICAgICAgICAgICAgfSlgXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMucmVjb25uZWN0U3RyZWFtQW5kTG9nUmVzdWx0aW5nSWNlQ29ubmVjdGlvblN0YXRlKEV4Y2VwdGlvbkV2ZW50TmFtZS5JQ0VfQ09OTkVDVElPTl9GQUlMRUQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25JY2VDb25uZWN0aW9uRGlzY29ubmVjdGVkKCkge1xuICAgICAgICAvLyBXYWl0IHRvIHNlZSBpZiB0aGUgSUNFIGNvbm5lY3Rpb24gaXMgYWJsZSB0byByZWNvbm5lY3RcbiAgICAgICAgbG9nZ2VyLmxvZyhcbiAgICAgICAgICAgIGBbSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVEXSBIYW5kbGluZyBJQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURUQgZXZlbnQuIFdhaXRpbmcgZm9yIElDRSB0byBiZSByZXN0b3JlZCBhbmQgcmVjb25uZWN0IHN0cmVhbSAke3RoaXMuc3RyZWFtSWRcbiAgICAgICAgICAgIH0gKCR7dGhpcy5pc0xvY2FsKCkgPyAnUHVibGlzaGVyJyA6ICdTdWJzY3JpYmVyJ30pIGlmIG5vdCBwb3NzaWJsZWBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgdGltZW91dCA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlQ29ubmVjdGlvbkRpc2Nvbm5lY3RlZEV4Y2VwdGlvblRpbWVvdXQgfHwgNDAwMDtcbiAgICAgICAgdGhpcy5hd2FpdFdlYlJ0Y1BlZXJDb25uZWN0aW9uU3RhdGUodGltZW91dCkudGhlbigoc3RhdGUpID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAoc3RhdGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdmYWlsZWQnOlxuICAgICAgICAgICAgICAgICAgICAvLyBEbyBub3RoaW5nLCBhcyBhbiBJQ0VfQ09OTkVDVElPTl9GQUlMRUQgZXZlbnQgd2lsbCBoYXZlIGFscmVhZHkgcmFpc2VkXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgICAgICAgICAgICAgICAgYFtJQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURURdIElDRSBjb25uZWN0aW9uIG9mIHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcidcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pIGlzIG5vdyBmYWlsZWQgYWZ0ZXIgSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVEYFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdjb25uZWN0ZWQnOlxuICAgICAgICAgICAgICAgIGNhc2UgJ2NvbXBsZXRlZCc6XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICBgW0lDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRF0gSUNFIGNvbm5lY3Rpb24gb2Ygc3RyZWFtICR7dGhpcy5zdHJlYW1JZH0gKCR7dGhpcy5pc0xvY2FsKCkgPyAnUHVibGlzaGVyJyA6ICdTdWJzY3JpYmVyJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkgYXV0b21hdGljYWxseSByZXN0b3JlZCBhZnRlciBJQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURUQuIEN1cnJlbnQgSUNFIGNvbm5lY3Rpb24gc3RhdGU6ICR7c3RhdGV9YFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdjbG9zZWQnOlxuICAgICAgICAgICAgICAgIGNhc2UgJ2NoZWNraW5nJzpcbiAgICAgICAgICAgICAgICBjYXNlICduZXcnOlxuICAgICAgICAgICAgICAgIGNhc2UgJ2Rpc2Nvbm5lY3RlZCc6XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc3Qgb2Ygc3RhdGVzXG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgICAgICAgICAgICAgICAgYFtJQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURURdIElDRSBjb25uZWN0aW9uIG9mIHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcidcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pIGNvdWxkbid0IGJlIHJlc3RvcmVkIGFmdGVyIElDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRCBldmVudC4gQ3VycmVudCBJQ0UgY29ubmVjdGlvbiBzdGF0ZSBhZnRlciAke3RpbWVvdXR9IG1zOiAke3N0YXRlfWBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3RTdHJlYW1BbmRMb2dSZXN1bHRpbmdJY2VDb25uZWN0aW9uU3RhdGUoRXhjZXB0aW9uRXZlbnROYW1lLklDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRCk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlY29ubmVjdFN0cmVhbUFuZExvZ1Jlc3VsdGluZ0ljZUNvbm5lY3Rpb25TdGF0ZShldmVudDogc3RyaW5nKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmaW5hbEljZVN0YXRlQWZ0ZXJSZWNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLnJlY29ubmVjdFN0cmVhbUFuZFJldHVybkljZUNvbm5lY3Rpb25TdGF0ZShldmVudCk7XG4gICAgICAgICAgICBzd2l0Y2ggKGZpbmFsSWNlU3RhdGVBZnRlclJlY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2Nvbm5lY3RlZCc6XG4gICAgICAgICAgICAgICAgY2FzZSAnY29tcGxldGVkJzpcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhcbiAgICAgICAgICAgICAgICAgICAgICAgIGBbJHtldmVudH1dIFN0cmVhbSAke3RoaXMuc3RyZWFtSWR9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcidcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pIHN1Y2Nlc3NmdWxseSByZWNvbm5lY3RlZCBhZnRlciAke2V2ZW50fS4gQ3VycmVudCBJQ0UgY29ubmVjdGlvbiBzdGF0ZTogJHtmaW5hbEljZVN0YXRlQWZ0ZXJSZWNvbm5lY3Rpb259YFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBgWyR7ZXZlbnR9XSBTdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHt0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSBmYWlsZWQgdG8gcmVjb25uZWN0IGFmdGVyICR7ZXZlbnR9LiBDdXJyZW50IElDRSBjb25uZWN0aW9uIHN0YXRlOiAke2ZpbmFsSWNlU3RhdGVBZnRlclJlY29ubmVjdGlvbn1gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgIGBbJHtldmVudH1dIEVycm9yIHJlY29ubmVjdGluZyBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHt0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInXG4gICAgICAgICAgICAgICAgfSkgYWZ0ZXIgJHtldmVudH06ICR7ZXJyb3J9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmVjb25uZWN0U3RyZWFtQW5kUmV0dXJuSWNlQ29ubmVjdGlvblN0YXRlKGV2ZW50OiBzdHJpbmcpOiBQcm9taXNlPFJUQ0ljZUNvbm5lY3Rpb25TdGF0ZT4ge1xuICAgICAgICBsb2dnZXIubG9nKGBbJHtldmVudH1dIFJlY29ubmVjdGluZyBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHt0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInfSkgYWZ0ZXIgZXZlbnQgJHtldmVudH1gKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmVjb25uZWN0U3RyZWFtKGV2ZW50KTtcbiAgICAgICAgICAgIGNvbnN0IHRpbWVvdXQgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZUNvbm5lY3Rpb25EaXNjb25uZWN0ZWRFeGNlcHRpb25UaW1lb3V0IHx8IDQwMDA7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hd2FpdFdlYlJ0Y1BlZXJDb25uZWN0aW9uU3RhdGUodGltZW91dCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICAgICAgICBgWyR7ZXZlbnR9XSBFcnJvciByZWNvbm5lY3Rpbmcgc3RyZWFtICR7dGhpcy5zdHJlYW1JZH0gKCR7dGhpcy5pc0xvY2FsKCkgPyAnUHVibGlzaGVyJyA6ICdTdWJzY3JpYmVyJ30pLiBSZWFzb246ICR7ZXJyb3J9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmF3YWl0V2ViUnRjUGVlckNvbm5lY3Rpb25TdGF0ZSgxKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgYXdhaXRXZWJSdGNQZWVyQ29ubmVjdGlvblN0YXRlKHRpbWVvdXQ6IG51bWJlcik6IFByb21pc2U8UlRDSWNlQ29ubmVjdGlvblN0YXRlPiB7XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuZ2V0UlRDUGVlckNvbm5lY3Rpb24oKS5pY2VDb25uZWN0aW9uU3RhdGU7XG4gICAgICAgIGNvbnN0IGludGVydmFsID0gMTUwO1xuICAgICAgICBjb25zdCBpbnRlcnZhbHMgPSBNYXRoLmNlaWwodGltZW91dCAvIGludGVydmFsKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnRlcnZhbHM7IGkrKykge1xuICAgICAgICAgICAgc3RhdGUgPSB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuaWNlQ29ubmVjdGlvblN0YXRlO1xuICAgICAgICAgICAgaWYgKHN0YXRlID09PSAnY29ubmVjdGVkJyB8fCBzdGF0ZSA9PT0gJ2NvbXBsZXRlZCcpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFNsZWVwXG4gICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCBpbnRlcnZhbCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlY29ubmVjdFN0cmVhbShldmVudDogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IGlzV3NDb25uZWN0ZWQgPSBhd2FpdCB0aGlzLmlzV2Vic29ja2V0Q29ubmVjdGVkKGV2ZW50LCAzMDAwKTtcbiAgICAgICAgaWYgKGlzV3NDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIC8vIFRoZXJlIGlzIGNvbm5lY3Rpb24gdG8gb3BlbnZpZHUtc2VydmVyLiBUaGUgUlRDUGVlckNvbm5lY3Rpb24gaXMgdGhlIG9ubHkgb25lIGJyb2tlblxuICAgICAgICAgICAgbG9nZ2VyLmxvZyhcbiAgICAgICAgICAgICAgICBgWyR7ZXZlbnR9XSBUcnlpbmcgdG8gcmVjb25uZWN0IHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcidcbiAgICAgICAgICAgICAgICB9KSBhbmQgdGhlIHdlYnNvY2tldCBpcyBvcGVuZWRgXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNMb2NhbCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5pdFdlYlJ0Y1BlZXJTZW5kKHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbml0V2ViUnRjUGVlclJlY2VpdmUodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBUaGVyZSBpcyBubyBjb25uZWN0aW9uIHRvIG9wZW52aWR1LXNlcnZlci4gTm90aGluZyBjYW4gYmUgZG9uZS4gVGhlIGF1dG9tYXRpYyByZWNvbm5lY3Rpb25cbiAgICAgICAgICAgIC8vIGZlYXR1cmUgc2hvdWxkIGhhbmRsZSBhIHBvc3NpYmxlIHJlY29ubmVjdGlvbiBvZiBSVENQZWVyQ29ubmVjdGlvbiBpbiBjYXNlIG5ldHdvcmsgY29tZXMgYmFja1xuICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBgWyR7ZXZlbnR9XSBUcnlpbmcgdG8gcmVjb25uZWN0IHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcidcbiAgICAgICAgICAgICAgICB9KSBidXQgdGhlIHdlYnNvY2tldCB3YXNuJ3Qgb3BlbmVkYDtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihlcnJvck1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGlzV2Vic29ja2V0Q29ubmVjdGVkKGV2ZW50OiBzdHJpbmcsIG1zUmVzcG9uc2VUaW1lb3V0OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHdzUmVhZHlTdGF0ZSA9IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5nZXRXc1JlYWR5U3RhdGUoKTtcbiAgICAgICAgICAgIGlmICh3c1JlYWR5U3RhdGUgPT09IDEpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNwb25zZVRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBbJHtldmVudH1dIFdlYnNvY2tldCB0aW1lb3V0IG9mICR7bXNSZXNwb25zZVRpbWVvdXR9bXNgKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgICAgICAgIH0sIG1zUmVzcG9uc2VUaW1lb3V0KTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2VjaG8nLCB7fSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQocmVzcG9uc2VUaW1lb3V0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgWyR7ZXZlbnR9XSBXZWJzb2NrZXQgJ2VjaG8nIHJldHVybmVkIGVycm9yOiAke2Vycm9yfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBbJHtldmVudH1dIFdlYnNvY2tldCByZWFkeVN0YXRlIGlzICR7d3NSZWFkeVN0YXRlfWApO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRXZWJSdGNTdGF0cygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy53ZWJSdGNTdGF0cyA9IG5ldyBXZWJSdGNTdGF0cyh0aGlzKTtcbiAgICAgICAgdGhpcy53ZWJSdGNTdGF0cy5pbml0V2ViUnRjU3RhdHMoKTtcblxuICAgICAgICAvL1RPRE86IHNlbmQgY29tbW9uIHdlYnJ0YyBzdGF0cyBmcm9tIGNsaWVudCB0byBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgLyppZiAodGhpcy5zZXNzaW9uLm9wZW52aWR1LndlYnJ0Y1N0YXRzSW50ZXJ2YWwgPiAwKSB7XG4gICAgICAgICAgICBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5nYXRoZXJTdGF0c0ZvclBlZXIoKS50aGVuKGpzb25TdGF0cyA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJvZHkgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbi5zZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudFByaXZhdGVJZDogdGhpcy5jb25uZWN0aW9uLnJwY1Nlc3Npb25JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRzOiBqc29uU3RhdHNcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5vcGVuKCdQT1NUJywgdGhpcy5zZXNzaW9uLm9wZW52aWR1Lmh0dHBVcmkgKyAnL2VsYXN0aWNzZWFyY2gvd2VicnRjLXN0YXRzJywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2VuZChKU09OLnN0cmluZ2lmeShib2R5KSk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH0sIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsICogMTAwMCk7XG4gICAgICAgIH0qL1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RvcFdlYlJ0Y1N0YXRzKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLndlYlJ0Y1N0YXRzICYmIHRoaXMud2ViUnRjU3RhdHMuaXNFbmFibGVkKCkpIHtcbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHMuc3RvcFdlYlJ0Y1N0YXRzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEljZVNlcnZlcnNDb25mKCk6IFJUQ0ljZVNlcnZlcltdIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgbGV0IHJldHVyblZhbHVlO1xuICAgICAgICBpZiAoISF0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnMpIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID1cbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnMgPT09ICdmcmVlaWNlJ1xuICAgICAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA6IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycykge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuaWNlU2VydmVycztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdhdGhlclN0YXRzRm9yUGVlcigpOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNMb2NhbCgpKSB7XG4gICAgICAgICAgICAgICAgLy8gUHVibGlzaGVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpXG4gICAgICAgICAgICAgICAgICAgIC5nZXRTZW5kZXJzKClcbiAgICAgICAgICAgICAgICAgICAgLmZvckVhY2goKHNlbmRlcikgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRlci5nZXRTdGF0cygpLnRoZW4oKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuZm9yRWFjaCgocmVwb3J0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzUmVwb3J0V2FudGVkKHJlcG9ydCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3NzcmMnXSA9IHJlcG9ydC5zc3JjO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmaXJDb3VudCddID0gcmVwb3J0LmZpckNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwbGlDb3VudCddID0gcmVwb3J0LnBsaUNvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WyduYWNrQ291bnQnXSA9IHJlcG9ydC5uYWNrQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3FwU3VtJ10gPSByZXBvcnQucXBTdW07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXQgbWVkaWEgdHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlcG9ydC5raW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5raW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoISFyZXBvcnQubWVkaWFUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5tZWRpYVR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIGRvZXMgbm90IGhhdmUgJ21lZGlhVHlwZScgZGVmaW5lZCBmb3IgaW5ib3VuZC1ydHAuIE11c3QgYmUgaW5mZXJyZWQgZnJvbSAnaWQnIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9IHJlcG9ydC5pZC5pbmRleE9mKCdWaWRlb1N0cmVhbScpICE9PSAtMSA/ICd2aWRlbycgOiAnYXVkaW8nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZyYW1lc0VuY29kZWQnXSA9IHJlcG9ydC5mcmFtZXNFbmNvZGVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzU2VudCddID0gcmVwb3J0LnBhY2tldHNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1NlbnQnXSA9IHJlcG9ydC5ieXRlc1NlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIENocm9tZSBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyB0aGUgZmluYWwgc2VsZWN0ZWQgY2FuZGlkYXRlIHBhaXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlJ10gPSByZXBvcnQuYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydydHQnXSA9IHJlcG9ydC5jdXJyZW50Um91bmRUcmlwVGltZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYXZlcmFnZVJ0dCddID0gcmVwb3J0LnRvdGFsUm91bmRUcmlwVGltZSAvIHJlcG9ydC5yZXNwb25zZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgRmlyZWZveCA+PSA2Ni4wXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtaW5ib3VuZC1ydHAnIHx8IHJlcG9ydC50eXBlID09PSAncmVtb3RlLW91dGJvdW5kLXJ0cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFN1YnNjcmliZXIgc3RyZWFtIHN0YXRzXG5cbiAgICAgICAgICAgICAgICB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKClcbiAgICAgICAgICAgICAgICAgICAgLmdldFJlY2VpdmVycygpXG4gICAgICAgICAgICAgICAgICAgIC5mb3JFYWNoKChyZWNlaXZlcikgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVyLmdldFN0YXRzKCkudGhlbigocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKChyZXBvcnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZXBvcnRXYW50ZWQocmVwb3J0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmluYWxSZXBvcnQgPSB7fTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3R5cGUnXSA9IHJlcG9ydC50eXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3RpbWVzdGFtcCddID0gcmVwb3J0LnRpbWVzdGFtcDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydpZCddID0gcmVwb3J0LmlkO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb21tb24gdG8gQ2hyb21lLCBGaXJlZm94IGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2luYm91bmQtcnRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wydzc3JjJ10gPSByZXBvcnQuc3NyYztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZmlyQ291bnQnXSA9IHJlcG9ydC5maXJDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGxpQ291bnQnXSA9IHJlcG9ydC5wbGlDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbmFja0NvdW50J10gPSByZXBvcnQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydxcFN1bSddID0gcmVwb3J0LnFwU3VtO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IG1lZGlhIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZXBvcnQua2luZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQua2luZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCEhcmVwb3J0Lm1lZGlhVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQubWVkaWFUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBkb2VzIG5vdCBoYXZlICdtZWRpYVR5cGUnIGRlZmluZWQgZm9yIGluYm91bmQtcnRwLiBNdXN0IGJlIGluZmVycmVkIGZyb20gJ2lkJyBmaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEgPyAndmlkZW8nIDogJ2F1ZGlvJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmcmFtZXNEZWNvZGVkJ10gPSByZXBvcnQuZnJhbWVzRGVjb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c1JlY2VpdmVkJ10gPSByZXBvcnQucGFja2V0c1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydwYWNrZXRzTG9zdCddID0gcmVwb3J0LnBhY2tldHNMb3N0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydqaXR0ZXInXSA9IHJlcG9ydC5qaXR0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2J5dGVzUmVjZWl2ZWQnXSA9IHJlcG9ydC5ieXRlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBDaHJvbWUgYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnY2FuZGlkYXRlLXBhaXInICYmIHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpbmFsIHNlbGVjdGVkIGNhbmRpZGF0ZSBwYWlyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2YWlsYWJsZUluY29taW5nQml0cmF0ZSddID0gcmVwb3J0LmF2YWlsYWJsZUluY29taW5nQml0cmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncnR0J10gPSByZXBvcnQuY3VycmVudFJvdW5kVHJpcFRpbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2ZXJhZ2VSdHQnXSA9IHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgLyByZXBvcnQucmVzcG9uc2VzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIEZpcmVmb3ggPj0gNjYuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAncmVtb3RlLWluYm91bmQtcnRwJyB8fCByZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1vdXRib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKGZpbmFsUmVwb3J0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1JlcG9ydFdhbnRlZChyZXBvcnQ6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgKHJlcG9ydC50eXBlID09PSAnaW5ib3VuZC1ydHAnICYmICF0aGlzLmlzTG9jYWwoKSkgfHxcbiAgICAgICAgICAgIChyZXBvcnQudHlwZSA9PT0gJ291dGJvdW5kLXJ0cCcgJiYgdGhpcy5pc0xvY2FsKCkpIHx8XG4gICAgICAgICAgICAocmVwb3J0LnR5cGUgPT09ICdjYW5kaWRhdGUtcGFpcicgJiYgcmVwb3J0Lm5vbWluYXRlZCAmJiByZXBvcnQuYnl0ZXNTZW50ID4gMClcbiAgICAgICAgKTtcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4vU3Vic2NyaWJlcic7XG5pbXBvcnQgeyBFdmVudERpc3BhdGNoZXIgfSBmcm9tICcuL0V2ZW50RGlzcGF0Y2hlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyVmlkZW8gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N0cmVhbU1hbmFnZXJWaWRlbyc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyRXZlbnRNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudE1hcC9TdHJlYW1NYW5hZ2VyRXZlbnRNYXAnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtTWFuYWdlckV2ZW50JztcbmltcG9ydCB7IFZpZGVvRWxlbWVudEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvVmlkZW9FbGVtZW50RXZlbnQnO1xuaW1wb3J0IHsgRXhjZXB0aW9uRXZlbnQsIEV4Y2VwdGlvbkV2ZW50TmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V4Y2VwdGlvbkV2ZW50JztcbmltcG9ydCB7IFZpZGVvSW5zZXJ0TW9kZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvVmlkZW9JbnNlcnRNb2RlJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9Mb2dnZXIvT3BlblZpZHVMb2dnZXInO1xuaW1wb3J0IHsgUGxhdGZvcm1VdGlscyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvVXRpbHMvUGxhdGZvcm0nO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuY29uc3QgbG9nZ2VyOiBPcGVuVmlkdUxvZ2dlciA9IE9wZW5WaWR1TG9nZ2VyLmdldEluc3RhbmNlKCk7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5sZXQgcGxhdGZvcm06IFBsYXRmb3JtVXRpbHM7XG5cbi8qKlxuICogSW50ZXJmYWNlIGluIGNoYXJnZSBvZiBkaXNwbGF5aW5nIHRoZSBtZWRpYSBzdHJlYW1zIGluIHRoZSBIVE1MIERPTS4gVGhpcyB3cmFwcyBhbnkge0BsaW5rIFB1Ymxpc2hlcn0gYW5kIHtAbGluayBTdWJzY3JpYmVyfSBvYmplY3QuXG4gKiBZb3UgY2FuIGluc2VydCBhcyBtYW55IHZpZGVvIHBsYXllcnMgZm8gdGhlIHNhbWUgU3RyZWFtIGFzIHlvdSB3YW50IGJ5IGNhbGxpbmcge0BsaW5rIFN0cmVhbU1hbmFnZXIuYWRkVmlkZW9FbGVtZW50fSBvclxuICoge0BsaW5rIFN0cmVhbU1hbmFnZXIuY3JlYXRlVmlkZW9FbGVtZW50fS5cbiAqIFRoZSB1c2Ugb2YgU3RyZWFtTWFuYWdlciB3cmFwcGVyIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiB5b3UgZG9uJ3QgbmVlZCB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gUHVibGlzaGVyIG9yIFN1YnNjcmliZXIgc3RyZWFtcyBvciBqdXN0XG4gKiB3YW50IHRvIGRpcmVjdGx5IG1hbmFnZSB5b3VyIG93biB2aWRlbyBlbGVtZW50cyAoZXZlbiBtb3JlIHRoYW4gb25lIHZpZGVvIGVsZW1lbnQgcGVyIFN0cmVhbSkuIFRoaXMgc2NlbmFyaW8gaXMgcHJldHR5IGNvbW1vbiBpblxuICogZGVjbGFyYXRpdmUsIE1WQyBmcm9udGVuZCBmcmFtZXdvcmtzIHN1Y2ggYXMgQW5ndWxhciwgUmVhY3Qgb3IgVnVlLmpzXG4gKlxuICogU2VlIGF2YWlsYWJsZSBldmVudCBsaXN0ZW5lcnMgYXQge0BsaW5rIFN0cmVhbU1hbmFnZXJFdmVudE1hcH0uXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBTdHJlYW1NYW5hZ2VyIGV4dGVuZHMgRXZlbnREaXNwYXRjaGVyIHtcbiAgICAvKipcbiAgICAgKiBUaGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gYnkgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBBbGwgdGhlIHZpZGVvcyBkaXNwbGF5aW5nIHRoZSBTdHJlYW0gb2YgdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlclxuICAgICAqL1xuICAgIHZpZGVvczogU3RyZWFtTWFuYWdlclZpZGVvW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIFN0cmVhbSByZXByZXNlbnRlZCBpbiB0aGUgRE9NIGlzIGxvY2FsIG9yIHJlbW90ZVxuICAgICAqIC0gYGZhbHNlYCBmb3Ige0BsaW5rIFB1Ymxpc2hlcn1cbiAgICAgKiAtIGB0cnVlYCBmb3Ige0BsaW5rIFN1YnNjcmliZXJ9XG4gICAgICovXG4gICAgcmVtb3RlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIERPTSBIVE1MRWxlbWVudCBhc3NpZ25lZCBhcyB0YXJnZXQgZWxlbWVudCB3aGVuIGNyZWF0aW5nIHRoZSB2aWRlbyBmb3IgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIHtAbGluayBQdWJsaXNoZXJ9IGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIHtAbGluayBPcGVuVmlkdS5pbml0UHVibGlzaGVyfSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqIC0ge0BsaW5rIFN1YnNjcmliZXJ9IGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIHtAbGluayBTZXNzaW9uLnN1YnNjcmliZX0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIGBpZGAgYXR0cmlidXRlIG9mIHRoZSBET00gdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlcidzIHN0cmVhbS4gVGhpcyBwcm9wZXJ0eSBpcyBvbmx5IGRlZmluZWQgaWY6XG4gICAgICogLSB7QGxpbmsgUHVibGlzaGVyfSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCB7QGxpbmsgT3BlblZpZHUuaW5pdFB1Ymxpc2hlcn0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIHtAbGluayBTdWJzY3JpYmVyfSBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIG1ldGhvZCB7QGxpbmsgU2Vzc2lvbi5zdWJzY3JpYmV9IHdpdGggYSB2YWxpZCBgdGFyZ2V0RWxlbWVudGAgcGFyYW1ldGVyXG4gICAgICovXG4gICAgaWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgZmlyc3RWaWRlb0VsZW1lbnQ/OiBTdHJlYW1NYW5hZ2VyVmlkZW87XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByb3RlY3RlZCBlbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGNhblBsYXlMaXN0ZW5lcjogRXZlbnRMaXN0ZW5lcjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJpdmF0ZSBzdHJlYW1QbGF5aW5nRXZlbnRFeGNlcHRpb25UaW1lb3V0PzogTm9kZUpTLlRpbWVvdXQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByaXZhdGUgbGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50PzogSFRNTEVsZW1lbnQgfCBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgcGxhdGZvcm0gPSBQbGF0Zm9ybVV0aWxzLmdldEluc3RhbmNlKCk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyID0gdGhpcztcbiAgICAgICAgdGhpcy5yZW1vdGUgPSAhdGhpcy5zdHJlYW0uaXNMb2NhbCgpO1xuXG4gICAgICAgIGlmICghIXRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGxldCB0YXJnRWw7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGFyZ0VsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IHRhcmdldEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghIXRhcmdFbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldEVsZW1lbnQ6IHRhcmdFbCxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyksXG4gICAgICAgICAgICAgICAgICAgIGlkOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzU2FmYXJpQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgICAgIChwbGF0Zm9ybS5pc0lQaG9uZU9ySVBhZCgpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAocGxhdGZvcm0uaXNDaHJvbWVNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0VkZ2VNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc09wZXJhTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNGaXJlZm94TW9iaWxlQnJvd3NlcigpKSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maXJzdFZpZGVvRWxlbWVudC52aWRlby5wbGF5c0lubGluZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0RWxlbWVudCA9IHRhcmdFbDtcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSB0YXJnRWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNhblBsYXlMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZGVhY3RpdmF0ZVN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQoKTtcbiAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIHtAbGluayBFdmVudERpc3BhdGNoZXIub259XG4gICAgICovXG4gICAgb248SyBleHRlbmRzIGtleW9mIFN0cmVhbU1hbmFnZXJFdmVudE1hcD4odHlwZTogSywgaGFuZGxlcjogKGV2ZW50OiBTdHJlYW1NYW5hZ2VyRXZlbnRNYXBbS10pID0+IHZvaWQpOiB0aGlzIHtcbiAgICAgICAgc3VwZXIub25BdXgodHlwZSwgXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIiwgaGFuZGxlcik7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50ID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNFxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVBsYXlpbmcnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLCAnc3RyZWFtUGxheWluZycsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5zdHJlYW0uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgIGlmICh0eXBlID09PSAncHVibGlzaGVyU3RhcnRTcGVha2luZycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVIYXJrU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZUhhcmtWb2x1bWVDaGFuZ2VFdmVudChmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIHtAbGluayBFdmVudERpc3BhdGNoZXIub25jZX1cbiAgICAgKi9cbiAgICBvbmNlPEsgZXh0ZW5kcyBrZXlvZiBTdHJlYW1NYW5hZ2VyRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI6IChldmVudDogU3RyZWFtTWFuYWdlckV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9uY2VBdXgodHlwZSwgXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBvbmNlIGJ5ICdcIiArICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArIFwiJ1wiLCBoYW5kbGVyKTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnN0cmVhbSAmJiB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodGhpcy52aWRlb3NbMF0udmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnRDcmVhdGVkJyldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbVBsYXlpbmcnKSB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlbyAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmN1cnJlbnRUaW1lID4gMCAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnBhdXNlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5lbmRlZCA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5yZWFkeVN0YXRlID09PSA0XG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5oYXNBdWRpbykge1xuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZU9uY2VIYXJrU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlT25jZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVPbmNlSGFya1ZvbHVtZUNoYW5nZUV2ZW50KGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUge0BsaW5rIEV2ZW50RGlzcGF0Y2hlci5vZmZ9XG4gICAgICovXG4gICAgb2ZmPEsgZXh0ZW5kcyBrZXlvZiBTdHJlYW1NYW5hZ2VyRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI/OiAoZXZlbnQ6IFN0cmVhbU1hbmFnZXJFdmVudE1hcFtLXSkgPT4gdm9pZCk6IHRoaXMge1xuICAgICAgICBzdXBlci5vZmZBdXgodHlwZSwgaGFuZGxlcik7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJykge1xuICAgICAgICAgICAgLy8gQm90aCBTdHJlYW1NYW5hZ2VyIGFuZCBTZXNzaW9uIGNhbiBoYXZlIFwicHVibGlzaGVyU3RhcnRTcGVha2luZ1wiIGV2ZW50IGxpc3RlbmVyc1xuICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nU3RhcnRTcGVha2luZ0V2ZW50TGlzdGVuZXJzID1cbiAgICAgICAgICAgICAgICB0aGlzLmVlLmdldExpc3RlbmVycyh0eXBlKS5sZW5ndGggKyB0aGlzLnN0cmVhbS5zZXNzaW9uLmVlLmdldExpc3RlbmVycyh0eXBlKS5sZW5ndGg7XG4gICAgICAgICAgICBpZiAocmVtYWluaW5nU3RhcnRTcGVha2luZ0V2ZW50TGlzdGVuZXJzID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzYWJsZUhhcmtTcGVha2luZ0V2ZW50KGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpIHtcbiAgICAgICAgICAgIC8vIEJvdGggU3RyZWFtTWFuYWdlciBhbmQgU2Vzc2lvbiBjYW4gaGF2ZSBcInB1Ymxpc2hlclN0b3BTcGVha2luZ1wiIGV2ZW50IGxpc3RlbmVyc1xuICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nU3RvcFNwZWFraW5nRXZlbnRMaXN0ZW5lcnMgPVxuICAgICAgICAgICAgICAgIHRoaXMuZWUuZ2V0TGlzdGVuZXJzKHR5cGUpLmxlbmd0aCArIHRoaXMuc3RyZWFtLnNlc3Npb24uZWUuZ2V0TGlzdGVuZXJzKHR5cGUpLmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChyZW1haW5pbmdTdG9wU3BlYWtpbmdFdmVudExpc3RlbmVycyA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc2FibGVIYXJrU3RvcHBlZFNwZWFraW5nRXZlbnQoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnKSB7XG4gICAgICAgICAgICAvLyBPbmx5IFN0cmVhbU1hbmFnZXIgY2FuIGhhdmUgXCJzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZVwiIGV2ZW50IGxpc3RlbmVyc1xuICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nVm9sdW1lRXZlbnRMaXN0ZW5lcnMgPSB0aGlzLmVlLmdldExpc3RlbmVycyh0eXBlKS5sZW5ndGg7XG4gICAgICAgICAgICBpZiAocmVtYWluaW5nVm9sdW1lRXZlbnRMaXN0ZW5lcnMgPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNhYmxlSGFya1ZvbHVtZUNoYW5nZUV2ZW50KGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ha2VzIGB2aWRlb2AgZWxlbWVudCBwYXJhbWV0ZXIgZGlzcGxheSB0aGlzIHtAbGluayBzdHJlYW19LiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSBhcmVcbiAgICAgKiBbbWFuYWdpbmcgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duXSgvZW4vc3RhYmxlL2NoZWF0c2hlZXQvbWFuYWdlLXZpZGVvcy8jeW91LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycylcbiAgICAgKlxuICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2Qgd2l0aCBhIHZpZGVvIGFscmVhZHkgYWRkZWQgdG8gb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBjYXVzZSB0aGUgdmlkZW8gZWxlbWVudCB0byBiZVxuICAgICAqIGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IHByZXZpb3VzIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCB0byBiZSBhc3NvY2lhdGVkIHRvIHRoaXMgb25lLlxuICAgICAqXG4gICAgICogQHJldHVybnMgMSBpZiB0aGUgdmlkZW8gd2Fzbid0IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICogMCBpZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgYWRkZWQgdG8gdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlci4gLTEgaWYgdGhlIHZpZGVvIHdhcyBwcmV2aW91c2x5IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyXG4gICAgICogUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBkaXNhc3NvY2lhdGVkIGZyb20gdGhhdCBvbmUgYW5kIHByb3Blcmx5IGFkZGVkIHRvIHRoaXMgb25lLlxuICAgICAqL1xuICAgIGFkZFZpZGVvRWxlbWVudCh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IG51bWJlciB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZVZpZGVvUHJvcGVydGllcyh2aWRlbyk7XG5cbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSAmJiB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgaWYgKHZpZGVvLnNyY09iamVjdCAhPT0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKSkge1xuICAgICAgICAgICAgICAgIHZpZGVvLnNyY09iamVjdCA9IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGUgdmlkZW8gZWxlbWVudCBpcyBhbHJlYWR5IHBhcnQgb2YgdGhpcyBTdHJlYW1NYW5hZ2VyIGRvIG5vdGhpbmdcbiAgICAgICAgZm9yIChjb25zdCB2IG9mIHRoaXMudmlkZW9zKSB7XG4gICAgICAgICAgICBpZiAodi52aWRlbyA9PT0gdmlkZW8pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxldCByZXR1cm5OdW1iZXIgPSAxO1xuXG4gICAgICAgIGZvciAoY29uc3Qgc3RyZWFtTWFuYWdlciBvZiB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzKSB7XG4gICAgICAgICAgICBpZiAoc3RyZWFtTWFuYWdlci5kaXNhc3NvY2lhdGVWaWRlbyh2aWRlbykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm5OdW1iZXIgPSAtMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMuZm9yRWFjaCgoc3RyZWFtTWFuYWdlcikgPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlci5kaXNhc3NvY2lhdGVWaWRlbyh2aWRlbyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh7XG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGlkOiB2aWRlby5pZCxcbiAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICB9KTtcblxuICAgICAgICBsb2dnZXIuaW5mbygnTmV3IHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byAnLCB0aGlzKTtcblxuICAgICAgICByZXR1cm4gcmV0dXJuTnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoaXMge0BsaW5rIHN0cmVhbX0uIFRoaXMgYWxsb3dzIHlvdSB0byBoYXZlIG11bHRpcGxlIHZpZGVvIGVsZW1lbnRzIGRpc3BsYXlpbmcgdGhlIHNhbWUgbWVkaWEgc3RyZWFtLlxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgdGhlIEhUTUwgdmlkZW8gZWxlbWVudCBoYXMgYmVlbiBhZGRlZCB0byBET00uIFNlZSB7QGxpbmsgVmlkZW9FbGVtZW50RXZlbnR9XG4gICAgICpcbiAgICAgKiBAcGFyYW0gdGFyZ2V0RWxlbWVudCBIVE1MIERPTSBlbGVtZW50IChvciBpdHMgYGlkYCBhdHRyaWJ1dGUpIGluIHdoaWNoIHRoZSB2aWRlbyBlbGVtZW50IG9mIHRoZSBQdWJsaXNoZXIvU3Vic2NyaWJlciB3aWxsIGJlIGluc2VydGVkXG4gICAgICogQHBhcmFtIGluc2VydE1vZGUgSG93IHRoZSB2aWRlbyBlbGVtZW50IHdpbGwgYmUgaW5zZXJ0ZWQgYWNjb3JkaW5nbHkgdG8gYHRhcmdldEVsZW1ldGBcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBjcmVhdGVkIEhUTUxWaWRlb0VsZW1lbnRcbiAgICAgKi9cbiAgICBjcmVhdGVWaWRlb0VsZW1lbnQodGFyZ2V0RWxlbWVudD86IHN0cmluZyB8IEhUTUxFbGVtZW50LCBpbnNlcnRNb2RlPzogVmlkZW9JbnNlcnRNb2RlKTogSFRNTFZpZGVvRWxlbWVudCB7XG4gICAgICAgIGxldCB0YXJnRWw7XG4gICAgICAgIGlmICh0eXBlb2YgdGFyZ2V0RWxlbWVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRhcmdFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgaWYgKCF0YXJnRWwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcHJvdmlkZWQgJ3RhcmdldEVsZW1lbnQnIGNvdWxkbid0IGJlIHJlc29sdmVkIHRvIGFueSBIVE1MIGVsZW1lbnQ6IFwiICsgdGFyZ2V0RWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0RWxlbWVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgICAgICB0YXJnRWwgPSB0YXJnZXRFbGVtZW50O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHByb3ZpZGVkICd0YXJnZXRFbGVtZW50JyBjb3VsZG4ndCBiZSByZXNvbHZlZCB0byBhbnkgSFRNTCBlbGVtZW50OiBcIiArIHRhcmdldEVsZW1lbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdmlkZW8gPSB0aGlzLmNyZWF0ZVZpZGVvKCk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZVZpZGVvUHJvcGVydGllcyh2aWRlbyk7XG5cbiAgICAgICAgbGV0IGluc01vZGUgPSAhIWluc2VydE1vZGUgPyBpbnNlcnRNb2RlIDogVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgc3dpdGNoIChpbnNNb2RlKSB7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5BRlRFUjpcbiAgICAgICAgICAgICAgICB0YXJnRWwucGFyZW50Tm9kZSEhLmluc2VydEJlZm9yZSh2aWRlbywgdGFyZ0VsLm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkFQUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQkVGT1JFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuUFJFUEVORDpcbiAgICAgICAgICAgICAgICB0YXJnRWwuaW5zZXJ0QmVmb3JlKHZpZGVvLCB0YXJnRWwuY2hpbGROb2Rlc1swXSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5SRVBMQUNFOlxuICAgICAgICAgICAgICAgIHRhcmdFbC5wYXJlbnROb2RlISEucmVwbGFjZUNoaWxkKHZpZGVvLCB0YXJnRWwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbnNNb2RlID0gVmlkZW9JbnNlcnRNb2RlLkFQUEVORDtcbiAgICAgICAgICAgICAgICB0YXJnRWwuYXBwZW5kQ2hpbGQodmlkZW8pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdjogU3RyZWFtTWFuYWdlclZpZGVvID0ge1xuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudDogdGFyZ0VsLFxuICAgICAgICAgICAgdmlkZW8sXG4gICAgICAgICAgICBpbnNlcnRNb2RlOiBpbnNNb2RlLFxuICAgICAgICAgICAgaWQ6IHZpZGVvLmlkLFxuICAgICAgICAgICAgY2FucGxheUxpc3RlbmVyQWRkZWQ6IGZhbHNlXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh2KTtcblxuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgndmlkZW9FbGVtZW50Q3JlYXRlZCcsIFtuZXcgVmlkZW9FbGVtZW50RXZlbnQodi52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICB0aGlzLmxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSAhIXRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgcmV0dXJuIHZpZGVvO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbiBmb3IgdGhlIHtAbGluayBQdWJsaXNoZXJTcGVha2luZ0V2ZW50fSBmZWF0dXJlIGFuZCB0aGUgW1N0cmVhbU1hbmFnZXJFdmVudC5zdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZV0oL2VuL3N0YWJsZS9hcGkvb3BlbnZpZHUtYnJvd3Nlci9jbGFzc2VzL1N0cmVhbU1hbmFnZXJFdmVudC5odG1sKSBmZWF0dXJlIGZvciB0aGlzIHNwZWNpZmljXG4gICAgICogU3RyZWFtTWFuYWdlciBhdWRpbyBzdHJlYW0sIG92ZXJyaWRpbmcgdGhlIGdsb2JhbCBvcHRpb25zIHNldCB3aXRoIHtAbGluayBPcGVuVmlkdS5zZXRBZHZhbmNlZENvbmZpZ3VyYXRpb259LiBUaGlzIHdheSB5b3UgY2FuIGN1c3RvbWl6ZSB0aGUgYXVkaW8gZXZlbnRzIG9wdGlvbnNcbiAgICAgKiBmb3IgZWFjaCBzcGVjaWZpYyBTdHJlYW1NYW5hZ2VyIGFuZCBjaGFuZ2UgdGhlbSBkeW5hbWljYWxseS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMgTmV3IG9wdGlvbnMgdG8gYmUgYXBwbGllZCB0byB0aGlzIFN0cmVhbU1hbmFnZXIncyBhdWRpbyBzdHJlYW0uIEl0IGlzIGFuIG9iamVjdCB3aGljaCBpbmNsdWRlcyB0aGUgZm9sbG93aW5nIG9wdGlvbmFsIHByb3BlcnRpZXM6XG4gICAgICogLSBgaW50ZXJ2YWxgOiAobnVtYmVyKSBob3cgZnJlcXVlbnRseSB0aGUgYW5hbHlzZXIgcG9sbHMgdGhlIGF1ZGlvIHN0cmVhbSB0byBjaGVjayBpZiBzcGVha2luZyBoYXMgc3RhcnRlZC9zdG9wcGVkIG9yIGF1ZGlvIHZvbHVtZSBoYXMgY2hhbmdlZC4gRGVmYXVsdCAqKjEwMCoqIChtcylcbiAgICAgKiAtIGB0aHJlc2hvbGRgOiAobnVtYmVyKSB0aGUgdm9sdW1lIGF0IHdoaWNoIF9wdWJsaXNoZXJTdGFydFNwZWFraW5nXywgX3B1Ymxpc2hlclN0b3BTcGVha2luZ18gZXZlbnRzIHdpbGwgYmUgZmlyZWQuIERlZmF1bHQgKiotNTAqKiAoZEIpXG4gICAgICovXG4gICAgdXBkYXRlUHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zKHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9uczogeyBpbnRlcnZhbD86IG51bWJlcjsgdGhyZXNob2xkPzogbnVtYmVyIH0pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY3VycmVudEhhcmtPcHRpb25zID0gISF0aGlzLnN0cmVhbS5oYXJrT3B0aW9uc1xuICAgICAgICAgICAgPyB0aGlzLnN0cmVhbS5oYXJrT3B0aW9uc1xuICAgICAgICAgICAgOiB0aGlzLnN0cmVhbS5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5wdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMgfHwge307XG4gICAgICAgIGNvbnN0IG5ld0ludGVydmFsID1cbiAgICAgICAgICAgIHR5cGVvZiBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMuaW50ZXJ2YWwgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgPyBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMuaW50ZXJ2YWxcbiAgICAgICAgICAgICAgICA6IHR5cGVvZiBjdXJyZW50SGFya09wdGlvbnMuaW50ZXJ2YWwgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgPyBjdXJyZW50SGFya09wdGlvbnMuaW50ZXJ2YWxcbiAgICAgICAgICAgICAgICA6IDEwMDtcbiAgICAgICAgY29uc3QgbmV3VGhyZXNob2xkID1cbiAgICAgICAgICAgIHR5cGVvZiBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMudGhyZXNob2xkID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgICAgID8gcHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zLnRocmVzaG9sZFxuICAgICAgICAgICAgICAgIDogdHlwZW9mIGN1cnJlbnRIYXJrT3B0aW9ucy50aHJlc2hvbGQgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgPyBjdXJyZW50SGFya09wdGlvbnMudGhyZXNob2xkXG4gICAgICAgICAgICAgICAgOiAtNTA7XG4gICAgICAgIHRoaXMuc3RyZWFtLmhhcmtPcHRpb25zID0ge1xuICAgICAgICAgICAgaW50ZXJ2YWw6IG5ld0ludGVydmFsLFxuICAgICAgICAgICAgdGhyZXNob2xkOiBuZXdUaHJlc2hvbGRcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0uc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNwZWVjaEV2ZW50LnNldEludGVydmFsKG5ld0ludGVydmFsKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNwZWVjaEV2ZW50LnNldFRocmVzaG9sZChuZXdUaHJlc2hvbGQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0aWFsaXplVmlkZW9Qcm9wZXJ0aWVzKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICghKCF0aGlzLnJlbW90ZSAmJiB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIHNldHRpbmcgdGhlIE1lZGlhU3RyZWFtIGludG8gdGhlIHNyY09iamVjdCBpZiByZW1vdGUgc3Vic2NyaXB0aW9uIGJlZm9yZSBwdWJsaXNoaW5nXG4gICAgICAgICAgICBpZiAodmlkZW8uc3JjT2JqZWN0ICE9PSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgc3JjT2JqZWN0IGFscmVhZHkgc2V0IGRvbid0IGRvIGl0IGFnYWluXG4gICAgICAgICAgICAgICAgdmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2aWRlby5hdXRvcGxheSA9IHRydWU7XG4gICAgICAgIHZpZGVvLmNvbnRyb2xzID0gZmFsc2U7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNTYWZhcmlCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5pc0lQaG9uZU9ySVBhZCgpICYmXG4gICAgICAgICAgICAgICAgKHBsYXRmb3JtLmlzQ2hyb21lTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzRWRnZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc09wZXJhTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzRmlyZWZveE1vYmlsZUJyb3dzZXIoKSkpXG4gICAgICAgICkge1xuICAgICAgICAgICAgdmlkZW8ucGxheXNJbmxpbmUgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF2aWRlby5pZCkge1xuICAgICAgICAgICAgdmlkZW8uaWQgPSAodGhpcy5yZW1vdGUgPyAncmVtb3RlLScgOiAnbG9jYWwtJykgKyAndmlkZW8tJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkO1xuICAgICAgICAgICAgLy8gREVQUkVDQVRFRCBwcm9wZXJ0eTogYXNzaWduIG9uY2UgdGhlIHByb3BlcnR5IGlkIGlmIHRoZSB1c2VyIHByb3ZpZGVkIGEgdmFsaWQgdGFyZ2V0RWxlbWVudFxuICAgICAgICAgICAgaWYgKCF0aGlzLmlkICYmICEhdGhpcy50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pZCA9IHZpZGVvLmlkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucmVtb3RlICYmIHRoaXMuaXNNaXJyb3JlZFZpZGVvKHZpZGVvKSkge1xuICAgICAgICAgICAgLy8gU3Vic2NyaWJlciB2aWRlbyBhc3NvY2lhdGVkIHRvIGEgcHJldmlvdXNseSBtaXJyb3JlZCB2aWRlbyBlbGVtZW50XG4gICAgICAgICAgICB0aGlzLnJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5yZW1vdGUgJiYgIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAvLyBQdWJsaXNoZXIgdmlkZW9cbiAgICAgICAgICAgIHZpZGVvLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTWlycm9yZWRWaWRlbyh2aWRlbykgJiYgIXRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLm1pcnJvcikge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSB2aWRlbyB3YXMgYWxyZWFkeSByb3RhdGVkIGFuZCBub3cgaXMgc2V0IHRvIG5vdCBtaXJyb3JcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZU1pcnJvclZpZGVvKHZpZGVvKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMubWlycm9yICYmICF0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSkge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSB2aWRlbyBpcyBub3cgc2V0IHRvIG1pcnJvciBhbmQgaXMgbm90IHNjcmVlbiBzaGFyZVxuICAgICAgICAgICAgICAgIHRoaXMubWlycm9yVmlkZW8odmlkZW8pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZUFsbFZpZGVvcygpOiB2b2lkIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzW2ldID09PSB0aGlzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKChzdHJlYW1NYW5hZ2VyVmlkZW8pID0+IHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBvbmNhbnBsYXkgZXZlbnQgbGlzdGVuZXIgKG9ubHkgT3BlblZpZHUgYnJvd3NlciBsaXN0ZW5lciwgbm90IHRoZSB1c2VyIG9uZXMpXG4gICAgICAgICAgICBpZiAoISFzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8gJiYgISFzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8ucmVtb3ZlRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLmNhbnBsYXlMaXN0ZW5lckFkZGVkID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoISFzdHJlYW1NYW5hZ2VyVmlkZW8udGFyZ2V0RWxlbWVudCkge1xuICAgICAgICAgICAgICAgIC8vIE9ubHkgcmVtb3ZlIGZyb20gRE9NIHZpZGVvcyBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIgKHRob3NlIGdlbmVyYXRlZCBieSBwYXNzaW5nIGEgdmFsaWQgdGFyZ2V0RWxlbWVudCBpbiBPcGVuVmlkdS5pbml0UHVibGlzaGVyXG4gICAgICAgICAgICAgICAgLy8gYW5kIFNlc3Npb24uc3Vic2NyaWJlIG9yIHRob3NlIGNyZWF0ZWQgYnkgU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnQpLiBBbGwgdGhpcyB2aWRlb3MgdHJpZ2dlcmVkIGEgdmlkZW9FbGVtZW50Q3JlYXRlZCBldmVudFxuICAgICAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnROb2RlIS5yZW1vdmVDaGlsZChzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8pO1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnREZXN0cm95ZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgIG5ldyBWaWRlb0VsZW1lbnRFdmVudChzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnREZXN0cm95ZWQnKVxuICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gUmVtb3ZlIHNyY09iamVjdCBmcm9tIHRoZSB2aWRlb1xuICAgICAgICAgICAgdGhpcy5yZW1vdmVTcmNPYmplY3Qoc3RyZWFtTWFuYWdlclZpZGVvKTtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIGNvbGxlY3Rpb24gb2YgdmlkZW9zIGV2ZXJ5IHZpZGVvIG1hbmFnZWQgYnkgT3BlblZpZHUgQnJvd3NlclxuICAgICAgICAgICAgdGhpcy52aWRlb3MuZmlsdGVyKCh2KSA9PiAhdi50YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2Fzc29jaWF0ZVZpZGVvKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBkaXNhc3NvY2lhdGVkID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy52aWRlb3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZGVvc1tpXS52aWRlbyA9PT0gdmlkZW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1tpXS52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICBkaXNhc3NvY2lhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnVmlkZW8gZWxlbWVudCBkaXNhc3NvY2lhdGVkIGZyb20gJywgdGhpcyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRpc2Fzc29jaWF0ZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpIHtcbiAgICAgICAgaWYgKCEhdGhpcy52aWRlb3NbMF0gJiYgISF0aGlzLnZpZGVvc1swXS52aWRlbyAmJiAhdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYWN0aXZhdGVTdHJlYW1QbGF5aW5nRXZlbnRFeGNlcHRpb25UaW1lb3V0KCk7XG4gICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5hZGRFdmVudExpc3RlbmVyKCdjYW5wbGF5JywgdGhpcy5jYW5QbGF5TGlzdGVuZXIpO1xuICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0uY2FucGxheUxpc3RlbmVyQWRkZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHVwZGF0ZU1lZGlhU3RyZWFtKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSkge1xuICAgICAgICB0aGlzLnZpZGVvcy5mb3JFYWNoKChzdHJlYW1NYW5hZ2VyVmlkZW8pID0+IHtcbiAgICAgICAgICAgIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5zcmNPYmplY3QgPSBtZWRpYVN0cmVhbTtcbiAgICAgICAgICAgIGlmIChwbGF0Zm9ybS5pc0lvbmljSW9zKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBpT1MgSW9uaWMuIExJTUlUQVRJT046IG11c3QgcmVpbnNlcnQgdGhlIHZpZGVvIGluIHRoZSBET00gZm9yXG4gICAgICAgICAgICAgICAgLy8gdGhlIG1lZGlhIHN0cmVhbSB0byBiZSB1cGRhdGVkXG4gICAgICAgICAgICAgICAgY29uc3QgdlBhcmVudCA9IHN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld1ZpZGVvID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvO1xuICAgICAgICAgICAgICAgIHZQYXJlbnQhIS5yZXBsYWNlQ2hpbGQobmV3VmlkZW8sIHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvID0gbmV3VmlkZW87XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbWl0RXZlbnQodHlwZTogc3RyaW5nLCBldmVudEFycmF5OiBhbnlbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCh0eXBlLCBldmVudEFycmF5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY3JlYXRlVmlkZW8oKTogSFRNTFZpZGVvRWxlbWVudCB7XG4gICAgICAgIHJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZW1vdmVTcmNPYmplY3Qoc3RyZWFtTWFuYWdlclZpZGVvOiBTdHJlYW1NYW5hZ2VyVmlkZW8pIHtcbiAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnNyY09iamVjdCA9IG51bGw7XG4gICAgICAgIHRoaXMuZGVhY3RpdmF0ZVN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWJzdHJhY3QgcmVwbGFjZVRyYWNrSW5NZWRpYVN0cmVhbSh0cmFjazogTWVkaWFTdHJlYW1UcmFjaywgdXBkYXRlTGFzdENvbnN0cmFpbnRzOiBib29sZWFuKTogdm9pZDtcblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJvdGVjdGVkIHB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8oc3RyZWFtTWFuYWdlclZpZGVvOiBTdHJlYW1NYW5hZ2VyVmlkZW8pIHtcbiAgICAgICAgdGhpcy52aWRlb3MucHVzaChzdHJlYW1NYW5hZ2VyVmlkZW8pO1xuICAgICAgICB0aGlzLmFkZFBsYXlFdmVudFRvRmlyc3RWaWRlbygpO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5pbmRleE9mKHRoaXMpID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5wdXNoKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtaXJyb3JWaWRlbyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IHZvaWQge1xuICAgICAgICBpZiAoIXBsYXRmb3JtLmlzSW9uaWNJb3MoKSkge1xuICAgICAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgICAgICAgICB2aWRlby5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAncm90YXRlWSgxODBkZWcpJztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3ZlTWlycm9yVmlkZW8odmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgdmlkZW8uc3R5bGUudHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICAgICAgdmlkZW8uc3R5bGUud2Via2l0VHJhbnNmb3JtID0gJ3Vuc2V0JztcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzTWlycm9yZWRWaWRlbyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdmlkZW8uc3R5bGUudHJhbnNmb3JtID09PSAncm90YXRlWSgxODBkZWcpJyB8fCB2aWRlby5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPT09ICdyb3RhdGVZKDE4MGRlZyknO1xuICAgIH1cblxuICAgIHByaXZhdGUgYWN0aXZhdGVTdHJlYW1QbGF5aW5nRXZlbnRFeGNlcHRpb25UaW1lb3V0KCkge1xuICAgICAgICBpZiAoIXRoaXMucmVtb3RlKSB7XG4gICAgICAgICAgICAvLyBFeGNlcHRpb25FdmVudCBOT19TVFJFQU1fUExBWUlOR19FVkVOVCBpcyBvbmx5IGZvciBzdWJzY3JpYmVyc1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gVGhlIHRpbWVvdXQgaXMgYWxyZWFkeSBhY3RpdmF0ZWRcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBUcmlnZ2VyIEV4Y2VwdGlvbkV2ZW50IE5PX1NUUkVBTV9QTEFZSU5HX0VWRU5UIGlmIGFmdGVyIHRpbWVvdXQgdGhlcmUgaXMgbm8gJ2NhbnBsYXknIGV2ZW50XG4gICAgICAgIGNvbnN0IG1zVGltZW91dCA9IHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLm5vU3RyZWFtUGxheWluZ0V2ZW50RXhjZXB0aW9uVGltZW91dCB8fCA0MDAwO1xuICAgICAgICB0aGlzLnN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1zZyA9XG4gICAgICAgICAgICAgICAgJ1N0cmVhbU1hbmFnZXIgb2YgU3RyZWFtICcgK1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbUlkICtcbiAgICAgICAgICAgICAgICAnICgnICtcbiAgICAgICAgICAgICAgICAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgK1xuICAgICAgICAgICAgICAgICcpIGRpZCBub3QgdHJpZ2dlciBcInN0cmVhbVBsYXlpbmdcIiBldmVudCBpbiAnICtcbiAgICAgICAgICAgICAgICBtc1RpbWVvdXQgK1xuICAgICAgICAgICAgICAgICcgbXMnO1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4obXNnKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uZW1pdEV2ZW50KCdleGNlcHRpb24nLCBbXG4gICAgICAgICAgICAgICAgbmV3IEV4Y2VwdGlvbkV2ZW50KHRoaXMuc3RyZWFtLnNlc3Npb24sIEV4Y2VwdGlvbkV2ZW50TmFtZS5OT19TVFJFQU1fUExBWUlOR19FVkVOVCwgKDxhbnk+dGhpcykgYXMgU3Vic2NyaWJlciwgbXNnKVxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zdHJlYW1QbGF5aW5nRXZlbnRFeGNlcHRpb25UaW1lb3V0O1xuICAgICAgICB9LCBtc1RpbWVvdXQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZGVhY3RpdmF0ZVN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQoKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQgYXMgYW55KTtcbiAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtUGxheWluZ0V2ZW50RXhjZXB0aW9uVGltZW91dDtcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTdWJzY3JpYmVyUHJvcGVydGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvU3Vic2NyaWJlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBQYWNrcyByZW1vdGUgbWVkaWEgc3RyZWFtcy4gUGFydGljaXBhbnRzIGF1dG9tYXRpY2FsbHkgcmVjZWl2ZSB0aGVtIHdoZW4gb3RoZXJzIHB1Ymxpc2ggdGhlaXIgc3RyZWFtcy4gSW5pdGlhbGl6ZWQgd2l0aCB7QGxpbmsgU2Vzc2lvbi5zdWJzY3JpYmV9IG1ldGhvZFxuICpcbiAqIFNlZSBhdmFpbGFibGUgZXZlbnQgbGlzdGVuZXJzIGF0IHtAbGluayBTdHJlYW1NYW5hZ2VyRXZlbnRNYXB9LlxuICovXG5leHBvcnQgY2xhc3MgU3Vic2NyaWJlciBleHRlbmRzIFN0cmVhbU1hbmFnZXIge1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCwgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMpIHtcbiAgICAgICAgc3VwZXIoc3RyZWFtLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLnRhcmdldEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSBhdWRpbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgYXVkaW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb0F1ZGlvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtXG4gICAgICAgICAgICAuZ2V0TWVkaWFTdHJlYW0oKVxuICAgICAgICAgICAgLmdldEF1ZGlvVHJhY2tzKClcbiAgICAgICAgICAgIC5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICBsb2dnZXIuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIHZpZGVvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9WaWRlbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbVxuICAgICAgICAgICAgLmdldE1lZGlhU3RyZWFtKClcbiAgICAgICAgICAgIC5nZXRWaWRlb1RyYWNrcygpXG4gICAgICAgICAgICAuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5lbmFibGVkID0gdmFsdWU7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgPSB2YWx1ZTtcbiAgICAgICAgbG9nZ2VyLmluZm8oXCInU3Vic2NyaWJlcicgaGFzIFwiICsgKHZhbHVlID8gJ3N1YnNjcmliZWQgdG8nIDogJ3Vuc3Vic2NyaWJlZCBmcm9tJykgKyAnIGl0cyB2aWRlbyBzdHJlYW0nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZXBsYWNlVHJhY2tJbk1lZGlhU3RyZWFtKHRyYWNrOiBNZWRpYVN0cmVhbVRyYWNrLCB1cGRhdGVMYXN0Q29uc3RyYWludHM6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgbGV0IHJlbW92ZWRUcmFjazogTWVkaWFTdHJlYW1UcmFjaztcbiAgICAgICAgaWYgKHRyYWNrLmtpbmQgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgIHJlbW92ZWRUcmFjayA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAgICAgICAgICBpZiAodXBkYXRlTGFzdENvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0ubGFzdFZpZGVvVHJhY2tDb25zdHJhaW50cyA9IHRyYWNrLmdldENvbnN0cmFpbnRzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZW1vdmVkVHJhY2sgPSBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdO1xuICAgICAgICB9XG4gICAgICAgIG1lZGlhU3RyZWFtLnJlbW92ZVRyYWNrKHJlbW92ZWRUcmFjayk7XG4gICAgICAgIHJlbW92ZWRUcmFjay5zdG9wKCk7XG4gICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKHRyYWNrKTtcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuZXhwb3J0IGVudW0gTG9jYWxSZWNvcmRlclN0YXRlIHtcbiAgICBSRUFEWSA9ICdSRUFEWScsXG4gICAgUkVDT1JESU5HID0gJ1JFQ09SRElORycsXG4gICAgUEFVU0VEID0gJ1BBVVNFRCcsXG4gICAgRklOSVNIRUQgPSAnRklOSVNIRUQnXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLyoqXG4gKiBEZWZpbmVzIHByb3BlcnR5IHtAbGluayBPcGVuVmlkdUVycm9yLm5hbWV9XG4gKi9cbmV4cG9ydCBlbnVtIE9wZW5WaWR1RXJyb3JOYW1lIHtcbiAgICAvKipcbiAgICAgKiBCcm93c2VyIGlzIG5vdCBzdXBwb3J0ZWQgYnkgT3BlblZpZHUuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwge0BsaW5rIFNlc3Npb24uY29ubmVjdH1cbiAgICAgKi9cbiAgICBCUk9XU0VSX05PVF9TVVBQT1JURUQgPSAnQlJPV1NFUl9OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIHRoZSByZXF1aXJlZCBpbnB1dCBkZXZpY2Ugd2hlbiB0aGUgYnJvd3NlciBhc2tlZCBmb3IgdGhlbS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCB7QGxpbmsgT3BlblZpZHUuaW5pdFB1Ymxpc2hlcn0gb3Ige0BsaW5rIE9wZW5WaWR1LmdldFVzZXJNZWRpYX1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUNDRVNTX0RFTklFRCA9ICdERVZJQ0VfQUNDRVNTX0RFTklFRCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWlyZWQgaW5wdXQgZGV2aWNlIGlzIHByb2JhYmx5IGJlaW5nIHVzZWQgYnkgb3RoZXIgcHJvY2VzcyB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciBpdC5cbiAgICAgKiBUaGlzIGVycm9yIGNhbiBhbHNvIGJlIHRyaWdnZXJlZCB3aGVuIHRoZSB1c2VyIGdyYW50ZWQgcGVybWlzc2lvbiB0byB1c2UgdGhlIGRldmljZXMgYnV0IGEgaGFyZHdhcmVcbiAgICAgKiBlcnJvciBvY2N1cnJlZCBhdCB0aGUgT1MsIGJyb3dzZXIgb3Igd2ViIHBhZ2UgbGV2ZWwsIHdoaWNoIHByZXZlbnRlZCBhY2Nlc3MgdG8gdGhlIGRldmljZS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCB7QGxpbmsgT3BlblZpZHUuaW5pdFB1Ymxpc2hlcn0gb3Ige0BsaW5rIE9wZW5WaWR1LmdldFVzZXJNZWRpYX1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUxSRUFEWV9JTl9VU0UgPSAnREVWSUNFX0FMUkVBRFlfSU5fVVNFJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIGNhcHR1cmUgc29tZSBkZXNrdG9wIHNjcmVlbiB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIHtAbGluayBPcGVuVmlkdS5pbml0UHVibGlzaGVyfSBvciB7QGxpbmsgT3BlblZpZHUuZ2V0VXNlck1lZGlhfVxuICAgICAqL1xuICAgIFNDUkVFTl9DQVBUVVJFX0RFTklFRCA9ICdTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQnLFxuXG4gICAgLyoqXG4gICAgICogQnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHNjcmVlbiBzaGFyaW5nLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIHtAbGluayBPcGVuVmlkdS5pbml0UHVibGlzaGVyfSBvciB7QGxpbmsgT3BlblZpZHUuZ2V0VXNlck1lZGlhfVxuICAgICAqL1xuICAgIFNDUkVFTl9TSEFSSU5HX05PVF9TVVBQT1JURUQgPSAnU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCcsXG5cbiAgICAvKipcbiAgICAgKiBPbmx5IGZvciBDaHJvbWUsIHRoZXJlJ3Mgbm8gc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGluc3RhbGxlZFxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIHtAbGluayBPcGVuVmlkdS5pbml0UHVibGlzaGVyfSBvciB7QGxpbmsgT3BlblZpZHUuZ2V0VXNlck1lZGlhfVxuICAgICAqL1xuICAgIFNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCA9ICdTQ1JFRU5fRVhURU5TSU9OX05PVF9JTlNUQUxMRUQnLFxuXG4gICAgLyoqXG4gICAgICogT25seSBmb3IgQ2hyb21lLCB0aGUgc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGlzIGluc3RhbGxlZCBidXQgaXMgZGlzYWJsZWRcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCB7QGxpbmsgT3BlblZpZHUuaW5pdFB1Ymxpc2hlcn0gb3Ige0BsaW5rIE9wZW5WaWR1LmdldFVzZXJNZWRpYX1cbiAgICAgKi9cbiAgICBTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEID0gJ1NDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQnLFxuXG4gICAgLyoqXG4gICAgICogTm8gdmlkZW8gaW5wdXQgZGV2aWNlIGZvdW5kIHdpdGggdGhlIHByb3ZpZGVkIGRldmljZUlkIChwcm9wZXJ0eSB7QGxpbmsgUHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZX0pXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwge0BsaW5rIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJ9IG9yIHtAbGluayBPcGVuVmlkdS5nZXRVc2VyTWVkaWF9XG4gICAgICovXG4gICAgSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORCA9ICdJTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EJyxcblxuICAgIC8qKlxuICAgICAqIE5vIGF1ZGlvIGlucHV0IGRldmljZSBmb3VuZCB3aXRoIHRoZSBwcm92aWRlZCBkZXZpY2VJZCAocHJvcGVydHkge0BsaW5rIFB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2V9KVxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIHtAbGluayBPcGVuVmlkdS5pbml0UHVibGlzaGVyfSBvciB7QGxpbmsgT3BlblZpZHUuZ2V0VXNlck1lZGlhfVxuICAgICAqL1xuICAgIElOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGVyZSB3YXMgYW4gdW5rbm93biBlcnJvciB3aGVuIHRyeWluZyB0byBhY2Nlc3MgdGhlIHNwZWNpZmllZCBhdWRpbyBkZXZpY2VcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCB7QGxpbmsgT3BlblZpZHUuaW5pdFB1Ymxpc2hlcn0gb3Ige0BsaW5rIE9wZW5WaWR1LmdldFVzZXJNZWRpYX1cbiAgICAgKi9cbiAgICBJTlBVVF9BVURJT19ERVZJQ0VfR0VORVJJQ19FUlJPUiA9ICdJTlBVVF9BVURJT19ERVZJQ0VfR0VORVJJQ19FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBNZXRob2Qge0BsaW5rIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJ9IG9yICB7QGxpbmsgT3BlblZpZHUuZ2V0VXNlck1lZGlhfSBoYXMgYmVlbiBjYWxsZWQgd2l0aCBwcm9wZXJ0aWVzIGB2aWRlb1NvdXJjZWAgYW5kIGBhdWRpb1NvdXJjZWAgb2ZcbiAgICAgKiB7QGxpbmsgUHVibGlzaGVyUHJvcGVydGllc30gcGFyYW1ldGVyIGJvdGggc2V0IHRvICpmYWxzZSogb3IgKm51bGwqXG4gICAgICovXG4gICAgTk9fSU5QVVRfU09VUkNFX1NFVCA9ICdOT19JTlBVVF9TT1VSQ0VfU0VUJyxcblxuICAgIC8qKlxuICAgICAqIFNvbWUgbWVkaWEgcHJvcGVydHkgb2Yge0BsaW5rIFB1Ymxpc2hlclByb3BlcnRpZXN9IHN1Y2ggYXMgYGZyYW1lUmF0ZWAgb3IgYHJlc29sdXRpb25gIGlzIG5vdCBzdXBwb3J0ZWRcbiAgICAgKiBieSB0aGUgaW5wdXQgZGV2aWNlcyAod2hlbmV2ZXIgaXQgaXMgcG9zc2libGUgdGhleSBhcmUgYXV0b21hdGljYWxseSBhZGp1c3RlZCB0byB0aGUgbW9zdCBzaW1pbGFyIHZhbHVlKS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCB7QGxpbmsgT3BlblZpZHUuaW5pdFB1Ymxpc2hlcn0gb3Ige0BsaW5rIE9wZW5WaWR1LmdldFVzZXJNZWRpYX1cbiAgICAgKi9cbiAgICBQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUiA9ICdQVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY2xpZW50IHRyaWVkIHRvIGNhbGwgYSBtZXRob2Qgd2l0aG91dCB0aGUgcmVxdWlyZWQgcGVybWlzc2lvbnMuIFRoaXMgY2FuIG9jY3VyIGZvciBtZXRob2RzIHtAbGluayBTZXNzaW9uLnB1Ymxpc2h9LFxuICAgICAqIHtAbGluayBTZXNzaW9uLmZvcmNlVW5wdWJsaXNofSwge0BsaW5rIFNlc3Npb24uZm9yY2VEaXNjb25uZWN0fSwge0BsaW5rIFN0cmVhbS5hcHBseUZpbHRlcn0sIHtAbGluayBTdHJlYW0ucmVtb3ZlRmlsdGVyfVxuICAgICAqL1xuICAgIE9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVEID0gJ09QRU5WSURVX1BFUk1JU1NJT05fREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZXJlIGlzIG5vIGNvbm5lY3Rpb24gdG8gdGhlIFNlc3Npb24uIFRoaXMgZXJyb3Igd2lsbCBiZSB0aHJvd24gd2hlbiBhbnkgbWV0aG9kIHJlcXVpcmluZyBhIGNvbm5lY3Rpb24gdG9cbiAgICAgKiBvcGVudmlkdS1zZXJ2ZXIgaXMgY2FsbGVkIGJlZm9yZSBzdWNjZXNzZnVsbHkgY2FsbGluZyBtZXRob2Qge0BsaW5rIFNlc3Npb24uY29ubmVjdH1cbiAgICAgKi9cbiAgICBPUEVOVklEVV9OT1RfQ09OTkVDVEVEID0gJ09QRU5WSURVX05PVF9DT05ORUNURUQnLFxuXG4gICAgLyoqXG4gICAgICogRXJyb3IgcmVsYXRlZCB0byBbVmlydHVhbCBCYWNrZ3JvdW5kXSgvZW4vc3RhYmxlL2FkdmFuY2VkLWZlYXR1cmVzL3ZpcnR1YWwtYmFja2dyb3VuZC8pXG4gICAgICovXG4gICAgVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SID0gJ1ZJUlRVQUxfQkFDS0dST1VORF9FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmljIGVycm9yXG4gICAgICovXG4gICAgR0VORVJJQ19FUlJPUiA9ICdHRU5FUklDX0VSUk9SJ1xufVxuXG4vKipcbiAqIFNpbXBsZSBvYmplY3QgdG8gaWRlbnRpZnkgcnVudGltZSBlcnJvcnMgb24gdGhlIGNsaWVudCBzaWRlXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuVmlkdUVycm9yIHtcbiAgICAvKipcbiAgICAgKiBVbmlxdWVseSBpZGVudGlmeWluZyBuYW1lIG9mIHRoZSBlcnJvclxuICAgICAqL1xuICAgIG5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lO1xuXG4gICAgLyoqXG4gICAgICogRnVsbCBkZXNjcmlwdGlvbiBvZiB0aGUgZXJyb3JcbiAgICAgKi9cbiAgICBtZXNzYWdlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IobmFtZTogT3BlblZpZHVFcnJvck5hbWUsIG1lc3NhZ2U6IHN0cmluZykge1xuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5leHBvcnQgZW51bSBUeXBlT2ZWaWRlbyB7XG4gICAgQ0FNRVJBID0gJ0NBTUVSQScsXG4gICAgU0NSRUVOID0gJ1NDUkVFTicsXG4gICAgQ1VTVE9NID0gJ0NVU1RPTScsXG4gICAgSVBDQU0gPSAnSVBDQU0nXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLyoqXG4gKiBIb3cgdGhlIHZpZGVvIHdpbGwgYmUgaW5zZXJ0ZWQgaW4gdGhlIERPTSBmb3IgUHVibGlzaGVycyBhbmQgU3Vic2NyaWJlcnMuIFNlZSB7QGxpbmsgUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlfSBhbmQge0BsaW5rIFN1YnNjcmliZXJQcm9wZXJ0aWVzLmluc2VydE1vZGV9XG4gKi9cbmV4cG9ydCBlbnVtIFZpZGVvSW5zZXJ0TW9kZSB7XG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYWZ0ZXIgdGhlIHRhcmdldCBlbGVtZW50IChhcyBuZXh0IHNpYmxpbmcpXG4gICAgICovXG4gICAgQUZURVIgPSAnQUZURVInLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFzIGxhc3QgY2hpbGQgb2YgdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgQVBQRU5EID0gJ0FQUEVORCcsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYmVmb3JlIHRoZSB0YXJnZXQgZWxlbWVudCAoYXMgcHJldmlvdXMgc2libGluZylcbiAgICAgKi9cbiAgICBCRUZPUkUgPSAnQkVGT1JFJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhcyBmaXJzdCBjaGlsZCBvZiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBQUkVQRU5EID0gJ1BSRVBFTkQnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIHJlcGxhY2VzIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgUkVQTEFDRSA9ICdSRVBMQUNFJ1xufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnRSZWFzb24gfSBmcm9tICcuL1R5cGVzL1R5cGVzJztcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnk6XG4gKiAtIHtAbGluayBTZXNzaW9uRXZlbnRNYXAuY29ubmVjdGlvbkNyZWF0ZWR9XG4gKiAtIHtAbGluayBTZXNzaW9uRXZlbnRNYXAuY29ubmVjdGlvbkRlc3Ryb3llZH1cbiAqL1xuZXhwb3J0IGNsYXNzIENvbm5lY3Rpb25FdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBDb25uZWN0aW9uIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBGb3IgYGNvbm5lY3Rpb25EZXN0cm95ZWRgIGV2ZW50OlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHRoZSByZW1vdGUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCI6IHRoZSByZW1vdGUgdXNlciBoYXMgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgb3RoZXIgdXNlciBjYWxsaW5nIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB0aGUgcmVtb3RlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgcmVtb3RlIHVzZXIgbmV0d29yayBjb25uZWN0aW9uIGhhcyBkcm9wcGVkXG4gICAgICogLSBcIm5vZGVDcmFzaGVkXCI6IGEgbm9kZSBoYXMgY3Jhc2hlZCBpbiB0aGUgc2VydmVyIHNpZGVcbiAgICAgKlxuICAgICAqIEZvciBgY29ubmVjdGlvbkNyZWF0ZWRgIGV2ZW50IGFuIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbjogQ29ubmVjdGlvbkV2ZW50UmVhc29uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBjb25uZWN0aW9uOiBDb25uZWN0aW9uLCByZWFzb246IENvbm5lY3Rpb25FdmVudFJlYXNvbikge1xuICAgICAgICBzdXBlcihjYW5jZWxhYmxlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5cbi8qKlxuICogKipUaGlzIGZlYXR1cmUgaXMgcGFydCBvZiBPcGVuVmlkdVxuICogPGEgaHJlZj1cImh0dHBzOi8vZG9jcy5vcGVudmlkdS5pby9lbi9zdGFibGUvb3BlbnZpZHUtcHJvL1wiIHN0eWxlPVwiZGlzcGxheTogaW5saW5lLWJsb2NrOyBiYWNrZ3JvdW5kLWNvbG9yOiByZ2IoMCwgMTM2LCAxNzApOyBjb2xvcjogd2hpdGU7IGZvbnQtd2VpZ2h0OiBib2xkOyBwYWRkaW5nOiAwcHggNXB4OyBtYXJnaW46IDAgMnB4IDAgMnB4OyBib3JkZXItcmFkaXVzOiAzcHg7IGZvbnQtc2l6ZTogMTNweDsgbGluZS1oZWlnaHQ6MjFweDsgdGV4dC1kZWNvcmF0aW9uOiBub25lOyBmb250LWZhbWlseTogTW9udHNlcnJhdCwgc2Fucy1zZXJpZlwiPlBSTzwvYT5cbiAqIGFuZFxuICogPGEgaHJlZj1cImh0dHBzOi8vZG9jcy5vcGVudmlkdS5pby9lbi9zdGFibGUvb3BlbnZpZHUtZW50ZXJwcmlzZS9cIiBzdHlsZT1cImRpc3BsYXk6IGlubGluZS1ibG9jazsgYmFja2dyb3VuZC1jb2xvcjogcmdiKDE1NiwgMzksIDE3Nik7IGNvbG9yOiB3aGl0ZTsgZm9udC13ZWlnaHQ6IGJvbGQ7IHBhZGRpbmc6IDBweCA1cHg7IG1hcmdpbjogMCAycHggMCAycHg7IGJvcmRlci1yYWRpdXM6IDNweDsgZm9udC1zaXplOiAxM3B4OyBsaW5lLWhlaWdodDoyMXB4OyB0ZXh0LWRlY29yYXRpb246IG5vbmU7IGZvbnQtZmFtaWx5OiBNb250c2VycmF0LCBzYW5zLXNlcmlmXCI+RU5URVJQUklTRTwvYT5cbiAqIGVkaXRpb25zKipcbiAqXG4gKiBUcmlnZ2VyZWQgYnkge0BsaW5rIFNlc3Npb25FdmVudE1hcC5jb25uZWN0aW9uUHJvcGVydHlDaGFuZ2VkfVxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIHdob3NlIHByb3BlcnR5IGhhcyBjaGFuZ2VkXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwcm9wZXJ0eSBvZiB0aGUgc3RyZWFtIHRoYXQgY2hhbmdlZC4gVGhpcyB2YWx1ZSBpcyBlaXRoZXIgYFwicm9sZVwiYCBvciBgXCJyZWNvcmRcImBcbiAgICAgKi9cbiAgICBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIE5ldyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGFmdGVyIGNoYW5nZSwgY3VycmVudCB2YWx1ZSlcbiAgICAgKi9cbiAgICBuZXdWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogUHJldmlvdXMgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChiZWZvcmUgY2hhbmdlKVxuICAgICAqL1xuICAgIG9sZFZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCBjb25uZWN0aW9uOiBDb25uZWN0aW9uLCBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZywgbmV3VmFsdWU6IE9iamVjdCwgb2xkVmFsdWU6IE9iamVjdCkge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCAnY29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZCcpO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgICAgICB0aGlzLmNoYW5nZWRQcm9wZXJ0eSA9IGNoYW5nZWRQcm9wZXJ0eTtcbiAgICAgICAgdGhpcy5uZXdWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB0aGlzLm9sZFZhbHVlID0gb2xkVmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7fVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgZXZlbnQgaGFzIGEgZGVmYXVsdCBiZWhhdmlvciB0aGF0IG1heSBiZSBwcmV2ZW50ZWQgYnkgY2FsbGluZyB7QGxpbmsgRXZlbnQucHJldmVudERlZmF1bHR9XG4gICAgICovXG4gICAgY2FuY2VsYWJsZTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBvYmplY3QgdGhhdCBkaXNwYXRjaGVkIHRoZSBldmVudFxuICAgICAqL1xuICAgIHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIgfCBGaWx0ZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBldmVudC4gVGhpcyBpcyB0aGUgc2FtZSBzdHJpbmcgeW91IHBhc3MgYXMgZmlyc3QgcGFyYW1ldGVyIHdoZW4gY2FsbGluZyBtZXRob2QgYG9uKClgIG9mIGFueSBvYmplY3QgaW1wbGVtZW50aW5nIHtAbGluayBFdmVudERpc3BhdGNoZXJ9IGludGVyZmFjZVxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXNCZWVuUHJldmVudGVkID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlciwgdHlwZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsYWJsZSA9IGNhbmNlbGFibGU7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGRlZmF1bHQgYmVhaGl2b3VyIG9mIHRoZSBldmVudCBoYXMgYmVlbiBwcmV2ZW50ZWQgb3Igbm90LiBDYWxsIHtAbGluayBFdmVudC5wcmV2ZW50RGVmYXVsdH0gdG8gcHJldmVudCBpdFxuICAgICAqL1xuICAgIGlzRGVmYXVsdFByZXZlbnRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzQmVlblByZXZlbnRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmV2ZW50cyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgZXZlbnQuIFRoZSBmb2xsb3dpbmcgZXZlbnRzIGhhdmUgYSBkZWZhdWx0IGJlaGF2aW9yOlxuICAgICAqXG4gICAgICogLSBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGA6IGRpc3BhdGNoZWQgYnkge0BsaW5rIFNlc3Npb259IG9iamVjdCwgYXV0b21hdGljYWxseSB1bnN1YnNjcmliZXMgdGhlIGxlYXZpbmcgcGFydGljaXBhbnQgZnJvbSBldmVyeSBTdWJzY3JpYmVyIG9iamVjdCBvZiB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBSVENQZWVyQ29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBlYWNoIFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIHtAbGluayBTZXNzaW9uLnN1YnNjcmliZX0gb3JcbiAgICAgKiBieSBjYWxsaW5nIHtAbGluayBTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudH0pLiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgZWFjaCBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIC0gYHN0cmVhbURlc3Ryb3llZGA6XG4gICAgICogICAtIElmIGRpc3BhdGNoZWQgYnkgYSB7QGxpbmsgUHVibGlzaGVyfSAoKnlvdSogaGF2ZSB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgc3RvcHMgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGBcbiAgICAgKiBpbiBtZXRob2Qge0BsaW5rIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJ9IG9yIGJ5IGNhbGxpbmcge0BsaW5rIFB1Ymxpc2hlci5jcmVhdGVWaWRlb0VsZW1lbnR9KS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IHtAbGluayBTZXNzaW9ufSAoKm90aGVyIHVzZXIqIGhhcyB1bnB1Ymxpc2hlZCk6IGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmVzIHRoZSBwcm9wZXIgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBSVENQZWVyQ29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGF0IFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyLCBlaXRoZXIgYnkgcGFzc2luZyBhIHZhbGlkIHBhcmFtZXRlciBhcyBgdGFyZ2V0RWxlbWVudGAgaW4gbWV0aG9kIHtAbGluayBTZXNzaW9uLnN1YnNjcmliZX0gb3JcbiAgICAgKiBieSBjYWxsaW5nIHtAbGluayBTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudH0pLiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqL1xuICAgIHByZXZlbnREZWZhdWx0KCkge1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICAgICAgdGhpcy5jYWxsRGVmYXVsdEJlaGF2aW9yID0gKCkgPT4ge307XG4gICAgICAgIHRoaXMuaGFzQmVlblByZXZlbnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFic3RyYWN0IGNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N1YnNjcmliZXInO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcblxuLyoqXG4gKiBEZWZpbmVzIHByb3BlcnR5IHtAbGluayBFeGNlcHRpb25FdmVudC5uYW1lfVxuICovXG5leHBvcnQgZW51bSBFeGNlcHRpb25FdmVudE5hbWUge1xuICAgIC8qKlxuICAgICAqIFRoZXJlIHdhcyBhbiB1bmV4cGVjdGVkIGVycm9yIG9uIHRoZSBzZXJ2ZXItc2lkZSBwcm9jZXNzaW5nIGFuIElDRSBjYW5kaWRhdGUgZ2VuZXJhdGVkIGFuZCBzZW50IGJ5IHRoZSBjbGllbnQtc2lkZS5cbiAgICAgKlxuICAgICAqIHtAbGluayBFeGNlcHRpb25FdmVudH0gb2JqZWN0cyB3aXRoIHRoaXMge0BsaW5rIEV4Y2VwdGlvbkV2ZW50Lm5hbWV9IHdpbGwgaGF2ZSBhcyB7QGxpbmsgRXhjZXB0aW9uRXZlbnQub3JpZ2lufSBwcm9wZXJ0eSBhIHtAbGluayBTZXNzaW9ufSBvYmplY3QuXG4gICAgICovXG4gICAgSUNFX0NBTkRJREFURV9FUlJPUiA9ICdJQ0VfQ0FORElEQVRFX0VSUk9SJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSBbSUNFIGNvbm5lY3Rpb24gc3RhdGVdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9SVENQZWVyQ29ubmVjdGlvbi9pY2VDb25uZWN0aW9uU3RhdGUpXG4gICAgICogb2YgYW4gW1JUQ1BlZXJDb25uZWN0aW9uXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUlRDUGVlckNvbm5lY3Rpb24pIHJlYWNoZWQgYGZhaWxlZGAgc3RhdHVzLlxuICAgICAqXG4gICAgICogVGhpcyBpcyBhIHRlcm1pbmFsIGVycm9yIHRoYXQgd29uJ3QgaGF2ZSBhbnkga2luZCBvZiBwb3NzaWJsZSByZWNvdmVyeS4gSWYgdGhlIGNsaWVudCBpcyBzdGlsbCBjb25uZWN0ZWQgdG8gT3BlblZpZHUgU2VydmVyLFxuICAgICAqIHRoZW4gYW4gYXV0b21hdGljIHJlY29ubmVjdGlvbiBwcm9jZXNzIG9mIHRoZSBtZWRpYSBzdHJlYW0gaXMgaW1tZWRpYXRlbHkgcGVyZm9ybWVkLiBJZiB0aGUgSUNFIGNvbm5lY3Rpb24gaGFzIGJyb2tlbiBkdWUgdG9cbiAgICAgKiBhIHRvdGFsIG5ldHdvcmsgZHJvcCwgdGhlbiBubyBhdXRvbWF0aWMgcmVjb25uZWN0aW9uIHByb2Nlc3Mgd2lsbCBiZSBwb3NzaWJsZS5cbiAgICAgKlxuICAgICAqIHtAbGluayBFeGNlcHRpb25FdmVudH0gb2JqZWN0cyB3aXRoIHRoaXMge0BsaW5rIEV4Y2VwdGlvbkV2ZW50Lm5hbWV9IHdpbGwgaGF2ZSBhcyB7QGxpbmsgRXhjZXB0aW9uRXZlbnQub3JpZ2lufSBwcm9wZXJ0eSBhIHtAbGluayBTdHJlYW19IG9iamVjdC5cbiAgICAgKi9cbiAgICBJQ0VfQ09OTkVDVElPTl9GQUlMRUQgPSAnSUNFX0NPTk5FQ1RJT05fRkFJTEVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSBbSUNFIGNvbm5lY3Rpb24gc3RhdGVdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9SVENQZWVyQ29ubmVjdGlvbi9pY2VDb25uZWN0aW9uU3RhdGUpXG4gICAgICogb2YgYW4gW1JUQ1BlZXJDb25uZWN0aW9uXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUlRDUGVlckNvbm5lY3Rpb24pIHJlYWNoZWQgYGRpc2Nvbm5lY3RlZGAgc3RhdHVzLlxuICAgICAqXG4gICAgICogVGhpcyBpcyBub3QgYSB0ZXJtaW5hbCBlcnJvciwgYW5kIGl0IGlzIHBvc3NpYmxlIGZvciB0aGUgSUNFIGNvbm5lY3Rpb24gdG8gYmUgcmVjb25uZWN0ZWQuIElmIHRoZSBjbGllbnQgaXMgc3RpbGwgY29ubmVjdGVkIHRvXG4gICAgICogT3BlblZpZHUgU2VydmVyIGFuZCBhZnRlciBjZXJ0YWluIHRpbWVvdXQgdGhlIElDRSBjb25uZWN0aW9uIGhhcyBub3QgcmVhY2hlZCBhIHN1Y2Nlc3Mgb3IgdGVybWluYWwgc3RhdHVzLCB0aGVuIGFuIGF1dG9tYXRpY1xuICAgICAqIHJlY29ubmVjdGlvbiBwcm9jZXNzIG9mIHRoZSBtZWRpYSBzdHJlYW0gaXMgcGVyZm9ybWVkLiBJZiB0aGUgSUNFIGNvbm5lY3Rpb24gaGFzIGJyb2tlbiBkdWUgdG8gYSB0b3RhbCBuZXR3b3JrIGRyb3AsIHRoZW4gbm9cbiAgICAgKiBhdXRvbWF0aWMgcmVjb25uZWN0aW9uIHByb2Nlc3Mgd2lsbCBiZSBwb3NzaWJsZS5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4gY3VzdG9taXplIHRoZSB0aW1lb3V0IGZvciB0aGUgcmVjb25uZWN0aW9uIGF0dGVtcHQgd2l0aCBwcm9wZXJ0eSB7QGxpbmsgT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24uaWNlQ29ubmVjdGlvbkRpc2Nvbm5lY3RlZEV4Y2VwdGlvblRpbWVvdXR9LFxuICAgICAqIHdoaWNoIGJ5IGRlZmF1bHQgaXMgNDAwMCBtaWxsaXNlY29uZHMuXG4gICAgICpcbiAgICAgKiB7QGxpbmsgRXhjZXB0aW9uRXZlbnR9IG9iamVjdHMgd2l0aCB0aGlzIHtAbGluayBFeGNlcHRpb25FdmVudC5uYW1lfSB3aWxsIGhhdmUgYXMge0BsaW5rIEV4Y2VwdGlvbkV2ZW50Lm9yaWdpbn0gcHJvcGVydHkgYSB7QGxpbmsgU3RyZWFtfSBvYmplY3QuXG4gICAgICovXG4gICAgSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVEID0gJ0lDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRCcsXG5cbiAgICAvKipcbiAgICAgKiBBIHtAbGluayBTdWJzY3JpYmVyfSBvYmplY3QgaGFzIG5vdCBmaXJlZCBldmVudCBgc3RyZWFtUGxheWluZ2AgYWZ0ZXIgY2VydGFpbiB0aW1lb3V0LiBgc3RyZWFtUGxheWluZ2AgZXZlbnQgYmVsb25ncyB0byB7QGxpbmsgU3RyZWFtTWFuYWdlckV2ZW50fVxuICAgICAqIGNhdGVnb3J5LiBJdCB3cmFwcyBXZWIgQVBJIG5hdGl2ZSBldmVudCBbY2FucGxheV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hUTUxNZWRpYUVsZW1lbnQvY2FucGxheV9ldmVudCkuXG4gICAgICpcbiAgICAgKiBPcGVuVmlkdSBCcm93c2VyIGNhbiB0YWtlIGNhcmUgb2YgdGhlIHZpZGVvIHBsYXllcnMgKHNlZSBbaGVyZV0oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKSxcbiAgICAgKiBvciB5b3UgY2FuIHRha2UgY2FyZSBvZiB2aWRlbyBwbGF5ZXJzIG9uIHlvdXIgb3duIChzZWUgW2hlcmVdKC9lbi9zdGFibGUvY2hlYXRzaGVldC9tYW5hZ2UtdmlkZW9zLyN5b3UtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRWl0aGVyIHdheSwgd2hlbmV2ZXIgYSB7QGxpbmsgU3Vic2NyaWJlcn0gb2JqZWN0IGlzIGNvbW1hbmRlZCB0byBhdHRhY2ggaXRzIHtAbGluayBTdHJlYW19IHRvIGEgdmlkZW8gZWxlbWVudCwgaXQgaXMgc3VwcG9zZWQgdG8gZmlyZSBgc3RyZWFtUGxheWluZ2BcbiAgICAgKiBldmVudCBzaG9ydGx5IGFmdGVyLiBJZiBpdCBkb2VzIG5vdCwgdGhlbiB3ZSBjYW4gc2FmZWx5IGFzc3VtZSB0aGF0IHNvbWV0aGluZyB3cm9uZyBoYXMgaGFwcGVuZWQgd2hpbGUgcGxheWluZyB0aGUgcmVtb3RlIHZpZGVvIGFuZCB0aGVcbiAgICAgKiBhcHBsaWNhdGlvbiBtYXkgYmUgbm90aWZpZWQgdGhyb3VnaCB0aGlzIHNwZWNpZmljIEV4Y2VwdGlvbkV2ZW50LlxuICAgICAqXG4gICAgICogVGhlIHRpbWVvdXQgY2FuIGJlIGNvbmZpZ3VyZWQgd2l0aCBwcm9wZXJ0eSB7QGxpbmsgT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24ubm9TdHJlYW1QbGF5aW5nRXZlbnRFeGNlcHRpb25UaW1lb3V0fS4gQnkgZGVmYXVsdCBpdCBpcyA0MDAwIG1pbGxpc2Vjb25kcy5cbiAgICAgKlxuICAgICAqIFRoaXMgaXMganVzdCBhbiBpbmZvcm1hdGl2ZSBleGNlcHRpb24uIEl0IG9ubHkgbWVhbnMgdGhhdCBhIHJlbW90ZSBTdHJlYW0gdGhhdCBpcyBzdXBwb3NlZCB0byBiZSBwbGF5aW5nIGJ5IGEgdmlkZW8gcGxheWVyIGhhcyBub3QgZG9uZSBzb1xuICAgICAqIGluIGEgcmVhc29uYWJsZSB0aW1lLiBCdXQgdGhlIGxhY2sgb2YgdGhlIGV2ZW50IGNhbiBiZSBjYXVzZWQgYnkgbXVsdGlwbGUgcmVhc29ucy4gSWYgYSBTdWJzY3JpYmVyIGlzIG5vdCBwbGF5aW5nIGl0cyBTdHJlYW0sIHRoZSBvcmlnaW5cbiAgICAgKiBvZiB0aGUgcHJvYmxlbSBjb3VsZCBiZSBsb2NhdGVkIGF0IHRoZSBQdWJsaXNoZXIgc2lkZS4gT3IgbWF5IGJlIGNhdXNlZCBieSBhIHRyYW5zaWVudCBuZXR3b3JrIHByb2JsZW0uIEJ1dCBpdCBhbHNvIGNvdWxkIGJlIGEgcHJvYmxlbSB3aXRoXG4gICAgICogYXV0b3BsYXkgcGVybWlzc2lvbnMuIEJvdHRvbSBsaW5lLCB0aGUgY2F1c2UgY2FuIGJlIHZlcnkgdmFyaWVkLCBhbmQgZGVwZW5kaW5nIG9uIHRoZSBhcHBsaWNhdGlvbiB0aGUgbGFjayBvZiB0aGUgZXZlbnQgY291bGQgZXZlbiBiZSBleHBlY3RlZC5cbiAgICAgKlxuICAgICAqIHtAbGluayBFeGNlcHRpb25FdmVudH0gb2JqZWN0cyB3aXRoIHRoaXMge0BsaW5rIEV4Y2VwdGlvbkV2ZW50Lm5hbWV9IHdpbGwgaGF2ZSBhcyB7QGxpbmsgRXhjZXB0aW9uRXZlbnQub3JpZ2lufSBwcm9wZXJ0eSBhIHtAbGluayBTdWJzY3JpYmVyfSBvYmplY3QuXG4gICAgICovXG4gICAgTk9fU1RSRUFNX1BMQVlJTkdfRVZFTlQgPSAnTk9fU1RSRUFNX1BMQVlJTkdfRVZFTlQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlcmUgaGFzIGJlZW4gYSBzZXJ2ZXItc2lkZSBkaXNjb25uZWN0aW9uIG9mIHRoZSBTcGVlY2ggVG8gVGV4dCBtb2R1bGUuIEZyb20gdGhlIG1vbWVudCB0aGlzIGV4Y2VwdGlvbiBpcyBmaXJlZCB0byB0aGUgbW9tZW50IG1ldGhvZFxuICAgICAqIHtAbGluayBTZXNzaW9uLnN1YnNjcmliZVRvU3BlZWNoVG9UZXh0fSBpcyBjYWxsZWQgYWdhaW4sIHRoZSB0cmFuc2NyaXB0aW9uIG9mIHRoZSBhdWRpbyBzdHJlYW0gd2lsbCBub3QgYmUgYXZhaWxhYmxlIGFuZCBubyB7QGxpbmsgU3BlZWNoVG9UZXh0RXZlbnR9XG4gICAgICogd2lsbCBiZSBmaXJlZC5cbiAgICAgKlxuICAgICAqIHtAbGluayBFeGNlcHRpb25FdmVudH0gb2JqZWN0cyB3aXRoIHRoaXMge0BsaW5rIEV4Y2VwdGlvbkV2ZW50Lm5hbWV9IHdpbGwgaGF2ZSBhcyB7QGxpbmsgRXhjZXB0aW9uRXZlbnQub3JpZ2lufSBwcm9wZXJ0eSBhIHtAbGluayBTZXNzaW9ufSBvYmplY3QuXG4gICAgICovXG4gICAgU1BFRUNIX1RPX1RFWFRfRElTQ09OTkVDVEVEID0gJ1NQRUVDSF9UT19URVhUX0RJU0NPTk5FQ1RFRCcsXG59XG5cbi8qKlxuICogVHJpZ2dlcmVkIGJ5IHtAbGluayBTZXNzaW9uRXZlbnRNYXAuZXhjZXB0aW9ufVxuICovXG5leHBvcnQgY2xhc3MgRXhjZXB0aW9uRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogTmFtZSBvZiB0aGUgZXhjZXB0aW9uXG4gICAgICovXG4gICAgbmFtZTogRXhjZXB0aW9uRXZlbnROYW1lO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGFmZmVjdGVkIGJ5IHRoZSBleGNlcHRpb24uIERlcGVuZGluZyBvbiB0aGUge0BsaW5rIEV4Y2VwdGlvbkV2ZW50Lm5hbWV9IHByb3BlcnR5OlxuICAgICAqIC0ge0BsaW5rIFNlc3Npb259OiBgSUNFX0NBTkRJREFURV9FUlJPUmBcbiAgICAgKiAtIHtAbGluayBTdHJlYW19OiBgSUNFX0NPTk5FQ1RJT05fRkFJTEVEYCwgYElDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRGBcbiAgICAgKiAtIHtAbGluayBTdWJzY3JpYmVyfTogYE5PX1NUUkVBTV9QTEFZSU5HX0VWRU5UYFxuICAgICAqL1xuICAgIG9yaWdpbjogU2Vzc2lvbiB8IFN0cmVhbSB8IFN1YnNjcmliZXI7XG5cbiAgICAvKipcbiAgICAgKiBJbmZvcm1hdGl2ZSBkZXNjcmlwdGlvbiBvZiB0aGUgZXhjZXB0aW9uXG4gICAgICovXG4gICAgbWVzc2FnZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQW55IGV4dHJhIGluZm9ybWF0aW9uIGFzc29jaWF0ZWQgdG8gdGhlIGV4Y2VwdGlvblxuICAgICAqL1xuICAgIGRhdGE/OiBhbnk7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Ioc2Vzc2lvbjogU2Vzc2lvbiwgbmFtZTogRXhjZXB0aW9uRXZlbnROYW1lLCBvcmlnaW46IFNlc3Npb24gfCBTdHJlYW0gfCBTdWJzY3JpYmVyLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiBhbnkpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHNlc3Npb24sICdleGNlcHRpb24nKTtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5vcmlnaW4gPSBvcmlnaW47XG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvRmlsdGVyJztcblxuLyoqXG4gKiBEZWZpbmVzIGV2ZXJ5IGV2ZW50IGRpc3BhdGNoZWQgYnkgYXVkaW8vdmlkZW8gc3RyZWFtIGZpbHRlcnMuIFlvdSBjYW4gc3Vic2NyaWJlIHRvIGZpbHRlciBldmVudHMgYnkgY2FsbGluZyB7QGxpbmsgRmlsdGVyLmFkZEV2ZW50TGlzdGVuZXJ9XG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXJFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBEYXRhIG9mIHRoZSBldmVudFxuICAgICAqL1xuICAgIGRhdGE6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IEZpbHRlciwgZXZlbnRUeXBlOiBzdHJpbmcsIGRhdGE6IE9iamVjdCkge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCBldmVudFR5cGUpO1xuICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge31cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuXG4vKipcbiAqIFRyaWdnZXJlZCBieSB7QGxpbmsgU2Vzc2lvbkV2ZW50TWFwLm5ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkfVxuICovXG5leHBvcnQgY2xhc3MgTmV0d29ya1F1YWxpdHlMZXZlbENoYW5nZWRFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBOZXcgdmFsdWUgb2YgdGhlIG5ldHdvcmsgcXVhbGl0eSBsZXZlbFxuICAgICAqL1xuICAgIG5ld1ZhbHVlOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBPbGQgdmFsdWUgb2YgdGhlIG5ldHdvcmsgcXVhbGl0eSBsZXZlbFxuICAgICAqL1xuICAgIG9sZFZhbHVlOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBDb25uZWN0aW9uIGZvciB3aG9tIHRoZSBuZXR3b3JrIHF1YWxpdHkgbGV2ZWwgY2hhbmdlZFxuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCBuZXdWYWx1ZTogbnVtYmVyLCBvbGRWYWx1ZTogbnVtYmVyLCBjb25uZWN0aW9uOiBDb25uZWN0aW9uKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsICduZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZCcpO1xuICAgICAgICB0aGlzLm5ld1ZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgIHRoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHt9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnk6XG4gKiAtIGBwdWJsaXNoZXJTdGFydFNwZWFraW5nYCAoYXZhaWxhYmxlIGZvciBbU2Vzc2lvbl0oL2VuL3N0YWJsZS9hcGkvb3BlbnZpZHUtYnJvd3Nlci9pbnRlcmZhY2VzL1Nlc3Npb25FdmVudE1hcC5odG1sI3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcpIGFuZCBbU3RyZWFtTWFuYWdlcl0oL2VuL3N0YWJsZS9hcGkvb3BlbnZpZHUtYnJvd3Nlci9pbnRlcmZhY2VzL1N0cmVhbU1hbmFnZXJFdmVudE1hcC5odG1sI3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcpIG9iamVjdHMpXG4gKiAtIGBwdWJsaXNoZXJTdG9wU3BlYWtpbmdgIChhdmFpbGFibGUgZm9yIFtTZXNzaW9uXSgvZW4vc3RhYmxlL2FwaS9vcGVudmlkdS1icm93c2VyL2ludGVyZmFjZXMvU2Vzc2lvbkV2ZW50TWFwLmh0bWwjcHVibGlzaGVyU3RvcFNwZWFraW5nKSBhbmQgW1N0cmVhbU1hbmFnZXJdKC9lbi9zdGFibGUvYXBpL29wZW52aWR1LWJyb3dzZXIvaW50ZXJmYWNlcy9TdHJlYW1NYW5hZ2VyRXZlbnRNYXAuaHRtbCNwdWJsaXNoZXJTdG9wU3BlYWtpbmcpIG9iamVjdHMpXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzdGFydGVkIG9yIHN0b3BwZWQgc3BlYWtpbmdcbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHN0cmVhbUlkIG9mIHRoZSBTdHJlYW0gYWZmZWN0ZWQgYnkgdGhlIHNwZWFraW5nIGV2ZW50XG4gICAgICovXG4gICAgc3RyZWFtSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHN0cmVhbUlkOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMuc3RyZWFtSWQgPSBzdHJlYW1JZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHt9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFJlY29yZGluZ0V2ZW50UmVhc29uIH0gZnJvbSAnLi9UeXBlcy9UeXBlcyc7XG5cbi8qKlxuICogVHJpZ2dlcmVkIGJ5OlxuICogLSB7QGxpbmsgU2Vzc2lvbkV2ZW50TWFwLnJlY29yZGluZ1N0YXJ0ZWR9XG4gKiAtIHtAbGluayBTZXNzaW9uRXZlbnRNYXAucmVjb3JkaW5nU3RvcHBlZH1cbiAqL1xuZXhwb3J0IGNsYXNzIFJlY29yZGluZ0V2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIFRoZSByZWNvcmRpbmcgSUQgZ2VuZXJhdGVkIGluIG9wZW52aWR1LXNlcnZlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIG5hbWUgeW91IHN1cHBsaWVkIHRvIG9wZW52aWR1LXNlcnZlci4gRm9yIGV4YW1wbGUsIHRvIG5hbWUgeW91ciByZWNvcmRpbmcgZmlsZSBNWV9SRUNPUkRJTkc6XG4gICAgICogLSBXaXRoICoqQVBJIFJFU1QqKjogUE9TVCB0byBgL2FwaS9yZWNvcmRpbmdzL3N0YXJ0YCBwYXNzaW5nIEpTT04gYm9keSBge1wic2Vzc2lvblwiOlwic2Vzc2lvbklkXCIsXCJuYW1lXCI6XCJNWV9SRUNPUkRJTkdcIn1gXG4gICAgICogLSBXaXRoICoqb3BlbnZpZHUtamF2YS1jbGllbnQqKjogYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwgXCJNWV9SRUNPUkRJTkdcIilgIG9yIGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIG5ldyBSZWNvcmRpbmdQcm9wZXJ0aWVzLkJ1aWxkZXIoKS5uYW1lKFwiTVlfUkVDT1JESU5HXCIpLmJ1aWxkKCkpYFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LW5vZGUtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCB7bmFtZTogXCJNWV9SRUNPUkRJTkdcIn0pYFxuICAgICAqXG4gICAgICogSWYgbm8gbmFtZSBpcyBzdXBwbGllZCwgdGhpcyBwcm9wZXJ0eSB3aWxsIGJlIHVuZGVmaW5lZCBhbmQgdGhlIHJlY29yZGVkIGZpbGUgd2lsbCBiZSBuYW1lZCBhZnRlciBwcm9wZXJ0eSB7QGxpbmsgaWR9XG4gICAgICovXG4gICAgbmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RvcHBlZCcgZXZlbnQ6XG4gICAgICogLSBcInJlY29yZGluZ1N0b3BwZWRCeVNlcnZlclwiOiB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIGdyYWNlZnVsbHkgc3RvcHBlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiYXV0b21hdGljU3RvcFwiOiBzZWUgW0F1dG9tYXRpYyBzdG9wIG9mIHJlY29yZGluZ3NdKC9lbi9zdGFibGUvYWR2YW5jZWQtZmVhdHVyZXMvcmVjb3JkaW5nLyNhdXRvbWF0aWMtc3RvcC1vZi1yZWNvcmRpbmdzKVxuICAgICAqIC0gXCJub2RlQ3Jhc2hlZFwiOiBhIG5vZGUgaGFzIGNyYXNoZWQgaW4gdGhlIHNlcnZlciBzaWRlXG4gICAgICpcbiAgICAgKiBGb3IgJ3JlY29yZGluZ1N0YXJ0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbj86IFJlY29yZGluZ0V2ZW50UmVhc29uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIHJlYXNvbj86IFJlY29yZGluZ0V2ZW50UmVhc29uKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIGlmIChuYW1lICE9PSBpZCkge1xuICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnRSZWFzb24gfSBmcm9tICcuL1R5cGVzL1R5cGVzJztcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqIFRyaWdnZXJlZCBieSB7QGxpbmsgU2Vzc2lvbkV2ZW50TWFwLnNlc3Npb25EaXNjb25uZWN0ZWR9XG4gKi9cbmV4cG9ydCBjbGFzcyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogLSBcImRpc2Nvbm5lY3RcIjogeW91IGhhdmUgY2FsbGVkIGBTZXNzaW9uLmRpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCI6IHlvdSBoYXZlIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IG90aGVyIHVzZXIgY2FsbGluZyBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWBcbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogeW91IGhhdmUgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcInNlc3Npb25DbG9zZWRCeVNlcnZlclwiOiB0aGUgU2Vzc2lvbiBoYXMgYmVlbiBjbG9zZWQgYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcIm5ldHdvcmtEaXNjb25uZWN0XCI6IHlvdXIgbmV0d29yayBjb25uZWN0aW9uIGhhcyBkcm9wcGVkLiBCZWZvcmUgYSBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgd2l0aCB0aGlzIHJlYXNvbiBpcyB0cmlnZ2VyZWQsXG4gICAgICogICAgICBTZXNzaW9uIG9iamVjdCB3aWxsIGFsd2F5cyBoYXZlIHByZXZpb3VzbHkgZGlzcGF0Y2hlZCBhIGByZWNvbm5lY3RpbmdgIGV2ZW50LiBJZiB0aGUgcmVjb25uZWN0aW9uIHByb2Nlc3Mgc3VjY2VlZHMsXG4gICAgICogICAgICBTZXNzaW9uIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHJlY29ubmVjdGVkYCBldmVudC4gSWYgaXQgZmFpbHMsIFNlc3Npb24gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnRcbiAgICAgKiAgICAgIHdpdGggcmVhc29uIFwibmV0d29ya0Rpc2Nvbm5lY3RcIlxuICAgICAqIC0gXCJub2RlQ3Jhc2hlZFwiOiBhIG5vZGUgaGFzIGNyYXNoZWQgaW4gdGhlIHNlcnZlciBzaWRlLiBZb3UgY2FuIHVzZSB0aGlzIHJlYXNvbiB0byBhc2sgeW91ciBhcHBsaWNhdGlvbidzIGJhY2tlbmQgdG8gcmVjb25uZWN0XG4gICAgICogdG8gYSBuZXcgc2Vzc2lvbiB0byByZXBsYWNlIHRoZSBjcmFzaGVkIG9uZVxuICAgICAqL1xuICAgIHJlYXNvbjogQ29ubmVjdGlvbkV2ZW50UmVhc29uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgcmVhc29uOiBDb25uZWN0aW9uRXZlbnRSZWFzb24pIHtcbiAgICAgICAgc3VwZXIodHJ1ZSwgdGFyZ2V0LCAnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcpO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG5cbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IDxTZXNzaW9uPnRoaXMudGFyZ2V0O1xuXG4gICAgICAgIC8vIERpc3Bvc2UgYW5kIGRlbGV0ZSBhbGwgcmVtb3RlIENvbm5lY3Rpb25zXG4gICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMuZm9yRWFjaCgocmVtb3RlQ29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkID0gcmVtb3RlQ29ubmVjdGlvbi5jb25uZWN0aW9uSWQ7XG4gICAgICAgICAgICBpZiAoISFzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zLmdldChjb25uZWN0aW9uSWQpPy5zdHJlYW0pIHtcbiAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zLmdldChjb25uZWN0aW9uSWQpPy5zdHJlYW0hLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9ucy5nZXQoY29ubmVjdGlvbklkKT8uc3RyZWFtIS5kaXNwb3NlTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9ucy5nZXQoY29ubmVjdGlvbklkKT8uc3RyZWFtIS5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMuZ2V0KGNvbm5lY3Rpb25JZCk/LnN0cmVhbSEuc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtSWQgPSBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zLmdldChjb25uZWN0aW9uSWQpPy5zdHJlYW0/LnN0cmVhbUlkO1xuICAgICAgICAgICAgICAgIGlmICghIXN0cmVhbUlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWQuZGVsZXRlKHN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9ucy5nZXQoY29ubmVjdGlvbklkKT8uZGlzcG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9ucy5kZWxldGUoY29ubmVjdGlvbklkKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cbi8qKlxuICogVHJpZ2dlcmVkIGJ5IHtAbGluayBTZXNzaW9uRXZlbnRNYXAuc2lnbmFsfVxuICovXG5leHBvcnQgY2xhc3MgU2lnbmFsRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2Ygc2lnbmFsLiBJdCBpcyBzdHJpbmcgYFwic2lnbmFsXCJgIGZvciB0aG9zZSBzaWduYWxzIHNlbnQgd2l0aCBubyB7QGxpbmsgU2lnbmFsT3B0aW9ucy50eXBlfSBwcm9wZXJ0eSwgYW5kIGBcInNpZ25hbDp0eXBlXCJgIGlmIHdhcyBzZW50IHdpdGggYVxuICAgICAqIHZhbGlkIHtAbGluayBTaWduYWxPcHRpb25zLnR5cGV9IHByb3BlcnR5LlxuICAgICAqXG4gICAgICogVGhlIGNsaWVudCBtdXN0IGJlIHNwZWNpZmljYWxseSBzdWJzY3JpYmVkIHRvIGBTZXNzaW9uLm9uKCdzaWduYWw6dHlwZScsIGZ1bmN0aW9uKHNpZ25hbEV2ZW50KSB7Li4ufSlgIHRvIHRyaWdnZXIgdGhhdCB0eXBlIG9mIHNpZ25hbC5cbiAgICAgKlxuICAgICAqIFN1YnNjcmliaW5nIHRvIGBTZXNzaW9uLm9uKCdzaWduYWwnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB3aWxsIHRyaWdnZXIgYWxsIHNpZ25hbHMsIG5vIG1hdHRlciB0aGVpciB0eXBlLlxuICAgICAqL1xuICAgIHR5cGU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBtZXNzYWdlIG9mIHRoZSBzaWduYWwgKGNhbiBiZSBlbXB0eSlcbiAgICAgKi9cbiAgICBkYXRhPzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0aGF0IHNlbnQgdGhlIHNpZ25hbC4gVGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQgaWYgdGhlIHNpZ25hbFxuICAgICAqIHdhcyBkaXJlY3RseSBnZW5lcmF0ZWQgYnkgdGhlIGFwcGxpY2F0aW9uIHNlcnZlciAobm90IGJ5IG90aGVyIGNsaWVudClcbiAgICAgKi9cbiAgICBmcm9tPzogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHR5cGU/OiBzdHJpbmcsIGRhdGE/OiBzdHJpbmcsIGZyb20/OiBDb25uZWN0aW9uKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsICdzaWduYWwnKTtcbiAgICAgICAgaWYgKCEhdHlwZSkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gJ3NpZ25hbDonICsgdHlwZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgICAgICB0aGlzLmZyb20gPSBmcm9tO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge31cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3BlZWNoVG9UZXh0RXZlbnRSZWFzb24gfSBmcm9tICcuL1R5cGVzL1R5cGVzJztcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnkge0BsaW5rIFNlc3Npb25FdmVudE1hcC5zcGVlY2hUb1RleHRNZXNzYWdlfVxuICovXG5leHBvcnQgY2xhc3MgU3BlZWNoVG9UZXh0RXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUge0BsaW5rIENvbm5lY3Rpb259IG93bmluZyB0aGUgU3RyZWFtIHRoYXQgcHJvZHVjZWQgdGhlIHNwZWVjaC10by10ZXh0IGV2ZW50LlxuICAgICAqIEluIG90aGVyIHdvcmRzLCB0aGlzIGlzIHRoZSBwYXJ0aWNpcGFudCB0aGF0IHNwb2tlIGFuZCBwcm9kdWNlZCB0aGlzIHRyYW5zY3JpcHRpb24gZXZlbnQuXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0ZXh0IG9mIHRoZSBldmVudC4gVGhpcyBpcyB0aGUgdHJhbnNjcmlwdGlvbiBmb3IgdGhpcyBzcGVjaWZpYyBwaWVjZSBvZiBhdWRpbyBzdHJlYW1cbiAgICAgKi9cbiAgICB0ZXh0OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBbGwgc3BlZWNoLXRvLXRleHQgZXZlbnRzIGFyZSBnZW5lcmF0ZWQgXG4gICAgICovXG4gICAgcmVhc29uOiBTcGVlY2hUb1RleHRFdmVudFJlYXNvbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBvcmlnaW5hbCBldmVudCBmcm9tIHRoZSBzcGVlY2ggdG8gdGV4dCBlbmdpbmUuIFRoaXMgY2FuIHZhcnkgZGVwZW5kaW5nIG9uIHRoZSBlbmdpbmVcbiAgICAgKi9cbiAgICByYXc6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFtCQ1AtNDddKGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9iY3A0NykgbGFuZ3VhZ2UgdGFnIChsaWtlIFwiZW4tVVNcIiBvciBcImVzLUVTXCIpIG9mIHRoZSByZWNvZ25pemVkIHRleHQuIFRoaXMgd2lsbCBiZSB0aGUgc2FtZSBhcyB0aGUgbGFuZ3VhZ2UgcHJvdmlkZWRcbiAgICAgKiBpbiBtZXRob2Qge0BsaW5rIFNlc3Npb24uc3Vic2NyaWJlVG9TcGVlY2hUb1RleHR9IG1ldGhvZFxuICAgICAqL1xuICAgIGxhbmc6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHRleHQ6IHN0cmluZywgcmVhc29uOiBTcGVlY2hUb1RleHRFdmVudFJlYXNvbiwgcmF3OiBzdHJpbmcsIGxhbmc6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCAnc3BlZWNoVG9UZXh0TWVzc2FnZScpO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgICAgICB0aGlzLnRleHQgPSB0ZXh0O1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICAgICAgdGhpcy5yYXcgPSByYXc7XG4gICAgICAgIHRoaXMubGFuZyA9IGxhbmc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvUHVibGlzaGVyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbSc7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5pbXBvcnQgeyBTdHJlYW1FdmVudFJlYXNvbiB9IGZyb20gJy4vVHlwZXMvVHlwZXMnO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuY29uc3QgbG9nZ2VyOiBPcGVuVmlkdUxvZ2dlciA9IE9wZW5WaWR1TG9nZ2VyLmdldEluc3RhbmNlKCk7XG5cbi8qKlxuICogVHJpZ2dlcmVkIGJ5OlxuICogLSBgc3RyZWFtQ3JlYXRlZGAgKGF2YWlsYWJsZSBmb3IgW1Nlc3Npb25dKC9lbi9zdGFibGUvYXBpL29wZW52aWR1LWJyb3dzZXIvaW50ZXJmYWNlcy9TZXNzaW9uRXZlbnRNYXAuaHRtbCNzdHJlYW1DcmVhdGVkKSBhbmQgW1B1Ymxpc2hlcl0oL2VuL3N0YWJsZS9hcGkvb3BlbnZpZHUtYnJvd3Nlci9pbnRlcmZhY2VzL1B1Ymxpc2hlckV2ZW50TWFwLmh0bWwjc3RyZWFtQ3JlYXRlZCkgb2JqZWN0cylcbiAqIC0gYHN0cmVhbURlc3Ryb3llZGAgKGF2YWlsYWJsZSBmb3IgW1Nlc3Npb25dKC9lbi9zdGFibGUvYXBpL29wZW52aWR1LWJyb3dzZXIvaW50ZXJmYWNlcy9TZXNzaW9uRXZlbnRNYXAuaHRtbCNzdHJlYW1EZXN0cm95ZWQpIGFuZCBbUHVibGlzaGVyXSgvZW4vc3RhYmxlL2FwaS9vcGVudmlkdS1icm93c2VyL2ludGVyZmFjZXMvUHVibGlzaGVyRXZlbnRNYXAuaHRtbCNzdHJlYW1EZXN0cm95ZWQpIG9iamVjdHMpXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1FdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBTdHJlYW0gb2JqZWN0IHRoYXQgd2FzIGNyZWF0ZWQgb3IgZGVzdHJveWVkXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBGb3IgJ3N0cmVhbURlc3Ryb3llZCcgZXZlbnQ6XG4gICAgICogLSBcInVucHVibGlzaFwiOiBtZXRob2QgYFNlc3Npb24udW5wdWJsaXNoKClgIGhhcyBiZWVuIGNhbGxlZFxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IG1ldGhvZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgIGhhcyBiZWVuIGNhbGxlZFxuICAgICAqIC0gXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiOiBzb21lIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5mb3JjZVVucHVibGlzaCgpYCBvdmVyIHRoZSBTdHJlYW1cbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCI6IHNvbWUgdXNlciBoYXMgY2FsbGVkIGBTZXNzaW9uLmZvcmNlRGlzY29ubmVjdCgpYCBvdmVyIHRoZSBTdHJlYW1cbiAgICAgKiAtIFwiZm9yY2VVbnB1Ymxpc2hCeVNlcnZlclwiOiB0aGUgdXNlcidzIHN0cmVhbSBoYXMgYmVlbiB1bnB1Ymxpc2hlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVNlcnZlclwiOiB0aGUgdXNlciBoYXMgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcInNlc3Npb25DbG9zZWRCeVNlcnZlclwiOiB0aGUgU2Vzc2lvbiBoYXMgYmVlbiBjbG9zZWQgYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcIm5ldHdvcmtEaXNjb25uZWN0XCI6IHRoZSB1c2VyJ3MgbmV0d29yayBjb25uZWN0aW9uIGhhcyBkcm9wcGVkXG4gICAgICogLSBcIm5vZGVDcmFzaGVkXCI6IGEgbm9kZSBoYXMgY3Jhc2hlZCBpbiB0aGUgc2VydmVyIHNpZGVcbiAgICAgKlxuICAgICAqIEZvciAnc3RyZWFtQ3JlYXRlZCcgZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uOiBTdHJlYW1FdmVudFJlYXNvbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihjYW5jZWxhYmxlOiBib29sZWFuLCB0YXJnZXQ6IFNlc3Npb24gfCBQdWJsaXNoZXIsIHR5cGU6IHN0cmluZywgc3RyZWFtOiBTdHJlYW0sIHJlYXNvbjogU3RyZWFtRXZlbnRSZWFzb24pIHtcbiAgICAgICAgc3VwZXIoY2FuY2VsYWJsZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnc3RyZWFtRGVzdHJveWVkJykge1xuICAgICAgICAgICAgaWYgKHRoaXMudGFyZ2V0IGluc3RhbmNlb2YgU2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIC8vIFJlbW90ZSBTdHJlYW1cbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdTZXNzaW9uJ1wiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIFB1Ymxpc2hlcikge1xuICAgICAgICAgICAgICAgIC8vIExvY2FsIFN0cmVhbVxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKFwiQ2FsbGluZyBkZWZhdWx0IGJlaGF2aW9yIHVwb24gJ1wiICsgdGhpcy50eXBlICsgXCInIGV2ZW50IGRpc3BhdGNoZWQgYnkgJ1B1Ymxpc2hlcidcIik7XG4gICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCgoPFB1Ymxpc2hlcj50aGlzLnRhcmdldCkuc2NyZWVuU2hhcmVSZXNpemVJbnRlcnZhbCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVJlYWR5VG9QdWJsaXNoID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAvLyBEZWxldGUgUHVibGlzaGVyIG9iamVjdCBmcm9tIE9wZW5WaWR1IHB1Ymxpc2hlcnMgYXJyYXlcbiAgICAgICAgICAgICAgICBjb25zdCBvcGVudmlkdVB1Ymxpc2hlcnMgPSAoPFB1Ymxpc2hlcj50aGlzLnRhcmdldCkub3BlbnZpZHUucHVibGlzaGVycztcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wZW52aWR1UHVibGlzaGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAob3BlbnZpZHVQdWJsaXNoZXJzW2ldID09PSA8UHVibGlzaGVyPnRoaXMudGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVudmlkdVB1Ymxpc2hlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIERpc3Bvc2UgdGhlIE1lZGlhU3RyZWFtIGxvY2FsIG9iamVjdFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIERPTSBhbGwgdmlkZW8gZWxlbWVudHMgYXNzb2NpYXRlZCB0byB0aGlzIFN0cmVhbSwgaWYgdGhlcmUncyBhIFN0cmVhbU1hbmFnZXIgZGVmaW5lZFxuICAgICAgICAgICAgLy8gKG1ldGhvZCBTZXNzaW9uLnN1YnNjcmliZSBtdXN0IGhhdmUgYmVlbiBjYWxsZWQpXG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlcikgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlci5yZW1vdmVBbGxWaWRlb3MoKTtcblxuICAgICAgICAgICAgLy8gRGVsZXRlIHN0cmVhbSBmcm9tIFNlc3Npb24ucmVtb3RlU3RyZWFtc0NyZWF0ZWQgbWFwXG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkLmRlbGV0ZSh0aGlzLnN0cmVhbS5zdHJlYW1JZCk7XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBTdHJlYW1PcHRpb25zU2VydmVyIGZyb20gcmVtb3RlIENvbm5lY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNvbm5lY3Rpb24gPSB0aGlzLnN0cmVhbS5zZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zLmdldCh0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uICYmICEhcmVtb3RlQ29ubmVjdGlvbi5yZW1vdGVPcHRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtT3B0aW9uc1NlcnZlciA9IHJlbW90ZUNvbm5lY3Rpb24ucmVtb3RlT3B0aW9ucy5zdHJlYW1zO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBzdHJlYW1PcHRpb25zU2VydmVyLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW1PcHRpb25zU2VydmVyW2ldLmlkID09PSB0aGlzLnN0cmVhbS5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtT3B0aW9uc1NlcnZlci5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW1NYW5hZ2VyJztcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnk6XG4gKiAtIHtAbGluayBTdHJlYW1NYW5hZ2VyRXZlbnRNYXAuc3RyZWFtUGxheWluZ31cbiAqIC0ge0BsaW5rIFN0cmVhbU1hbmFnZXJFdmVudE1hcC5zdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZX1cbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbU1hbmFnZXJFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBGb3IgYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYCBldmVudDpcbiAgICAgKiAtIGB7bmV3VmFsdWU6IG51bWJlciwgb2xkVmFsdWU6IG51bWJlcn1gOiBuZXcgYW5kIG9sZCBhdWRpbyB2b2x1bWUgdmFsdWVzLiBUaGVzZSB2YWx1ZXMgYXJlIGJldHdlZW4gLTEwMCAoc2lsZW5jZSkgYW5kIDAgKGxvdWRlc3QgcG9zc2libGUgdm9sdW1lKS5cbiAgICAgKiBUaGV5IGFyZSBub3QgZXhhY3QgYW5kIGRlcGVuZCBvbiBob3cgdGhlIGJyb3dzZXIgaXMgbWFuYWdpbmcgdGhlIGF1ZGlvIHRyYWNrLCBidXQgLTEwMCBhbmQgMCBjYW4gYmUgdGFrZW4gYXMgbGltaXQgdmFsdWVzLlxuICAgICAqXG4gICAgICogRm9yIGBzdHJlYW1QbGF5aW5nYCBldmVudCB1bmRlZmluZWRcbiAgICAgKi9cbiAgICB2YWx1ZTogT2JqZWN0IHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU3RyZWFtTWFuYWdlciwgdHlwZTogc3RyaW5nLCB2YWx1ZTogT2JqZWN0IHwgdW5kZWZpbmVkKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7fVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRSZWFzb24sIENoYW5nZWRQcm9wZXJ0eVR5cGUgfSBmcm9tICcuL1R5cGVzL1R5cGVzJztcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnkgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgKGF2YWlsYWJsZSBmb3IgW1Nlc3Npb25dKC9lbi9zdGFibGUvYXBpL29wZW52aWR1LWJyb3dzZXIvaW50ZXJmYWNlcy9TZXNzaW9uRXZlbnRNYXAuaHRtbCNzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQpIGFuZCBbU3RyZWFtTWFuYWdlcl0oL2VuL3N0YWJsZS9hcGkvb3BlbnZpZHUtYnJvd3Nlci9pbnRlcmZhY2VzL1N0cmVhbU1hbmFnZXJFdmVudE1hcC5odG1sI3N0cmVhbVByb3BlcnR5Q2hhbmdlZCkgb2JqZWN0cylcbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gd2hvc2UgcHJvcGVydHkgaGFzIGNoYW5nZWQuIFlvdSBjYW4gYWx3YXlzIGlkZW50aWZ5IHRoZSB1c2VyIHB1Ymxpc2hpbmcgdGhlIGNoYW5nZWQgc3RyZWFtIGJ5IGNvbnN1bHRpbmcgcHJvcGVydHkge0BsaW5rIFN0cmVhbS5jb25uZWN0aW9ufVxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHByb3BlcnR5IG9mIHRoZSBzdHJlYW0gdGhhdCBjaGFuZ2VkLiBUaGlzIHZhbHVlIGlzIGVpdGhlciBgXCJ2aWRlb0FjdGl2ZVwiYCwgYFwiYXVkaW9BY3RpdmVcImAsIGBcInZpZGVvVHJhY2tcImAsIGBcImF1ZGlvVHJhY2tcImAsIGBcInZpZGVvRGltZW5zaW9uc1wiYCBvciBgXCJmaWx0ZXJcImBcbiAgICAgKi9cbiAgICBjaGFuZ2VkUHJvcGVydHk6IENoYW5nZWRQcm9wZXJ0eVR5cGU7XG5cbiAgICAvKipcbiAgICAgKiBDYXVzZSBvZiB0aGUgY2hhbmdlIG9uIHRoZSBzdHJlYW0ncyBwcm9wZXJ0eTpcbiAgICAgKiAtIEZvciBgdmlkZW9BY3RpdmVgOiBgXCJwdWJsaXNoVmlkZW9cImBcbiAgICAgKiAtIEZvciBgYXVkaW9BY3RpdmVgOiBgXCJwdWJsaXNoQXVkaW9cImBcbiAgICAgKiAtIEZvciBgdmlkZW9UcmFja2A6IGBcInRyYWNrUmVwbGFjZWRcImBcbiAgICAgKiAtIEZvciBgYXVkaW9UcmFja2A6IGBcInRyYWNrUmVwbGFjZWRcImBcbiAgICAgKiAtIEZvciBgdmlkZW9EaW1lbnNpb25zYDogYFwiZGV2aWNlUm90YXRlZFwiYCwgYFwic2NyZWVuUmVzaXplZFwiYCBvciBgXCJ0cmFja1JlcGxhY2VkXCJgXG4gICAgICogLSBGb3IgYGZpbHRlcmA6IGBcImFwcGx5RmlsdGVyXCJgLCBgXCJleGVjRmlsdGVyTWV0aG9kXCJgIG9yIGBcInJlbW92ZUZpbHRlclwiYFxuICAgICAqL1xuICAgIHJlYXNvbjogU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRSZWFzb247XG5cbiAgICAvKipcbiAgICAgKiBOZXcgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChhZnRlciBjaGFuZ2UsIGN1cnJlbnQgdmFsdWUpXG4gICAgICovXG4gICAgbmV3VmFsdWU6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIFByZXZpb3VzIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSAoYmVmb3JlIGNoYW5nZSlcbiAgICAgKi9cbiAgICBvbGRWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICB0YXJnZXQ6IFNlc3Npb24gfCBTdHJlYW1NYW5hZ2VyLFxuICAgICAgICBzdHJlYW06IFN0cmVhbSxcbiAgICAgICAgY2hhbmdlZFByb3BlcnR5OiBDaGFuZ2VkUHJvcGVydHlUeXBlLFxuICAgICAgICBuZXdWYWx1ZTogT2JqZWN0LFxuICAgICAgICBvbGRWYWx1ZTogT2JqZWN0LFxuICAgICAgICByZWFzb246IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50UmVhc29uXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnKTtcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgIHRoaXMuY2hhbmdlZFByb3BlcnR5ID0gY2hhbmdlZFByb3BlcnR5O1xuICAgICAgICB0aGlzLm5ld1ZhbHVlID0gbmV3VmFsdWU7XG4gICAgICAgIHRoaXMub2xkVmFsdWUgPSBvbGRWYWx1ZTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7IH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIFRyaWdnZXJlZCBieTpcbiAqIC0ge0BsaW5rIFN0cmVhbU1hbmFnZXJFdmVudE1hcC52aWRlb0VsZW1lbnRDcmVhdGVkfVxuICogLSB7QGxpbmsgU3RyZWFtTWFuYWdlckV2ZW50TWFwLnZpZGVvRWxlbWVudERlc3Ryb3llZH1cbiAqL1xuZXhwb3J0IGNsYXNzIFZpZGVvRWxlbWVudEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIFZpZGVvIGVsZW1lbnQgdGhhdCB3YXMgY3JlYXRlZCBvciBkZXN0cm95ZWRcbiAgICAgKi9cbiAgICBlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGVsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQsIHRhcmdldDogU3RyZWFtTWFuYWdlciwgdHlwZTogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge31cbn1cbiIsImZ1bmN0aW9uIE1hcHBlcigpIHtcbiAgICB2YXIgc291cmNlcyA9IHt9O1xuXG4gICAgdGhpcy5mb3JFYWNoID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2VzKSB7XG4gICAgICAgICAgICB2YXIgc291cmNlID0gc291cmNlc1trZXldO1xuXG4gICAgICAgICAgICBmb3IgKHZhciBrZXkyIGluIHNvdXJjZSkgY2FsbGJhY2soc291cmNlW2tleTJdKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB0aGlzLmdldCA9IGZ1bmN0aW9uIChpZCwgc291cmNlKSB7XG4gICAgICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgICAgIGlmIChpZHMgPT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICAgIHJldHVybiBpZHNbaWRdO1xuICAgIH07XG5cbiAgICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uIChpZCwgc291cmNlKSB7XG4gICAgICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgICAgIGlmIChpZHMgPT0gdW5kZWZpbmVkKSByZXR1cm47XG5cbiAgICAgICAgZGVsZXRlIGlkc1tpZF07XG5cbiAgICAgICAgLy8gQ2hlY2sgaXQncyBlbXB0eVxuICAgICAgICBmb3IgKHZhciBpIGluIGlkcykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVsZXRlIHNvdXJjZXNbc291cmNlXTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZXQgPSBmdW5jdGlvbiAodmFsdWUsIGlkLCBzb3VyY2UpIHtcbiAgICAgICAgaWYgKHZhbHVlID09IHVuZGVmaW5lZCkgcmV0dXJuIHRoaXMucmVtb3ZlKGlkLCBzb3VyY2UpO1xuXG4gICAgICAgIHZhciBpZHMgPSBzb3VyY2VzW3NvdXJjZV07XG4gICAgICAgIGlmIChpZHMgPT0gdW5kZWZpbmVkKSBzb3VyY2VzW3NvdXJjZV0gPSBpZHMgPSB7fTtcblxuICAgICAgICBpZHNbaWRdID0gdmFsdWU7XG4gICAgfTtcbn1cblxuTWFwcGVyLnByb3RvdHlwZS5wb3AgPSBmdW5jdGlvbiAoaWQsIHNvdXJjZSkge1xuICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KGlkLCBzb3VyY2UpO1xuICAgIGlmICh2YWx1ZSA9PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICAgIHJldHVybiB2YWx1ZTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gTWFwcGVyO1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBKc29uUnBjQ2xpZW50ID0gcmVxdWlyZSgnLi9qc29ucnBjY2xpZW50Jyk7XG5cbmV4cG9ydHMuSnNvblJwY0NsaWVudCA9IEpzb25ScGNDbGllbnQ7XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE0IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxudmFyIFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi8nKTtcbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uID0gcmVxdWlyZSgnLi90cmFuc3BvcnRzL3dlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24nKTtcbnZhciBPcGVuVmlkdUxvZ2dlciA9IHJlcXVpcmUoJy4uLy4uLy4uL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcicpLk9wZW5WaWR1TG9nZ2VyO1xuXG5EYXRlLm5vdyA9XG4gICAgRGF0ZS5ub3cgfHxcbiAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiArbmV3IERhdGUoKTtcbiAgICB9O1xuXG52YXIgUElOR19JTlRFUlZBTCA9IDUwMDA7XG5cbnZhciBSRUNPTk5FQ1RJTkcgPSAnUkVDT05ORUNUSU5HJztcbnZhciBDT05ORUNURUQgPSAnQ09OTkVDVEVEJztcbnZhciBESVNDT05ORUNURUQgPSAnRElTQ09OTkVDVEVEJztcblxudmFyIExvZ2dlciA9IE9wZW5WaWR1TG9nZ2VyLmdldEluc3RhbmNlKCk7XG5cbi8qKlxuICpcbiAqIGhlYXJ0YmVhdDogaW50ZXJ2YWwgaW4gbXMgZm9yIGVhY2ggaGVhcnRiZWF0IG1lc3NhZ2UsXG4gKiA8cHJlPlxuICogd3MgOiB7XG4gKiBcdHVyaSA6IFVSSSB0byBjb25udGVjdCB0byxcbiAqIFx0b25jb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLFxuICogXHRvbmRpc2Nvbm5lY3QgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgbG9zdCAobWF4IHJldHJpZXMgZm9yIHJlY29ubmVjdGluZyByZWFjaGVkKSxcbiAqIFx0b25yZWNvbm5lY3RpbmcgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBpcyByZWNvbm5lY3RpbmcsXG4gKiBcdG9ucmVjb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBzdWNjZXNzZnVsbHkgcmVjb25uZWN0cyxcbiAqIFx0b25lcnJvciA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGVyZSBpcyBhbiBlcnJvclxuICogfSxcbiAqIHJwYyA6IHtcbiAqIFx0cmVxdWVzdFRpbWVvdXQgOiB0aW1lb3V0IGZvciBhIHJlcXVlc3QsXG4gKiBcdHNlc3Npb25TdGF0dXNDaGFuZ2VkOiBjYWxsYmFjayBtZXRob2QgZm9yIGNoYW5nZXMgaW4gc2Vzc2lvbiBzdGF0dXMsXG4gKiBcdG1lZGlhUmVuZWdvdGlhdGlvbjogbWVkaWFSZW5lZ290aWF0aW9uXG4gKiB9XG4gKiA8L3ByZT5cbiAqL1xuZnVuY3Rpb24gSnNvblJwY0NsaWVudChjb25maWd1cmF0aW9uKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyIHdzQ29uZmlnID0gY29uZmlndXJhdGlvbi53cztcblxuICAgIHZhciBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuID0gLTE7XG5cbiAgICB2YXIgcGluZ05leHROdW0gPSAwO1xuICAgIHZhciBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgIHZhciBwaW5nUG9uZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICB2YXIgcGluZ0ludGVydmFsO1xuXG4gICAgdmFyIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgIHZhciBvbnJlY29ubmVjdGluZyA9IHdzQ29uZmlnLm9ucmVjb25uZWN0aW5nO1xuICAgIHZhciBvbnJlY29ubmVjdGVkID0gd3NDb25maWcub25yZWNvbm5lY3RlZDtcbiAgICB2YXIgb25jb25uZWN0ZWQgPSB3c0NvbmZpZy5vbmNvbm5lY3RlZDtcbiAgICB2YXIgb25lcnJvciA9IHdzQ29uZmlnLm9uZXJyb3I7XG5cbiAgICBjb25maWd1cmF0aW9uLnJwYy5wdWxsID0gZnVuY3Rpb24gKHBhcmFtcywgcmVxdWVzdCkge1xuICAgICAgICByZXF1ZXN0LnJlcGx5KG51bGwsICdwdXNoJyk7XG4gICAgfTtcblxuICAgIHdzQ29uZmlnLm9ucmVjb25uZWN0aW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoJy0tLS0tLS0tLSBPTlJFQ09OTkVDVElORyAtLS0tLS0tLS0tLScpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBSRUNPTk5FQ1RJTkcpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcignV2Vic29ja2V0IGFscmVhZHkgaW4gUkVDT05ORUNUSU5HIHN0YXRlIHdoZW4gcmVjZWl2aW5nIGEgbmV3IE9OUkVDT05ORUNUSU5HIG1lc3NhZ2UuIElnbm9yaW5nIGl0Jyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIHN0YXR1cyA9IFJFQ09OTkVDVElORztcbiAgICAgICAgaWYgKG9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICBvbnJlY29ubmVjdGluZygpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzQ29uZmlnLm9ucmVjb25uZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZygnLS0tLS0tLS0tIE9OUkVDT05ORUNURUQgLS0tLS0tLS0tLS0nKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoJ1dlYnNvY2tldCBhbHJlYWR5IGluIENPTk5FQ1RFRCBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTlJFQ09OTkVDVEVEIG1lc3NhZ2UuIElnbm9yaW5nIGl0Jyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKTtcblxuICAgICAgICBpZiAob25yZWNvbm5lY3RlZCkge1xuICAgICAgICAgICAgb25yZWNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzQ29uZmlnLm9uY29ubmVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoJy0tLS0tLS0tLSBPTkNPTk5FQ1RFRCAtLS0tLS0tLS0tLScpO1xuICAgICAgICBpZiAoc3RhdHVzID09PSBDT05ORUNURUQpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcignV2Vic29ja2V0IGFscmVhZHkgaW4gQ09OTkVDVEVEIHN0YXRlIHdoZW4gcmVjZWl2aW5nIGEgbmV3IE9OQ09OTkVDVEVEIG1lc3NhZ2UuIElnbm9yaW5nIGl0Jyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgc3RhdHVzID0gQ09OTkVDVEVEO1xuXG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHVzZVBpbmcoKTtcblxuICAgICAgICBpZiAob25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9uY29ubmVjdGVkKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgd3NDb25maWcub25lcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICBMb2dnZXIuZGVidWcoJy0tLS0tLS0tLSBPTkVSUk9SIC0tLS0tLS0tLS0tJyk7XG5cbiAgICAgICAgc3RhdHVzID0gRElTQ09OTkVDVEVEO1xuXG4gICAgICAgIHN0b3BQaW5nKCk7XG5cbiAgICAgICAgaWYgKG9uZXJyb3IpIHtcbiAgICAgICAgICAgIG9uZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHZhciB3cyA9IG5ldyBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKHdzQ29uZmlnKTtcblxuICAgIExvZ2dlci5kZWJ1ZygnQ29ubmVjdGluZyB3ZWJzb2NrZXQgdG8gVVJJOiAnICsgd3NDb25maWcudXJpKTtcblxuICAgIHZhciBycGNCdWlsZGVyT3B0aW9ucyA9IHtcbiAgICAgICAgcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5yZXF1ZXN0VGltZW91dCxcbiAgICAgICAgcGluZ19yZXF1ZXN0X3RpbWVvdXQ6IGNvbmZpZ3VyYXRpb24ucnBjLmhlYXJ0YmVhdFJlcXVlc3RUaW1lb3V0XG4gICAgfTtcblxuICAgIHZhciBycGMgPSBuZXcgUnBjQnVpbGRlcihScGNCdWlsZGVyLnBhY2tlcnMuSnNvblJQQywgcnBjQnVpbGRlck9wdGlvbnMsIHdzLCBmdW5jdGlvbiAocmVxdWVzdCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoJ1JlY2VpdmVkIHJlcXVlc3Q6ICcgKyBKU09OLnN0cmluZ2lmeShyZXF1ZXN0KSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhciBmdW5jID0gY29uZmlndXJhdGlvbi5ycGNbcmVxdWVzdC5tZXRob2RdO1xuXG4gICAgICAgICAgICBpZiAoZnVuYyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdNZXRob2QgJyArIHJlcXVlc3QubWV0aG9kICsgJyBub3QgcmVnaXN0ZXJlZCBpbiBjbGllbnQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZnVuYyhyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdFeGNlcHRpb24gcHJvY2Vzc2luZyByZXF1ZXN0OiAnICsgSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpO1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKGVycik7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuc2VuZCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhcmFtcywgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHJlcXVlc3RUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgICAgICBycGMuZW5jb2RlKG1ldGhvZCwgcGFyYW1zLCBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ0VSUk9SOicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgaW4gUmVxdWVzdDogbWV0aG9kOicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJyBwYXJhbXM6JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkocGFyYW1zKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJyByZXF1ZXN0OicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yLnJlcXVlc3RcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignRVJST1IgREFUQTonICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IuZGF0YSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgICAgICAgICBlcnJvci5yZXF1ZXN0VGltZSA9IHJlcXVlc3RUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPSB1bmRlZmluZWQgJiYgcmVzdWx0LnZhbHVlICE9PSAncG9uZycpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZXNwb25zZTogJyArIEpTT04uc3RyaW5naWZ5KHJlc3VsdCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHVwZGF0ZU5vdFJlY29ubmVjdElmTGVzc1RoYW4oKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1Zygnbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9ICcgKyBwaW5nTmV4dE51bSArICcgKG9sZD0nICsgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiArICcpJyk7XG4gICAgICAgIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSBwaW5nTmV4dE51bTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzZW5kUGluZygpIHtcbiAgICAgICAgaWYgKGVuYWJsZWRQaW5ncykge1xuICAgICAgICAgICAgdmFyIHBhcmFtcyA9IG51bGw7XG4gICAgICAgICAgICBpZiAocGluZ05leHROdW0gPT0gMCB8fCBwaW5nTmV4dE51bSA9PSBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgcGFyYW1zID0ge1xuICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbDogY29uZmlndXJhdGlvbi5oZWFydGJlYXQgfHwgUElOR19JTlRFUlZBTFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwaW5nTmV4dE51bSsrO1xuXG4gICAgICAgICAgICBzZWxmLnNlbmQoXG4gICAgICAgICAgICAgICAgJ3BpbmcnLFxuICAgICAgICAgICAgICAgIHBhcmFtcyxcbiAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKHBpbmdOdW0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoJ0Vycm9yIGluIHBpbmcgcmVxdWVzdCAjJyArIHBpbmdOdW0gKyAnICgnICsgZXJyb3IubWVzc2FnZSArICcpJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBpbmdOdW0gPiBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnU2VydmVyIGRpZCBub3QgcmVzcG9uZCB0byBwaW5nIG1lc3NhZ2UgIycgKyBwaW5nTnVtICsgJy4gUmVjb25uZWN0aW5nLi4uICcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cy5yZWNvbm5lY3RXcygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShwaW5nTmV4dE51bSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1RyeWluZyB0byBzZW5kIHBpbmcsIGJ1dCBwaW5nIGlzIG5vdCBlbmFibGVkJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKlxuICAgICAqIElmIGNvbmZpZ3VyYXRpb24uaGVhcmJlYXQgaGFzIGFueSB2YWx1ZSwgdGhlIHBpbmctcG9uZyB3aWxsIHdvcmsgd2l0aCB0aGUgaW50ZXJ2YWxcbiAgICAgKiBvZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0XG4gICAgICovXG4gICAgZnVuY3Rpb24gdXNlUGluZygpIHtcbiAgICAgICAgaWYgKCFwaW5nUG9uZ1N0YXJ0ZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnU3RhcnRpbmcgcGluZyAoaWYgY29uZmlndXJlZCknKTtcbiAgICAgICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIGlmIChjb25maWd1cmF0aW9uLmhlYXJ0YmVhdCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBwaW5nSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChzZW5kUGluZywgY29uZmlndXJhdGlvbi5oZWFydGJlYXQpO1xuICAgICAgICAgICAgICAgIHNlbmRQaW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzdG9wUGluZygpIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChwaW5nSW50ZXJ2YWwpO1xuICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgZW5hYmxlZFBpbmdzID0gZmFsc2U7XG4gICAgICAgIHBpbmdOZXh0TnVtID0gLTE7XG4gICAgICAgIHJwYy5jYW5jZWwoKTtcbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlID0gZnVuY3Rpb24gKGNvZGUsIHJlYXNvbikge1xuICAgICAgICBMb2dnZXIuZGVidWcoJ0Nsb3NpbmcgIHdpdGggY29kZTogJyArIGNvZGUgKyAnIGJlY2F1c2U6ICcgKyByZWFzb24pO1xuICAgICAgICBpZiAocGluZ0ludGVydmFsICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdDbGVhcmluZyBwaW5nIGludGVydmFsJyk7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICB3cy5jbG9zZShjb2RlLCByZWFzb24pO1xuICAgIH07XG5cbiAgICB0aGlzLnJlY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd3MucmVjb25uZWN0V3MoKTtcbiAgICB9O1xuXG4gICAgdGhpcy5yZXNldFBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IHRydWU7XG4gICAgICAgIHBpbmdOZXh0TnVtID0gMDtcbiAgICAgICAgdXNlUGluZygpO1xuICAgIH07XG5cbiAgICB0aGlzLmdldFJlYWR5U3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB3cy5nZXRSZWFkeVN0YXRlKCk7XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBKc29uUnBjQ2xpZW50O1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uID0gcmVxdWlyZSgnLi93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uJyk7XG5cbmV4cG9ydHMuV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiA9IFdlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb247XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDEzLTIwMTUgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBPcGVuVmlkdUxvZ2dlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcicpLk9wZW5WaWR1TG9nZ2VyO1xudmFyIExvZ2dlciA9IE9wZW5WaWR1TG9nZ2VyLmdldEluc3RhbmNlKCk7XG5cbnZhciBNQVhfUkVUUklFUyA9IDIwMDA7IC8vIEZvcmV2ZXIuLi5cbnZhciBSRVRSWV9USU1FX01TID0gMzAwMDsgLy8gRklYTUU6IEltcGxlbWVudCBleHBvbmVudGlhbCB3YWl0IHRpbWVzLi4uXG5cbnZhciBDT05ORUNUSU5HID0gMDtcbnZhciBPUEVOID0gMTtcbnZhciBDTE9TSU5HID0gMjtcbnZhciBDTE9TRUQgPSAzO1xuXG4vKlxuY29uZmlnID0ge1xudXJpIDogd3NVcmksXG5vbmNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiBjb25uZWN0aW9uIGlzIHN1Y2Nlc3NmdWwsXG5vbmRpc2Nvbm5lY3QgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgbG9zdCAobWF4IHJldHJpZXMgZm9yIHJlY29ubmVjdGluZyByZWFjaGVkKSxcbm9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxub25yZWNvbm5lY3RlZCA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IHN1Y2Nlc3NmdWxseSByZWNvbm5lY3RzLFxufTtcbiovXG5mdW5jdGlvbiBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uKGNvbmZpZykge1xuICAgIHZhciBjbG9zaW5nID0gZmFsc2U7XG4gICAgdmFyIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXI7XG4gICAgdmFyIHdzVXJpID0gY29uZmlnLnVyaTtcbiAgICB2YXIgcmVjb25uZWN0aW5nID0gZmFsc2U7XG5cbiAgICB2YXIgd3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcblxuICAgIHdzLm9ub3BlbiA9ICgpID0+IHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCdXZWJTb2NrZXQgY29ubmVjdGVkIHRvICcgKyB3c1VyaSk7XG4gICAgICAgIGlmIChjb25maWcub25jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzLm9uZXJyb3IgPSAoZXJyb3IpID0+IHtcbiAgICAgICAgTG9nZ2VyLmVycm9yKCdDb3VsZCBub3QgY29ubmVjdCB0byAnICsgd3NVcmkgKyAnIChpbnZva2luZyBvbmVycm9yIGlmIGRlZmluZWQpJywgZXJyb3IpO1xuICAgICAgICBpZiAoY29uZmlnLm9uZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbmZpZy5vbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgcmVjb25uZWN0aW9uT25DbG9zZSA9ICgpID0+IHtcbiAgICAgICAgaWYgKHdzLnJlYWR5U3RhdGUgPT09IENMT1NFRCkge1xuICAgICAgICAgICAgaWYgKGNsb3NpbmcpIHtcbiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoJ0Nvbm5lY3Rpb24gY2xvc2VkIGJ5IHVzZXInKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbmZpZy5pc21hc3Rlcm5vZGVjcmFzaGVkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdNYXN0ZXIgTm9kZSBoYXMgY3Jhc2hlZC4gU3RvcHBpbmcgcmVjb25uZWN0aW9uIHByb2Nlc3MnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoJ0Nvbm5lY3Rpb24gY2xvc2VkIHVuZXhwZWN0ZWRseS4gUmVjb25uZWN0aW5nLi4uJyk7XG4gICAgICAgICAgICAgICAgICAgIHJlY29ubmVjdChNQVhfUkVUUklFUywgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdDbG9zZSBjYWxsYmFjayBmcm9tIHByZXZpb3VzIHdlYnNvY2tldC4gSWdub3JpbmcgaXQnKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3cy5vbmNsb3NlID0gcmVjb25uZWN0aW9uT25DbG9zZTtcblxuICAgIGZ1bmN0aW9uIHJlY29ubmVjdChtYXhSZXRyaWVzLCBudW1SZXRyaWVzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZygncmVjb25uZWN0IChhdHRlbXB0ICMnICsgbnVtUmV0cmllcyArICcsIG1heD0nICsgbWF4UmV0cmllcyArICcpJyk7XG4gICAgICAgIGlmIChudW1SZXRyaWVzID09PSAxKSB7XG4gICAgICAgICAgICBpZiAocmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLndhcm4oJ1RyeWluZyB0byByZWNvbm5lY3Qgd2hlbiBhbHJlYWR5IHJlY29ubmVjdGluZy4uLiBJZ25vcmluZyB0aGlzIHJlY29ubmVjdGlvbi4nKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY29uZmlnLm9ucmVjb25uZWN0aW5nKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0aW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmVjb25uZWN0QXV4KG1heFJldHJpZXMsIG51bVJldHJpZXMpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZFJlY29ubmVjdGlvblF1ZXJ5UGFyYW1zSWZNaXNzaW5nKHVyaVN0cmluZykge1xuICAgICAgICB2YXIgc2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyhuZXcgVVJMKHVyaVN0cmluZykuc2VhcmNoKTtcbiAgICAgICAgaWYgKCFzZWFyY2hQYXJhbXMuaGFzKCdyZWNvbm5lY3QnKSkge1xuICAgICAgICAgICAgdXJpU3RyaW5nID0gQXJyYXkuZnJvbShzZWFyY2hQYXJhbXMpLmxlbmd0aCA+IDAgPyB1cmlTdHJpbmcgKyAnJnJlY29ubmVjdD10cnVlJyA6IHVyaVN0cmluZyArICc/cmVjb25uZWN0PXRydWUnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1cmlTdHJpbmc7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVjb25uZWN0QXV4KG1heFJldHJpZXMsIG51bVJldHJpZXMpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZWNvbm5lY3Rpb24gYXR0ZW1wdCAjJyArIG51bVJldHJpZXMpO1xuICAgICAgICB3cy5jbG9zZSg0MTA0LCAnQ29ubmVjdGlvbiBjbG9zZWQgZm9yIHJlY29ubmVjdGlvbicpO1xuXG4gICAgICAgIHdzVXJpID0gYWRkUmVjb25uZWN0aW9uUXVlcnlQYXJhbXNJZk1pc3Npbmcod3NVcmkpO1xuICAgICAgICB3cyA9IG5ldyBXZWJTb2NrZXQod3NVcmkpO1xuXG4gICAgICAgIHdzLm9ub3BlbiA9ICgpID0+IHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVjb25uZWN0ZWQgdG8gJyArIHdzVXJpICsgJyBhZnRlciAnICsgbnVtUmV0cmllcyArICcgYXR0ZW1wdHMuLi4nKTtcbiAgICAgICAgICAgIHJlY29ubmVjdGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcigpO1xuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGVkKCkpIHtcbiAgICAgICAgICAgICAgICBjb25maWcub25yZWNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgd3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG4gICAgICAgIH07XG5cbiAgICAgICAgd3Mub25lcnJvciA9IChlcnJvcikgPT4ge1xuICAgICAgICAgICAgTG9nZ2VyLndhcm4oJ1JlY29ubmVjdGlvbiBlcnJvcjogJywgZXJyb3IpO1xuICAgICAgICAgICAgaWYgKG51bVJldHJpZXMgPT09IG1heFJldHJpZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm9uZGlzY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcub25kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmVjb25uZWN0KG1heFJldHJpZXMsIG51bVJldHJpZXMgKyAxKTtcbiAgICAgICAgICAgICAgICB9LCBSRVRSWV9USU1FX01TKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLmNsb3NlID0gKGNvZGUsIHJlYXNvbikgPT4ge1xuICAgICAgICBjbG9zaW5nID0gdHJ1ZTtcbiAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICB9O1xuXG4gICAgdGhpcy5yZWNvbm5lY3RXcyA9ICgpID0+IHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCdyZWNvbm5lY3RXcycpO1xuICAgICAgICByZWNvbm5lY3QoTUFYX1JFVFJJRVMsIDEpO1xuICAgIH07XG5cbiAgICB0aGlzLnNlbmQgPSAobWVzc2FnZSkgPT4ge1xuICAgICAgICB3cy5zZW5kKG1lc3NhZ2UpO1xuICAgIH07XG5cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIgPSAodHlwZSwgY2FsbGJhY2spID0+IHtcbiAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlciA9ICgpID0+IHtcbiAgICAgICAgICAgIHdzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgY2FsbGJhY2spO1xuICAgICAgICB9O1xuICAgICAgICByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyKCk7XG4gICAgfTtcblxuICAgIHRoaXMuZ2V0UmVhZHlTdGF0ZSA9ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHdzLnJlYWR5U3RhdGU7XG4gICAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uO1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBkZWZpbmVQcm9wZXJ0eV9JRTggPSBmYWxzZTtcbmlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHtcbiAgICB0cnkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICd4Jywge30pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgZGVmaW5lUHJvcGVydHlfSUU4ID0gdHJ1ZTtcbiAgICB9XG59XG5cbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL0Z1bmN0aW9uL2JpbmRcbmlmICghRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQpIHtcbiAgICBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uIChvVGhpcykge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIC8vIGNsb3Nlc3QgdGhpbmcgcG9zc2libGUgdG8gdGhlIEVDTUFTY3JpcHQgNVxuICAgICAgICAgICAgLy8gaW50ZXJuYWwgSXNDYWxsYWJsZSBmdW5jdGlvblxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgLSB3aGF0IGlzIHRyeWluZyB0byBiZSBib3VuZCBpcyBub3QgY2FsbGFibGUnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBhQXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSksXG4gICAgICAgICAgICBmVG9CaW5kID0gdGhpcyxcbiAgICAgICAgICAgIGZOT1AgPSBmdW5jdGlvbiAoKSB7fSxcbiAgICAgICAgICAgIGZCb3VuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZlRvQmluZC5hcHBseSh0aGlzIGluc3RhbmNlb2YgZk5PUCAmJiBvVGhpcyA/IHRoaXMgOiBvVGhpcywgYUFyZ3MuY29uY2F0KEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgZk5PUC5wcm90b3R5cGUgPSB0aGlzLnByb3RvdHlwZTtcbiAgICAgICAgZkJvdW5kLnByb3RvdHlwZSA9IG5ldyBmTk9QKCk7XG5cbiAgICAgICAgcmV0dXJuIGZCb3VuZDtcbiAgICB9O1xufVxuXG52YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xuXG52YXIgaW5oZXJpdHMgPSByZXF1aXJlKCdpbmhlcml0cycpO1xuXG52YXIgcGFja2VycyA9IHJlcXVpcmUoJy4vcGFja2VycycpO1xudmFyIE1hcHBlciA9IHJlcXVpcmUoJy4vTWFwcGVyJyk7XG5cbnZhciBCQVNFX1RJTUVPVVQgPSA1MDAwO1xuXG5mdW5jdGlvbiB1bmlmeVJlc3BvbnNlTWV0aG9kcyhyZXNwb25zZU1ldGhvZHMpIHtcbiAgICBpZiAoIXJlc3BvbnNlTWV0aG9kcykgcmV0dXJuIHt9O1xuXG4gICAgZm9yICh2YXIga2V5IGluIHJlc3BvbnNlTWV0aG9kcykge1xuICAgICAgICB2YXIgdmFsdWUgPSByZXNwb25zZU1ldGhvZHNba2V5XTtcblxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnKVxuICAgICAgICAgICAgcmVzcG9uc2VNZXRob2RzW2tleV0gPSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2U6IHZhbHVlXG4gICAgICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiByZXNwb25zZU1ldGhvZHM7XG59XG5cbmZ1bmN0aW9uIHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCkge1xuICAgIGlmICghdHJhbnNwb3J0KSByZXR1cm47XG5cbiAgICAvLyBUcmFuc3BvcnQgYXMgYSBmdW5jdGlvblxuICAgIGlmICh0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNlbmQ6IHRyYW5zcG9ydFxuICAgICAgICB9O1xuXG4gICAgLy8gV2ViU29ja2V0ICYgRGF0YUNoYW5uZWxcbiAgICBpZiAodHJhbnNwb3J0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbikgcmV0dXJuIHRyYW5zcG9ydDtcblxuICAgIC8vIE1lc3NhZ2UgQVBJIChJbnRlci13aW5kb3cgJiBXZWJXb3JrZXIpXG4gICAgaWYgKHRyYW5zcG9ydC5wb3N0TWVzc2FnZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgIHRyYW5zcG9ydC5zZW5kID0gdHJhbnNwb3J0LnBvc3RNZXNzYWdlO1xuICAgICAgICByZXR1cm4gdHJhbnNwb3J0O1xuICAgIH1cblxuICAgIC8vIFN0cmVhbSBBUElcbiAgICBpZiAodHJhbnNwb3J0LndyaXRlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgICAgdHJhbnNwb3J0LnNlbmQgPSB0cmFuc3BvcnQud3JpdGU7XG4gICAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNwb3J0cyB0aGF0IG9ubHkgY2FuIHJlY2VpdmUgbWVzc2FnZXMsIGJ1dCBub3Qgc2VuZFxuICAgIGlmICh0cmFuc3BvcnQub25tZXNzYWdlICE9PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICBpZiAodHJhbnNwb3J0LnBhdXNlIGluc3RhbmNlb2YgRnVuY3Rpb24pIHJldHVybjtcblxuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignVHJhbnNwb3J0IGlzIG5vdCBhIGZ1bmN0aW9uIG5vciBhIHZhbGlkIG9iamVjdCcpO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudGF0aW9uIG9mIGEgUlBDIG5vdGlmaWNhdGlvblxuICpcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgLW1ldGhvZCBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gKi9cbmZ1bmN0aW9uIFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcykge1xuICAgIGlmIChkZWZpbmVQcm9wZXJ0eV9JRTgpIHtcbiAgICAgICAgdGhpcy5tZXRob2QgPSBtZXRob2Q7XG4gICAgICAgIHRoaXMucGFyYW1zID0gcGFyYW1zO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnbWV0aG9kJywge1xuICAgICAgICAgICAgdmFsdWU6IG1ldGhvZCxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGFyYW1zJywge1xuICAgICAgICAgICAgdmFsdWU6IHBhcmFtcyxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWVcbiAgICAgICAgfSk7XG4gICAgfVxufVxuXG4vKipcbiAqIEBjbGFzc1xuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYWNrZXJcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFt0cmFuc3BvcnRdXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29uUmVxdWVzdF1cbiAqL1xuZnVuY3Rpb24gUnBjQnVpbGRlcihwYWNrZXIsIG9wdGlvbnMsIHRyYW5zcG9ydCwgb25SZXF1ZXN0KSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKCFwYWNrZXIpIHRocm93IG5ldyBTeW50YXhFcnJvcignUGFja2VyIGlzIG5vdCBkZWZpbmVkJyk7XG5cbiAgICBpZiAoIXBhY2tlci5wYWNrIHx8ICFwYWNrZXIudW5wYWNrKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBpbnZhbGlkJyk7XG5cbiAgICB2YXIgcmVzcG9uc2VNZXRob2RzID0gdW5pZnlSZXNwb25zZU1ldGhvZHMocGFja2VyLnJlc3BvbnNlTWV0aG9kcyk7XG5cbiAgICBpZiAob3B0aW9ucyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgIGlmICh0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgICAgICBvblJlcXVlc3QgPSBvcHRpb25zO1xuICAgICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICAgIG9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgICAgaWYgKHRyYW5zcG9ydCAmJiAhKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSkgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdPbmx5IGEgZnVuY3Rpb24gY2FuIGJlIGFmdGVyIHRyYW5zcG9ydCcpO1xuXG4gICAgICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICAgICAgdHJhbnNwb3J0ID0gb3B0aW9ucztcbiAgICAgICAgb3B0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgICAgaWYgKG9uUmVxdWVzdCAhPSB1bmRlZmluZWQpIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgb25SZXF1ZXN0XCIpO1xuXG4gICAgICAgIG9uUmVxdWVzdCA9IHRyYW5zcG9ydDtcbiAgICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmICh0cmFuc3BvcnQgJiYgdHJhbnNwb3J0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICAgICAgaWYgKG9uUmVxdWVzdCAmJiAhKG9uUmVxdWVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSkgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdPbmx5IGEgZnVuY3Rpb24gY2FuIGJlIGFmdGVyIHRyYW5zcG9ydCcpO1xuXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgICBFdmVudEVtaXR0ZXIuY2FsbCh0aGlzKTtcblxuICAgIGlmIChvblJlcXVlc3QpIHRoaXMub24oJ3JlcXVlc3QnLCBvblJlcXVlc3QpO1xuXG4gICAgaWYgKGRlZmluZVByb3BlcnR5X0lFOCkgdGhpcy5wZWVySUQgPSBvcHRpb25zLnBlZXJJRDtcbiAgICBlbHNlXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAncGVlcklEJywge1xuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucGVlcklEXG4gICAgICAgIH0pO1xuXG4gICAgdmFyIG1heF9yZXRyaWVzID0gb3B0aW9ucy5tYXhfcmV0cmllcyB8fCAwO1xuXG4gICAgZnVuY3Rpb24gdHJhbnNwb3J0TWVzc2FnZShldmVudCkge1xuICAgICAgICBzZWxmLmRlY29kZShldmVudC5kYXRhIHx8IGV2ZW50KTtcbiAgICB9XG5cbiAgICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgICB9O1xuICAgIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIC8vIFJlbW92ZSBsaXN0ZW5lciBmcm9tIG9sZCB0cmFuc3BvcnRcbiAgICAgICAgaWYgKHRyYW5zcG9ydCkge1xuICAgICAgICAgICAgLy8gVzNDIHRyYW5zcG9ydHNcbiAgICAgICAgICAgIGlmICh0cmFuc3BvcnQucmVtb3ZlRXZlbnRMaXN0ZW5lcikgdHJhbnNwb3J0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICAgICAgICAgIC8vIE5vZGUuanMgU3RyZWFtcyBBUElcbiAgICAgICAgICAgIGVsc2UgaWYgKHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcikgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgbGlzdGVuZXIgb24gbmV3IHRyYW5zcG9ydFxuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIC8vIFczQyB0cmFuc3BvcnRzXG4gICAgICAgICAgICBpZiAodmFsdWUuYWRkRXZlbnRMaXN0ZW5lcikgdmFsdWUuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgICAgICAgICAgLy8gTm9kZS5qcyBTdHJlYW1zIEFQSVxuICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUuYWRkTGlzdGVuZXIpIHZhbHVlLmFkZExpc3RlbmVyKCdkYXRhJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gICAgfTtcblxuICAgIGlmICghZGVmaW5lUHJvcGVydHlfSUU4KVxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsIHtcbiAgICAgICAgICAgIGdldDogdGhpcy5nZXRUcmFuc3BvcnQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIHNldDogdGhpcy5zZXRUcmFuc3BvcnQuYmluZCh0aGlzKVxuICAgICAgICB9KTtcblxuICAgIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICB2YXIgcmVxdWVzdF90aW1lb3V0ID0gb3B0aW9ucy5yZXF1ZXN0X3RpbWVvdXQgfHwgQkFTRV9USU1FT1VUO1xuICAgIHZhciBwaW5nX3JlcXVlc3RfdGltZW91dCA9IG9wdGlvbnMucGluZ19yZXF1ZXN0X3RpbWVvdXQgfHwgcmVxdWVzdF90aW1lb3V0O1xuICAgIHZhciByZXNwb25zZV90aW1lb3V0ID0gb3B0aW9ucy5yZXNwb25zZV90aW1lb3V0IHx8IEJBU0VfVElNRU9VVDtcbiAgICB2YXIgZHVwbGljYXRlc190aW1lb3V0ID0gb3B0aW9ucy5kdXBsaWNhdGVzX3RpbWVvdXQgfHwgQkFTRV9USU1FT1VUO1xuXG4gICAgdmFyIHJlcXVlc3RJRCA9IDA7XG5cbiAgICB2YXIgcmVxdWVzdHMgPSBuZXcgTWFwcGVyKCk7XG4gICAgdmFyIHJlc3BvbnNlcyA9IG5ldyBNYXBwZXIoKTtcbiAgICB2YXIgcHJvY2Vzc2VkUmVzcG9uc2VzID0gbmV3IE1hcHBlcigpO1xuXG4gICAgdmFyIG1lc3NhZ2UyS2V5ID0ge307XG5cbiAgICAvKipcbiAgICAgKiBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGR1cGxpY2F0ZSByZXF1ZXN0IGxhdGVyXG4gICAgICovXG4gICAgZnVuY3Rpb24gc3RvcmVSZXNwb25zZShtZXNzYWdlLCBpZCwgZGVzdCkge1xuICAgICAgICB2YXIgcmVzcG9uc2UgPSB7XG4gICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICAgICAgLyoqIFRpbWVvdXQgdG8gYXV0by1jbGVhbiBvbGQgcmVzcG9uc2VzICovXG4gICAgICAgICAgICB0aW1lb3V0OiBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXNwb25zZXMucmVtb3ZlKGlkLCBkZXN0KTtcbiAgICAgICAgICAgIH0sIHJlc3BvbnNlX3RpbWVvdXQpXG4gICAgICAgIH07XG5cbiAgICAgICAgcmVzcG9uc2VzLnNldChyZXNwb25zZSwgaWQsIGRlc3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0b3JlIHRoZSByZXNwb25zZSB0byBpZ25vcmUgZHVwbGljYXRlZCBtZXNzYWdlcyBsYXRlclxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0b3JlUHJvY2Vzc2VkUmVzcG9uc2UoYWNrLCBmcm9tKSB7XG4gICAgICAgIHZhciB0aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwcm9jZXNzZWRSZXNwb25zZXMucmVtb3ZlKGFjaywgZnJvbSk7XG4gICAgICAgIH0sIGR1cGxpY2F0ZXNfdGltZW91dCk7XG5cbiAgICAgICAgcHJvY2Vzc2VkUmVzcG9uc2VzLnNldCh0aW1lb3V0LCBhY2ssIGZyb20pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcHJlc2VudGF0aW9uIG9mIGEgUlBDIHJlcXVlc3RcbiAgICAgKlxuICAgICAqIEBjbGFzc1xuICAgICAqIEBleHRlbmRzIFJwY05vdGlmaWNhdGlvblxuICAgICAqXG4gICAgICogQGNvbnN0cnVjdG9yXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICAgKiBAcGFyYW0ge0ludGVnZXJ9IGlkIC0gaWRlbnRpZmllciBvZiB0aGUgcmVxdWVzdFxuICAgICAqIEBwYXJhbSBbZnJvbV0gLSBzb3VyY2Ugb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgICAqL1xuICAgIGZ1bmN0aW9uIFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkLCBmcm9tLCB0cmFuc3BvcnQpIHtcbiAgICAgICAgUnBjTm90aWZpY2F0aW9uLmNhbGwodGhpcywgbWV0aG9kLCBwYXJhbXMpO1xuXG4gICAgICAgIHRoaXMuZ2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZXRUcmFuc3BvcnQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHZhbHVlKTtcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAndHJhbnNwb3J0Jywge1xuICAgICAgICAgICAgICAgIGdldDogdGhpcy5nZXRUcmFuc3BvcnQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHZhciByZXNwb25zZSA9IHJlc3BvbnNlcy5nZXQoaWQsIGZyb20pO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAY29uc3RhbnQge0Jvb2xlYW59IGR1cGxpY2F0ZWRcbiAgICAgICAgICovXG4gICAgICAgIGlmICghKHRyYW5zcG9ydCB8fCBzZWxmLmdldFRyYW5zcG9ydCgpKSkge1xuICAgICAgICAgICAgaWYgKGRlZmluZVByb3BlcnR5X0lFOCkgdGhpcy5kdXBsaWNhdGVkID0gQm9vbGVhbihyZXNwb25zZSk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdkdXBsaWNhdGVkJywge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogQm9vbGVhbihyZXNwb25zZSlcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXNwb25zZU1ldGhvZCA9IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdO1xuXG4gICAgICAgIHRoaXMucGFjayA9IHBhY2tlci5wYWNrLmJpbmQocGFja2VyLCB0aGlzLCBpZCk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdlbmVyYXRlIGEgcmVzcG9uc2UgdG8gdGhpcyByZXF1ZXN0XG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7RXJyb3J9IFtlcnJvcl1cbiAgICAgICAgICogQHBhcmFtIHsqfSBbcmVzdWx0XVxuICAgICAgICAgKlxuICAgICAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5yZXBseSA9IGZ1bmN0aW9uIChlcnJvciwgcmVzdWx0LCB0cmFuc3BvcnQpIHtcbiAgICAgICAgICAgIC8vIEZpeCBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBGdW5jdGlvbiB8fCAoZXJyb3IgJiYgZXJyb3Iuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSkge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgICAgICAgICAgdHJhbnNwb3J0ID0gZXJyb3I7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gbnVsbDtcbiAgICAgICAgICAgICAgICBlcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzdWx0IGluc3RhbmNlb2YgRnVuY3Rpb24gfHwgKHJlc3VsdCAmJiByZXN1bHQuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSkge1xuICAgICAgICAgICAgICAgIGlmICh0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgICAgICAgICAgdHJhbnNwb3J0ID0gcmVzdWx0O1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgICAgIC8vIER1cGxpY2F0ZWQgcmVxdWVzdCwgcmVtb3ZlIG9sZCByZXNwb25zZSB0aW1lb3V0XG4gICAgICAgICAgICBpZiAocmVzcG9uc2UpIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcblxuICAgICAgICAgICAgaWYgKGZyb20gIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSBlcnJvci5kZXN0ID0gZnJvbTtcblxuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQpIHJlc3VsdC5kZXN0ID0gZnJvbTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIG1lc3NhZ2U7XG5cbiAgICAgICAgICAgIC8vIE5ldyByZXF1ZXN0IG9yIG92ZXJyaWRlbiBvbmUsIGNyZWF0ZSBuZXcgcmVzcG9uc2Ugd2l0aCBwcm92aWRlZCBkYXRhXG4gICAgICAgICAgICBpZiAoZXJyb3IgfHwgcmVzdWx0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGlmIChzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSBlcnJvci5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgcmVzdWx0LmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBQcm90b2NvbCBpbmRpY2F0ZXMgdGhhdCByZXNwb25zZXMgaGFzIG93biByZXF1ZXN0IG1ldGhvZHNcbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2VNZXRob2QpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlTWV0aG9kLmVycm9yID09IHVuZGVmaW5lZCAmJiBlcnJvcilcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtZXRob2QgPSBlcnJvciA/IHJlc3BvbnNlTWV0aG9kLmVycm9yIDogcmVzcG9uc2VNZXRob2QucmVzcG9uc2U7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zOiBlcnJvciB8fCByZXN1bHRcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdDogcmVzdWx0XG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSwgaWQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEdXBsaWNhdGUgJiBub3Qtb3ZlcnJpZGVuIHJlcXVlc3QsIHJlLXNlbmQgb2xkIHJlc3BvbnNlXG4gICAgICAgICAgICBlbHNlIGlmIChyZXNwb25zZSkgbWVzc2FnZSA9IHJlc3BvbnNlLm1lc3NhZ2U7XG4gICAgICAgICAgICAvLyBOZXcgZW1wdHkgcmVwbHksIHJlc3BvbnNlIG51bGwgdmFsdWVcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2soXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdDogbnVsbFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpZFxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIFN0b3JlIHRoZSByZXNwb25zZSB0byBwcmV2ZW50IHRvIHByb2Nlc3MgYSBkdXBsaWNhdGVkIHJlcXVlc3QgbGF0ZXJcbiAgICAgICAgICAgIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGZyb20pO1xuXG4gICAgICAgICAgICAvLyBSZXR1cm4gdGhlIHN0b3JlZCByZXNwb25zZSBzbyBpdCBjYW4gYmUgZGlyZWN0bHkgc2VuZCBiYWNrXG4gICAgICAgICAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuXG4gICAgICAgICAgICBpZiAodHJhbnNwb3J0KSByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICB9O1xuICAgIH1cbiAgICBpbmhlcml0cyhScGNSZXF1ZXN0LCBScGNOb3RpZmljYXRpb24pO1xuXG4gICAgZnVuY3Rpb24gY2FuY2VsKG1lc3NhZ2UpIHtcbiAgICAgICAgdmFyIGtleSA9IG1lc3NhZ2UyS2V5W21lc3NhZ2VdO1xuICAgICAgICBpZiAoIWtleSkgcmV0dXJuO1xuXG4gICAgICAgIGRlbGV0ZSBtZXNzYWdlMktleVttZXNzYWdlXTtcblxuICAgICAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLnBvcChrZXkuaWQsIGtleS5kZXN0KTtcbiAgICAgICAgaWYgKCFyZXF1ZXN0KSByZXR1cm47XG5cbiAgICAgICAgY2xlYXJUaW1lb3V0KHJlcXVlc3QudGltZW91dCk7XG5cbiAgICAgICAgLy8gU3RhcnQgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgICAgICBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGtleS5pZCwga2V5LmRlc3QpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFsbG93IHRvIGNhbmNlbCBhIHJlcXVlc3QgYW5kIGRvbid0IHdhaXQgZm9yIGEgcmVzcG9uc2VcbiAgICAgKlxuICAgICAqIElmIGBtZXNzYWdlYCBpcyBub3QgZ2l2ZW4sIGNhbmNlbCBhbGwgdGhlIHJlcXVlc3RcbiAgICAgKi9cbiAgICB0aGlzLmNhbmNlbCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgICAgIGlmIChtZXNzYWdlKSByZXR1cm4gY2FuY2VsKG1lc3NhZ2UpO1xuXG4gICAgICAgIGZvciAodmFyIG1lc3NhZ2UgaW4gbWVzc2FnZTJLZXkpIGNhbmNlbChtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gUHJldmVudCB0byByZWNlaXZlIG5ldyBtZXNzYWdlc1xuICAgICAgICB2YXIgdHJhbnNwb3J0ID0gdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICAgICAgaWYgKHRyYW5zcG9ydCAmJiB0cmFuc3BvcnQuY2xvc2UpIHRyYW5zcG9ydC5jbG9zZSg0MDAzLCAnQ2FuY2VsIHJlcXVlc3QnKTtcblxuICAgICAgICAvLyBSZXF1ZXN0ICYgcHJvY2Vzc2VkIHJlc3BvbnNlc1xuICAgICAgICB0aGlzLmNhbmNlbCgpO1xuXG4gICAgICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5mb3JFYWNoKGNsZWFyVGltZW91dCk7XG5cbiAgICAgICAgLy8gUmVzcG9uc2VzXG4gICAgICAgIHJlc3BvbnNlcy5mb3JFYWNoKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlc3BvbnNlLnRpbWVvdXQpO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGVzIGFuZCBlbmNvZGUgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgICAqIEBwYXJhbSBwYXJhbXMgLSBwYXJhbWV0ZXJzIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICAgKiBAcGFyYW0gW2Rlc3RdIC0gZGVzdGluYXRpb24gb2YgdGhlIG5vdGlmaWNhdGlvblxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBbdHJhbnNwb3J0XSAtIHRyYW5zcG9ydCB3aGVyZSB0byBzZW5kIHRoZSBtZXNzYWdlXG4gICAgICogQHBhcmFtIFtjYWxsYmFja10gLSBmdW5jdGlvbiBjYWxsZWQgd2hlbiBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdCBpc1xuICAgICAqICAgcmVjZWl2ZWQuIElmIG5vdCBkZWZpbmVkLCBhIG5vdGlmaWNhdGlvbiB3aWxsIGJlIHNlbmQgaW5zdGVhZFxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ30gQSByYXcgSnNvblJQQyAyLjAgcmVxdWVzdCBvciBub3RpZmljYXRpb24gc3RyaW5nXG4gICAgICovXG4gICAgdGhpcy5lbmNvZGUgPSBmdW5jdGlvbiAobWV0aG9kLCBwYXJhbXMsIGRlc3QsIHRyYW5zcG9ydCwgY2FsbGJhY2spIHtcbiAgICAgICAgLy8gRml4IG9wdGlvbmFsIHBhcmFtZXRlcnNcbiAgICAgICAgaWYgKHBhcmFtcyBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgICAgICBpZiAoZGVzdCAhPSB1bmRlZmluZWQpIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlRoZXJlIGNhbid0IGJlIHBhcmFtZXRlcnMgYWZ0ZXIgY2FsbGJhY2tcIik7XG5cbiAgICAgICAgICAgIGNhbGxiYWNrID0gcGFyYW1zO1xuICAgICAgICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgZGVzdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHBhcmFtcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgfSBlbHNlIGlmIChkZXN0IGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICh0cmFuc3BvcnQgIT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgICAgICBjYWxsYmFjayA9IGRlc3Q7XG4gICAgICAgICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBkZXN0ID0gdW5kZWZpbmVkO1xuICAgICAgICB9IGVsc2UgaWYgKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgICAgICBpZiAoY2FsbGJhY2sgIT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgICAgICBjYWxsYmFjayA9IHRyYW5zcG9ydDtcbiAgICAgICAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzZWxmLnBlZXJJRCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgICAgICAgcGFyYW1zLmZyb20gPSBzZWxmLnBlZXJJRDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkZXN0ICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuXG4gICAgICAgICAgICBwYXJhbXMuZGVzdCA9IGRlc3Q7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFbmNvZGUgbWVzc2FnZVxuICAgICAgICB2YXIgbWVzc2FnZSA9IHtcbiAgICAgICAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgICAgICAgcGFyYW1zOiBwYXJhbXNcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHZhciBpZCA9IHJlcXVlc3RJRCsrO1xuICAgICAgICAgICAgdmFyIHJldHJpZWQgPSAwO1xuXG4gICAgICAgICAgICBtZXNzYWdlID0gcGFja2VyLnBhY2sobWVzc2FnZSwgaWQpO1xuXG4gICAgICAgICAgICBmdW5jdGlvbiBkaXNwYXRjaENhbGxiYWNrKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBzZWxmLmNhbmNlbChtZXNzYWdlKTtcblxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVycm9yLCByZXN1bHQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgcmVxdWVzdCA9IHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICAgICAgICAgIGNhbGxiYWNrOiBkaXNwYXRjaENhbGxiYWNrLFxuICAgICAgICAgICAgICAgIHJlc3BvbnNlTWV0aG9kczogcmVzcG9uc2VNZXRob2RzW21ldGhvZF0gfHwge31cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHZhciBlbmNvZGVfdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KTtcblxuICAgICAgICAgICAgZnVuY3Rpb24gc2VuZFJlcXVlc3QodHJhbnNwb3J0KSB7XG4gICAgICAgICAgICAgICAgdmFyIHJ0ID0gbWV0aG9kID09PSAncGluZycgPyBwaW5nX3JlcXVlc3RfdGltZW91dCA6IHJlcXVlc3RfdGltZW91dDtcbiAgICAgICAgICAgICAgICByZXF1ZXN0LnRpbWVvdXQgPSBzZXRUaW1lb3V0KHRpbWVvdXQsIHJ0ICogTWF0aC5wb3coMiwgcmV0cmllZCsrKSk7XG4gICAgICAgICAgICAgICAgbWVzc2FnZTJLZXlbbWVzc2FnZV0gPSB7XG4gICAgICAgICAgICAgICAgICAgIGlkOiBpZCxcbiAgICAgICAgICAgICAgICAgICAgZGVzdDogZGVzdFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmVxdWVzdHMuc2V0KHJlcXVlc3QsIGlkLCBkZXN0KTtcblxuICAgICAgICAgICAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCBlbmNvZGVfdHJhbnNwb3J0IHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG4gICAgICAgICAgICAgICAgaWYgKHRyYW5zcG9ydCkgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKG1lc3NhZ2UpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHJldHJ5KHRyYW5zcG9ydCkge1xuICAgICAgICAgICAgICAgIHRyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4ocmV0cmllZCArICcgcmV0cnkgZm9yIHJlcXVlc3QgbWVzc2FnZTonLCBtZXNzYWdlKTtcblxuICAgICAgICAgICAgICAgIHZhciB0aW1lb3V0ID0gcHJvY2Vzc2VkUmVzcG9uc2VzLnBvcChpZCwgZGVzdCk7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHRpbWVvdXQoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJldHJpZWQgPCBtYXhfcmV0cmllcykgcmV0dXJuIHJldHJ5KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1JlcXVlc3QgaGFzIHRpbWVkIG91dCcpO1xuICAgICAgICAgICAgICAgIGVycm9yLnJlcXVlc3QgPSBtZXNzYWdlO1xuXG4gICAgICAgICAgICAgICAgZXJyb3IucmV0cnkgPSByZXRyeTtcblxuICAgICAgICAgICAgICAgIGRpc3BhdGNoQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gc2VuZFJlcXVlc3QodHJhbnNwb3J0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJldHVybiB0aGUgcGFja2VkIG1lc3NhZ2VcbiAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UpO1xuXG4gICAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydCB8fCB0aGlzLmdldFRyYW5zcG9ydCgpO1xuICAgICAgICBpZiAodHJhbnNwb3J0KSByZXR1cm4gdHJhbnNwb3J0LnNlbmQobWVzc2FnZSk7XG5cbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERlY29kZSBhbmQgcHJvY2VzcyBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gc3RyaW5nIHdpdGggdGhlIGNvbnRlbnQgb2YgdGhlIG1lc3NhZ2VcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtScGNOb3RpZmljYXRpb258UnBjUmVxdWVzdHx1bmRlZmluZWR9IC0gdGhlIHJlcHJlc2VudGF0aW9uIG9mIHRoZVxuICAgICAqICAgbm90aWZpY2F0aW9uIG9yIHRoZSByZXF1ZXN0LiBJZiBhIHJlc3BvbnNlIHdhcyBwcm9jZXNzZWQsIGl0IHdpbGwgcmV0dXJuXG4gICAgICogICBgdW5kZWZpbmVkYCB0byBub3RpZnkgdGhhdCBpdCB3YXMgcHJvY2Vzc2VkXG4gICAgICpcbiAgICAgKiBAdGhyb3dzIHtUeXBlRXJyb3J9IC0gTWVzc2FnZSBpcyBub3QgZGVmaW5lZFxuICAgICAqL1xuICAgIHRoaXMuZGVjb2RlID0gZnVuY3Rpb24gKG1lc3NhZ2UsIHRyYW5zcG9ydCkge1xuICAgICAgICBpZiAoIW1lc3NhZ2UpIHRocm93IG5ldyBUeXBlRXJyb3IoJ01lc3NhZ2UgaXMgbm90IGRlZmluZWQnKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbWVzc2FnZSA9IHBhY2tlci51bnBhY2sobWVzc2FnZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBpbnZhbGlkIG1lc3NhZ2VzXG4gICAgICAgICAgICByZXR1cm4gY29uc29sZS5kZWJ1ZyhlLCBtZXNzYWdlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpZCA9IG1lc3NhZ2UuaWQ7XG4gICAgICAgIHZhciBhY2sgPSBtZXNzYWdlLmFjaztcbiAgICAgICAgdmFyIG1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuICAgICAgICB2YXIgcGFyYW1zID0gbWVzc2FnZS5wYXJhbXMgfHwge307XG5cbiAgICAgICAgdmFyIGZyb20gPSBwYXJhbXMuZnJvbTtcbiAgICAgICAgdmFyIGRlc3QgPSBwYXJhbXMuZGVzdDtcblxuICAgICAgICAvLyBJZ25vcmUgbWVzc2FnZXMgc2VuZCBieSB1c1xuICAgICAgICBpZiAoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkICYmIGZyb20gPT0gc2VsZi5wZWVySUQpIHJldHVybjtcblxuICAgICAgICAvLyBOb3RpZmljYXRpb25cbiAgICAgICAgaWYgKGlkID09IHVuZGVmaW5lZCAmJiBhY2sgPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB2YXIgbm90aWZpY2F0aW9uID0gbmV3IFJwY05vdGlmaWNhdGlvbihtZXRob2QsIHBhcmFtcyk7XG5cbiAgICAgICAgICAgIGlmIChzZWxmLmVtaXQoJ3JlcXVlc3QnLCBub3RpZmljYXRpb24pKSByZXR1cm47XG4gICAgICAgICAgICByZXR1cm4gbm90aWZpY2F0aW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1JlcXVlc3QoKSB7XG4gICAgICAgICAgICAvLyBJZiB3ZSBoYXZlIGEgdHJhbnNwb3J0IGFuZCBpdCdzIGEgZHVwbGljYXRlZCByZXF1ZXN0LCByZXBseSBpbm1lZGlhdGx5XG4gICAgICAgICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpIHx8IHNlbGYuZ2V0VHJhbnNwb3J0KCk7XG4gICAgICAgICAgICBpZiAodHJhbnNwb3J0KSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gcmVzcG9uc2VzLmdldChpZCwgZnJvbSk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlKSByZXR1cm4gdHJhbnNwb3J0LnNlbmQocmVzcG9uc2UubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBpZEFjayA9IGlkICE9IHVuZGVmaW5lZCA/IGlkIDogYWNrO1xuICAgICAgICAgICAgdmFyIHJlcXVlc3QgPSBuZXcgUnBjUmVxdWVzdChtZXRob2QsIHBhcmFtcywgaWRBY2ssIGZyb20sIHRyYW5zcG9ydCk7XG5cbiAgICAgICAgICAgIGlmIChzZWxmLmVtaXQoJ3JlcXVlc3QnLCByZXF1ZXN0KSkgcmV0dXJuO1xuICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgcmVxdWVzdC5jYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGR1cGxpY2F0ZWRSZXNwb25zZSh0aW1lb3V0KSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1Jlc3BvbnNlIGFscmVhZHkgcHJvY2Vzc2VkJywgbWVzc2FnZSk7XG5cbiAgICAgICAgICAgIC8vIFVwZGF0ZSBkdXBsaWNhdGVkIHJlc3BvbnNlcyB0aW1lb3V0XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgICAgICBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGFjaywgZnJvbSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZXF1ZXN0LCBvciByZXNwb25zZSB3aXRoIG93biBtZXRob2RcbiAgICAgICAgaWYgKG1ldGhvZCkge1xuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgaXQncyBhIHJlc3BvbnNlIHdpdGggb3duIG1ldGhvZFxuICAgICAgICAgICAgaWYgKGRlc3QgPT0gdW5kZWZpbmVkIHx8IGRlc3QgPT0gc2VsZi5wZWVySUQpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVxdWVzdCA9IHJlcXVlc3RzLmdldChhY2ssIGZyb20pO1xuICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXNwb25zZU1ldGhvZHMgPSByZXF1ZXN0LnJlc3BvbnNlTWV0aG9kcztcblxuICAgICAgICAgICAgICAgICAgICBpZiAobWV0aG9kID09IHJlc3BvbnNlTWV0aG9kcy5lcnJvcikgcmV0dXJuIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBwYXJhbXMpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChtZXRob2QgPT0gcmVzcG9uc2VNZXRob2RzLnJlc3BvbnNlKSByZXR1cm4gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIG51bGwsIHBhcmFtcyk7XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb2Nlc3NSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIHByb2Nlc3NlZCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc2VkKSByZXR1cm4gZHVwbGljYXRlZFJlc3BvbnNlKHByb2Nlc3NlZCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJlcXVlc3RcbiAgICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVxdWVzdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGVycm9yID0gbWVzc2FnZS5lcnJvcjtcbiAgICAgICAgdmFyIHJlc3VsdCA9IG1lc3NhZ2UucmVzdWx0O1xuXG4gICAgICAgIC8vIElnbm9yZSByZXNwb25zZXMgbm90IHNlbmQgdG8gdXNcbiAgICAgICAgaWYgKGVycm9yICYmIGVycm9yLmRlc3QgJiYgZXJyb3IuZGVzdCAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuICAgICAgICBpZiAocmVzdWx0ICYmIHJlc3VsdC5kZXN0ICYmIHJlc3VsdC5kZXN0ICE9IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAgICAgLy8gUmVzcG9uc2VcbiAgICAgICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgaWYgKCFyZXF1ZXN0KSB7XG4gICAgICAgICAgICB2YXIgcHJvY2Vzc2VkID0gcHJvY2Vzc2VkUmVzcG9uc2VzLmdldChhY2ssIGZyb20pO1xuICAgICAgICAgICAgaWYgKHByb2Nlc3NlZCkgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuXG4gICAgICAgICAgICByZXR1cm4gY29uc29sZS53YXJuKCdObyBjYWxsYmFjayB3YXMgZGVmaW5lZCBmb3IgdGhpcyBtZXNzYWdlJywgbWVzc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQcm9jZXNzIHJlc3BvbnNlXG4gICAgICAgIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBlcnJvciwgcmVzdWx0KTtcbiAgICB9O1xufVxuaW5oZXJpdHMoUnBjQnVpbGRlciwgRXZlbnRFbWl0dGVyKTtcblxuUnBjQnVpbGRlci5ScGNOb3RpZmljYXRpb24gPSBScGNOb3RpZmljYXRpb247XG5cbm1vZHVsZS5leHBvcnRzID0gUnBjQnVpbGRlcjtcblxudmFyIGNsaWVudHMgPSByZXF1aXJlKCcuL2NsaWVudHMnKTtcbnZhciB0cmFuc3BvcnRzID0gcmVxdWlyZSgnLi9jbGllbnRzL3RyYW5zcG9ydHMnKTtcblxuUnBjQnVpbGRlci5jbGllbnRzID0gY2xpZW50cztcblJwY0J1aWxkZXIuY2xpZW50cy50cmFuc3BvcnRzID0gdHJhbnNwb3J0cztcblJwY0J1aWxkZXIucGFja2VycyA9IHBhY2tlcnM7XG4iLCIvKipcbiAqIEpzb25SUEMgMi4wIHBhY2tlclxuICovXG5cbi8qKlxuICogUGFjayBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbWVzc2FnZSAtIG9iamVjdCB0byBiZSBwYWNrYWdlZC4gSXQgcmVxdWlyZXMgdG8gaGF2ZSBhbGwgdGhlXG4gKiAgIGZpZWxkcyBuZWVkZWQgYnkgdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgdGhhdCBpdCdzIGdvaW5nIHRvIGJlIGdlbmVyYXRlZFxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gLSB0aGUgc3RyaW5naWZpZWQgSnNvblJQQyAyLjAgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBwYWNrKG1lc3NhZ2UsIGlkKSB7XG4gICAgdmFyIHJlc3VsdCA9IHtcbiAgICAgICAganNvbnJwYzogJzIuMCdcbiAgICB9O1xuXG4gICAgLy8gUmVxdWVzdFxuICAgIGlmIChtZXNzYWdlLm1ldGhvZCkge1xuICAgICAgICByZXN1bHQubWV0aG9kID0gbWVzc2FnZS5tZXRob2Q7XG5cbiAgICAgICAgaWYgKG1lc3NhZ2UucGFyYW1zKSByZXN1bHQucGFyYW1zID0gbWVzc2FnZS5wYXJhbXM7XG5cbiAgICAgICAgLy8gUmVxdWVzdCBpcyBhIG5vdGlmaWNhdGlvblxuICAgICAgICBpZiAoaWQgIT0gdW5kZWZpbmVkKSByZXN1bHQuaWQgPSBpZDtcbiAgICB9XG5cbiAgICAvLyBSZXNwb25zZVxuICAgIGVsc2UgaWYgKGlkICE9IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAobWVzc2FnZS5lcnJvcikge1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2UucmVzdWx0ICE9PSB1bmRlZmluZWQpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0JvdGggcmVzdWx0IGFuZCBlcnJvciBhcmUgZGVmaW5lZCcpO1xuXG4gICAgICAgICAgICByZXN1bHQuZXJyb3IgPSBtZXNzYWdlLmVycm9yO1xuICAgICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UucmVzdWx0ICE9PSB1bmRlZmluZWQpIHJlc3VsdC5yZXN1bHQgPSBtZXNzYWdlLnJlc3VsdDtcbiAgICAgICAgZWxzZSB0aHJvdyBuZXcgVHlwZUVycm9yKCdObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZCcpO1xuXG4gICAgICAgIHJlc3VsdC5pZCA9IGlkO1xuICAgIH1cblxuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShyZXN1bHQpO1xufVxuXG4vKipcbiAqIFVucGFjayBhIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWVzc2FnZSAtIHN0cmluZyB3aXRoIHRoZSBjb250ZW50IG9mIHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHRocm93cyB7VHlwZUVycm9yfSAtIEludmFsaWQgSnNvblJQQyB2ZXJzaW9uXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSAtIG9iamVjdCBmaWxsZWQgd2l0aCB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZSBjb250ZW50XG4gKi9cbmZ1bmN0aW9uIHVucGFjayhtZXNzYWdlKSB7XG4gICAgdmFyIHJlc3VsdCA9IG1lc3NhZ2U7XG5cbiAgICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnIHx8IG1lc3NhZ2UgaW5zdGFuY2VvZiBTdHJpbmcpIHtcbiAgICAgICAgcmVzdWx0ID0gSlNPTi5wYXJzZShtZXNzYWdlKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBpdCdzIGEgdmFsaWQgbWVzc2FnZVxuXG4gICAgdmFyIHZlcnNpb24gPSByZXN1bHQuanNvbnJwYztcbiAgICBpZiAodmVyc2lvbiAhPT0gJzIuMCcpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIEpzb25SUEMgdmVyc2lvbiAnXCIgKyB2ZXJzaW9uICsgXCInOiBcIiArIG1lc3NhZ2UpO1xuXG4gICAgLy8gUmVzcG9uc2VcbiAgICBpZiAocmVzdWx0Lm1ldGhvZCA9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHJlc3VsdC5pZCA9PSB1bmRlZmluZWQpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbWVzc2FnZTogJyArIG1lc3NhZ2UpO1xuXG4gICAgICAgIHZhciByZXN1bHRfZGVmaW5lZCA9IHJlc3VsdC5yZXN1bHQgIT09IHVuZGVmaW5lZDtcbiAgICAgICAgdmFyIGVycm9yX2RlZmluZWQgPSByZXN1bHQuZXJyb3IgIT09IHVuZGVmaW5lZDtcblxuICAgICAgICAvLyBDaGVjayBvbmx5IHJlc3VsdCBvciBlcnJvciBpcyBkZWZpbmVkLCBub3QgYm90aCBvciBub25lXG4gICAgICAgIGlmIChyZXN1bHRfZGVmaW5lZCAmJiBlcnJvcl9kZWZpbmVkKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWQ6ICcgKyBtZXNzYWdlKTtcblxuICAgICAgICBpZiAoIXJlc3VsdF9kZWZpbmVkICYmICFlcnJvcl9kZWZpbmVkKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdObyByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZDogJyArIG1lc3NhZ2UpO1xuXG4gICAgICAgIHJlc3VsdC5hY2sgPSByZXN1bHQuaWQ7XG4gICAgICAgIGRlbGV0ZSByZXN1bHQuaWQ7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIHVucGFja2VkIG1lc3NhZ2VcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnRzLnBhY2sgPSBwYWNrO1xuZXhwb3J0cy51bnBhY2sgPSB1bnBhY2s7XG4iLCJmdW5jdGlvbiBwYWNrKG1lc3NhZ2UpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdOb3QgeWV0IGltcGxlbWVudGVkJyk7XG59XG5cbmZ1bmN0aW9uIHVucGFjayhtZXNzYWdlKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignTm90IHlldCBpbXBsZW1lbnRlZCcpO1xufVxuXG5leHBvcnRzLnBhY2sgPSBwYWNrO1xuZXhwb3J0cy51bnBhY2sgPSB1bnBhY2s7XG4iLCJ2YXIgSnNvblJQQyA9IHJlcXVpcmUoJy4vSnNvblJQQycpO1xudmFyIFhtbFJQQyA9IHJlcXVpcmUoJy4vWG1sUlBDJyk7XG5cbmV4cG9ydHMuSnNvblJQQyA9IEpzb25SUEM7XG5leHBvcnRzLlhtbFJQQyA9IFhtbFJQQztcbiIsInR5cGUgQ29uc29sZUZ1bmN0aW9uID0gKC4uLmRhdGE6IGFueSkgPT4gdm9pZDtcbmV4cG9ydCBjbGFzcyBDb25zb2xlTG9nZ2VyIHtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbG9nZ2VyOiBDb25zb2xlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxvZzogQ29uc29sZUZ1bmN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluZm86IENvbnNvbGVGdW5jdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkZWJ1ZzogQ29uc29sZUZ1bmN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHdhcm46IENvbnNvbGVGdW5jdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlcnJvcjogQ29uc29sZUZ1bmN0aW9uO1xuXG4gICAgY29uc3RydWN0b3IoY29uc29sZTogQ29uc29sZSkge1xuICAgICAgICB0aGlzLmxvZ2dlciA9IGNvbnNvbGU7XG4gICAgICAgICh0aGlzLmxvZyA9IGNvbnNvbGUubG9nKSxcbiAgICAgICAgICAgICh0aGlzLmluZm8gPSBjb25zb2xlLmluZm8pLFxuICAgICAgICAgICAgKHRoaXMuZGVidWcgPSBjb25zb2xlLmRlYnVnKSxcbiAgICAgICAgICAgICh0aGlzLndhcm4gPSBjb25zb2xlLndhcm4pLFxuICAgICAgICAgICAgKHRoaXMuZXJyb3IgPSBjb25zb2xlLmVycm9yKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBKTCB9IGZyb20gJ2pzbmxvZyc7XG5pbXBvcnQgeyBPcGVuVmlkdSB9IGZyb20gJy4uLy4uL09wZW5WaWR1L09wZW5WaWR1JztcbmltcG9ydCB7IENvbnNvbGVMb2dnZXIgfSBmcm9tICcuL0NvbnNvbGVMb2dnZXInO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXJDb25maWd1cmF0aW9uIH0gZnJvbSAnLi9PcGVuVmlkdUxvZ2dlckNvbmZpZ3VyYXRpb24nO1xuXG5leHBvcnQgY2xhc3MgT3BlblZpZHVMb2dnZXIge1xuICAgIHByaXZhdGUgc3RhdGljIGluc3RhbmNlOiBPcGVuVmlkdUxvZ2dlcjtcblxuICAgIHByaXZhdGUgSlNOTE9HX1VSTDogc3RyaW5nID0gJy9vcGVudmlkdS9lbGsvb3BlbnZpZHUtYnJvd3Nlci1sb2dzJztcbiAgICBwcml2YXRlIE1BWF9KU05MT0dfQkFUQ0hfTE9HX01FU1NBR0VTOiBudW1iZXIgPSAxMDA7XG4gICAgcHJpdmF0ZSBNQVhfTVNFQ09ORFNfQkFUQ0hfTUVTU0FHRVM6IG51bWJlciA9IDUwMDA7XG4gICAgcHJpdmF0ZSBNQVhfTEVOR1RIX1NUUklOR19KU09OOiBudW1iZXIgPSAxMDAwO1xuXG4gICAgcHJpdmF0ZSBkZWZhdWx0Q29uc29sZUxvZ2dlcjogQ29uc29sZUxvZ2dlciA9IG5ldyBDb25zb2xlTG9nZ2VyKGdsb2JhbFRoaXMuY29uc29sZSk7XG5cbiAgICBwcml2YXRlIGN1cnJlbnRBcHBlbmRlcjogYW55O1xuXG4gICAgcHJpdmF0ZSBpc1Byb2RNb2RlID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBpc0pTTkxvZ1NldHVwID0gZmFsc2U7XG5cbiAgICAvLyBUaGlzIHR3byB2YXJpYWJsZXMgYXJlIHVzZWQgdG8gcmVzdGFydCBKU05Mb2dcbiAgICAvLyBvbiBkaWZmZXJlbnQgc2Vzc2lvbnMgYW5kIGRpZmZlcmVudCB1c2VySWRzXG4gICAgcHJpdmF0ZSBsb2dnaW5nU2Vzc2lvbklkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3RhdGljIGNvbmZpZ3VyZUpTTkxvZyhvcGVuVmlkdTogT3BlblZpZHUsIHRva2VuOiBzdHJpbmcpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIElmIGRldiBtb2RlIG9yLi4uXG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgZ2xvYmFsVGhpc1snTE9HX0pTTkxPR19SRVNVTFRTJ10gfHxcbiAgICAgICAgICAgICAgICAvLyBJZiBpbnN0YW5jZSBpcyBjcmVhdGVkIGFuZCBpdCBpcyBPcGVuVmlkdSBQcm9cbiAgICAgICAgICAgICAgICAodGhpcy5pbnN0YW5jZSAmJlxuICAgICAgICAgICAgICAgICAgICBvcGVuVmlkdS5pc0F0TGVhc3RQcm8gJiZcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgbG9ncyBhcmUgZW5hYmxlZFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmluc3RhbmNlLmlzT3BlblZpZHVCcm93c2VyTG9nc0RlYnVnQWN0aXZlKG9wZW5WaWR1KSAmJlxuICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IHJlY29uZmlndXJlIGl0IGlmIHNlc3Npb24gb3IgZmluYWxVc2VySWQgaGFzIGNoYW5nZWRcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5jYW5Db25maWd1cmVKU05Mb2cob3BlblZpZHUsIHRoaXMuaW5zdGFuY2UpKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgYXBwIGxvZ3MgY2FuIGJlIHNlbnRcbiAgICAgICAgICAgICAgICAvLyBhbmQgcmVwbGFjZSBjb25zb2xlLmxvZyBmdW5jdGlvbiB0byBzZW5kXG4gICAgICAgICAgICAgICAgLy8gbG9ncyBvZiB0aGUgYXBwbGljYXRpb25cbiAgICAgICAgICAgICAgICBpZiAob3BlblZpZHUuc2VuZEJyb3dzZXJMb2dzID09PSBPcGVuVmlkdUxvZ2dlckNvbmZpZ3VyYXRpb24uZGVidWdfYXBwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UucmVwbGFjZVdpbmRvd0NvbnNvbGUoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBpc0pTTkxvZ1NldHVwIHdpbGwgbm90IGJlIHRydWUgdW50aWwgY29tcGxldGVkIHNldHVwXG4gICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5pc0pTTkxvZ1NldHVwID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5pbmZvKCdDb25maWd1cmluZyBKU05Mb2dzLicpO1xuXG4gICAgICAgICAgICAgICAgY29uc3QgZmluYWxVc2VySWQgPSBvcGVuVmlkdS5maW5hbFVzZXJJZDtcbiAgICAgICAgICAgICAgICBjb25zdCBzZXNzaW9uSWQgPSBvcGVuVmlkdS5zZXNzaW9uLnNlc3Npb25JZDtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGJlZm9yZVNlbmRDYWxsYmFjayA9ICh4aHIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgNDAxIG9yIDQwMyBvciA0MDQgbW9kaWZ5IHJlYWR5IGFuZCBzdGF0dXMgc28gSlNOTG9nIGRvbid0IHJldHJ5IHRvIHNlbmQgbG9nc1xuICAgICAgICAgICAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbXBlcmRlY2svanNubG9nLmpzL2Jsb2IvdjIuMzAuMC9qc25sb2cudHMjTDgwNS1MODE4XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcmVudFJlYWR5U3RhdGVGdW5jdGlvbiA9IHhoci5vbnJlYWR5c3RhdGVjaGFuZ2U7XG4gICAgICAgICAgICAgICAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0ludmFsaWRSZXNwb25zZSh4aHIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHhociwgJ3JlYWR5U3RhdGUnLCB7IHZhbHVlOiA0IH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh4aHIsICdzdGF0dXMnLCB7IHZhbHVlOiAyMDAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGlzYWJsZSBKU05Mb2cgdG9vIHRvIG5vdCBzZW5kIHBlcmlvZGljYWxseSBlcnJvcnNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluc3RhbmNlLmRpc2FibGVMb2dnZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudFJlYWR5U3RhdGVGdW5jdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIEhlYWRlcnMgdG8gaWRlbnRpZnkgYW5kIGF1dGhlbnRpY2F0ZSBsb2dzXG4gICAgICAgICAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdBdXRob3JpemF0aW9uJywgJ0Jhc2ljICcgKyBidG9hKGAke2ZpbmFsVXNlcklkfSUvJSR7c2Vzc2lvbklkfWAgKyAnOicgKyB0b2tlbikpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignWC1SZXF1ZXN0ZWQtV2l0aCcsICdYTUxIdHRwUmVxdWVzdCcpO1xuICAgICAgICAgICAgICAgICAgICAvLyBBZGRpdGlvbmFsIGhlYWRlcnMgZm9yIE9wZW5WaWR1XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdPVi1GaW5hbC1Vc2VyLUlkJywgZmluYWxVc2VySWQpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignT1YtU2Vzc2lvbi1JZCcsIHNlc3Npb25JZCk7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdPVi1Ub2tlbicsIHRva2VuKTtcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgLy8gQ3JlYXRpb24gb2YgdGhlIGFwcGVuZGVyLlxuICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuY3VycmVudEFwcGVuZGVyID0gSkwuY3JlYXRlQWpheEFwcGVuZGVyKGBhcHBlbmRlci0ke2ZpbmFsVXNlcklkfS0ke3Nlc3Npb25JZH1gKTtcbiAgICAgICAgICAgICAgICB0aGlzLmluc3RhbmNlLmN1cnJlbnRBcHBlbmRlci5zZXRPcHRpb25zKHtcbiAgICAgICAgICAgICAgICAgICAgYmVmb3JlU2VuZDogYmVmb3JlU2VuZENhbGxiYWNrLFxuICAgICAgICAgICAgICAgICAgICBtYXhCYXRjaFNpemU6IDEwMDAsXG4gICAgICAgICAgICAgICAgICAgIGJhdGNoU2l6ZTogdGhpcy5pbnN0YW5jZS5NQVhfSlNOTE9HX0JBVENIX0xPR19NRVNTQUdFUyxcbiAgICAgICAgICAgICAgICAgICAgYmF0Y2hUaW1lb3V0OiB0aGlzLmluc3RhbmNlLk1BWF9NU0VDT05EU19CQVRDSF9NRVNTQUdFU1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgLy8gQXZvaWQgY2lyY3VsYXIgZGVwZW5kZW5jaWVzXG4gICAgICAgICAgICAgICAgY29uc3QgbG9nU2VyaWFsaXplciA9IChvYmopOiBzdHJpbmcgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBnZXRDaXJjdWxhclJlcGxhY2VyID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2VlbiA9IG5ldyBXZWFrU2V0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGtleSwgdmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWVuLmhhcyh2YWx1ZSkgfHwgKGdsb2JhbFRoaXMuSFRNTEVsZW1lbnQgJiYgdmFsdWUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVuLmFkZCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQ3V0IGxvbmcgbWVzc2FnZXNcbiAgICAgICAgICAgICAgICAgICAgbGV0IHN0cmluZ2lmeUpzb24gPSBKU09OLnN0cmluZ2lmeShvYmosIGdldENpcmN1bGFyUmVwbGFjZXIoKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHJpbmdpZnlKc29uLmxlbmd0aCA+IHRoaXMuaW5zdGFuY2UuTUFYX0xFTkdUSF9TVFJJTkdfSlNPTikge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5naWZ5SnNvbiA9IGAke3N0cmluZ2lmeUpzb24uc3Vic3RyaW5nKDAsIHRoaXMuaW5zdGFuY2UuTUFYX0xFTkdUSF9TVFJJTkdfSlNPTil9Li4uYDtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChnbG9iYWxUaGlzWydMT0dfSlNOTE9HX1JFU1VMVFMnXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coc3RyaW5naWZ5SnNvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RyaW5naWZ5SnNvbjtcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBKTCB0byBzZW5kIGxvZ3NcbiAgICAgICAgICAgICAgICBKTC5zZXRPcHRpb25zKHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdEFqYXhVcmw6IG9wZW5WaWR1Lmh0dHBVcmkgKyB0aGlzLmluc3RhbmNlLkpTTkxPR19VUkwsXG4gICAgICAgICAgICAgICAgICAgIHNlcmlhbGl6ZTogbG9nU2VyaWFsaXplcixcbiAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIEpMKCkuc2V0T3B0aW9ucyh7XG4gICAgICAgICAgICAgICAgICAgIGFwcGVuZGVyczogW3RoaXMuaW5zdGFuY2UuY3VycmVudEFwcGVuZGVyXVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5pc0pTTkxvZ1NldHVwID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLmluc3RhbmNlLmxvZ2dpbmdTZXNzaW9uSWQgPSBzZXNzaW9uSWQ7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5pbmZvKCdKU05Mb2cgY29uZmlndXJlZC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgLy8gUHJpbnQgZXJyb3JcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGNvbmZpZ3VyaW5nIEpTTkxvZzogJyk7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICAgICAgLy8gUmVzdG9yZSBkZWZhdWx0cyB2YWx1ZXMganVzdCBpbiBjYXNlIGFueSBleGNlcHRpb24gaGFwcGVuLVxuICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5kaXNhYmxlTG9nZ2VyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3RhdGljIGdldEluc3RhbmNlKCk6IE9wZW5WaWR1TG9nZ2VyIHtcbiAgICAgICAgaWYgKCFPcGVuVmlkdUxvZ2dlci5pbnN0YW5jZSkge1xuICAgICAgICAgICAgT3BlblZpZHVMb2dnZXIuaW5zdGFuY2UgPSBuZXcgT3BlblZpZHVMb2dnZXIoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gT3BlblZpZHVMb2dnZXIuaW5zdGFuY2U7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgaXNJbnZhbGlkUmVzcG9uc2UoeGhyOiBYTUxIdHRwUmVxdWVzdCkge1xuICAgICAgICByZXR1cm4geGhyLnN0YXR1cyA9PSA0MDEgfHwgeGhyLnN0YXR1cyA9PSA0MDMgfHwgeGhyLnN0YXR1cyA9PSA0MDQgfHwgeGhyLnN0YXR1cyA9PSAwO1xuICAgIH1cblxuICAgIHByaXZhdGUgY2FuQ29uZmlndXJlSlNOTG9nKG9wZW5WaWR1OiBPcGVuVmlkdSwgbG9nZ2VyOiBPcGVuVmlkdUxvZ2dlcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gb3BlblZpZHUuc2Vzc2lvbi5zZXNzaW9uSWQgIT0gbG9nZ2VyLmxvZ2dpbmdTZXNzaW9uSWQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc09wZW5WaWR1QnJvd3NlckxvZ3NEZWJ1Z0FjdGl2ZShvcGVuVmlkdTogT3BlblZpZHUpIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIG9wZW5WaWR1LnNlbmRCcm93c2VyTG9ncyA9PT0gT3BlblZpZHVMb2dnZXJDb25maWd1cmF0aW9uLmRlYnVnIHx8XG4gICAgICAgICAgICBvcGVuVmlkdS5zZW5kQnJvd3NlckxvZ3MgPT09IE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbi5kZWJ1Z19hcHBcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gY29uc29sZSBmdW5jdGlvbnMgd2l0aCBqc25sb2cgaW50ZWdyYXRpb25cbiAgICBwcml2YXRlIGdldENvbnNvbGVXaXRoSlNOTG9nKCkge1xuICAgICAgICByZXR1cm4gKGZ1bmN0aW9uIChvcGVuVmlkdUxvZ2dlcjogT3BlblZpZHVMb2dnZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgbG9nOiBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgICAgICAgICAgICAgICAgICBvcGVuVmlkdUxvZ2dlci5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2cuYXBwbHkob3BlblZpZHVMb2dnZXIuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3BlblZpZHVMb2dnZXIuaXNKU05Mb2dTZXR1cCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgSkwoKS5pbmZvKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGluZm86IGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgICAgIG9wZW5WaWR1TG9nZ2VyLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmluZm8uYXBwbHkob3BlblZpZHVMb2dnZXIuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3BlblZpZHVMb2dnZXIuaXNKU05Mb2dTZXR1cCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgSkwoKS5pbmZvKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGRlYnVnOiBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgICAgICAgICAgICAgICAgICBvcGVuVmlkdUxvZ2dlci5kZWZhdWx0Q29uc29sZUxvZ2dlci5kZWJ1Zy5hcHBseShvcGVuVmlkdUxvZ2dlci5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2dnZXIsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB3YXJuOiBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgICAgICAgICAgICAgICAgICBvcGVuVmlkdUxvZ2dlci5kZWZhdWx0Q29uc29sZUxvZ2dlci53YXJuLmFwcGx5KG9wZW5WaWR1TG9nZ2VyLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmxvZ2dlciwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW5WaWR1TG9nZ2VyLmlzSlNOTG9nU2V0dXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEpMKCkud2Fybihhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlblZpZHVMb2dnZXIuZGVmYXVsdENvbnNvbGVMb2dnZXIuZXJyb3IuYXBwbHkob3BlblZpZHVMb2dnZXIuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3BlblZpZHVMb2dnZXIuaXNKU05Mb2dTZXR1cCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgSkwoKS5lcnJvcihhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkodGhpcyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZXBsYWNlV2luZG93Q29uc29sZSgpIHtcbiAgICAgICAgZ2xvYmFsVGhpcy5jb25zb2xlID0gdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2dnZXI7XG4gICAgICAgIGdsb2JhbFRoaXMuY29uc29sZS5sb2cgPSB0aGlzLmdldENvbnNvbGVXaXRoSlNOTG9nKCkubG9nO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUuaW5mbyA9IHRoaXMuZ2V0Q29uc29sZVdpdGhKU05Mb2coKS5pbmZvO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUuZGVidWcgPSB0aGlzLmdldENvbnNvbGVXaXRoSlNOTG9nKCkuZGVidWc7XG4gICAgICAgIGdsb2JhbFRoaXMuY29uc29sZS53YXJuID0gdGhpcy5nZXRDb25zb2xlV2l0aEpTTkxvZygpLndhcm47XG4gICAgICAgIGdsb2JhbFRoaXMuY29uc29sZS5lcnJvciA9IHRoaXMuZ2V0Q29uc29sZVdpdGhKU05Mb2coKS5lcnJvcjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGRpc2FibGVMb2dnZXIoKSB7XG4gICAgICAgIEpMLnNldE9wdGlvbnMoeyBlbmFibGVkOiBmYWxzZSB9KTtcbiAgICAgICAgdGhpcy5pc0pTTkxvZ1NldHVwID0gZmFsc2U7XG4gICAgICAgIHRoaXMubG9nZ2luZ1Nlc3Npb25JZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5jdXJyZW50QXBwZW5kZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIGdsb2JhbFRoaXMuY29uc29sZSA9IHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUubG9nID0gdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2c7XG4gICAgICAgIGdsb2JhbFRoaXMuY29uc29sZS5pbmZvID0gdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5pbmZvO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUuZGVidWcgPSB0aGlzLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmRlYnVnO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUud2FybiA9IHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIud2FybjtcbiAgICAgICAgZ2xvYmFsVGhpcy5jb25zb2xlLmVycm9yID0gdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5lcnJvcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbG9nKC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICAgIGlmICghdGhpcy5pc1Byb2RNb2RlKSB7XG4gICAgICAgICAgICB0aGlzLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmxvZy5hcHBseSh0aGlzLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmxvZ2dlciwgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5pc0pTTkxvZ1NldHVwKSB7XG4gICAgICAgICAgICBKTCgpLmluZm8oYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkZWJ1ZyguLi5hcmdzOiBhbnlbXSkge1xuICAgICAgICBpZiAoIXRoaXMuaXNQcm9kTW9kZSkge1xuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5kZWJ1Zy5hcHBseSh0aGlzLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmxvZ2dlciwgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbmZvKC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICAgIGlmICghdGhpcy5pc1Byb2RNb2RlKSB7XG4gICAgICAgICAgICB0aGlzLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmluZm8uYXBwbHkodGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2dnZXIsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaXNKU05Mb2dTZXR1cCkge1xuICAgICAgICAgICAgSkwoKS5pbmZvKGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgd2FybiguLi5hcmdzOiBhbnlbXSkge1xuICAgICAgICB0aGlzLmRlZmF1bHRDb25zb2xlTG9nZ2VyLndhcm4uYXBwbHkodGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2dnZXIsIGFyZ3VtZW50cyk7XG4gICAgICAgIGlmICh0aGlzLmlzSlNOTG9nU2V0dXApIHtcbiAgICAgICAgICAgIEpMKCkud2Fybihhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVycm9yKC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICAgIHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIuZXJyb3IuYXBwbHkodGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2dnZXIsIGFyZ3VtZW50cyk7XG4gICAgICAgIGlmICh0aGlzLmlzSlNOTG9nU2V0dXApIHtcbiAgICAgICAgICAgIEpMKCkuZXJyb3IoYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBmbHVzaCgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNKU05Mb2dTZXR1cCAmJiB0aGlzLmN1cnJlbnRBcHBlbmRlciAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRBcHBlbmRlci5zZW5kQmF0Y2goKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGVuYWJsZVByb2RNb2RlKCkge1xuICAgICAgICB0aGlzLmlzUHJvZE1vZGUgPSB0cnVlO1xuICAgIH1cbn1cbiIsImV4cG9ydCBlbnVtIE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbiB7XG4gICAgZGlzYWJsZWQgPSAnZGlzYWJsZWQnLFxuICAgIGRlYnVnID0gJ2RlYnVnJyxcbiAgICBkZWJ1Z19hcHAgPSAnZGVidWdfYXBwJ1xufVxuIiwiLy8gTGFzdCB0aW1lIHVwZGF0ZWQgb24gSnVuZSAwOCwgMjAxOFxuXG4vLyBMYXRlc3QgZmlsZSBjYW4gYmUgZm91bmQgaGVyZTogaHR0cHM6Ly9jZG4ud2VicnRjLWV4cGVyaW1lbnQuY29tL2dldFNjcmVlbklkLmpzXG5cbi8vIE11YXogS2hhbiAgICAgICAgIC0gd3d3Lk11YXpLaGFuLmNvbVxuLy8gTUlUIExpY2Vuc2UgICAgICAgLSB3d3cuV2ViUlRDLUV4cGVyaW1lbnQuY29tL2xpY2VuY2Vcbi8vIERvY3VtZW50YXRpb24gICAgIC0gaHR0cHM6Ly9naXRodWIuY29tL211YXota2hhbi9nZXRTY3JlZW5JZC5cblxuLy8gX19fX19fX19fX19fX19cbi8vIGdldFNjcmVlbklkLmpzXG5cbi8qXG5nZXRTY3JlZW5JZChmdW5jdGlvbiAoZXJyb3IsIHNvdXJjZUlkLCBzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAvLyBlcnJvciAgICA9PSBudWxsIHx8ICdwZXJtaXNzaW9uLWRlbmllZCcgfHwgJ25vdC1pbnN0YWxsZWQnIHx8ICdpbnN0YWxsZWQtZGlzYWJsZWQnIHx8ICdub3QtY2hyb21lJ1xuICAgIC8vIHNvdXJjZUlkID09IG51bGwgfHwgJ3N0cmluZycgfHwgJ2ZpcmVmb3gnXG5cbiAgICBpZihtaWNyb3NvZnRFZGdlKSB7XG4gICAgICAgIG5hdmlnYXRvci5nZXREaXNwbGF5TWVkaWEoc2NyZWVuX2NvbnN0cmFpbnRzKS50aGVuKG9uU3VjY2Vzcywgb25GYWlsdXJlKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MpY2F0Y2gob25GYWlsdXJlKTtcbiAgICB9XG59LCAncGFzcyBzZWNvbmQgcGFyYW1ldGVyIG9ubHkgaWYgeW91IHdhbnQgc3lzdGVtIGF1ZGlvJyk7XG4qL1xuXG5nbG9iYWxUaGlzLmdldFNjcmVlbklkID0gZnVuY3Rpb24gKGZpcmVmb3hTdHJpbmcsIGNhbGxiYWNrLCBjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgaWYgKG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignRWRnZScpICE9PSAtMSAmJiAoISFuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYiB8fCAhIW5hdmlnYXRvci5tc1NhdmVCbG9iKSkge1xuICAgICAgICAvLyBtaWNyb3NvZnQgZWRnZSA9PiBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgICAgIGNhbGxiYWNrKHtcbiAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gZm9yIEZpcmVmb3g6XG4gICAgLy8gc291cmNlSWQgPT0gJ2ZpcmVmb3gnXG4gICAgLy8gc2NyZWVuX2NvbnN0cmFpbnRzID0gey4uLn1cbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwsICdmaXJlZm94Jywge1xuICAgICAgICAgICAgdmlkZW86IHtcbiAgICAgICAgICAgICAgICBtb3pNZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZyxcbiAgICAgICAgICAgICAgICBtZWRpYVNvdXJjZTogZmlyZWZveFN0cmluZ1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuXG4gICAgZnVuY3Rpb24gb25JRnJhbWVDYWxsYmFjayhldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LmRhdGEpIHJldHVybjtcblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkKSB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkID09PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdwZXJtaXNzaW9uLWRlbmllZCcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLFxuICAgICAgICAgICAgICAgICAgICBnZXRTY3JlZW5Db25zdHJhaW50cyhudWxsLCBldmVudC5kYXRhLmNocm9tZU1lZGlhU291cmNlSWQsIGV2ZW50LmRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2spXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgZ2xvYmFsVGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzLCBudWxsLCBnZXRTY3JlZW5Db25zdHJhaW50cyhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykpO1xuXG4gICAgICAgICAgICAvLyB0aGlzIGV2ZW50IGxpc3RlbmVyIGlzIG5vIG1vcmUgbmVlZGVkXG4gICAgICAgICAgICBnbG9iYWxUaGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICghY3VzdG9tX3BhcmFtZXRlcikge1xuICAgICAgICBzZXRUaW1lb3V0KHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UsIDEwMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzKGVycm9yLCBzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICB2YXIgc2NyZWVuX2NvbnN0cmFpbnRzID0ge1xuICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgICAgICBtYXhXaWR0aDogZ2xvYmFsVGhpcy5zY3JlZW4ud2lkdGggPiAxOTIwID8gZ2xvYmFsVGhpcy5zY3JlZW4ud2lkdGggOiAxOTIwLFxuICAgICAgICAgICAgICAgIG1heEhlaWdodDogZ2xvYmFsVGhpcy5zY3JlZW4uaGVpZ2h0ID4gMTA4MCA/IGdsb2JhbFRoaXMuc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoISFjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gPSB7XG4gICAgICAgICAgICBtYW5kYXRvcnk6IHtcbiAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogZXJyb3IgPyAnc2NyZWVuJyA6ICdkZXNrdG9wJ1xuICAgICAgICAgICAgICAgIC8vIGVjaG9DYW5jZWxsYXRpb246IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvcHRpb25hbDogW11cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoc291cmNlSWQpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG5cbiAgICAgICAgaWYgKHNjcmVlbl9jb25zdHJhaW50cy5hdWRpbyAmJiBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5KSB7XG4gICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuYXVkaW8ubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzY3JlZW5fY29uc3RyYWludHM7XG59XG5cbmZ1bmN0aW9uIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcikge1xuICAgIGlmICghaWZyYW1lKSB7XG4gICAgICAgIGxvYWRJRnJhbWUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0sIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJyonXG4gICAgICAgICk7XG4gICAgfSBlbHNlIGlmICghIWN1c3RvbV9wYXJhbWV0ZXIuZm9yRWFjaCkge1xuICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjYXB0dXJlQ3VzdG9tU291cmNlSWQ6IGN1c3RvbV9wYXJhbWV0ZXJcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnKidcbiAgICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZShcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjYXB0dXJlU291cmNlSWRXaXRoQXVkaW86IHRydWVcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAnKidcbiAgICAgICAgKTtcbiAgICB9XG59XG5cbnZhciBpZnJhbWU7XG5cbi8vIHRoaXMgZnVuY3Rpb24gaXMgdXNlZCBpbiBSVENNdWx0aUNvbm5lY3Rpb24gdjNcbmdsb2JhbFRoaXMuZ2V0U2NyZWVuQ29uc3RyYWludHMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZ2V0U2NyZWVuSWQoZnVuY3Rpb24gKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuX2NvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICBpZiAoIXNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IHRydWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgc2NyZWVuX2NvbnN0cmFpbnRzLnZpZGVvKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG5mdW5jdGlvbiBsb2FkSUZyYW1lKGxvYWRDYWxsYmFjaykge1xuICAgIGlmIChpZnJhbWUpIHtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICBpZnJhbWUub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZnJhbWUuaXNMb2FkZWQgPSB0cnVlO1xuICAgICAgICBsb2FkQ2FsbGJhY2soKTtcbiAgICB9O1xuICAgIGlmcmFtZS5zcmMgPSAnaHR0cHM6Ly9vcGVudmlkdS5naXRodWIuaW8vb3BlbnZpZHUtc2NyZWVuLXNoYXJpbmctY2hyb21lLWV4dGVuc2lvbi8nO1xuICAgIGlmcmFtZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIChkb2N1bWVudC5ib2R5IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbn1cblxuZ2xvYmFsVGhpcy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAvLyBmb3IgRmlyZWZveDpcbiAgICBpZiAoISFuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKSB7XG4gICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZW5hYmxlZCcpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZ2xvYmFsVGhpcy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG5cbiAgICBmdW5jdGlvbiBvbklGcmFtZUNhbGxiYWNrKGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQuZGF0YSkgcmV0dXJuO1xuXG4gICAgICAgIGlmIChldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cykge1xuICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpO1xuXG4gICAgICAgICAgICAvLyB0aGlzIGV2ZW50IGxpc3RlbmVyIGlzIG5vIG1vcmUgbmVlZGVkXG4gICAgICAgICAgICBnbG9iYWxUaGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG59O1xuXG5mdW5jdGlvbiBwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSgpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaWZyYW1lLmlzTG9hZGVkKSB7XG4gICAgICAgIHNldFRpbWVvdXQocG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UsIDEwMCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZnJhbWUuY29udGVudFdpbmRvdy5wb3N0TWVzc2FnZShcbiAgICAgICAge1xuICAgICAgICAgICAgZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzOiB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgICcqJ1xuICAgICk7XG59XG5cbmV4cG9ydHMuZ2V0U2NyZWVuSWQgPSBnbG9iYWxUaGlzLmdldFNjcmVlbklkO1xuIiwiLy8gZ2xvYmFsIHZhcmlhYmxlc1xudmFyIGNocm9tZU1lZGlhU291cmNlID0gJ3NjcmVlbic7XG52YXIgc291cmNlSWQ7XG52YXIgc2NyZWVuQ2FsbGJhY2s7XG5cbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgbmF2aWdhdG9yLnVzZXJBZ2VudCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB2YXIgaXNGaXJlZm94ID0gdHlwZW9mIHdpbmRvdy5JbnN0YWxsVHJpZ2dlciAhPT0gJ3VuZGVmaW5lZCc7XG4gICAgdmFyIGlzT3BlcmEgPSAhIXdpbmRvdy5vcGVyYSB8fCBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJyBPUFIvJykgPj0gMDtcbiAgICB2YXIgaXNDaHJvbWUgPSAhIXdpbmRvdy5jaHJvbWUgJiYgIWlzT3BlcmE7XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICBpZiAoZXZlbnQub3JpZ2luICE9IHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBvbk1lc3NhZ2VDYWxsYmFjayhldmVudC5kYXRhKTtcbiAgICB9KTtcbn1cblxuLy8gYW5kIHRoZSBmdW5jdGlvbiB0aGF0IGhhbmRsZXMgcmVjZWl2ZWQgbWVzc2FnZXNcbmZ1bmN0aW9uIG9uTWVzc2FnZUNhbGxiYWNrKGRhdGEpIHtcbiAgICAvLyBcImNhbmNlbFwiIGJ1dHRvbiBpcyBjbGlja2VkXG4gICAgaWYgKGRhdGEgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgaWYgKHNjcmVlbkNhbGxiYWNrKSByZXR1cm4gc2NyZWVuQ2FsbGJhY2soJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpO1xuICAgICAgICBlbHNlIHRocm93IG5ldyBFcnJvcignUGVybWlzc2lvbkRlbmllZEVycm9yJyk7XG4gICAgfVxuICAgIC8vIGV4dGVuc2lvbiBub3RpZmllZCBoaXMgcHJlc2VuY2VcbiAgICBpZiAoZGF0YSA9PSAncnRjbXVsdGljb25uZWN0aW9uLWV4dGVuc2lvbi1sb2FkZWQnKSB7XG4gICAgICAgIGNocm9tZU1lZGlhU291cmNlID0gJ2Rlc2t0b3AnO1xuICAgIH1cbiAgICAvLyBleHRlbnNpb24gc2hhcmVkIHRlbXAgc291cmNlSWRcbiAgICBpZiAoZGF0YS5zb3VyY2VJZCAmJiBzY3JlZW5DYWxsYmFjaykge1xuICAgICAgICBzY3JlZW5DYWxsYmFjaygoc291cmNlSWQgPSBkYXRhLnNvdXJjZUlkKSwgZGF0YS5jYW5SZXF1ZXN0QXVkaW9UcmFjayA9PT0gdHJ1ZSk7XG4gICAgfVxufVxuXG4vLyB0aGlzIG1ldGhvZCBjYW4gYmUgdXNlZCB0byBjaGVjayBpZiBjaHJvbWUgZXh0ZW5zaW9uIGlzIGluc3RhbGxlZCAmIGVuYWJsZWQuXG5mdW5jdGlvbiBpc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZShjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spIHJldHVybjtcbiAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ2Rlc2t0b3AnKSByZXR1cm4gY2FsbGJhY2sodHJ1ZSk7XG5cbiAgICAvLyBhc2sgZXh0ZW5zaW9uIGlmIGl0IGlzIGF2YWlsYWJsZVxuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXJlLXlvdS10aGVyZScsICcqJyk7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgY2FsbGJhY2soZmFsc2UpO1xuICAgICAgICB9IGVsc2UgY2FsbGJhY2sodHJ1ZSk7XG4gICAgfSwgMjAwMCk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRTb3VyY2VJZChjYWxsYmFjaykge1xuICAgIGlmICghY2FsbGJhY2spIHRocm93ICdcImNhbGxiYWNrXCIgcGFyYW1ldGVyIGlzIG1hbmRhdG9yeS4nO1xuICAgIGlmIChzb3VyY2VJZCkgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnZ2V0LXNvdXJjZUlkJywgJyonKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldEN1c3RvbVNvdXJjZUlkKGFyciwgY2FsbGJhY2spIHtcbiAgICBpZiAoIWFyciB8fCAhYXJyLmZvckVhY2gpIHRocm93ICdcImFyclwiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkgYW5kIGl0IG11c3QgYmUgYW4gYXJyYXkuJztcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcblxuICAgIGlmIChzb3VyY2VJZCkgcmV0dXJuIGNhbGxiYWNrKHNvdXJjZUlkKTtcblxuICAgIHNjcmVlbkNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgd2luZG93LnBvc3RNZXNzYWdlKFxuICAgICAgICB7XG4gICAgICAgICAgICAnZ2V0LWN1c3RvbS1zb3VyY2VJZCc6IGFyclxuICAgICAgICB9LFxuICAgICAgICAnKidcbiAgICApO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWRXaXRoQXVkaW8oY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgnYXVkaW8tcGx1cy10YWInLCAnKicpO1xufVxuXG5mdW5jdGlvbiBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMoZXh0ZW5zaW9uaWQsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGlzRmlyZWZveCkgcmV0dXJuIGNhbGxiYWNrKCdub3QtY2hyb21lJyk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggIT0gMikge1xuICAgICAgICBjYWxsYmFjayA9IGV4dGVuc2lvbmlkO1xuICAgICAgICBleHRlbnNpb25pZCA9ICdsZmNnZmVwYWZub2JkbG9lY2NobmZhY2xpYmVuam9sZCc7IC8vIGRlZmF1bHQgZXh0ZW5zaW9uLWlkXG4gICAgfVxuICAgIHZhciBpbWFnZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgIGltYWdlLnNyYyA9ICdjaHJvbWUtZXh0ZW5zaW9uOi8vJyArIGV4dGVuc2lvbmlkICsgJy9pY29uLnBuZyc7XG4gICAgaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZSA9ICdzY3JlZW4nO1xuICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnc2NyZWVuJykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCdpbnN0YWxsZWQtZGlzYWJsZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSBjYWxsYmFjaygnaW5zdGFsbGVkLWVuYWJsZWQnKTtcbiAgICAgICAgfSwgMjAwMCk7XG4gICAgfTtcbiAgICBpbWFnZS5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBjYWxsYmFjaygnbm90LWluc3RhbGxlZCcpO1xuICAgIH07XG59XG5cbmZ1bmN0aW9uIGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgZ2V0U2NyZWVuQ29uc3RyYWludHMoY2FsbGJhY2ssIHRydWUpO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGV4cGxhaW5zIGhvdyB0byB1c2UgYWJvdmUgbWV0aG9kcy9vYmplY3RzXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhjYWxsYmFjaywgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvKSB7XG4gICAgc291cmNlSWQgPSAnJztcbiAgICB2YXIgZmlyZWZveFNjcmVlbkNvbnN0cmFpbnRzID0ge1xuICAgICAgICBtb3pNZWRpYVNvdXJjZTogJ3dpbmRvdycsXG4gICAgICAgIG1lZGlhU291cmNlOiAnd2luZG93J1xuICAgIH07XG4gICAgaWYgKGlzRmlyZWZveCkgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGZpcmVmb3hTY3JlZW5Db25zdHJhaW50cyk7XG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgZGVmaW5lcyBnZXRVc2VyTWVkaWEgY29uc3RyYWludHNcbiAgICAvLyB0aGF0IHdpbGwgYmUgdXNlZCB0byBjYXB0dXJlIGNvbnRlbnQgb2Ygc2NyZWVuXG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogY2hyb21lTWVkaWFTb3VyY2UsXG4gICAgICAgICAgICBtYXhXaWR0aDogc2NyZWVuLndpZHRoID4gMTkyMCA/IHNjcmVlbi53aWR0aCA6IDE5MjAsXG4gICAgICAgICAgICBtYXhIZWlnaHQ6IHNjcmVlbi5oZWlnaHQgPiAxMDgwID8gc2NyZWVuLmhlaWdodCA6IDEwODBcbiAgICAgICAgfSxcbiAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgfTtcbiAgICAvLyB0aGlzIHN0YXRlbWVudCB2ZXJpZmllcyBjaHJvbWUgZXh0ZW5zaW9uIGF2YWlsYWJpbGl0eVxuICAgIC8vIGlmIGluc3RhbGxlZCBhbmQgYXZhaWxhYmxlIHRoZW4gaXQgd2lsbCBpbnZva2UgZXh0ZW5zaW9uIEFQSVxuICAgIC8vIG90aGVyd2lzZSBpdCB3aWxsIGZhbGxiYWNrIHRvIGNvbW1hbmQtbGluZSBiYXNlZCBzY3JlZW4gY2FwdHVyaW5nIEFQSVxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcgJiYgIXNvdXJjZUlkKSB7XG4gICAgICAgIGlmIChjYXB0dXJlU291cmNlSWRXaXRoQXVkaW8pIHtcbiAgICAgICAgICAgIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGZ1bmN0aW9uIChzb3VyY2VJZCwgY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcblxuICAgICAgICAgICAgICAgIGlmIChjYW5SZXF1ZXN0QXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhzb3VyY2VJZCA9PSAnUGVybWlzc2lvbkRlbmllZEVycm9yJyA/IHNvdXJjZUlkIDogbnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZ2V0U291cmNlSWQoZnVuY3Rpb24gKHNvdXJjZUlkKSB7XG4gICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soc291cmNlSWQgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicgPyBzb3VyY2VJZCA6IG51bGwsIHNjcmVlbl9jb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgc2V0cyBnZXRzICdzb3VyY2VJZFwiIGFuZCBzZXRzIFwiY2hyb21lTWVkaWFTb3VyY2VJZFwiXG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykge1xuICAgICAgICBzY3JlZW5fY29uc3RyYWludHMubWFuZGF0b3J5LmNocm9tZU1lZGlhU291cmNlSWQgPSBzb3VyY2VJZDtcbiAgICB9XG5cbiAgICAvLyBub3cgaW52b2tpbmcgbmF0aXZlIGdldFVzZXJNZWRpYSBBUElcbiAgICBjYWxsYmFjayhudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZ2V0U2NyZWVuQ29uc3RyYWludHM7XG5leHBvcnRzLmdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvID0gZ2V0U2NyZWVuQ29uc3RyYWludHNXaXRoQXVkaW87XG5leHBvcnRzLmlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlID0gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGU7XG5leHBvcnRzLmdldENocm9tZUV4dGVuc2lvblN0YXR1cyA9IGdldENocm9tZUV4dGVuc2lvblN0YXR1cztcbmV4cG9ydHMuZ2V0U291cmNlSWQgPSBnZXRTb3VyY2VJZDtcbiIsImltcG9ydCBwbGF0Zm9ybSA9IHJlcXVpcmUoJ3BsYXRmb3JtJyk7XG5cbmV4cG9ydCBjbGFzcyBQbGF0Zm9ybVV0aWxzIHtcbiAgICBwcm90ZWN0ZWQgc3RhdGljIGluc3RhbmNlOiBQbGF0Zm9ybVV0aWxzO1xuICAgIGNvbnN0cnVjdG9yKCkge31cblxuICAgIHN0YXRpYyBnZXRJbnN0YW5jZSgpOiBQbGF0Zm9ybVV0aWxzIHtcbiAgICAgICAgaWYgKCF0aGlzLmluc3RhbmNlKSB7XG4gICAgICAgICAgICB0aGlzLmluc3RhbmNlID0gbmV3IFBsYXRmb3JtVXRpbHMoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUGxhdGZvcm1VdGlscy5pbnN0YW5jZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNDaHJvbWVCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ0Nocm9tZSc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc1NhZmFyaUJyb3dzZXIoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5uYW1lID09PSAnU2FmYXJpJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzQ2hyb21lTW9iaWxlQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgPT09ICdDaHJvbWUgTW9iaWxlJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzRmlyZWZveEJyb3dzZXIoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5uYW1lID09PSAnRmlyZWZveCc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0ZpcmVmb3hNb2JpbGVCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ0ZpcmVmb3ggTW9iaWxlJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnRmlyZWZveCBmb3IgaU9TJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzT3BlcmFCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzT3BlcmFNb2JpbGVCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ09wZXJhIE1vYmlsZSc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0VkZ2VCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCB2ZXJzaW9uID0gcGxhdGZvcm0/LnZlcnNpb24gPyBwYXJzZUZsb2F0KHBsYXRmb3JtLnZlcnNpb24pIDogLTE7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5uYW1lID09PSAnTWljcm9zb2Z0IEVkZ2UnICYmIHZlcnNpb24gPj0gODA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0VkZ2VNb2JpbGVCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCB2ZXJzaW9uID0gcGxhdGZvcm0/LnZlcnNpb24gPyBwYXJzZUZsb2F0KHBsYXRmb3JtLnZlcnNpb24pIDogLTE7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5uYW1lID09PSAnTWljcm9zb2Z0IEVkZ2UnICYmIChwbGF0Zm9ybS5vcz8uZmFtaWx5ID09PSAnQW5kcm9pZCcgfHwgcGxhdGZvcm0ub3M/LmZhbWlseSA9PT0gJ2lPUycpICYmIHZlcnNpb24gPiA0NTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzQW5kcm9pZEJyb3dzZXIoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5uYW1lID09PSAnQW5kcm9pZCBCcm93c2VyJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzRWxlY3Ryb24oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5uYW1lID09PSAnRWxlY3Ryb24nO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNOb2RlSnMoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5uYW1lID09PSAnTm9kZS5qcyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc1NhbXN1bmdCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ1NhbXN1bmcgSW50ZXJuZXQgTW9iaWxlJyB8fCBwbGF0Zm9ybS5uYW1lID09PSAnU2Ftc3VuZyBJbnRlcm5ldCc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0lQaG9uZU9ySVBhZCgpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdXNlckFnZW50ID0gISFwbGF0Zm9ybS51YSA/IHBsYXRmb3JtLnVhIDogbmF2aWdhdG9yLnVzZXJBZ2VudDtcbiAgICAgICAgY29uc3QgaXNUb3VjaGFibGUgPSAnb250b3VjaGVuZCcgaW4gZG9jdW1lbnQ7XG4gICAgICAgIGNvbnN0IGlzSVBhZCA9IC9cXGIoXFx3Kk1hY2ludG9zaFxcdyopXFxiLy50ZXN0KHVzZXJBZ2VudCkgJiYgaXNUb3VjaGFibGU7XG4gICAgICAgIGNvbnN0IGlzSVBob25lID0gL1xcYihcXHcqaVBob25lXFx3KilcXGIvLnRlc3QodXNlckFnZW50KSAmJiAvXFxiKFxcdypNb2JpbGVcXHcqKVxcYi8udGVzdCh1c2VyQWdlbnQpICYmIGlzVG91Y2hhYmxlO1xuICAgICAgICByZXR1cm4gaXNJUGFkIHx8IGlzSVBob25lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNJT1NXaXRoU2FmYXJpKCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCB1c2VyQWdlbnQgPSAhIXBsYXRmb3JtLnVhID8gcGxhdGZvcm0udWEgOiBuYXZpZ2F0b3IudXNlckFnZW50O1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgdGhpcy5pc0lQaG9uZU9ySVBhZCgpICYmXG4gICAgICAgICAgICAvXFxiKFxcdypBcHBsZVxcdyopXFxiLy50ZXN0KG5hdmlnYXRvci52ZW5kb3IpICYmXG4gICAgICAgICAgICAvXFxiKFxcdypTYWZhcmlcXHcqKVxcYi8udGVzdCh1c2VyQWdlbnQpICYmXG4gICAgICAgICAgICAhL1xcYihcXHcqQ3JpT1NcXHcqKVxcYi8udGVzdCh1c2VyQWdlbnQpICYmXG4gICAgICAgICAgICAhL1xcYihcXHcqRnhpT1NcXHcqKVxcYi8udGVzdCh1c2VyQWdlbnQpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0lvbmljSW9zKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pc0lQaG9uZU9ySVBhZCgpICYmIHBsYXRmb3JtLnVhISEuaW5kZXhPZignU2FmYXJpJykgPT09IC0xO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNJb25pY0FuZHJvaWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnICYmIHBsYXRmb3JtLm5hbWUgPT0gJ0FuZHJvaWQgQnJvd3Nlcic7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc01vYmlsZURldmljZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm9zISEuZmFtaWx5ID09PSAnaU9TJyB8fCBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ0FuZHJvaWQnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNSZWFjdE5hdGl2ZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNDaHJvbWl1bSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHRoaXMuaXNDaHJvbWVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNDaHJvbWVNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNPcGVyYUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgdGhpcy5pc09wZXJhTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICB0aGlzLmlzRWRnZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgdGhpcy5pc0VkZ2VNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNTYW1zdW5nQnJvd3NlcigpIHx8XG4gICAgICAgICAgICB0aGlzLmlzSW9uaWNBbmRyb2lkKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNJb25pY0lvcygpIHx8XG4gICAgICAgICAgICB0aGlzLmlzRWxlY3Ryb24oKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgY2FuU2NyZWVuU2hhcmUoKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHZlcnNpb24gPSBwbGF0Zm9ybT8udmVyc2lvbiA/IHBhcnNlRmxvYXQocGxhdGZvcm0udmVyc2lvbikgOiAtMTtcbiAgICAgICAgLy8gUmVqZWN0IG1vYmlsZSBkZXZpY2VzXG4gICAgICAgIGlmICh0aGlzLmlzTW9iaWxlRGV2aWNlKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgdGhpcy5pc0Nocm9tZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgdGhpcy5pc0ZpcmVmb3hCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNPcGVyYUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgdGhpcy5pc0VsZWN0cm9uKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNFZGdlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAodGhpcy5pc1NhZmFyaUJyb3dzZXIoKSAmJiB2ZXJzaW9uID49IDEzKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0TmFtZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSB8fCAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGdldFZlcnNpb24oKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLnZlcnNpb24gfHwgJyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRGYW1pbHkoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm9zISEuZmFtaWx5IHx8ICcnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0RGVzY3JpcHRpb24oKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLmRlc2NyaXB0aW9uIHx8ICcnO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgZnJlZWljZSA9IHJlcXVpcmUoJ2ZyZWVpY2UnKTtcbmltcG9ydCB7IHY0IGFzIHV1aWR2NCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHsgVHlwZU9mVmlkZW8gfSBmcm9tICcuLi9FbnVtcy9UeXBlT2ZWaWRlbyc7XG5pbXBvcnQgeyBFeGNlcHRpb25FdmVudE5hbWUgfSBmcm9tICcuLi9FdmVudHMvRXhjZXB0aW9uRXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXIgfSBmcm9tICcuLi9Mb2dnZXIvT3BlblZpZHVMb2dnZXInO1xuaW1wb3J0IHsgUGxhdGZvcm1VdGlscyB9IGZyb20gJy4uL1V0aWxzL1BsYXRmb3JtJztcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmxldCBwbGF0Zm9ybTogUGxhdGZvcm1VdGlscztcblxuZXhwb3J0IGludGVyZmFjZSBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbiB7XG4gICAgbWVkaWFDb25zdHJhaW50czoge1xuICAgICAgICBhdWRpbzogYm9vbGVhbjtcbiAgICAgICAgdmlkZW86IGJvb2xlYW47XG4gICAgfTtcbiAgICBzaW11bGNhc3Q6IGJvb2xlYW47XG4gICAgbWVkaWFTZXJ2ZXI6IHN0cmluZztcbiAgICBvbkljZUNhbmRpZGF0ZTogKGV2ZW50OiBSVENJY2VDYW5kaWRhdGUpID0+IHZvaWQ7XG4gICAgb25JY2VDb25uZWN0aW9uU3RhdGVFeGNlcHRpb246IChleGNlcHRpb25OYW1lOiBFeGNlcHRpb25FdmVudE5hbWUsIG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IGFueSkgPT4gdm9pZDtcbiAgICBpY2VTZXJ2ZXJzPzogUlRDSWNlU2VydmVyW107XG4gICAgbWVkaWFTdHJlYW0/OiBNZWRpYVN0cmVhbSB8IG51bGw7XG4gICAgbW9kZT86ICdzZW5kb25seScgfCAncmVjdm9ubHknIHwgJ3NlbmRyZWN2JztcbiAgICBpZD86IHN0cmluZztcbiAgICB0eXBlT2ZWaWRlbzogVHlwZU9mVmlkZW8gfCB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyIHtcbiAgICBwYzogUlRDUGVlckNvbm5lY3Rpb247XG4gICAgcmVtb3RlQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuICAgIGxvY2FsQ2FuZGlkYXRlc1F1ZXVlOiBSVENJY2VDYW5kaWRhdGVbXSA9IFtdO1xuXG4gICAgLy8gU2FtZSBhcyBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbiBidXQgd2l0aG91dCBvcHRpb25hbCBmaWVsZHMuXG4gICAgcHJvdGVjdGVkIGNvbmZpZ3VyYXRpb246IFJlcXVpcmVkPFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uPjtcblxuICAgIHByaXZhdGUgaWNlQ2FuZGlkYXRlTGlzdDogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcblxuICAgIGNvbnN0cnVjdG9yKGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIHBsYXRmb3JtID0gUGxhdGZvcm1VdGlscy5nZXRJbnN0YW5jZSgpO1xuXG4gICAgICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IHtcbiAgICAgICAgICAgIC4uLmNvbmZpZ3VyYXRpb24sXG4gICAgICAgICAgICBpY2VTZXJ2ZXJzOiAhIWNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyAmJiBjb25maWd1cmF0aW9uLmljZVNlcnZlcnMubGVuZ3RoID4gMCA/IGNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyA6IGZyZWVpY2UoKSxcbiAgICAgICAgICAgIG1lZGlhU3RyZWFtOiBjb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtICE9PSB1bmRlZmluZWQgPyBjb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtIDogbnVsbCxcbiAgICAgICAgICAgIG1vZGU6ICEhY29uZmlndXJhdGlvbi5tb2RlID8gY29uZmlndXJhdGlvbi5tb2RlIDogJ3NlbmRyZWN2JyxcbiAgICAgICAgICAgIGlkOiAhIWNvbmZpZ3VyYXRpb24uaWQgPyBjb25maWd1cmF0aW9uLmlkIDogdGhpcy5nZW5lcmF0ZVVuaXF1ZUlkKClcbiAgICAgICAgfTtcbiAgICAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgW1dlYlJ0Y1BlZXJdIGNvbmZpZ3VyYXRpb246XFxuJHtKU09OLnN0cmluZ2lmeSh0aGlzLmNvbmZpZ3VyYXRpb24sIG51bGwsIDIpfWApO1xuXG4gICAgICAgIHRoaXMucGMgPSBuZXcgUlRDUGVlckNvbm5lY3Rpb24oeyBpY2VTZXJ2ZXJzOiB0aGlzLmNvbmZpZ3VyYXRpb24uaWNlU2VydmVycyB9KTtcblxuICAgICAgICB0aGlzLnBjLmFkZEV2ZW50TGlzdGVuZXIoJ2ljZWNhbmRpZGF0ZScsIChldmVudDogUlRDUGVlckNvbm5lY3Rpb25JY2VFdmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmNhbmRpZGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIGBSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50LmNhbmRpZGF0ZWAgaXMgc3VwcG9zZWQgdG8gYmUgYW4gUlRDSWNlQ2FuZGlkYXRlOlxuICAgICAgICAgICAgICAgIC8vIGh0dHBzOi8vdzNjLmdpdGh1Yi5pby93ZWJydGMtcGMvI2RvbS1ydGNwZWVyY29ubmVjdGlvbmljZWV2ZW50LWNhbmRpZGF0ZVxuICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgLy8gQnV0IGluIHByYWN0aWNlLCBpdCBpcyBhY3R1YWxseSBhbiBSVENJY2VDYW5kaWRhdGVJbml0IHRoYXQgY2FuIGJlIHVzZWQgdG9cbiAgICAgICAgICAgICAgICAvLyBvYnRhaW4gYSBwcm9wZXIgY2FuZGlkYXRlLCB1c2luZyB0aGUgUlRDSWNlQ2FuZGlkYXRlIGNvbnN0cnVjdG9yOlxuICAgICAgICAgICAgICAgIC8vIGh0dHBzOi8vdzNjLmdpdGh1Yi5pby93ZWJydGMtcGMvI2RvbS1ydGNpY2VjYW5kaWRhdGUtY29uc3RydWN0b3JcbiAgICAgICAgICAgICAgICBjb25zdCBjYW5kaWRhdGVJbml0OiBSVENJY2VDYW5kaWRhdGVJbml0ID0gZXZlbnQuY2FuZGlkYXRlIGFzIFJUQ0ljZUNhbmRpZGF0ZUluaXQ7XG4gICAgICAgICAgICAgICAgY29uc3QgaWNlQ2FuZGlkYXRlID0gbmV3IFJUQ0ljZUNhbmRpZGF0ZShjYW5kaWRhdGVJbml0KTtcblxuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5vbkljZUNhbmRpZGF0ZShpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgIGlmIChpY2VDYW5kaWRhdGUuY2FuZGlkYXRlICE9PSAnJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlLnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucGMuYWRkRXZlbnRMaXN0ZW5lcignc2lnbmFsaW5nc3RhdGVjaGFuZ2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ3N0YWJsZScpIHtcbiAgICAgICAgICAgICAgICAvLyBTRFAgT2ZmZXIvQW5zd2VyIGZpbmlzaGVkLiBBZGQgc3RvcmVkIHJlbW90ZSBjYW5kaWRhdGVzLlxuICAgICAgICAgICAgICAgIHdoaWxlICh0aGlzLmljZUNhbmRpZGF0ZUxpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgY2FuZGlkYXRlID0gdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZSg8UlRDSWNlQ2FuZGlkYXRlPmNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIHdoZW4gY2FsbGluZyBSVENQZWVyQ29ubmVjdGlvbiNhZGRJY2VDYW5kaWRhdGUgZm9yIFJUQ1BlZXJDb25uZWN0aW9uICcgKyB0aGlzLmdldElkKCksIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZ2V0SWQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlndXJhdGlvbi5pZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCBmcmVlcyB0aGUgcmVzb3VyY2VzIHVzZWQgYnkgV2ViUnRjUGVlclxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnRGlzcG9zaW5nIFdlYlJ0Y1BlZXInKTtcbiAgICAgICAgaWYgKHRoaXMucGMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucGMuY2xvc2UoKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlID0gW107XG4gICAgICAgICAgICB0aGlzLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlID0gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBERVBSRUNBVEVEIExFR0FDWSBNRVRIT0Q6IE9sZCBXZWJSVEMgdmVyc2lvbnMgZG9uJ3QgaW1wbGVtZW50XG4gICAgLy8gVHJhbnNjZWl2ZXJzLCBhbmQgaW5zdGVhZCBkZXBlbmQgb24gdGhlIGRlcHJlY2F0ZWRcbiAgICAvLyBcIm9mZmVyVG9SZWNlaXZlQXVkaW9cIiBhbmQgXCJvZmZlclRvUmVjZWl2ZVZpZGVvXCIuXG4gICAgcHJpdmF0ZSBjcmVhdGVPZmZlckxlZ2FjeSgpOiBQcm9taXNlPFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQ+IHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLmRlcHJlY2F0ZWRQZWVyQ29ubmVjdGlvblRyYWNrQXBpKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBoYXNBdWRpbyA9IHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLmF1ZGlvO1xuICAgICAgICBjb25zdCBoYXNWaWRlbyA9IHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLnZpZGVvO1xuXG4gICAgICAgIGNvbnN0IG9wdGlvbnM6IFJUQ09mZmVyT3B0aW9ucyA9IHtcbiAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlQXVkaW86IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlICE9PSAnc2VuZG9ubHknICYmIGhhc0F1ZGlvLFxuICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVWaWRlbzogdGhpcy5jb25maWd1cmF0aW9uLm1vZGUgIT09ICdzZW5kb25seScgJiYgaGFzVmlkZW9cbiAgICAgICAgfTtcblxuICAgICAgICBsb2dnZXIuZGVidWcoJ1tjcmVhdGVPZmZlckxlZ2FjeV0gUlRDUGVlckNvbm5lY3Rpb24uY3JlYXRlT2ZmZXIoKSBvcHRpb25zOicsIEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5wYy5jcmVhdGVPZmZlcihvcHRpb25zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIFNEUCBvZmZlciBmcm9tIHRoZSBsb2NhbCBSVENQZWVyQ29ubmVjdGlvbiB0byBzZW5kIHRvIHRoZSBvdGhlciBwZWVyLlxuICAgICAqIE9ubHkgaWYgdGhlIG5lZ290aWF0aW9uIHdhcyBpbml0aWF0ZWQgYnkgdGhpcyBwZWVyLlxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZU9mZmVyKCk6IFByb21pc2U8UlRDU2Vzc2lvbkRlc2NyaXB0aW9uSW5pdD4ge1xuICAgICAgICAvLyBUT0RPOiBEZWxldGUgdGhpcyBjb25kaXRpb25hbCB3aGVuIGFsbCBzdXBwb3J0ZWQgYnJvd3NlcnMgYXJlXG4gICAgICAgIC8vIG1vZGVybiBlbm91Z2ggdG8gaW1wbGVtZW50IHRoZSBUcmFuc2NlaXZlciBtZXRob2RzLlxuICAgICAgICBpZiAoISgnYWRkVHJhbnNjZWl2ZXInIGluIHRoaXMucGMpKSB7XG4gICAgICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICAgICAgICAnW2NyZWF0ZU9mZmVyXSBNZXRob2QgUlRDUGVlckNvbm5lY3Rpb24uYWRkVHJhbnNjZWl2ZXIoKSBpcyBOT1QgYXZhaWxhYmxlOyB1c2luZyBMRUdBQ1kgb2ZmZXJUb1JlY2VpdmV7QXVkaW8sVmlkZW99J1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZU9mZmVyTGVnYWN5KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1tjcmVhdGVPZmZlcl0gTWV0aG9kIFJUQ1BlZXJDb25uZWN0aW9uLmFkZFRyYW5zY2VpdmVyKCkgaXMgYXZhaWxhYmxlOyB1c2luZyBpdCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3BlYyBkb2M6IGh0dHBzOi8vdzNjLmdpdGh1Yi5pby93ZWJydGMtcGMvI2RvbS1ydGNwZWVyY29ubmVjdGlvbi1hZGR0cmFuc2NlaXZlclxuXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3JlY3Zvbmx5Jykge1xuICAgICAgICAgICAgLy8gVG8gc2VuZCBtZWRpYSwgYXNzdW1lIHRoYXQgYWxsIGRlc2lyZWQgbWVkaWEgdHJhY2tzIGhhdmUgYmVlblxuICAgICAgICAgICAgLy8gYWxyZWFkeSBhZGRlZCBieSBoaWdoZXIgbGV2ZWwgY29kZSB0byBvdXIgTWVkaWFTdHJlYW0uXG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICBgW1dlYlJ0Y1BlZXIuY3JlYXRlT2ZmZXJdIERpcmVjdGlvbiBpcyAnJHt0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZX0nLCBidXQgbm8gc3RyZWFtIHdhcyBjb25maWd1cmVkIHRvIGJlIHNlbnRgXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChjb25zdCB0cmFjayBvZiB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0uZ2V0VHJhY2tzKCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0Y0luaXQ6IFJUQ1J0cFRyYW5zY2VpdmVySW5pdCA9IHtcbiAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSxcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtczogW3RoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbV1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaWYgKHRyYWNrLmtpbmQgPT09ICd2aWRlbycgJiYgdGhpcy5jb25maWd1cmF0aW9uLnNpbXVsY2FzdCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgcmVxdWVzdGVkIHNpemUgaXMgZW5vdWdoIHRvIGFzayBmb3IgMyBsYXllcnMuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRyYWNrU2V0dGluZ3MgPSB0cmFjay5nZXRTZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0cmFja0NvbnN0cyA9IHRyYWNrLmdldENvbnN0cmFpbnRzKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhY2tXaWR0aDogbnVtYmVyID1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrU2V0dGluZ3Mud2lkdGggPz8gKHRyYWNrQ29uc3RzLndpZHRoIGFzIENvbnN0cmFpblVMb25nUmFuZ2UpLmlkZWFsID8/ICh0cmFja0NvbnN0cy53aWR0aCBhcyBudW1iZXIpID8/IDA7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRyYWNrSGVpZ2h0OiBudW1iZXIgPVxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2tTZXR0aW5ncy5oZWlnaHQgPz8gKHRyYWNrQ29uc3RzLmhlaWdodCBhcyBDb25zdHJhaW5VTG9uZ1JhbmdlKS5pZGVhbCA/PyAodHJhY2tDb25zdHMuaGVpZ2h0IGFzIG51bWJlcikgPz8gMDtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYFtjcmVhdGVPZmZlcl0gVmlkZW8gdHJhY2sgZGltZW5zaW9uczogJHt0cmFja1dpZHRofXgke3RyYWNrSGVpZ2h0fWApO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRyYWNrUGl4ZWxzID0gdHJhY2tXaWR0aCAqIHRyYWNrSGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICBsZXQgbWF4TGF5ZXJzID0gMDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRyYWNrUGl4ZWxzID49IDk2MCAqIDU0MCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWF4TGF5ZXJzID0gMztcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0cmFja1BpeGVscyA+PSA0ODAgKiAyNzApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heExheWVycyA9IDI7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXhMYXllcnMgPSAxO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgdGNJbml0LnNlbmRFbmNvZGluZ3MgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgbCA9IDA7IGwgPCBtYXhMYXllcnM7IGwrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbGF5ZXJEaXYgPSAyICoqIChtYXhMYXllcnMgLSBsIC0gMSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuY29kaW5nOiBSVENSdHBFbmNvZGluZ1BhcmFtZXRlcnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlkOiAncmRpdicgKyBsYXllckRpdi50b1N0cmluZygpLFxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZSAtLSBQcm9wZXJ0eSBtaXNzaW5nIGZyb20gRE9NIHR5cGVzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxhYmlsaXR5TW9kZTogJ0wxVDEnXG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoWydkZXRhaWwnLCAndGV4dCddLmluY2x1ZGVzKHRyYWNrLmNvbnRlbnRIaW50KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFByaW9yaXRpemUgYmVzdCByZXNvbHV0aW9uLCBmb3IgbWF4aW11bSBwaWN0dXJlIGRldGFpbC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZy5zY2FsZVJlc29sdXRpb25Eb3duQnkgPSAxLjA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlIC0tIFByb3BlcnR5IG1pc3NpbmcgZnJvbSBET00gdHlwZXMuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcubWF4RnJhbWVyYXRlID0gTWF0aC5mbG9vcigzMCAvIGxheWVyRGl2KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2Rpbmcuc2NhbGVSZXNvbHV0aW9uRG93bkJ5ID0gbGF5ZXJEaXY7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRjSW5pdC5zZW5kRW5jb2RpbmdzLnB1c2goZW5jb2RpbmcpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgdGMgPSB0aGlzLnBjLmFkZFRyYW5zY2VpdmVyKHRyYWNrLCB0Y0luaXQpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRyYWNrLmtpbmQgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHNlbmRQYXJhbXMgPSB0Yy5zZW5kZXIuZ2V0UGFyYW1ldGVycygpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgbmVlZFNldFBhcmFtcyA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICghc2VuZFBhcmFtcy5kZWdyYWRhdGlvblByZWZlcmVuY2U/Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVncmFkYXRpb25QcmVmZXJlbmNlIGZvciB2aWRlbzogXCJiYWxhbmNlZFwiLCBcIm1haW50YWluLWZyYW1lcmF0ZVwiLCBcIm1haW50YWluLXJlc29sdXRpb25cIi5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDE4L0NSLXdlYnJ0Yy0yMDE4MDkyNy8jZG9tLXJ0Y2RlZ3JhZGF0aW9ucHJlZmVyZW5jZVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFsnZGV0YWlsJywgJ3RleHQnXS5pbmNsdWRlcyh0cmFjay5jb250ZW50SGludCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUGFyYW1zLmRlZ3JhZGF0aW9uUHJlZmVyZW5jZSA9ICdtYWludGFpbi1yZXNvbHV0aW9uJztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBhcmFtcy5kZWdyYWRhdGlvblByZWZlcmVuY2UgPSAnYmFsYW5jZWQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhgW2NyZWF0ZU9mZmVyXSBWaWRlbyBzZW5kZXIgRGVncmFkYXRpb24gUHJlZmVyZW5jZSBzZXQ6ICR7c2VuZFBhcmFtcy5kZWdyYWRhdGlvblByZWZlcmVuY2V9YCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBGaXJlZm94IGltcGxlbWVudHMgZGVncmFkYXRpb25QcmVmZXJlbmNlIG9uIGVhY2ggaW5kaXZpZHVhbCBlbmNvZGluZyFcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIChzZXQgaXQgb24gZXZlcnkgZWxlbWVudCBvZiB0aGUgc2VuZFBhcmFtcy5lbmNvZGluZ3MgYXJyYXkpXG5cbiAgICAgICAgICAgICAgICAgICAgICAgIG5lZWRTZXRQYXJhbXMgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRklYTUU6IENoZWNrIHRoYXQgdGhlIHNpbXVsY2FzdCBlbmNvZGluZ3Mgd2VyZSBhcHBsaWVkLlxuICAgICAgICAgICAgICAgICAgICAvLyBGaXJlZm94IGRvZXNuJ3QgaW1wbGVtZW50IGBSVENSdHBUcmFuc2NlaXZlckluaXQuc2VuZEVuY29kaW5nc2BcbiAgICAgICAgICAgICAgICAgICAgLy8gc28gdGhlIG9ubHkgd2F5IHRvIGVuYWJsZSBzaW11bGNhc3QgaXMgd2l0aCBgUlRDUnRwU2VuZGVyLnNldFBhcmFtZXRlcnMoKWAuXG4gICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgbmV4dCBibG9jayBjYW4gYmUgZGVsZXRlZCB3aGVuIEZpcmVmb3ggZml4ZXMgYnVnICMxMzk2OTE4OlxuICAgICAgICAgICAgICAgICAgICAvLyBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD0xMzk2OTE4XG4gICAgICAgICAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAgICAgICAgIC8vIE5PVEU6IFRoaXMgaXMgZG9uZSBpbiBhIHdheSB0aGF0IGlzIGNvbXBhdGlibGUgd2l0aCBhbGwgYnJvd3NlcnMsIHRvIHNhdmUgb25cbiAgICAgICAgICAgICAgICAgICAgLy8gYnJvd3Nlci1jb25kaXRpb25hbCBjb2RlLiBUaGUgaWRlYSBjb21lcyBmcm9tIFdlYlJUQyBBZGFwdGVyLmpzOlxuICAgICAgICAgICAgICAgICAgICAvLyAqIGh0dHBzOi8vZ2l0aHViLmNvbS93ZWJydGNIYWNrcy9hZGFwdGVyL2lzc3Vlcy85OThcbiAgICAgICAgICAgICAgICAgICAgLy8gKiBodHRwczovL2dpdGh1Yi5jb20vd2VicnRjSGFja3MvYWRhcHRlci9ibG9iL3Y3LjcuMC9zcmMvanMvZmlyZWZveC9maXJlZm94X3NoaW0uanMjTDIzMS1MMjU1XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZ3VyYXRpb24uc2ltdWxjYXN0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VuZFBhcmFtcy5lbmNvZGluZ3M/Lmxlbmd0aCAhPT0gdGNJbml0LnNlbmRFbmNvZGluZ3MhLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQYXJhbXMuZW5jb2RpbmdzID0gdGNJbml0LnNlbmRFbmNvZGluZ3MhO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmVlZFNldFBhcmFtcyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAobmVlZFNldFBhcmFtcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBbY3JlYXRlT2ZmZXJdIFNldHRpbmcgbmV3IFJUQ1J0cFNlbmRQYXJhbWV0ZXJzIHRvIHZpZGVvIHNlbmRlcmApO1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0Yy5zZW5kZXIuc2V0UGFyYW1ldGVycyhzZW5kUGFyYW1zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG1lc3NhZ2UgPSBgW1dlYlJ0Y1BlZXIuY3JlYXRlT2ZmZXJdIENhbm5vdCBzZXQgUlRDUnRwU2VuZFBhcmFtZXRlcnMgdG8gdmlkZW8gc2VuZGVyYDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlICs9IGA6ICR7ZXJyb3IubWVzc2FnZX1gO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBERUJVRzogVW5jb21tZW50IGZvciBkZXRhaWxzLlxuICAgICAgICAgICAgICAgIC8vIGlmICh0cmFjay5raW5kID09PSBcInZpZGVvXCIgJiYgdGhpcy5jb25maWd1cmF0aW9uLnNpbXVsY2FzdCkge1xuICAgICAgICAgICAgICAgIC8vICAgICAvLyBQcmludCBicm93c2VyIGNhcGFiaWxpdGllcy5cbiAgICAgICAgICAgICAgICAvLyAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgICAgICAgICAgLy8gICAgIGxvZ2dlci5kZWJ1ZyhgW2NyZWF0ZU9mZmVyXSBUcmFuc2NlaXZlciBzZW5kIGNhcGFiaWxpdGllcyAoc3RhdGljKTpcXG4ke0pTT04uc3RyaW5naWZ5KFJUQ1J0cFNlbmRlci5nZXRDYXBhYmlsaXRpZXM/LihcInZpZGVvXCIpLCBudWxsLCAyKX1gKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgICAgICAgICAgLy8gICAgIGxvZ2dlci5kZWJ1ZyhgW2NyZWF0ZU9mZmVyXSBUcmFuc2NlaXZlciByZWN2IGNhcGFiaWxpdGllcyAoc3RhdGljKTpcXG4ke0pTT04uc3RyaW5naWZ5KFJUQ1J0cFJlY2VpdmVyLmdldENhcGFiaWxpdGllcz8uKFwidmlkZW9cIiksIG51bGwsIDIpfWApO1xuXG4gICAgICAgICAgICAgICAgLy8gICAgIC8vIFByaW50IHJlcXVlc3RlZCBUcmFuc2NlaXZlciBlbmNvZGluZ3MgYW5kIHBhcmFtZXRlcnMuXG4gICAgICAgICAgICAgICAgLy8gICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICAgICAgICAgIC8vICAgICBsb2dnZXIuZGVidWcoYFtjcmVhdGVPZmZlcl0gVHJhbnNjZWl2ZXIgc2VuZCBlbmNvZGluZ3MgKHJlcXVlc3RlZCk6XFxuJHtKU09OLnN0cmluZ2lmeSh0Y0luaXQuc2VuZEVuY29kaW5ncywgbnVsbCwgMil9YCk7XG4gICAgICAgICAgICAgICAgLy8gICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICAgICAgICAgIC8vICAgICBsb2dnZXIuZGVidWcoYFtjcmVhdGVPZmZlcl0gVHJhbnNjZWl2ZXIgc2VuZCBwYXJhbWV0ZXJzIChhY2NlcHRlZCk6XFxuJHtKU09OLnN0cmluZ2lmeSh0Yy5zZW5kZXIuZ2V0UGFyYW1ldGVycygpLCBudWxsLCAyKX1gKTtcbiAgICAgICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBUbyBqdXN0IHJlY2VpdmUgbWVkaWEsIGNyZWF0ZSBuZXcgcmVjdm9ubHkgdHJhbnNjZWl2ZXJzLlxuICAgICAgICAgICAgZm9yIChjb25zdCBraW5kIG9mIFsnYXVkaW8nLCAndmlkZW8nXSkge1xuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBtZWRpYSBraW5kIHNob3VsZCBiZSB1c2VkLlxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHNba2luZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFuc2NlaXZlcihraW5kLCB7XG4gICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLm1vZGUsXG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbXM6IFt0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW1dXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc2RwT2ZmZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzZHBPZmZlciA9IGF3YWl0IHRoaXMucGMuY3JlYXRlT2ZmZXIoKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxldCBtZXNzYWdlID0gYFtXZWJSdGNQZWVyLmNyZWF0ZU9mZmVyXSBCcm93c2VyIGZhaWxlZCBjcmVhdGluZyBhbiBTRFAgT2ZmZXJgO1xuICAgICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlICs9IGA6ICR7ZXJyb3IubWVzc2FnZX1gO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNkcE9mZmVyO1xuICAgIH1cblxuICAgIGRlcHJlY2F0ZWRQZWVyQ29ubmVjdGlvblRyYWNrQXBpKCkge1xuICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSEuZ2V0VHJhY2tzKCkpIHtcbiAgICAgICAgICAgIHRoaXMucGMuYWRkVHJhY2sodHJhY2ssIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBTRFAgYW5zd2VyIGZyb20gdGhlIGxvY2FsIFJUQ1BlZXJDb25uZWN0aW9uIHRvIHNlbmQgdG8gdGhlIG90aGVyIHBlZXJcbiAgICAgKiBPbmx5IGlmIHRoZSBuZWdvdGlhdGlvbiB3YXMgaW5pdGlhdGVkIGJ5IHRoZSBvdGhlciBwZWVyXG4gICAgICovXG4gICAgY3JlYXRlQW5zd2VyKCk6IFByb21pc2U8UlRDU2Vzc2lvbkRlc2NyaXB0aW9uSW5pdD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgLy8gVE9ETzogRGVsZXRlIHRoaXMgY29uZGl0aW9uYWwgd2hlbiBhbGwgc3VwcG9ydGVkIGJyb3dzZXJzIGFyZVxuICAgICAgICAgICAgLy8gbW9kZXJuIGVub3VnaCB0byBpbXBsZW1lbnQgdGhlIFRyYW5zY2VpdmVyIG1ldGhvZHMuXG4gICAgICAgICAgICBpZiAoJ2dldFRyYW5zY2VpdmVycycgaW4gdGhpcy5wYykge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnW2NyZWF0ZUFuc3dlcl0gTWV0aG9kIFJUQ1BlZXJDb25uZWN0aW9uLmdldFRyYW5zY2VpdmVycygpIGlzIGF2YWlsYWJsZTsgdXNpbmcgaXQnKTtcblxuICAgICAgICAgICAgICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBQZWVyQ29ubmVjdGlvbiBhbHJlYWR5IGNvbnRhaW5zIG9uZSBUcmFuc2NlaXZlclxuICAgICAgICAgICAgICAgIC8vIGZvciBlYWNoIGtpbmQgb2YgbWVkaWEuXG4gICAgICAgICAgICAgICAgLy8gVGhlIFRyYW5zY2VpdmVycyBzaG91bGQgaGF2ZSBiZWVuIGFscmVhZHkgY3JlYXRlZCBpbnRlcm5hbGx5IGJ5XG4gICAgICAgICAgICAgICAgLy8gdGhlIFBDIGl0c2VsZiwgd2hlbiBgcGMuc2V0UmVtb3RlRGVzY3JpcHRpb24oc2RwT2ZmZXIpYCB3YXMgY2FsbGVkLlxuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBraW5kIG9mIFsnYXVkaW8nLCAndmlkZW8nXSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgbWVkaWEga2luZCBzaG91bGQgYmUgdXNlZC5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50c1traW5kXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBsZXQgdGMgPSB0aGlzLnBjLmdldFRyYW5zY2VpdmVycygpLmZpbmQoKHRjKSA9PiB0Yy5yZWNlaXZlci50cmFjay5raW5kID09PSBraW5kKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEVuZm9yY2Ugb3VyIGRlc2lyZWQgZGlyZWN0aW9uLlxuICAgICAgICAgICAgICAgICAgICAgICAgdGMuZGlyZWN0aW9uID0gdGhpcy5jb25maWd1cmF0aW9uLm1vZGU7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcihgJHtraW5kfSByZXF1ZXN0ZWQsIGJ1dCBubyB0cmFuc2NlaXZlciB3YXMgY3JlYXRlZCBmcm9tIHJlbW90ZSBkZXNjcmlwdGlvbmApKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMucGNcbiAgICAgICAgICAgICAgICAgICAgLmNyZWF0ZUFuc3dlcigpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKChzZHBBbnN3ZXIpID0+IHJlc29sdmUoc2RwQW5zd2VyKSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFRPRE86IERlbGV0ZSBlbHNlIGJyYW5jaCB3aGVuIGFsbCBzdXBwb3J0ZWQgYnJvd3NlcnMgYXJlXG4gICAgICAgICAgICAgICAgLy8gbW9kZXJuIGVub3VnaCB0byBpbXBsZW1lbnQgdGhlIFRyYW5zY2VpdmVyIG1ldGhvZHNcblxuICAgICAgICAgICAgICAgIGxldCBvZmZlckF1ZGlvLFxuICAgICAgICAgICAgICAgICAgICBvZmZlclZpZGVvID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cykge1xuICAgICAgICAgICAgICAgICAgICBvZmZlckF1ZGlvID1cbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy5hdWRpbyA9PT0gJ2Jvb2xlYW4nID8gdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW8gOiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBvZmZlclZpZGVvID1cbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy52aWRlbyA9PT0gJ2Jvb2xlYW4nID8gdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW8gOiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25zdHJhaW50czogUlRDT2ZmZXJPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVBdWRpbzogb2ZmZXJBdWRpbyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9mZmVyVG9SZWNlaXZlVmlkZW86IG9mZmVyVmlkZW9cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgKHRoaXMucGMgYXMgUlRDUGVlckNvbm5lY3Rpb24pLmNyZWF0ZUFuc3dlcihjb25zdHJhaW50cylcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKChzZHBBbnN3ZXIpID0+IHJlc29sdmUoc2RwQW5zd2VyKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gZWxzZSwgdGhlcmUgaXMgbm90aGluZyB0byBkbzsgdGhlIGxlZ2FjeSBjcmVhdGVBbnN3ZXIoKSBvcHRpb25zIGRvXG4gICAgICAgICAgICAvLyBub3Qgb2ZmZXIgYW55IGNvbnRyb2wgb3ZlciB3aGljaCB0cmFja3MgYXJlIGluY2x1ZGVkIGluIHRoZSBhbnN3ZXIuXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgcGVlciBpbml0aWF0ZWQgbmVnb3RpYXRpb24uIFN0ZXAgMS80IG9mIFNEUCBvZmZlci1hbnN3ZXIgcHJvdG9jb2xcbiAgICAgKi9cbiAgICBwcm9jZXNzTG9jYWxPZmZlcihvZmZlcjogUlRDU2Vzc2lvbkRlc2NyaXB0aW9uSW5pdCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5wY1xuICAgICAgICAgICAgICAgIC5zZXRMb2NhbERlc2NyaXB0aW9uKG9mZmVyKVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbG9jYWxEZXNjcmlwdGlvbiA9IHRoaXMucGMubG9jYWxEZXNjcmlwdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhbG9jYWxEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdMb2NhbCBkZXNjcmlwdGlvbiBzZXQnLCBsb2NhbERlc2NyaXB0aW9uLnNkcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCgnTG9jYWwgZGVzY3JpcHRpb24gaXMgbm90IGRlZmluZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE90aGVyIHBlZXIgaW5pdGlhdGVkIG5lZ290aWF0aW9uLiBTdGVwIDIvNCBvZiBTRFAgb2ZmZXItYW5zd2VyIHByb3RvY29sXG4gICAgICovXG4gICAgcHJvY2Vzc1JlbW90ZU9mZmVyKHNkcE9mZmVyOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG9mZmVyOiBSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0ID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdvZmZlcicsXG4gICAgICAgICAgICAgICAgc2RwOiBzZHBPZmZlclxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnU0RQIG9mZmVyIHJlY2VpdmVkLCBzZXR0aW5nIHJlbW90ZSBkZXNjcmlwdGlvbicsIG9mZmVyKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCgnUlRDUGVlckNvbm5lY3Rpb24gaXMgY2xvc2VkIHdoZW4gdHJ5aW5nIHRvIHNldCByZW1vdGUgZGVzY3JpcHRpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc2V0UmVtb3RlRGVzY3JpcHRpb24ob2ZmZXIpXG4gICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPdGhlciBwZWVyIGluaXRpYXRlZCBuZWdvdGlhdGlvbi4gU3RlcCAzLzQgb2YgU0RQIG9mZmVyLWFuc3dlciBwcm90b2NvbFxuICAgICAqL1xuICAgIHByb2Nlc3NMb2NhbEFuc3dlcihhbnN3ZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnU0RQIGFuc3dlciBjcmVhdGVkLCBzZXR0aW5nIGxvY2FsIGRlc2NyaXB0aW9uJyk7XG4gICAgICAgICAgICBpZiAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KCdSVENQZWVyQ29ubmVjdGlvbiBpcyBjbG9zZWQgd2hlbiB0cnlpbmcgdG8gc2V0IGxvY2FsIGRlc2NyaXB0aW9uJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnBjXG4gICAgICAgICAgICAgICAgLnNldExvY2FsRGVzY3JpcHRpb24oYW5zd2VyKVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHJlc29sdmUoKSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBwZWVyIGluaXRpYXRlZCBuZWdvdGlhdGlvbi4gU3RlcCA0LzQgb2YgU0RQIG9mZmVyLWFuc3dlciBwcm90b2NvbFxuICAgICAqL1xuICAgIHByb2Nlc3NSZW1vdGVBbnN3ZXIoc2RwQW5zd2VyOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFuc3dlcjogUlRDU2Vzc2lvbkRlc2NyaXB0aW9uSW5pdCA9IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnYW5zd2VyJyxcbiAgICAgICAgICAgICAgICBzZHA6IHNkcEFuc3dlclxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnU0RQIGFuc3dlciByZWNlaXZlZCwgc2V0dGluZyByZW1vdGUgZGVzY3JpcHRpb24nKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCgnUlRDUGVlckNvbm5lY3Rpb24gaXMgY2xvc2VkIHdoZW4gdHJ5aW5nIHRvIHNldCByZW1vdGUgZGVzY3JpcHRpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuc2V0UmVtb3RlRGVzY3JpcHRpb24oYW5zd2VyKVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gREVCVUc6IFVuY29tbWVudCBmb3IgZGV0YWlscy5cbiAgICAgICAgICAgICAgICAgICAgLy8ge1xuICAgICAgICAgICAgICAgICAgICAvLyAgICAgY29uc3QgdGMgPSB0aGlzLnBjLmdldFRyYW5zY2VpdmVycygpLmZpbmQoKHRjKSA9PiB0Yy5zZW5kZXIudHJhY2s/LmtpbmQgPT09IFwidmlkZW9cIik7XG4gICAgICAgICAgICAgICAgICAgIC8vICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgIGxvZ2dlci5kZWJ1ZyhgW3Byb2Nlc3NSZW1vdGVBbnN3ZXJdIFRyYW5zY2VpdmVyIHNlbmQgcGFyYW1ldGVycyAoZWZmZWN0aXZlKTpcXG4ke0pTT04uc3RyaW5naWZ5KHRjPy5zZW5kZXIuZ2V0UGFyYW1ldGVycygpLCBudWxsLCAyKX1gKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gfVxuXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYXN5bmMgc2V0UmVtb3RlRGVzY3JpcHRpb24oc2RwOiBSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiB0aGlzLnBjLnNldFJlbW90ZURlc2NyaXB0aW9uKHNkcCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgZnVuY3Rpb24gaW52b2tlZCB3aGVuIGFuIElDRSBjYW5kaWRhdGUgaXMgcmVjZWl2ZWRcbiAgICAgKi9cbiAgICBhZGRJY2VDYW5kaWRhdGUoaWNlQ2FuZGlkYXRlOiBSVENJY2VDYW5kaWRhdGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnUmVtb3RlIElDRSBjYW5kaWRhdGUgcmVjZWl2ZWQnLCBpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDYW5kaWRhdGVzUXVldWUucHVzaChpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgc3dpdGNoICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnY2xvc2VkJzpcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignUGVlckNvbm5lY3Rpb24gb2JqZWN0IGlzIGNsb3NlZCcpKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnc3RhYmxlJzpcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5wYy5yZW1vdGVEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wY1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRJY2VDYW5kaWRhdGUoaWNlQ2FuZGlkYXRlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHJlc29sdmUoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pY2VDYW5kaWRhdGVMaXN0LnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhZGRJY2VDb25uZWN0aW9uU3RhdGVDaGFuZ2VMaXN0ZW5lcihvdGhlcklkOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5wYy5hZGRFdmVudExpc3RlbmVyKCdpY2Vjb25uZWN0aW9uc3RhdGVjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpY2VDb25uZWN0aW9uU3RhdGU6IFJUQ0ljZUNvbm5lY3Rpb25TdGF0ZSA9IHRoaXMucGMuaWNlQ29ubmVjdGlvblN0YXRlO1xuICAgICAgICAgICAgc3dpdGNoIChpY2VDb25uZWN0aW9uU3RhdGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdkaXNjb25uZWN0ZWQnOlxuICAgICAgICAgICAgICAgICAgICAvLyBQb3NzaWJsZSBuZXR3b3JrIGRpc2Nvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbXNnMSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAnSWNlQ29ubmVjdGlvblN0YXRlIG9mIFJUQ1BlZXJDb25uZWN0aW9uICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLmlkICtcbiAgICAgICAgICAgICAgICAgICAgICAgICcgKCcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgb3RoZXJJZCArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSBjaGFuZ2UgdG8gXCJkaXNjb25uZWN0ZWRcIi4gUG9zc2libGUgbmV0d29yayBkaXNjb25uZWN0aW9uJztcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4obXNnMSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5vbkljZUNvbm5lY3Rpb25TdGF0ZUV4Y2VwdGlvbihFeGNlcHRpb25FdmVudE5hbWUuSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVELCBtc2cxKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnZmFpbGVkJzpcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbXNnMiA9ICdJY2VDb25uZWN0aW9uU3RhdGUgb2YgUlRDUGVlckNvbm5lY3Rpb24gJyArIHRoaXMuY29uZmlndXJhdGlvbi5pZCArICcgKCcgKyBvdGhlcklkICsgJykgdG8gXCJmYWlsZWRcIic7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihtc2cyKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLm9uSWNlQ29ubmVjdGlvblN0YXRlRXhjZXB0aW9uKEV4Y2VwdGlvbkV2ZW50TmFtZS5JQ0VfQ09OTkVDVElPTl9GQUlMRUQsIG1zZzIpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdjbG9zZWQnOlxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ0ljZUNvbm5lY3Rpb25TdGF0ZSBvZiBSVENQZWVyQ29ubmVjdGlvbiAnICsgdGhpcy5jb25maWd1cmF0aW9uLmlkICsgJyAoJyArIG90aGVySWQgKyAnKSBjaGFuZ2UgdG8gXCJjbG9zZWRcIidcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnbmV3JzpcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZygnSWNlQ29ubmVjdGlvblN0YXRlIG9mIFJUQ1BlZXJDb25uZWN0aW9uICcgKyB0aGlzLmNvbmZpZ3VyYXRpb24uaWQgKyAnICgnICsgb3RoZXJJZCArICcpIGNoYW5nZSB0byBcIm5ld1wiJyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2NoZWNraW5nJzpcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhcbiAgICAgICAgICAgICAgICAgICAgICAgICdJY2VDb25uZWN0aW9uU3RhdGUgb2YgUlRDUGVlckNvbm5lY3Rpb24gJyArIHRoaXMuY29uZmlndXJhdGlvbi5pZCArICcgKCcgKyBvdGhlcklkICsgJykgY2hhbmdlIHRvIFwiY2hlY2tpbmdcIidcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnY29ubmVjdGVkJzpcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhcbiAgICAgICAgICAgICAgICAgICAgICAgICdJY2VDb25uZWN0aW9uU3RhdGUgb2YgUlRDUGVlckNvbm5lY3Rpb24gJyArIHRoaXMuY29uZmlndXJhdGlvbi5pZCArICcgKCcgKyBvdGhlcklkICsgJykgY2hhbmdlIHRvIFwiY29ubmVjdGVkXCInXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2NvbXBsZXRlZCc6XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICAnSWNlQ29ubmVjdGlvblN0YXRlIG9mIFJUQ1BlZXJDb25uZWN0aW9uICcgKyB0aGlzLmNvbmZpZ3VyYXRpb24uaWQgKyAnICgnICsgb3RoZXJJZCArICcpIGNoYW5nZSB0byBcImNvbXBsZXRlZFwiJ1xuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdlbmVyYXRlVW5pcXVlSWQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHV1aWR2NCgpO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXJSZWN2b25seSBleHRlbmRzIFdlYlJ0Y1BlZXIge1xuICAgIGNvbnN0cnVjdG9yKGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIGNvbmZpZ3VyYXRpb24ubW9kZSA9ICdyZWN2b25seSc7XG4gICAgICAgIHN1cGVyKGNvbmZpZ3VyYXRpb24pO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXJTZW5kb25seSBleHRlbmRzIFdlYlJ0Y1BlZXIge1xuICAgIGNvbnN0cnVjdG9yKGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIGNvbmZpZ3VyYXRpb24ubW9kZSA9ICdzZW5kb25seSc7XG4gICAgICAgIHN1cGVyKGNvbmZpZ3VyYXRpb24pO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFdlYlJ0Y1BlZXJTZW5kcmVjdiBleHRlbmRzIFdlYlJ0Y1BlZXIge1xuICAgIGNvbnN0cnVjdG9yKGNvbmZpZ3VyYXRpb246IFdlYlJ0Y1BlZXJDb25maWd1cmF0aW9uKSB7XG4gICAgICAgIGNvbmZpZ3VyYXRpb24ubW9kZSA9ICdzZW5kcmVjdic7XG4gICAgICAgIHN1cGVyKGNvbmZpZ3VyYXRpb24pO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vLyB0c2xpbnQ6ZGlzYWJsZTpuby1zdHJpbmctbGl0ZXJhbFxuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXIgfSBmcm9tICcuLi9Mb2dnZXIvT3BlblZpZHVMb2dnZXInO1xuaW1wb3J0IHsgUGxhdGZvcm1VdGlscyB9IGZyb20gJy4uL1V0aWxzL1BsYXRmb3JtJztcbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcbi8qKlxuICogQGhpZGRlblxuICovXG5sZXQgcGxhdGZvcm06IFBsYXRmb3JtVXRpbHM7XG5cbmludGVyZmFjZSBXZWJydGNTdGF0c0NvbmZpZyB7XG4gICAgaW50ZXJ2YWw6IG51bWJlcjtcbiAgICBodHRwRW5kcG9pbnQ6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIEpTT05TdGF0c1Jlc3BvbnNlIHtcbiAgICAnQHRpbWVzdGFtcCc6IHN0cmluZztcbiAgICBwYXJ0aWNpcGFudF9pZDogc3RyaW5nO1xuICAgIHNlc3Npb25faWQ6IHN0cmluZztcbiAgICBwbGF0Zm9ybTogc3RyaW5nO1xuICAgIHBsYXRmb3JtX2Rlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgc3RyZWFtOiBzdHJpbmc7XG4gICAgd2VicnRjX3N0YXRzOiBJV2VicnRjU3RhdHM7XG59XG5cbi8qKlxuICogQ29tbW9uIFdlYlJ0Y1NUYXRzIGZvciBsYXRlc3QgQ2hyb21pdW0gYW5kIEZpcmVmb3ggdmVyc2lvbnNcbiAqL1xuaW50ZXJmYWNlIElXZWJydGNTdGF0cyB7XG4gICAgaW5ib3VuZD86IHtcbiAgICAgICAgYXVkaW86XG4gICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIGppdHRlcjogbnVtYmVyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB8IHt9O1xuICAgICAgICB2aWRlbzpcbiAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgICAgYnl0ZXNSZWNlaXZlZDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgcGFja2V0c1JlY2VpdmVkOiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBwYWNrZXRzTG9zdDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgaml0dGVyPzogbnVtYmVyOyAvLyBGaXJlZm94XG4gICAgICAgICAgICAgICAgICBqaXR0ZXJCdWZmZXJEZWxheT86IG51bWJlcjsgLy8gQ2hyb21lXG4gICAgICAgICAgICAgICAgICBmcmFtZXNEZWNvZGVkOiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBmaXJDb3VudDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgbmFja0NvdW50OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBwbGlDb3VudDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgZnJhbWVIZWlnaHQ/OiBudW1iZXI7IC8vIENocm9tZVxuICAgICAgICAgICAgICAgICAgZnJhbWVXaWR0aD86IG51bWJlcjsgLy8gQ2hyb21lXG4gICAgICAgICAgICAgICAgICBmcmFtZXNEcm9wcGVkPzogbnVtYmVyOyAvLyBDaHJvbWVcbiAgICAgICAgICAgICAgICAgIGZyYW1lc1JlY2VpdmVkPzogbnVtYmVyOyAvLyBDaHJvbWVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfCB7fTtcbiAgICB9O1xuICAgIG91dGJvdW5kPzoge1xuICAgICAgICBhdWRpbzpcbiAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogbnVtYmVyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB8IHt9O1xuICAgICAgICB2aWRlbzpcbiAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgICAgYnl0ZXNTZW50OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBwYWNrZXRzU2VudDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgZmlyQ291bnQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIGZyYW1lc0VuY29kZWQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIG5hY2tDb3VudDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgcGxpQ291bnQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIHFwU3VtOiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBmcmFtZUhlaWdodD86IG51bWJlcjsgLy8gQ2hyb21lXG4gICAgICAgICAgICAgICAgICBmcmFtZVdpZHRoPzogbnVtYmVyOyAvLyBDaHJvbWVcbiAgICAgICAgICAgICAgICAgIGZyYW1lc1NlbnQ/OiBudW1iZXI7IC8vIENocm9tZVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB8IHt9O1xuICAgIH07XG4gICAgY2FuZGlkYXRlcGFpcj86IHtcbiAgICAgICAgY3VycmVudFJvdW5kVHJpcFRpbWU/OiBudW1iZXI7IC8vIENocm9tZVxuICAgICAgICBhdmFpbGFibGVPdXRnb2luZ0JpdHJhdGU/OiBudW1iZXI7IC8vQ2hyb21lXG4gICAgICAgIC8vIGF2YWlsYWJsZUluY29taW5nQml0cmF0ZT86IG51bWJlciAvLyBObyBzdXBwb3J0IGZvciBhbnkgYnJvd3NlcnMgKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9SVENJY2VDYW5kaWRhdGVQYWlyU3RhdHMvYXZhaWxhYmxlSW5jb21pbmdCaXRyYXRlKVxuICAgIH07XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNTdGF0cyB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBTVEFUU19JVEVNX05BTUUgPSAnd2VicnRjLXN0YXRzLWNvbmZpZyc7XG5cbiAgICBwcml2YXRlIHdlYlJ0Y1N0YXRzRW5hYmxlZCA9IGZhbHNlO1xuICAgIHByaXZhdGUgd2ViUnRjU3RhdHNJbnRlcnZhbElkOiBOb2RlSlMuVGltZXI7XG4gICAgcHJpdmF0ZSBzdGF0c0ludGVydmFsID0gMTtcbiAgICBwcml2YXRlIFBPU1RfVVJMOiBzdHJpbmc7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHN0cmVhbTogU3RyZWFtKSB7XG4gICAgICAgIHBsYXRmb3JtID0gUGxhdGZvcm1VdGlscy5nZXRJbnN0YW5jZSgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc0VuYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1N0YXRzRW5hYmxlZDtcbiAgICB9XG5cbiAgICBwdWJsaWMgaW5pdFdlYlJ0Y1N0YXRzKCk6IHZvaWQge1xuICAgICAgICBjb25zdCB3ZWJydGNPYmogPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLlNUQVRTX0lURU1fTkFNRSk7XG5cbiAgICAgICAgaWYgKCEhd2VicnRjT2JqKSB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0c0NvbmZpZzogV2VicnRjU3RhdHNDb25maWcgPSBKU09OLnBhcnNlKHdlYnJ0Y09iaik7XG4gICAgICAgICAgICAvLyB3ZWJydGMgb2JqZWN0IGZvdW5kIGluIGxvY2FsIHN0b3JhZ2VcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgICAgICAgICdXZWJSdGMgc3RhdHMgZW5hYmxlZCBmb3Igc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBsb2dnZXIud2FybignbG9jYWxTdG9yYWdlIGl0ZW06ICcgKyBKU09OLnN0cmluZ2lmeSh3ZWJydGNTdGF0c0NvbmZpZykpO1xuXG4gICAgICAgICAgICB0aGlzLlBPU1RfVVJMID0gd2VicnRjU3RhdHNDb25maWcuaHR0cEVuZHBvaW50O1xuICAgICAgICAgICAgdGhpcy5zdGF0c0ludGVydmFsID0gd2VicnRjU3RhdHNDb25maWcuaW50ZXJ2YWw7IC8vIEludGVydmFsIGluIHNlY29uZHNcblxuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQgPSBzZXRJbnRlcnZhbChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zZW5kU3RhdHNUb0h0dHBFbmRwb2ludCgpO1xuICAgICAgICAgICAgfSwgdGhpcy5zdGF0c0ludGVydmFsICogMTAwMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1dlYlJ0YyBzdGF0cyBub3QgZW5hYmxlZCcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8ge1xuICAgIC8vIFwibG9jYWxDYW5kaWRhdGVcIjoge1xuICAgIC8vICAgICBcImlkXCI6IFwiUlRDSWNlQ2FuZGlkYXRlXy9yNFAxeTJRXCIsXG4gICAgLy8gICAgIFwidGltZXN0YW1wXCI6IDE2MTYwODAxNTU2MTcsXG4gICAgLy8gICAgIFwidHlwZVwiOiBcImxvY2FsLWNhbmRpZGF0ZVwiLFxuICAgIC8vICAgICBcInRyYW5zcG9ydElkXCI6IFwiUlRDVHJhbnNwb3J0XzBfMVwiLFxuICAgIC8vICAgICBcImlzUmVtb3RlXCI6IGZhbHNlLFxuICAgIC8vICAgICBcIm5ldHdvcmtUeXBlXCI6IFwid2lmaVwiLFxuICAgIC8vICAgICBcImlwXCI6IFwiMTIzLjQ1LjY3Ljg5XCIsXG4gICAgLy8gICAgIFwicG9ydFwiOiA2MzM0MCxcbiAgICAvLyAgICAgXCJwcm90b2NvbFwiOiBcInVkcFwiLFxuICAgIC8vICAgICBcImNhbmRpZGF0ZVR5cGVcIjogXCJzcmZseFwiLFxuICAgIC8vICAgICBcInByaW9yaXR5XCI6IDE2ODYwNTI2MDcsXG4gICAgLy8gICAgIFwiZGVsZXRlZFwiOiBmYWxzZSxcbiAgICAvLyAgICAgXCJyYXdcIjogW1xuICAgIC8vICAgICBcImNhbmRpZGF0ZTozMzQ1NDEyOTIxIDEgdWRwIDE2ODYwNTI2MDcgMTIzLjQ1LjY3Ljg5IDYzMzQwIHR5cCBzcmZseCByYWRkciAxOTIuMTY4LjEuMzEgcnBvcnQgNjMzNDAgZ2VuZXJhdGlvbiAwIHVmcmFnIDBadFQgbmV0d29yay1pZCAxIG5ldHdvcmstY29zdCAxMFwiLFxuICAgIC8vICAgICBcImNhbmRpZGF0ZTo1ODA5NDQ4MiAxIHVkcCA0MTg4NTY5NSA5OC43Ni41NC4zMiA0NDQzMSB0eXAgcmVsYXkgcmFkZHIgMTIzLjQ1LjY3Ljg5IHJwb3J0IDYzMzQwIGdlbmVyYXRpb24gMCB1ZnJhZyAwWnRUIG5ldHdvcmstaWQgMSBuZXR3b3JrLWNvc3QgMTBcIlxuICAgIC8vICAgICBdXG4gICAgLy8gfSxcbiAgICAvLyBcInJlbW90ZUNhbmRpZGF0ZVwiOiB7XG4gICAgLy8gICAgIFwiaWRcIjogXCJSVENJY2VDYW5kaWRhdGVfMVlPMThncGhcIixcbiAgICAvLyAgICAgXCJ0aW1lc3RhbXBcIjogMTYxNjA4MDE1NTYxNyxcbiAgICAvLyAgICAgXCJ0eXBlXCI6IFwicmVtb3RlLWNhbmRpZGF0ZVwiLFxuICAgIC8vICAgICBcInRyYW5zcG9ydElkXCI6IFwiUlRDVHJhbnNwb3J0XzBfMVwiLFxuICAgIC8vICAgICBcImlzUmVtb3RlXCI6IHRydWUsXG4gICAgLy8gICAgIFwiaXBcIjogXCIxMi4zNC41Ni43OFwiLFxuICAgIC8vICAgICBcInBvcnRcIjogNjQ5ODksXG4gICAgLy8gICAgIFwicHJvdG9jb2xcIjogXCJ1ZHBcIixcbiAgICAvLyAgICAgXCJjYW5kaWRhdGVUeXBlXCI6IFwic3JmbHhcIixcbiAgICAvLyAgICAgXCJwcmlvcml0eVwiOiAxNjc5ODE5MjYzLFxuICAgIC8vICAgICBcImRlbGV0ZWRcIjogZmFsc2UsXG4gICAgLy8gICAgIFwicmF3XCI6IFtcbiAgICAvLyAgICAgXCJjYW5kaWRhdGU6MTYgMSBVRFAgMTY3OTgxOTI2MyAxMi4zNC41Ni43OCA2NDk4OSB0eXAgc3JmbHggcmFkZHIgMTcyLjE5LjAuMSBycG9ydCA2NDk4OVwiLFxuICAgIC8vICAgICBcImNhbmRpZGF0ZToxNiAxIFVEUCAxNjc5ODE5MjYzIDEyLjM0LjU2Ljc4IDY0OTg5IHR5cCBzcmZseCByYWRkciAxNzIuMTkuMC4xIHJwb3J0IDY0OTg5XCJcbiAgICAvLyAgICAgXVxuICAgIC8vIH1cbiAgICAvLyB9XG4gICAgLy8gSGF2ZSBiZWVuIHRlc3RlZCBpbjpcbiAgICAvLyAgIC0gTGludXggRGVza3RvcDpcbiAgICAvLyAgICAgICAtIENocm9tZSA4OS4wLjQzODkuOTBcbiAgICAvLyAgICAgICAtIE9wZXJhIDc0LjAuMzkxMS4yMThcbiAgICAvLyAgICAgICAtIEZpcmVmb3ggODZcbiAgICAvLyAgICAgICAtIE1pY3Jvc29mdCBFZGdlIDkxLjAuODI1LjBcbiAgICAvLyAgICAgICAtIEVsZWN0cm9uIDExLjMuMCAoQ2hyb21pdW0gODcuMC40MjgwLjE0MSlcbiAgICAvLyAgIC0gV2luZG93cyBEZXNrdG9wOlxuICAgIC8vICAgICAgIC0gQ2hyb21lIDg5LjAuNDM4OS45MFxuICAgIC8vICAgICAgIC0gT3BlcmEgNzQuMC4zOTExLjIzMlxuICAgIC8vICAgICAgIC0gRmlyZWZveCA4Ni4wLjFcbiAgICAvLyAgICAgICAtIE1pY3Jvc29mdCBFZGdlIDg5LjAuNzc0LjU0XG4gICAgLy8gICAgICAgLSBFbGVjdHJvbiAxMS4zLjAgKENocm9taXVtIDg3LjAuNDI4MC4xNDEpXG4gICAgLy8gICAtIE1hY09TIERlc2t0b3A6XG4gICAgLy8gICAgICAgLSBDaHJvbWUgODkuMC40Mzg5LjkwXG4gICAgLy8gICAgICAgLSBGaXJlZm94IDg3LjBcbiAgICAvLyAgICAgICAtIE9wZXJhIDc1LjAuMzk2OS45M1xuICAgIC8vICAgICAgIC0gTWljcm9zb2Z0IEVkZ2UgODkuMC43NzQuNTdcbiAgICAvLyAgICAgICAtIFNhZmFyaSAxNC4wICgxNDYxMC4xLjI4LjEuOSlcbiAgICAvLyAgICAgICAtIEVsZWN0cm9uIDExLjMuMCAoQ2hyb21pdW0gODcuMC40MjgwLjE0MSlcbiAgICAvLyAgIC0gQW5kcm9pZDpcbiAgICAvLyAgICAgICAtIENocm9tZSBNb2JpbGUgODkuMC40Mzg5LjkwXG4gICAgLy8gICAgICAgLSBPcGVyYSA2Mi4zLjMxNDYuNTc3NjNcbiAgICAvLyAgICAgICAtIEZpcmVmb3ggTW9iaWxlIDg2LjYuMVxuICAgIC8vICAgICAgIC0gTWljcm9zb2Z0IEVkZ2UgTW9iaWxlIDQ2LjAyLjQuNTE0N1xuICAgIC8vICAgICAgIC0gSW9uaWMgNVxuICAgIC8vICAgICAgIC0gUmVhY3QgTmF0aXZlIDAuNjRcbiAgICAvLyAgIC0gaU9TOlxuICAgIC8vICAgICAgIC0gU2FmYXJpIE1vYmlsZVxuICAgIC8vICAgICAgIC0gwr9Jb25pYz9cbiAgICAvLyAgICAgICAtIMK/UmVhY3QgTmF0aXZlP1xuICAgIHB1YmxpYyBnZXRTZWxlY3RlZEljZUNhbmRpZGF0ZUluZm8oKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXRzUmVwb3J0OiBhbnkgPSBhd2FpdCB0aGlzLnN0cmVhbS5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFN0YXRzKCk7XG4gICAgICAgICAgICBsZXQgdHJhbnNwb3J0U3RhdDtcbiAgICAgICAgICAgIGNvbnN0IGNhbmRpZGF0ZVBhaXJzOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgY29uc3QgbG9jYWxDYW5kaWRhdGVzOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgY29uc3QgcmVtb3RlQ2FuZGlkYXRlczogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIHN0YXRzUmVwb3J0LmZvckVhY2goKHN0YXQ6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChzdGF0LnR5cGUgPT09ICd0cmFuc3BvcnQnICYmIChwbGF0Zm9ybS5pc0Nocm9taXVtKCkgfHwgcGxhdGZvcm0uaXNTYWZhcmlCcm93c2VyKCkgfHwgcGxhdGZvcm0uaXNSZWFjdE5hdGl2ZSgpKSkge1xuICAgICAgICAgICAgICAgICAgICB0cmFuc3BvcnRTdGF0ID0gc3RhdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc3dpdGNoIChzdGF0LnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnY2FuZGlkYXRlLXBhaXInOlxuICAgICAgICAgICAgICAgICAgICAgICAgY2FuZGlkYXRlUGFpcnMuc2V0KHN0YXQuaWQsIHN0YXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2xvY2FsLWNhbmRpZGF0ZSc6XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZXMuc2V0KHN0YXQuaWQsIHN0YXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3JlbW90ZS1jYW5kaWRhdGUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ2FuZGlkYXRlcy5zZXQoc3RhdC5pZCwgc3RhdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGxldCBzZWxlY3RlZENhbmRpZGF0ZVBhaXI7XG4gICAgICAgICAgICBpZiAodHJhbnNwb3J0U3RhdCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRDYW5kaWRhdGVQYWlySWQgPSB0cmFuc3BvcnRTdGF0LnNlbGVjdGVkQ2FuZGlkYXRlUGFpcklkO1xuICAgICAgICAgICAgICAgIHNlbGVjdGVkQ2FuZGlkYXRlUGFpciA9IGNhbmRpZGF0ZVBhaXJzLmdldChzZWxlY3RlZENhbmRpZGF0ZVBhaXJJZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYmFzaWNhbGx5IEZpcmVmb3hcbiAgICAgICAgICAgICAgICBjb25zdCBsZW5ndGggPSBjYW5kaWRhdGVQYWlycy5zaXplO1xuICAgICAgICAgICAgICAgIGNvbnN0IGl0ZXJhdG9yID0gY2FuZGlkYXRlUGFpcnMudmFsdWVzKCk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjYW5kaWRhdGVQYWlyID0gaXRlcmF0b3IubmV4dCgpLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY2FuZGlkYXRlUGFpclsnc2VsZWN0ZWQnXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRDYW5kaWRhdGVQYWlyID0gY2FuZGlkYXRlUGFpcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbG9jYWxDYW5kaWRhdGVJZCA9IHNlbGVjdGVkQ2FuZGlkYXRlUGFpci5sb2NhbENhbmRpZGF0ZUlkO1xuICAgICAgICAgICAgY29uc3QgcmVtb3RlQ2FuZGlkYXRlSWQgPSBzZWxlY3RlZENhbmRpZGF0ZVBhaXIucmVtb3RlQ2FuZGlkYXRlSWQ7XG4gICAgICAgICAgICBsZXQgZmluYWxMb2NhbENhbmRpZGF0ZSA9IGxvY2FsQ2FuZGlkYXRlcy5nZXQobG9jYWxDYW5kaWRhdGVJZCk7XG4gICAgICAgICAgICBpZiAoISFmaW5hbExvY2FsQ2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZExpc3QgPSB0aGlzLnN0cmVhbS5nZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjYW5kID0gY2FuZExpc3QuZmlsdGVyKChjOiBSVENJY2VDYW5kaWRhdGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgICAgICEhYy5jYW5kaWRhdGUgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUuaXApID49IDAgfHwgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLmFkZHJlc3MpID49IDApICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsTG9jYWxDYW5kaWRhdGUucG9ydCkgPj0gMFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGZpbmFsTG9jYWxDYW5kaWRhdGUucmF3ID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgYyBvZiBjYW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpbmFsTG9jYWxDYW5kaWRhdGUucmF3LnB1c2goYy5jYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZmluYWxMb2NhbENhbmRpZGF0ZSA9ICdFUlJPUjogTm8gYWN0aXZlIGxvY2FsIElDRSBjYW5kaWRhdGUuIFByb2JhYmx5IElDRS1UQ1AgaXMgYmVpbmcgdXNlZCc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBmaW5hbFJlbW90ZUNhbmRpZGF0ZSA9IHJlbW90ZUNhbmRpZGF0ZXMuZ2V0KHJlbW90ZUNhbmRpZGF0ZUlkKTtcbiAgICAgICAgICAgIGlmICghIWZpbmFsUmVtb3RlQ2FuZGlkYXRlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZExpc3QgPSB0aGlzLnN0cmVhbS5nZXRSZW1vdGVJY2VDYW5kaWRhdGVMaXN0KCk7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZCA9IGNhbmRMaXN0LmZpbHRlcigoYzogUlRDSWNlQ2FuZGlkYXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAhIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5pcCkgPj0gMCB8fCBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLmFkZHJlc3MpID49IDApICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBjLmNhbmRpZGF0ZS5pbmRleE9mKGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnBvcnQpID49IDBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBmaW5hbFJlbW90ZUNhbmRpZGF0ZS5yYXcgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBjIG9mIGNhbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgZmluYWxSZW1vdGVDYW5kaWRhdGUucmF3LnB1c2goYy5jYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZmluYWxSZW1vdGVDYW5kaWRhdGUgPSAnRVJST1I6IE5vIGFjdGl2ZSByZW1vdGUgSUNFIGNhbmRpZGF0ZS4gUHJvYmFibHkgSUNFLVRDUCBpcyBiZWluZyB1c2VkJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgIGxvY2FsQ2FuZGlkYXRlOiBmaW5hbExvY2FsQ2FuZGlkYXRlLFxuICAgICAgICAgICAgICAgIHJlbW90ZUNhbmRpZGF0ZTogZmluYWxSZW1vdGVDYW5kaWRhdGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RvcFdlYlJ0Y1N0YXRzKCkge1xuICAgICAgICBpZiAodGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQpIHtcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy53ZWJSdGNTdGF0c0ludGVydmFsSWQpO1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgICAgICAgJ1dlYlJ0YyBzdGF0cyBzdG9wcGVkIGZvciBkaXNwb3NlZCBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgJyBvZiBjb25uZWN0aW9uICcgKyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgc2VuZFN0YXRzKHVybDogc3RyaW5nLCByZXNwb25zZTogSlNPTlN0YXRzUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbmZpZ3VyYXRpb246IFJlcXVlc3RJbml0ID0ge1xuICAgICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgJ0NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkocmVzcG9uc2UpLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgYXdhaXQgZmV0Y2godXJsLCBjb25maWd1cmF0aW9uKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgc2VuZFN0YXRzIGVycm9yOiAke0pTT04uc3RyaW5naWZ5KGVycm9yKX1gKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB3ZWJydGNTdGF0czogSVdlYnJ0Y1N0YXRzID0gYXdhaXQgdGhpcy5nZXRDb21tb25TdGF0cygpO1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLmdlbmVyYXRlSlNPTlN0YXRzUmVzcG9uc2Uod2VicnRjU3RhdHMpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5zZW5kU3RhdHModGhpcy5QT1NUX1VSTCwgcmVzcG9uc2UpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmxvZyhlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBIYXZlIGJlZW4gdGVzdGVkIGluOlxuICAgIC8vICAgLSBMaW51eCBEZXNrdG9wOlxuICAgIC8vICAgICAgIC0gQ2hyb21lIDg5LjAuNDM4OS45MFxuICAgIC8vICAgICAgIC0gT3BlcmEgNzQuMC4zOTExLjIxOFxuICAgIC8vICAgICAgIC0gRmlyZWZveCA4NlxuICAgIC8vICAgICAgIC0gTWljcm9zb2Z0IEVkZ2UgOTEuMC44MjUuMFxuICAgIC8vICAgICAgIC0gRWxlY3Ryb24gMTEuMy4wIChDaHJvbWl1bSA4Ny4wLjQyODAuMTQxKVxuICAgIC8vICAgLSBXaW5kb3dzIERlc2t0b3A6XG4gICAgLy8gICAgICAgLSBDaHJvbWUgODkuMC40Mzg5LjkwXG4gICAgLy8gICAgICAgLSBPcGVyYSA3NC4wLjM5MTEuMjMyXG4gICAgLy8gICAgICAgLSBGaXJlZm94IDg2LjAuMVxuICAgIC8vICAgICAgIC0gTWljcm9zb2Z0IEVkZ2UgODkuMC43NzQuNTRcbiAgICAvLyAgICAgICAtIEVsZWN0cm9uIDExLjMuMCAoQ2hyb21pdW0gODcuMC40MjgwLjE0MSlcbiAgICAvLyAgIC0gTWFjT1MgRGVza3RvcDpcbiAgICAvLyAgICAgICAtIENocm9tZSA4OS4wLjQzODkuOTBcbiAgICAvLyAgICAgICAtIE9wZXJhIDc1LjAuMzk2OS45M1xuICAgIC8vICAgICAgIC0gRmlyZWZveCA4Ny4wXG4gICAgLy8gICAgICAgLSBNaWNyb3NvZnQgRWRnZSA4OS4wLjc3NC41N1xuICAgIC8vICAgICAgIC0gU2FmYXJpIDE0LjAgKDE0NjEwLjEuMjguMS45KVxuICAgIC8vICAgICAgIC0gRWxlY3Ryb24gMTEuMy4wIChDaHJvbWl1bSA4Ny4wLjQyODAuMTQxKVxuICAgIC8vICAgLSBBbmRyb2lkOlxuICAgIC8vICAgICAgIC0gQ2hyb21lIE1vYmlsZSA4OS4wLjQzODkuOTBcbiAgICAvLyAgICAgICAtIE9wZXJhIDYyLjMuMzE0Ni41Nzc2M1xuICAgIC8vICAgICAgIC0gRmlyZWZveCBNb2JpbGUgODYuNi4xXG4gICAgLy8gICAgICAgLSBNaWNyb3NvZnQgRWRnZSBNb2JpbGUgNDYuMDIuNC41MTQ3XG4gICAgLy8gICAgICAgLSBJb25pYyA1XG4gICAgLy8gICAgICAgLSBSZWFjdCBOYXRpdmUgMC42NFxuICAgIC8vICAgLSBpT1M6XG4gICAgLy8gICAgICAgLSBTYWZhcmkgTW9iaWxlXG4gICAgLy8gICAgICAgLSDCv0lvbmljP1xuICAgIC8vICAgICAgIC0gwr9SZWFjdCBOYXRpdmU/XG4gICAgcHVibGljIGFzeW5jIGdldENvbW1vblN0YXRzKCk6IFByb21pc2U8SVdlYnJ0Y1N0YXRzPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXRzUmVwb3J0OiBhbnkgPSBhd2FpdCB0aGlzLnN0cmVhbS5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFN0YXRzKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2U6IElXZWJydGNTdGF0cyA9IHRoaXMuZ2V0V2ViUnRjU3RhdHNSZXNwb25zZU91dGxpbmUoKTtcbiAgICAgICAgICAgICAgICBjb25zdCB2aWRlb1RyYWNrU3RhdHMgPSBbJ2ZyYW1lc1JlY2VpdmVkJywgJ2ZyYW1lc0Ryb3BwZWQnLCAnZnJhbWVzU2VudCcsICdmcmFtZUhlaWdodCcsICdmcmFtZVdpZHRoJ107XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlUGFpclN0YXRzID0gWydhdmFpbGFibGVPdXRnb2luZ0JpdHJhdGUnLCAnY3VycmVudFJvdW5kVHJpcFRpbWUnXTtcblxuICAgICAgICAgICAgICAgIHN0YXRzUmVwb3J0LmZvckVhY2goKHN0YXQ6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgbWVkaWFUeXBlID0gc3RhdC5tZWRpYVR5cGUgIT0gbnVsbCA/IHN0YXQubWVkaWFUeXBlIDogc3RhdC5raW5kO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGRTdGF0ID0gKGRpcmVjdGlvbjogc3RyaW5nLCBrZXk6IHN0cmluZyk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXRba2V5XSAhPSBudWxsICYmIHJlc3BvbnNlW2RpcmVjdGlvbl0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbWVkaWFUeXBlICYmIHZpZGVvVHJhY2tTdGF0cy5pbmRleE9mKGtleSkgPiAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRpYVR5cGUgPSAndmlkZW8nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGlyZWN0aW9uICE9IG51bGwgJiYgbWVkaWFUeXBlICE9IG51bGwgJiYga2V5ICE9IG51bGwgJiYgcmVzcG9uc2VbZGlyZWN0aW9uXVttZWRpYVR5cGVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VbZGlyZWN0aW9uXVttZWRpYVR5cGVdW2tleV0gPSBOdW1iZXIoc3RhdFtrZXldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiAhPSBudWxsICYmIGtleSAhPSBudWxsICYmIGNhbmRpZGF0ZVBhaXJTdGF0cy5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNhbmRpZGF0ZS1wYWlyLXN0YXRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlW2RpcmVjdGlvbl1ba2V5XSA9IE51bWJlcihzdGF0W2tleV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHN0YXQudHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnb3V0Ym91bmQtcnRwJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdvdXRib3VuZCcsICdieXRlc1NlbnQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdvdXRib3VuZCcsICdwYWNrZXRzU2VudCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ291dGJvdW5kJywgJ2ZyYW1lc0VuY29kZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdvdXRib3VuZCcsICduYWNrQ291bnQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdvdXRib3VuZCcsICdmaXJDb3VudCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ291dGJvdW5kJywgJ3BsaUNvdW50Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnb3V0Ym91bmQnLCAncXBTdW0nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2luYm91bmQtcnRwJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdpbmJvdW5kJywgJ2J5dGVzUmVjZWl2ZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdpbmJvdW5kJywgJ3BhY2tldHNSZWNlaXZlZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ2luYm91bmQnLCAncGFja2V0c0xvc3QnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdpbmJvdW5kJywgJ2ppdHRlcicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ2luYm91bmQnLCAnZnJhbWVzRGVjb2RlZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ2luYm91bmQnLCAnbmFja0NvdW50Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnaW5ib3VuZCcsICdmaXJDb3VudCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ2luYm91bmQnLCAncGxpQ291bnQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3RyYWNrJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdpbmJvdW5kJywgJ2ppdHRlckJ1ZmZlckRlbGF5Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnaW5ib3VuZCcsICdmcmFtZXNSZWNlaXZlZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ291dGJvdW5kJywgJ2ZyYW1lc0Ryb3BwZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdvdXRib3VuZCcsICdmcmFtZXNTZW50Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCh0aGlzLnN0cmVhbS5pc0xvY2FsKCkgPyAnb3V0Ym91bmQnIDogJ2luYm91bmQnLCAnZnJhbWVIZWlnaHQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KHRoaXMuc3RyZWFtLmlzTG9jYWwoKSA/ICdvdXRib3VuZCcgOiAnaW5ib3VuZCcsICdmcmFtZVdpZHRoJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdjYW5kaWRhdGUtcGFpcic6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnY2FuZGlkYXRlcGFpcicsICdjdXJyZW50Um91bmRUcmlwVGltZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ2NhbmRpZGF0ZXBhaXInLCAnYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIC8vIERlbGV0ZSBjYW5kaWRhdGVwYWlyIGZyb20gcmVzcG9uc2UgaWYgbnVsbFxuICAgICAgICAgICAgICAgIGlmICghcmVzcG9uc2U/LmNhbmRpZGF0ZXBhaXIgfHwgT2JqZWN0LmtleXMoPE9iamVjdD5yZXNwb25zZS5jYW5kaWRhdGVwYWlyKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHJlc3BvbnNlLmNhbmRpZGF0ZXBhaXI7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGdldHRpbmcgY29tbW9uIHN0YXRzOiAnLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2VuZXJhdGVKU09OU3RhdHNSZXNwb25zZShzdGF0czogSVdlYnJ0Y1N0YXRzKTogSlNPTlN0YXRzUmVzcG9uc2Uge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgJ0B0aW1lc3RhbXAnOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICBwYXJ0aWNpcGFudF9pZDogdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5kYXRhLFxuICAgICAgICAgICAgc2Vzc2lvbl9pZDogdGhpcy5zdHJlYW0uc2Vzc2lvbi5zZXNzaW9uSWQsXG4gICAgICAgICAgICBwbGF0Zm9ybTogcGxhdGZvcm0uZ2V0TmFtZSgpLFxuICAgICAgICAgICAgcGxhdGZvcm1fZGVzY3JpcHRpb246IHBsYXRmb3JtLmdldERlc2NyaXB0aW9uKCksXG4gICAgICAgICAgICBzdHJlYW06ICd3ZWJSVEMnLFxuICAgICAgICAgICAgd2VicnRjX3N0YXRzOiBzdGF0c1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0V2ViUnRjU3RhdHNSZXNwb25zZU91dGxpbmUoKTogSVdlYnJ0Y1N0YXRzIHtcbiAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBvdXRib3VuZDoge1xuICAgICAgICAgICAgICAgICAgICBhdWRpbzoge30sXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB7fVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgY2FuZGlkYXRlcGFpcjoge31cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGluYm91bmQ6IHtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW86IHt9LFxuICAgICAgICAgICAgICAgICAgICB2aWRlbzoge31cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxufVxuIl19