openvidu-livekit-tutorials/openvidu-js/web/openvidu-browser-2.24.0.js
2022-11-18 12:40:54 +01:00

14085 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":37}],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, "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, "NIL", {
enumerable: true,
get: function () {
return _nil.default;
}
});
Object.defineProperty(exports, "version", {
enumerable: true,
get: function () {
return _version.default;
}
});
Object.defineProperty(exports, "validate", {
enumerable: true,
get: function () {
return _validate.default;
}
});
Object.defineProperty(exports, "stringify", {
enumerable: true,
get: function () {
return _stringify.default;
}
});
Object.defineProperty(exports, "parse", {
enumerable: true,
get: function () {
return _parse.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":24,"./parse.js":25,"./stringify.js":29,"./v1.js":30,"./v3.js":31,"./v4.js":33,"./v5.js":34,"./validate.js":35,"./version.js":36}],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;
var _default = '00000000-0000-0000-0000-000000000000';
exports.default = _default;
},{}],25:[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":35}],26:[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;
},{}],27:[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. Also,
// find the complete implementation of crypto (msCrypto) on IE11.
getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
if (!getRandomValues) {
throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
}
}
return getRandomValues(rnds8);
}
},{}],28:[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;
},{}],29:[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 }; }
/**
* 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).substr(1));
}
function stringify(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
const uuid = (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(); // 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":35}],30:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _rng = _interopRequireDefault(require("./rng.js"));
var _stringify = _interopRequireDefault(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.default)(b);
}
var _default = v1;
exports.default = _default;
},{"./rng.js":27,"./stringify.js":29}],31:[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":32}],32:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _default;
exports.URL = exports.DNS = void 0;
var _stringify = _interopRequireDefault(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 _default(name, version, hashfunc) {
function generateUUID(value, namespace, buf, offset) {
if (typeof value === 'string') {
value = stringToBytes(value);
}
if (typeof namespace === 'string') {
namespace = (0, _parse.default)(namespace);
}
if (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.default)(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":25,"./stringify.js":29}],33:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _rng = _interopRequireDefault(require("./rng.js"));
var _stringify = _interopRequireDefault(require("./stringify.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function v4(options, buf, offset) {
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.default)(rnds);
}
var _default = v4;
exports.default = _default;
},{"./rng.js":27,"./stringify.js":29}],34:[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":28,"./v35.js":32}],35:[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":26}],36:[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.substr(14, 1), 16);
}
var _default = version;
exports.default = _default;
},{"./validate.js":35}],37:[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);
},{}],38:[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 || {}));
},{}],39:[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.7",
"uuid": "8.3.2",
"wolfy87-eventemitter": "5.2.9",
"events": "3.3.0",
"inherits": "2.0.4"
},
"description": "OpenVidu Browser",
"devDependencies": {
"@types/node": "18.0.0",
"@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.14.1",
"tsify": "5.0.4",
"tslint": "6.1.3",
"typedoc": "0.22.17",
"typescript": "4.5.4"
},
"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.24.0"
}
},{}],40:[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":45,"jsnlog":7}],41:[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":58,"../OpenViduInternal/Logger/OpenViduLogger":80,"./Stream":48}],42:[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":80,"wolfy87-eventemitter":38}],43:[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":52,"../OpenViduInternal/Events/StreamPropertyChangedEvent":68,"../OpenViduInternal/Logger/OpenViduLogger":80}],44:[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":51,"../OpenViduInternal/Logger/OpenViduLogger":80,"../OpenViduInternal/Utils/Platform":84,"mime/lite":9}],45:[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 (_) 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":39,"../OpenViduInternal/Enums/OpenViduError":52,"../OpenViduInternal/Enums/VideoInsertMode":54,"../OpenViduInternal/Events/SessionDisconnectedEvent":63,"../OpenViduInternal/Events/StreamPropertyChangedEvent":68,"../OpenViduInternal/KurentoUtils/kurento-jsonrpc":75,"../OpenViduInternal/Logger/OpenViduLogger":80,"../OpenViduInternal/Logger/OpenViduLoggerConfiguration":81,"../OpenViduInternal/ScreenSharing/Screen-Capturing":83,"../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto":82,"../OpenViduInternal/Utils/Platform":84,"./LocalRecorder":44,"./Publisher":46,"./Session":47,"wolfy87-eventemitter":38}],46:[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 (_) 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":52,"../OpenViduInternal/Enums/TypeOfVideo":53,"../OpenViduInternal/Events/StreamEvent":66,"../OpenViduInternal/Events/StreamPropertyChangedEvent":68,"../OpenViduInternal/Logger/OpenViduLogger":80,"../OpenViduInternal/Utils/Platform":84,"./Session":47,"./Stream":48,"./StreamManager":49}],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 (_) 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":52,"../OpenViduInternal/Enums/VideoInsertMode":54,"../OpenViduInternal/Events/ConnectionEvent":55,"../OpenViduInternal/Events/ConnectionPropertyChangedEvent":56,"../OpenViduInternal/Events/ExceptionEvent":58,"../OpenViduInternal/Events/FilterEvent":59,"../OpenViduInternal/Events/NetworkQualityLevelChangedEvent":60,"../OpenViduInternal/Events/RecordingEvent":62,"../OpenViduInternal/Events/SessionDisconnectedEvent":63,"../OpenViduInternal/Events/SignalEvent":64,"../OpenViduInternal/Events/SpeechToTextEvent":65,"../OpenViduInternal/Events/StreamEvent":66,"../OpenViduInternal/Events/StreamPropertyChangedEvent":68,"../OpenViduInternal/Logger/OpenViduLogger":80,"../OpenViduInternal/Utils/Platform":84,"./Connection":41,"./EventDispatcher":42,"./Filter":43,"./Subscriber":50,"semver/functions/major":15,"semver/functions/minor":16}],48:[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 (_) 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":52,"../OpenViduInternal/Enums/TypeOfVideo":53,"../OpenViduInternal/Events/ExceptionEvent":58,"../OpenViduInternal/Events/PublisherSpeakingEvent":61,"../OpenViduInternal/Events/StreamManagerEvent":67,"../OpenViduInternal/Events/StreamPropertyChangedEvent":68,"../OpenViduInternal/Logger/OpenViduLogger":80,"../OpenViduInternal/Utils/Platform":84,"../OpenViduInternal/WebRtcPeer/WebRtcPeer":85,"../OpenViduInternal/WebRtcStats/WebRtcStats":86,"./Filter":43,"./Subscriber":50,"hark":5,"uuid":22,"wolfy87-eventemitter":38}],49:[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":54,"../OpenViduInternal/Events/ExceptionEvent":58,"../OpenViduInternal/Events/StreamManagerEvent":67,"../OpenViduInternal/Events/VideoElementEvent":69,"../OpenViduInternal/Logger/OpenViduLogger":80,"../OpenViduInternal/Utils/Platform":84,"./EventDispatcher":42}],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.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":80,"./StreamManager":49}],51:[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 = {}));
},{}],52:[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;
},{}],53:[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 = {}));
},{}],54:[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 = {}));
},{}],55:[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":57}],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.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":57}],57:[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;
},{}],58:[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":57}],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.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":57}],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.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":57}],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.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":57}],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.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":57}],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.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":80,"./Event":57}],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.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":57}],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.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":57}],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.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":46,"../../OpenVidu/Session":47,"../Logger/OpenViduLogger":80,"./Event":57}],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.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":57}],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.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":57}],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.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":57}],70:[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;
},{}],71:[function(require,module,exports){
var JsonRpcClient = require('./jsonrpcclient');
exports.JsonRpcClient = JsonRpcClient;
},{"./jsonrpcclient":72}],72:[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;
},{"../":75,"../../../Logger/OpenViduLogger":80,"./transports/webSocketWithReconnection":74}],73:[function(require,module,exports){
var WebSocketWithReconnection = require('./webSocketWithReconnection');
exports.WebSocketWithReconnection = WebSocketWithReconnection;
},{"./webSocketWithReconnection":74}],74:[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":80}],75:[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":70,"./clients":71,"./clients/transports":73,"./packers":78,"events":1,"inherits":6}],76:[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;
},{}],77:[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;
},{}],78:[function(require,module,exports){
var JsonRPC = require('./JsonRPC');
var XmlRPC = require('./XmlRPC');
exports.JsonRPC = JsonRPC;
exports.XmlRPC = XmlRPC;
},{"./JsonRPC":76,"./XmlRPC":77}],79:[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;
},{}],80:[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":79,"./OpenViduLoggerConfiguration":81,"jsnlog":7}],81:[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 = {}));
},{}],82:[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;
},{}],83:[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;
},{}],84:[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}],85:[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 (_) 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 = [];
this.candidategatheringdone = false;
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 () {
if (_this.pc.signalingState === 'stable') {
while (_this.iceCandidateList.length > 0) {
var candidate = _this.iceCandidateList.shift();
_this.pc.addIceCandidate(candidate);
}
}
});
}
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_1, message, _k, _l, kind, sdpOffer, error_2, 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_1 = _m.sent();
message = "[WebRtcPeer.createOffer] Cannot set RTCRtpSendParameters to video sender";
if (error_1 instanceof Error) {
message += ": ".concat(error_1.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_2 = _m.sent();
message = "[WebRtcPeer.createOffer] Browser failed creating an SDP Offer";
if (error_2 instanceof Error) {
message += ": ".concat(error_2.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) {
var _this = this;
configuration.mode = 'recvonly';
_this = _super.call(this, configuration) || this;
return _this;
}
return WebRtcPeerRecvonly;
}(WebRtcPeer));
exports.WebRtcPeerRecvonly = WebRtcPeerRecvonly;
var WebRtcPeerSendonly = (function (_super) {
__extends(WebRtcPeerSendonly, _super);
function WebRtcPeerSendonly(configuration) {
var _this = this;
configuration.mode = 'sendonly';
_this = _super.call(this, configuration) || this;
return _this;
}
return WebRtcPeerSendonly;
}(WebRtcPeer));
exports.WebRtcPeerSendonly = WebRtcPeerSendonly;
var WebRtcPeerSendrecv = (function (_super) {
__extends(WebRtcPeerSendrecv, _super);
function WebRtcPeerSendrecv(configuration) {
var _this = this;
configuration.mode = 'sendrecv';
_this = _super.call(this, configuration) || this;
return _this;
}
return WebRtcPeerSendrecv;
}(WebRtcPeer));
exports.WebRtcPeerSendrecv = WebRtcPeerSendrecv;
},{"../Events/ExceptionEvent":58,"../Logger/OpenViduLogger":80,"../Utils/Platform":84,"freeice":2,"uuid":22}],86:[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 (_) 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":80,"../Utils/Platform":84}]},{},[40])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIuLi9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qcyIsIi4uL25vZGVfbW9kdWxlcy9mcmVlaWNlL2luZGV4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2Uvc3R1bi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2ZyZWVpY2UvdHVybi5qc29uIiwiLi4vbm9kZV9tb2R1bGVzL2hhcmsvaGFyay5qcyIsIi4uL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL2pzbmxvZy9qc25sb2cuanMiLCIuLi9ub2RlX21vZHVsZXMvbWltZS9NaW1lLmpzIiwiLi4vbm9kZV9tb2R1bGVzL21pbWUvbGl0ZS5qcyIsIi4uL25vZGVfbW9kdWxlcy9taW1lL3R5cGVzL3N0YW5kYXJkLmpzIiwiLi4vbm9kZV9tb2R1bGVzL25vcm1hbGljZS9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy9wbGF0Zm9ybS9wbGF0Zm9ybS5qcyIsIi4uL25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiLCIuLi9ub2RlX21vZHVsZXMvc2VtdmVyL2NsYXNzZXMvc2VtdmVyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3NlbXZlci9mdW5jdGlvbnMvbWFqb3IuanMiLCIuLi9ub2RlX21vZHVsZXMvc2VtdmVyL2Z1bmN0aW9ucy9taW5vci5qcyIsIi4uL25vZGVfbW9kdWxlcy9zZW12ZXIvaW50ZXJuYWwvY29uc3RhbnRzLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3NlbXZlci9pbnRlcm5hbC9kZWJ1Zy5qcyIsIi4uL25vZGVfbW9kdWxlcy9zZW12ZXIvaW50ZXJuYWwvaWRlbnRpZmllcnMuanMiLCIuLi9ub2RlX21vZHVsZXMvc2VtdmVyL2ludGVybmFsL3BhcnNlLW9wdGlvbnMuanMiLCIuLi9ub2RlX21vZHVsZXMvc2VtdmVyL2ludGVybmFsL3JlLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9pbmRleC5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvbWQ1LWJyb3dzZXIuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L25pbC5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvcGFyc2UuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L3JlZ2V4LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9ybmctYnJvd3Nlci5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3Qvc2hhMS1icm93c2VyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC9zdHJpbmdpZnkuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L3YxLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC92My5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvdjM1LmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC92NC5qcyIsIi4uL25vZGVfbW9kdWxlcy91dWlkL2Rpc3QvdjUuanMiLCIuLi9ub2RlX21vZHVsZXMvdXVpZC9kaXN0L3ZhbGlkYXRlLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3V1aWQvZGlzdC92ZXJzaW9uLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3dpbGRlbWl0dGVyL3dpbGRlbWl0dGVyLmpzIiwiLi4vbm9kZV9tb2R1bGVzL3dvbGZ5ODctZXZlbnRlbWl0dGVyL0V2ZW50RW1pdHRlci5qcyIsIi4uL3BhY2thZ2UuanNvbiIsIk1haW4udHMiLCJPcGVuVmlkdS9Db25uZWN0aW9uLnRzIiwiT3BlblZpZHUvRXZlbnREaXNwYXRjaGVyLnRzIiwiT3BlblZpZHUvRmlsdGVyLnRzIiwiT3BlblZpZHUvTG9jYWxSZWNvcmRlci50cyIsIk9wZW5WaWR1L09wZW5WaWR1LnRzIiwiT3BlblZpZHUvUHVibGlzaGVyLnRzIiwiT3BlblZpZHUvU2Vzc2lvbi50cyIsIk9wZW5WaWR1L1N0cmVhbS50cyIsIk9wZW5WaWR1L1N0cmVhbU1hbmFnZXIudHMiLCJPcGVuVmlkdS9TdWJzY3JpYmVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9Mb2NhbFJlY29yZGVyU3RhdGUudHMiLCJPcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3IudHMiLCJPcGVuVmlkdUludGVybmFsL0VudW1zL1R5cGVPZlZpZGVvLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uUHJvcGVydHlDaGFuZ2VkRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V4Y2VwdGlvbkV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9OZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvUHVibGlzaGVyU3BlYWtpbmdFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1JlY29yZGluZ0V2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2lnbmFsRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9TcGVlY2hUb1RleHRFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbUV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtTWFuYWdlckV2ZW50LnRzIiwiT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQudHMiLCJPcGVuVmlkdUludGVybmFsL0V2ZW50cy9WaWRlb0VsZW1lbnRFdmVudC50cyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9NYXBwZXIuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy9pbmRleC5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9jbGllbnRzL2pzb25ycGNjbGllbnQuanMiLCJPcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMvY2xpZW50cy90cmFuc3BvcnRzL2luZGV4LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2NsaWVudHMvdHJhbnNwb3J0cy93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL2luZGV4LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9LdXJlbnRvVXRpbHMva3VyZW50by1qc29ucnBjL3BhY2tlcnMvSnNvblJQQy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL1htbFJQQy5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvS3VyZW50b1V0aWxzL2t1cmVudG8tanNvbnJwYy9wYWNrZXJzL2luZGV4LmpzIiwiT3BlblZpZHVJbnRlcm5hbC9Mb2dnZXIvQ29uc29sZUxvZ2dlci50cyIsIk9wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9Mb2dnZXIvT3BlblZpZHVMb2dnZXJDb25maWd1cmF0aW9uLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9TY3JlZW5TaGFyaW5nL1NjcmVlbi1DYXB0dXJpbmctQXV0by5qcyIsIk9wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nLmpzIiwiT3BlblZpZHVJbnRlcm5hbC9VdGlscy9QbGF0Zm9ybS50cyIsIk9wZW5WaWR1SW50ZXJuYWwvV2ViUnRjUGVlci9XZWJSdGNQZWVyLnRzIiwiT3BlblZpZHVJbnRlcm5hbC9XZWJSdGNTdGF0cy9XZWJSdGNTdGF0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3AvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTs7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDNXVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL1JBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOU5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RlQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN4REEsZ0RBQStDO0FBQy9DLGlDQUE0QjtBQUU1QixJQUFJLE9BQU8sVUFBVSxLQUFLLFdBQVcsRUFBRTtJQUNuQyxVQUFVLENBQUMsVUFBVSxDQUFDLEdBQUcsbUJBQVEsQ0FBQztDQUNyQztBQUdELFdBQUUsQ0FBQyxVQUFVLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQzs7Ozs7O0FDVWxDLG1DQUFrQztBQUtsQyw0RUFBMkU7QUFDM0UsNEVBQStGO0FBSy9GLElBQU0sTUFBTSxHQUFtQiwrQkFBYyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBTTVEO0lBOERJLG9CQUFvQixPQUFnQixFQUFFLGlCQUFtRTtRQUFyRixZQUFPLEdBQVAsT0FBTyxDQUFTO1FBVnBDLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFXYixJQUFJLEdBQUcsR0FBRyx1QkFBdUIsQ0FBQztRQUNsQyxJQUFJLENBQUMsQ0FBMEIsaUJBQWtCLENBQUMsSUFBSSxFQUFFO1lBRXBELElBQUksQ0FBQyxZQUFZLEdBQTJCLGlCQUFpQixDQUFDO1lBQzlELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDekMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQztZQUNoRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUM7WUFDaEQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQztZQUNuQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDO1lBQ3ZDLEdBQUcsSUFBSSxTQUFTLENBQUM7U0FDcEI7YUFBTTtZQUVILElBQUksQ0FBQyxhQUFhLEdBQTRCLGlCQUFpQixDQUFDO1lBQ2hFLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUM7WUFDMUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQztZQUNqRCxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFO2dCQUM3QixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDO2FBQzNDO1lBQ0QsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRTtnQkFDNUIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7YUFDdEQ7WUFDRCxHQUFHLElBQUksZ0NBQWdDLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDO1NBQ3pFO1FBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBT0QscUNBQWdCLEdBQWhCLFVBQWlCLFNBQTBCO1FBQTNDLGlCQStCQztRQTdCRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNoQixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsZUFBZSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFFeEgsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUM3QixnQkFBZ0IsRUFDaEI7Z0JBQ0ksWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO2dCQUMvQixTQUFTLEVBQUUsU0FBUyxDQUFDLFNBQVM7Z0JBQzlCLE1BQU0sRUFBRSxTQUFTLENBQUMsTUFBTTtnQkFDeEIsYUFBYSxFQUFFLFNBQVMsQ0FBQyxhQUFhO2FBQ3pDLEVBQ0QsVUFBQyxLQUFLLEVBQUUsUUFBUTtnQkFDWixJQUFJLEtBQUssRUFBRTtvQkFDUCxNQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztvQkFDdEUsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFO3dCQUNoQyxJQUFJLCtCQUFjLENBQ2QsS0FBSSxDQUFDLE9BQU8sRUFDWixtQ0FBa0IsQ0FBQyxtQkFBbUIsRUFDdEMsS0FBSSxDQUFDLE9BQU8sRUFDWixvSEFBb0gsRUFDcEgsS0FBSyxDQUNSO3FCQUNKLENBQUMsQ0FBQztpQkFDTjtZQUNMLENBQUMsQ0FDSixDQUFDO1NBQ0w7YUFBTTtZQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMscUJBQWMsSUFBSSxDQUFDLFlBQVksMkVBQXdFLENBQUMsQ0FBQztTQUN4SDtJQUNMLENBQUM7SUFLRCxzQ0FBaUIsR0FBakIsVUFBa0IsT0FBOEI7UUFBaEQsaUJBMEJDO1FBdkJHLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBQyxJQUFJO1lBQ2pCLElBQU0sYUFBYSxHQUF5QjtnQkFDeEMsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFO2dCQUNYLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztnQkFDekIsVUFBVSxFQUFFLEtBQUk7Z0JBQ2hCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtnQkFDdkIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO2dCQUN2QixXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7Z0JBQzdCLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztnQkFDN0IsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO2dCQUM3QixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7Z0JBQ3pCLGVBQWUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQ3RGLE1BQU0sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUzthQUNsRCxDQUFDO1lBQ0YsSUFBTSxNQUFNLEdBQUcsSUFBSSxlQUFNLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQztZQUV2RCxLQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLElBQUksQ0FDUCwyQ0FBMkMsR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLDBEQUEwRCxFQUM1SCxJQUFJLENBQUMsTUFBTyxDQUFDLGlCQUFpQixDQUNqQyxDQUFDO0lBQ04sQ0FBQztJQUtELDhCQUFTLEdBQVQsVUFBVSxNQUFjO1FBQ3BCLE1BQU0sQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQ3pCLENBQUM7SUFLRCxpQ0FBWSxHQUFaO1FBQ0ksT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7SUFLRCw0QkFBTyxHQUFQO1FBQ0ksSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDckIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFDTCxpQkFBQztBQUFELENBckxBLEFBcUxDLElBQUE7QUFyTFksZ0NBQVU7Ozs7OztBQ2hCdkIsNEVBQTJFO0FBRTNFLG1EQUFzRDtBQUt0RCxJQUFNLE1BQU0sR0FBbUIsK0JBQWMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztBQUU1RDtJQUFBO1FBSUksNEJBQXVCLEdBQTRELElBQUksT0FBTyxFQUFFLENBQUM7UUFJakcsT0FBRSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7SUEyRTVCLENBQUM7SUFqREcsK0JBQUssR0FBTCxVQUFNLElBQVksRUFBRSxPQUFlLEVBQUUsT0FBK0I7UUFDaEUsSUFBTSxZQUFZLEdBQUcsVUFBQyxLQUFLO1lBQ3ZCLElBQUksS0FBSyxFQUFFO2dCQUNQLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQ2hDO2lCQUFNO2dCQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7YUFDekI7WUFDRCxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkIsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQy9CLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFLRCxpQ0FBTyxHQUFQLFVBQVEsSUFBWSxFQUFFLE9BQWUsRUFBRSxPQUErQjtRQUF0RSxpQkFjQztRQWJHLElBQU0sWUFBWSxHQUFHLFVBQUMsS0FBSztZQUN2QixJQUFJLEtBQUssRUFBRTtnQkFDUCxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQzthQUNoQztpQkFBTTtnQkFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ3pCO1lBQ0QsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRWYsS0FBSSxDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNqRCxDQUFDLENBQUM7UUFDRixJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxZQUFZLENBQUMsQ0FBQztRQUN4RCxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDakMsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUtELGdDQUFNLEdBQU4sVUFBTyxJQUFZLEVBQUUsT0FBZ0M7UUFDakQsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNWLElBQUksQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDcEM7YUFBTTtZQUVILElBQU0sWUFBWSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDL0QsSUFBSSxDQUFDLENBQUMsWUFBWSxFQUFFO2dCQUNoQixJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUM7YUFDbkM7WUFDRCxJQUFJLENBQUMsdUJBQXVCLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ2hEO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUNMLHNCQUFDO0FBQUQsQ0FuRkEsQUFtRkMsSUFBQTtBQW5GcUIsMENBQWU7Ozs7OztBQ1RyQyxvR0FBbUc7QUFDbkcseUVBQTJGO0FBQzNGLDRFQUEyRTtBQUszRSxJQUFNLE1BQU0sR0FBbUIsK0JBQWMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztBQU81RDtJQTZDSSxnQkFBWSxJQUFZLEVBQUUsT0FBZTtRQVh6QyxhQUFRLEdBQThDLElBQUksR0FBRyxFQUFFLENBQUM7UUFZNUQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDM0IsQ0FBQztJQVFELDJCQUFVLEdBQVYsVUFBVyxNQUFjLEVBQUUsTUFBYztRQUF6QyxpQkErR0M7UUE5R0csT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNOztZQUMvQixNQUFNLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFekUsSUFBSSxXQUFXLENBQUM7WUFFaEIsSUFBTSxpQkFBaUIsR0FBRyxVQUFDLFlBQVk7Z0JBQ25DLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0RBQWdELEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDckYsSUFBTSxRQUFRLEdBQVMsTUFBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsS0FBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDOUQsS0FBSSxDQUFDLE1BQU0sQ0FBQyxNQUFPLENBQUMsY0FBYyxHQUFHLEVBQUUsTUFBTSxRQUFBLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxDQUFDO2dCQUNyRSxJQUFJLFlBQVksRUFBRTtvQkFDZCxLQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUU7d0JBQ25ELElBQUksdURBQTBCLENBQzFCLEtBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUNuQixLQUFJLENBQUMsTUFBTSxFQUNYLFFBQVEsRUFDUixLQUFJLENBQUMsTUFBTSxDQUFDLE1BQU8sRUFDbkIsUUFBUSxFQUNSLGtCQUFrQixDQUNyQjtxQkFDSixDQUFDLENBQUM7b0JBQ0gsS0FBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFO3dCQUN6RCxJQUFJLHVEQUEwQixDQUMxQixLQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFDekIsS0FBSSxDQUFDLE1BQU0sRUFDWCxRQUFRLEVBQ1IsS0FBSSxDQUFDLE1BQU0sQ0FBQyxNQUFPLEVBQ25CLFFBQVEsRUFDUixrQkFBa0IsQ0FDckI7cUJBQ0osQ0FBQyxDQUFDO2lCQUNOO2dCQUNELE9BQU8sT0FBTyxFQUFFLENBQUM7WUFDckIsQ0FBQyxDQUFDO1lBRUYsSUFBSSxLQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDN0IsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLEVBQUU7b0JBQzVCLElBQUk7d0JBQ0EsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7cUJBQy9CO29CQUFDLE9BQU8sS0FBSyxFQUFFO3dCQUNaLE9BQU8sTUFBTSxDQUFDLElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQyx3QkFBd0IsRUFBRSx1QkFBdUIsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO3FCQUNqSDtpQkFDSjtnQkFFRCxXQUFXLEdBQUcsTUFBTSxDQUFDO2dCQUVyQixJQUFJLE1BQU0sS0FBSyxRQUFRLEVBQUU7b0JBQ3JCLElBQUksQ0FBQyxDQUFBLE1BQUEsS0FBSSxDQUFDLE1BQU0sQ0FBQyw2QkFBNkIsMENBQUUsRUFBRSxDQUFBLEVBQUU7d0JBQ2hELE9BQU8sTUFBTSxDQUNULElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQyx3QkFBd0IsRUFBRSwrQ0FBK0MsQ0FBQyxDQUNqSCxDQUFDO3FCQUNMO3lCQUFNO3dCQUNILEtBQUksQ0FBQyxNQUFNLENBQUMsNkJBQTZCLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUM7NkJBQzVELElBQUksQ0FBQyxjQUFNLE9BQUEsaUJBQWlCLENBQUMsS0FBSyxDQUFDLEVBQXhCLENBQXdCLENBQUM7NkJBQ3BDLEtBQUssQ0FBQyxVQUFDLEtBQUs7NEJBQ1QsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLGlDQUFpQixDQUFDLHdCQUF3QixFQUFFO2dDQUMzRCxPQUFPLE1BQU0sQ0FBQyxJQUFJLDZCQUFhLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQzs2QkFDL0Q7aUNBQU07Z0NBQ0gsT0FBTyxNQUFNLENBQ1QsSUFBSSw2QkFBYSxDQUNiLGlDQUFpQixDQUFDLHdCQUF3QixFQUMxQyxzREFBc0QsR0FBRyxLQUFLLENBQ2pFLENBQ0osQ0FBQzs2QkFDTDt3QkFDTCxDQUFDLENBQUMsQ0FBQztxQkFDVjtpQkFDSjtxQkFBTTtvQkFDSCxPQUFPLE1BQU0sQ0FDVCxJQUFJLDZCQUFhLENBQUMsaUNBQWlCLENBQUMsd0JBQXdCLEVBQUUsOENBQXNDLE1BQU0sT0FBRyxDQUFDLENBQ2pILENBQUM7aUJBQ0w7YUFDSjtpQkFBTTtnQkFDSCxJQUFJLFlBQVksU0FBQSxDQUFDO2dCQUNqQixJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsRUFBRTtvQkFDNUIsSUFBSTt3QkFDQSxZQUFZLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztxQkFDekM7b0JBQUMsT0FBTyxLQUFLLEVBQUU7d0JBQ1osSUFBTSxRQUFRLEdBQUcsbURBQW1ELENBQUM7d0JBQ3JFLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7d0JBQ3ZCLE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO3FCQUMzQjtpQkFDSjtxQkFBTTtvQkFDSCxZQUFZLEdBQVcsTUFBTSxDQUFDO2lCQUNqQztnQkFFRCxXQUFXLEdBQUcsWUFBWSxDQUFDO2dCQUUzQixLQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUNwQyxrQkFBa0IsRUFDbEIsRUFBRSxRQUFRLEVBQUUsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxRQUFBLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxFQUNoRSxVQUFDLEtBQUssRUFBRSxRQUFRO29CQUNaLElBQUksS0FBSyxFQUFFO3dCQUNQLE1BQU0sQ0FBQyxLQUFLLENBQUMsMkNBQTJDLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7d0JBQ3hGLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxHQUFHLEVBQUU7NEJBQ3BCLE9BQU8sTUFBTSxDQUNULElBQUksNkJBQWEsQ0FDYixpQ0FBaUIsQ0FBQywwQkFBMEIsRUFDNUMsdURBQXVELENBQzFELENBQ0osQ0FBQzt5QkFDTDs2QkFBTTs0QkFDSCxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQzt5QkFDeEI7cUJBQ0o7eUJBQU07d0JBQ0gsT0FBTyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztxQkFDbEM7Z0JBQ0wsQ0FBQyxDQUNKLENBQUM7YUFDTDtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQVVELGlDQUFnQixHQUFoQixVQUFpQixTQUFpQixFQUFFLE9BQXFDO1FBQXpFLGlCQWdDQztRQS9CRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsTUFBTSxDQUFDLElBQUksQ0FBQyx3Q0FBd0MsR0FBRyxTQUFTLEdBQUcsYUFBYSxHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDekcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FDcEMsd0JBQXdCLEVBQ3hCLEVBQUUsUUFBUSxFQUFFLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLFNBQVMsV0FBQSxFQUFFLEVBQzdDLFVBQUMsS0FBSyxFQUFFLFFBQVE7Z0JBQ1osSUFBSSxLQUFLLEVBQUU7b0JBQ1AsTUFBTSxDQUFDLEtBQUssQ0FDUiw4Q0FBOEMsR0FBRyxTQUFTLEdBQUcsYUFBYSxHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUNqRyxLQUFLLENBQ1IsQ0FBQztvQkFDRixJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssR0FBRyxFQUFFO3dCQUNwQixPQUFPLE1BQU0sQ0FDVCxJQUFJLDZCQUFhLENBQ2IsaUNBQWlCLENBQUMsMEJBQTBCLEVBQzVDLDJEQUEyRCxDQUM5RCxDQUNKLENBQUM7cUJBQ0w7eUJBQU07d0JBQ0gsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQ3hCO2lCQUNKO3FCQUFNO29CQUNILEtBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztvQkFDdEMsTUFBTSxDQUFDLElBQUksQ0FDUCxpQ0FBaUMsR0FBRyxTQUFTLEdBQUcsa0NBQWtDLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQzVHLENBQUM7b0JBQ0YsT0FBTyxPQUFPLEVBQUUsQ0FBQztpQkFDcEI7WUFDTCxDQUFDLENBQ0osQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQVNELG9DQUFtQixHQUFuQixVQUFvQixTQUFpQjtRQUFyQyxpQkFnQ0M7UUEvQkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLE1BQU0sQ0FBQyxJQUFJLENBQUMsMENBQTBDLEdBQUcsU0FBUyxHQUFHLGFBQWEsR0FBRyxLQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzNHLEtBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQ3BDLDJCQUEyQixFQUMzQixFQUFFLFFBQVEsRUFBRSxLQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxTQUFTLFdBQUEsRUFBRSxFQUM3QyxVQUFDLEtBQUssRUFBRSxRQUFRO2dCQUNaLElBQUksS0FBSyxFQUFFO29CQUNQLE1BQU0sQ0FBQyxLQUFLLENBQ1IsZ0RBQWdELEdBQUcsU0FBUyxHQUFHLGFBQWEsR0FBRyxLQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFDbkcsS0FBSyxDQUNSLENBQUM7b0JBQ0YsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLEdBQUcsRUFBRTt3QkFDcEIsT0FBTyxNQUFNLENBQ1QsSUFBSSw2QkFBYSxDQUNiLGlDQUFpQixDQUFDLDBCQUEwQixFQUM1QywyREFBMkQsQ0FDOUQsQ0FDSixDQUFDO3FCQUNMO3lCQUFNO3dCQUNILE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO3FCQUN4QjtpQkFDSjtxQkFBTTtvQkFDSCxLQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDaEMsTUFBTSxDQUFDLElBQUksQ0FDUCxpQ0FBaUMsR0FBRyxTQUFTLEdBQUcsa0NBQWtDLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQzVHLENBQUM7b0JBQ0YsT0FBTyxPQUFPLEVBQUUsQ0FBQztpQkFDcEI7WUFDTCxDQUFDLENBQ0osQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUNMLGFBQUM7QUFBRCxDQTNQQSxBQTJQQyxJQUFBO0FBM1BZLHdCQUFNOzs7Ozs7QUNmbkIsbUZBQWtGO0FBQ2xGLDRFQUEyRTtBQUMzRSwrREFBbUU7QUFDbkUsZ0NBQW1DO0FBS25DLElBQU0sTUFBTSxHQUFtQiwrQkFBYyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBSzVELElBQUksUUFBdUIsQ0FBQztBQUs1QjtJQWNJLHVCQUFvQixNQUFjO1FBQWQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQVQxQixXQUFNLEdBQVUsRUFBRSxDQUFDO1FBVXZCLFFBQVEsR0FBRyx3QkFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDO1FBQzFHLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxZQUFZLEdBQUcsY0FBYyxDQUFDO1FBQzFFLElBQUksQ0FBQyxLQUFLLEdBQUcsdUNBQWtCLENBQUMsS0FBSyxDQUFDO0lBQzFDLENBQUM7SUF3QkQsOEJBQU0sR0FBTixVQUFPLE9BQWE7UUFBcEIsaUJBa0VDO1FBakVHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixJQUFJO2dCQUNBLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxJQUFJLE9BQU8sWUFBWSxNQUFNLEVBQUU7b0JBQzFELE9BQU8sTUFBTSxDQUNULGtJQUEwSCxPQUFPLFNBQUssQ0FDekksQ0FBQztpQkFDTDtnQkFDRCxJQUFJLE9BQU8sYUFBYSxLQUFLLFdBQVcsRUFBRTtvQkFDdEMsTUFBTSxDQUFDLEtBQUssQ0FDUiw0R0FBNEcsQ0FDL0csQ0FBQztvQkFDRixNQUFNLEtBQUssQ0FDUCw0R0FBNEcsQ0FDL0csQ0FBQztpQkFDTDtnQkFDRCxJQUFJLEtBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsS0FBSyxFQUFFO29CQUN6QyxNQUFNLEtBQUssQ0FDUCxrRkFBa0Y7d0JBQzlFLEtBQUksQ0FBQyxLQUFLO3dCQUNWLHFFQUFxRSxDQUM1RSxDQUFDO2lCQUNMO2dCQUNELE1BQU0sQ0FBQyxHQUFHLENBQUMsc0NBQXNDLEdBQUcsS0FBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsbUJBQW1CLEdBQUcsS0FBSSxDQUFDLFlBQVksR0FBRyxHQUFHLENBQUMsQ0FBQztnQkFFMUgsSUFBSSxDQUFDLE9BQU8sRUFBRTtvQkFDVixPQUFPLEdBQUcsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLENBQUM7aUJBQ3hDO3FCQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFO29CQUMxQixPQUFPLENBQUMsUUFBUSxHQUFHLFlBQVksQ0FBQztpQkFDbkM7Z0JBRUQsS0FBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLGFBQWEsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUM5RSxLQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO2FBQzlCO1lBQUMsT0FBTyxHQUFHLEVBQUU7Z0JBQ1YsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7YUFDdEI7WUFFRCxLQUFJLENBQUMsYUFBYSxDQUFDLGVBQWUsR0FBRyxVQUFDLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFO29CQUNqQixLQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7aUJBQzVCO1lBQ0wsQ0FBQyxDQUFDO1lBRUYsS0FBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEdBQUcsVUFBQyxDQUFDO2dCQUMzQixNQUFNLENBQUMsS0FBSyxDQUFDLHVCQUF1QixFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzdDLENBQUMsQ0FBQztZQUVGLEtBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxHQUFHO2dCQUN6QixNQUFNLENBQUMsR0FBRyxDQUFDLCtCQUErQixHQUFHLEtBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1lBQ2pGLENBQUMsQ0FBQztZQUVGLEtBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHO2dCQUN4QixLQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDekIsQ0FBQyxDQUFDO1lBRUYsS0FBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEdBQUc7Z0JBQ3pCLE1BQU0sQ0FBQyxHQUFHLENBQUMsOEJBQThCLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUM7WUFDaEYsQ0FBQyxDQUFDO1lBRUYsS0FBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEdBQUc7Z0JBQzFCLE1BQU0sQ0FBQyxHQUFHLENBQUMsK0JBQStCLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUM7WUFDakYsQ0FBQyxDQUFDO1lBRUYsS0FBSSxDQUFDLEtBQUssR0FBRyx1Q0FBa0IsQ0FBQyxTQUFTLENBQUM7WUFDMUMsT0FBTyxPQUFPLEVBQUUsQ0FBQztRQUNyQixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFNRCw0QkFBSSxHQUFKO1FBQUEsaUJBbUJDO1FBbEJHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixJQUFJO2dCQUNBLElBQUksS0FBSSxDQUFDLEtBQUssS0FBSyx1Q0FBa0IsQ0FBQyxLQUFLLElBQUksS0FBSSxDQUFDLEtBQUssS0FBSyx1Q0FBa0IsQ0FBQyxRQUFRLEVBQUU7b0JBQ3ZGLE1BQU0sS0FBSyxDQUNQLGdHQUFnRzt3QkFDNUYsS0FBSSxDQUFDLEtBQUs7d0JBQ1YseUNBQXlDLENBQ2hELENBQUM7aUJBQ0w7Z0JBQ0QsS0FBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUc7b0JBQ3hCLEtBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztvQkFDckIsT0FBTyxPQUFPLEVBQUUsQ0FBQztnQkFDckIsQ0FBQyxDQUFDO2dCQUNGLEtBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUM7YUFDN0I7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDUixPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNwQjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQU1ELDZCQUFLLEdBQUw7UUFBQSxpQkFtQkM7UUFsQkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLElBQUk7Z0JBQ0EsSUFBSSxLQUFJLENBQUMsS0FBSyxLQUFLLHVDQUFrQixDQUFDLFNBQVMsRUFBRTtvQkFDN0MsT0FBTyxNQUFNLENBQ1QsS0FBSyxDQUNELHFGQUFxRjt3QkFDakYsS0FBSSxDQUFDLEtBQUs7d0JBQ1YscUVBQXFFLENBQzVFLENBQ0osQ0FBQztpQkFDTDtnQkFDRCxLQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUMzQixLQUFJLENBQUMsS0FBSyxHQUFHLHVDQUFrQixDQUFDLE1BQU0sQ0FBQztnQkFDdkMsT0FBTyxPQUFPLEVBQUUsQ0FBQzthQUNwQjtZQUFDLE9BQU8sS0FBSyxFQUFFO2dCQUNaLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQ3hCO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBTUQsOEJBQU0sR0FBTjtRQUFBLGlCQWlCQztRQWhCRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBSTtnQkFDQSxJQUFJLEtBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsTUFBTSxFQUFFO29CQUMxQyxNQUFNLEtBQUssQ0FDUCxtRkFBbUY7d0JBQy9FLEtBQUksQ0FBQyxLQUFLO3dCQUNWLHlDQUF5QyxDQUNoRCxDQUFDO2lCQUNMO2dCQUNELEtBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQzVCLEtBQUksQ0FBQyxLQUFLLEdBQUcsdUNBQWtCLENBQUMsU0FBUyxDQUFDO2dCQUMxQyxPQUFPLE9BQU8sRUFBRSxDQUFDO2FBQ3BCO1lBQUMsT0FBTyxLQUFLLEVBQUU7Z0JBQ1osT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDeEI7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLRCwrQkFBTyxHQUFQLFVBQVEsYUFBYTtRQUNqQixJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsUUFBUSxFQUFFO1lBQzVDLE1BQU0sS0FBSyxDQUNQLHNGQUFzRjtnQkFDbEYsSUFBSSxDQUFDLEtBQUs7Z0JBQ1Ysd0NBQXdDLENBQy9DLENBQUM7U0FDTDtRQUVELElBQUksQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVwRCxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUVsQyxJQUFJLFFBQVEsQ0FBQyxlQUFlLEVBQUUsRUFBRTtZQUM1QixJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7U0FDeEM7UUFFRCxJQUFJLE9BQU8sYUFBYSxLQUFLLFFBQVEsRUFBRTtZQUNuQyxJQUFNLGdCQUFnQixHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDaEUsSUFBSSxnQkFBZ0IsRUFBRTtnQkFDbEIsSUFBSSxDQUFDLFlBQVksR0FBRyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO2FBQ3ZFO1NBQ0o7YUFBTTtZQUNILElBQUksQ0FBQyxZQUFZLEdBQUcsYUFBYSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDcEU7UUFFRCxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO1FBRTdDLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUM3QixDQUFDO0lBS0QsNkJBQUssR0FBTDtRQUFBLGlCQWFDO1FBWkcsSUFBTSxDQUFDLEdBQUc7WUFDTixPQUFPLEtBQUksQ0FBQyxJQUFJLENBQUM7WUFDakIsS0FBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7WUFDakIsS0FBSSxDQUFDLEtBQUssR0FBRyx1Q0FBa0IsQ0FBQyxLQUFLLENBQUM7UUFDMUMsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLHVDQUFrQixDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLHVDQUFrQixDQUFDLE1BQU0sRUFBRTtZQUN6RixJQUFJLENBQUMsSUFBSSxFQUFFO2lCQUNOLElBQUksQ0FBQyxjQUFNLE9BQUEsQ0FBQyxFQUFFLEVBQUgsQ0FBRyxDQUFDO2lCQUNmLEtBQUssQ0FBQyxjQUFNLE9BQUEsQ0FBQyxFQUFFLEVBQUgsQ0FBRyxDQUFDLENBQUM7U0FDekI7YUFBTTtZQUNILENBQUMsRUFBRSxDQUFDO1NBQ1A7SUFDTCxDQUFDO0lBS0QsZ0NBQVEsR0FBUjtRQUNJLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyx1Q0FBa0IsQ0FBQyxRQUFRLEVBQUU7WUFDNUMsTUFBTSxLQUFLLENBQ1AsdUZBQXVGO2dCQUNuRixJQUFJLENBQUMsS0FBSztnQkFDVix3Q0FBd0MsQ0FDL0MsQ0FBQztTQUNMO2FBQU07WUFDSCxJQUFNLENBQUMsR0FBc0IsUUFBUSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN6RCxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7WUFDekIsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFN0IsSUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzNELENBQUMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDO1lBQ2IsQ0FBQyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsRUFBRSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDaEUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1YsVUFBVSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFcEMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDaEM7SUFDTCxDQUFDO0lBS0QsK0JBQU8sR0FBUDtRQUNJLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyx1Q0FBa0IsQ0FBQyxRQUFRLEVBQUU7WUFDNUMsTUFBTSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztTQUNyRTthQUFNO1lBQ0gsT0FBTyxJQUFJLENBQUMsSUFBSyxDQUFDO1NBQ3JCO0lBQ0wsQ0FBQztJQVlELHNDQUFjLEdBQWQsVUFBZSxRQUFnQixFQUFFLE9BQWE7UUFBOUMsaUJBaUNDO1FBaENHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixJQUFJLEtBQUksQ0FBQyxLQUFLLEtBQUssdUNBQWtCLENBQUMsUUFBUSxFQUFFO2dCQUM1QyxPQUFPLE1BQU0sQ0FDVCxLQUFLLENBQ0QsNkZBQTZGO29CQUN6RixLQUFJLENBQUMsS0FBSztvQkFDVix3Q0FBd0MsQ0FDL0MsQ0FDSixDQUFDO2FBQ0w7aUJBQU07Z0JBQ0gsSUFBTSxNQUFJLEdBQUcsSUFBSSxjQUFjLEVBQUUsQ0FBQztnQkFDbEMsTUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUVsQyxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRTtvQkFDN0IsS0FBa0IsVUFBb0IsRUFBcEIsS0FBQSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFwQixjQUFvQixFQUFwQixJQUFvQixFQUFFO3dCQUFuQyxJQUFNLEdBQUcsU0FBQTt3QkFDVixNQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO3FCQUM1QztpQkFDSjtnQkFFRCxNQUFJLENBQUMsa0JBQWtCLEdBQUc7b0JBQ3RCLElBQUksTUFBSSxDQUFDLFVBQVUsS0FBSyxDQUFDLEVBQUU7d0JBQ3ZCLElBQUksTUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFOzRCQUUxQyxPQUFPLE9BQU8sQ0FBQyxNQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7eUJBQ3JDOzZCQUFNOzRCQUNILE9BQU8sTUFBTSxDQUFDLE1BQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzt5QkFDOUI7cUJBQ0o7Z0JBQ0wsQ0FBQyxDQUFDO2dCQUNGLE1BQUksQ0FBQyxJQUFJLENBQUMsS0FBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ3hCO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBWUQsNkNBQXFCLEdBQXJCLFVBQXNCLFFBQWdCLEVBQUUsT0FBYTtRQUFyRCxpQkFxQ0M7UUFwQ0csT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLElBQUksS0FBSSxDQUFDLEtBQUssS0FBSyx1Q0FBa0IsQ0FBQyxRQUFRLEVBQUU7Z0JBQzVDLE9BQU8sTUFBTSxDQUNULEtBQUssQ0FDRCxvR0FBb0c7b0JBQ2hHLEtBQUksQ0FBQyxLQUFLO29CQUNWLHdDQUF3QyxDQUMvQyxDQUNKLENBQUM7YUFDTDtpQkFBTTtnQkFDSCxJQUFNLE1BQUksR0FBRyxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNsQyxNQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBRWxDLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFO29CQUM3QixLQUFrQixVQUFvQixFQUFwQixLQUFBLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQXBCLGNBQW9CLEVBQXBCLElBQW9CLEVBQUU7d0JBQW5DLElBQU0sR0FBRyxTQUFBO3dCQUNWLE1BQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7cUJBQzVDO2lCQUNKO2dCQUVELElBQU0sUUFBUSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUM7Z0JBQ2hDLFFBQVEsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEtBQUksQ0FBQyxJQUFLLEVBQUUsS0FBSSxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFJLENBQUMsSUFBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBRXhGLE1BQUksQ0FBQyxrQkFBa0IsR0FBRztvQkFDdEIsSUFBSSxNQUFJLENBQUMsVUFBVSxLQUFLLENBQUMsRUFBRTt3QkFDdkIsSUFBSSxNQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUU7NEJBRTFDLE9BQU8sT0FBTyxDQUFDLE1BQUksQ0FBQyxZQUFZLENBQUMsQ0FBQzt5QkFDckM7NkJBQU07NEJBQ0gsT0FBTyxNQUFNLENBQUMsTUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO3lCQUM5QjtxQkFDSjtnQkFDTCxDQUFDLENBQUM7Z0JBRUYsTUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUN2QjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUlPLHFDQUFhLEdBQXJCO1FBQ0ksTUFBTSxDQUFDLEdBQUcsQ0FBQyxnQ0FBZ0MsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQztRQUU5RSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ3pFLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBRWpCLElBQUksQ0FBQyxlQUFlLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWpFLElBQUksQ0FBQyxLQUFLLEdBQUcsdUNBQWtCLENBQUMsUUFBUSxDQUFDO0lBQzdDLENBQUM7SUFDTCxvQkFBQztBQUFELENBM1hBLEFBMlhDLElBQUE7QUEzWFksc0NBQWE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ25CMUIsaURBQWdEO0FBQ2hELHlDQUF3QztBQUN4QyxxQ0FBb0M7QUFFcEMsZ0dBQStGO0FBQy9GLG9HQUFtRztBQUtuRyx5RUFBMkY7QUFDM0YsNkVBQTRFO0FBQzVFLDRFQUEyRTtBQUMzRSwrREFBbUU7QUFHbkUsMkZBQTZGO0FBQzdGLGtGQUFvRjtBQUNwRixzR0FBcUc7QUFJckcsbURBQXNEO0FBSXRELDZFQUFnRjtBQUtoRixJQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQztBQVFsRCxJQUFNLE1BQU0sR0FBbUIsK0JBQWMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztBQUs1RCxJQUFJLFFBQXVCLENBQUM7QUFNNUI7SUFxRkk7UUFBQSxpQkFpQkM7UUFwR08seUJBQW9CLEdBQUcsS0FBSyxDQUFDO1FBU3JDLGVBQVUsR0FBZ0IsRUFBRSxDQUFDO1FBWTdCLFdBQU0sR0FBRyxFQUFFLENBQUM7UUFJWixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBSWpCLFFBQUcsR0FBRyxLQUFLLENBQUM7UUF3QlosU0FBSSxHQUFXLENBQUMsQ0FBQyxDQUFDO1FBSWxCLDBCQUFxQixHQUFrQyxFQUFFLENBQUM7UUFJMUQsd0JBQW1CLEdBQVcsQ0FBQyxDQUFDLENBQUM7UUFJakMsb0JBQWUsR0FBZ0MseURBQTJCLENBQUMsUUFBUSxDQUFDO1FBSXBGLGlCQUFZLEdBQVksS0FBSyxDQUFDO1FBSTlCLGlCQUFZLEdBQVksS0FBSyxDQUFDO1FBUTlCLE9BQUUsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBR3BCLFFBQVEsR0FBRyx3QkFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxjQUFjLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQztRQUMxQyxNQUFNLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDcEMsTUFBTSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxRQUFRLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQztRQUMvRCxNQUFNLENBQUMsSUFBSSxDQUFDLDRCQUE0QixHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUVoRSxJQUFJLFFBQVEsQ0FBQyxjQUFjLEVBQUUsSUFBSSxRQUFRLENBQUMsYUFBYSxFQUFFLEVBQUU7WUFFdkQsSUFBSSxDQUFDLG9CQUFvQixDQUFDO2dCQUN0QixLQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxVQUFDLFNBQVM7b0JBQzlCLElBQUksU0FBUyxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUU7d0JBQzlGLEtBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxTQUFTLEVBQUUsZUFBZSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztxQkFDN0U7Z0JBQ0wsQ0FBQyxDQUFDLENBQUM7WUFDUCxDQUFDLENBQUMsQ0FBQztTQUNOO0lBQ0wsQ0FBQztJQUtELDhCQUFXLEdBQVg7UUFDSSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksaUJBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDeEIsQ0FBQztJQStCRCxnQ0FBYSxHQUFiLFVBQWMsYUFBK0MsRUFBRSxNQUFPLEVBQUUsTUFBTztRQUMzRSxJQUFJLFVBQStCLENBQUM7UUFFcEMsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLE9BQU8sTUFBTSxLQUFLLFVBQVUsRUFBRTtZQUcxQyxVQUFVLEdBQXdCLE1BQU0sQ0FBQztZQUV6QyxVQUFVLEdBQUc7Z0JBQ1QsV0FBVyxFQUFFLE9BQU8sVUFBVSxDQUFDLFdBQVcsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQy9GLFNBQVMsRUFDTCxPQUFPLGdCQUFnQixLQUFLLFdBQVcsSUFBSSxVQUFVLENBQUMsV0FBVyxZQUFZLGdCQUFnQjtvQkFDekYsQ0FBQyxDQUFDLFNBQVM7b0JBQ1gsQ0FBQyxDQUFDLE9BQU8sVUFBVSxDQUFDLFNBQVMsS0FBSyxXQUFXO3dCQUN6QyxDQUFDLENBQUMsVUFBVSxDQUFDLFNBQVM7d0JBQ3RCLENBQUMsQ0FBQyxTQUFTO2dCQUN2QixVQUFVLEVBQ04sT0FBTyxVQUFVLENBQUMsVUFBVSxLQUFLLFdBQVc7b0JBQ3hDLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssUUFBUTt3QkFDdkMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQzt3QkFDeEMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVO29CQUMzQixDQUFDLENBQUMsaUNBQWUsQ0FBQyxNQUFNO2dCQUNoQyxNQUFNLEVBQUUsT0FBTyxVQUFVLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSTtnQkFDM0UsWUFBWSxFQUFFLE9BQU8sVUFBVSxDQUFDLFlBQVksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUk7Z0JBQzdGLFlBQVksRUFBRSxPQUFPLFVBQVUsQ0FBQyxZQUFZLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUM3RixVQUFVLEVBQ04sT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLElBQUksVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0I7b0JBQ3pGLENBQUMsQ0FBQyxTQUFTO29CQUNYLENBQUMsQ0FBQyxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssV0FBVzt3QkFDMUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVO3dCQUN2QixDQUFDLENBQUMsU0FBUztnQkFDdkIsV0FBVyxFQUFFLE9BQU8sVUFBVSxDQUFDLFdBQVcsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQy9GLGNBQWMsRUFBRSxVQUFVLENBQUMsY0FBYztnQkFDekMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxNQUFNO2FBQzVCLENBQUM7U0FDTDthQUFNO1lBR0gsVUFBVSxHQUFHO2dCQUNULFVBQVUsRUFBRSxpQ0FBZSxDQUFDLE1BQU07Z0JBQ2xDLE1BQU0sRUFBRSxJQUFJO2dCQUNaLFlBQVksRUFBRSxJQUFJO2dCQUNsQixZQUFZLEVBQUUsSUFBSTtnQkFDbEIsVUFBVSxFQUFFLFNBQVM7YUFDeEIsQ0FBQztTQUNMO1FBRUQsSUFBTSxTQUFTLEdBQWMsSUFBSSxxQkFBUyxDQUFDLGFBQWEsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFNUUsSUFBSSxpQkFBcUQsQ0FBQztRQUMxRCxJQUFJLENBQUMsQ0FBQyxNQUFNLElBQUksT0FBTyxNQUFNLEtBQUssVUFBVSxFQUFFO1lBQzFDLGlCQUFpQixHQUFHLE1BQU0sQ0FBQztTQUM5QjthQUFNLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRTtZQUNqQixpQkFBaUIsR0FBRyxNQUFNLENBQUM7U0FDOUI7UUFFRCxTQUFTO2FBQ0osVUFBVSxFQUFFO2FBQ1osSUFBSSxDQUFDO1lBQ0YsSUFBSSxpQkFBaUIsS0FBSyxTQUFTLEVBQUU7Z0JBQ2pDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDO2FBQ2hDO1lBQ0QsU0FBUyxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDN0MsQ0FBQyxDQUFDO2FBQ0QsS0FBSyxDQUFDLFVBQUMsS0FBSztZQUNULElBQUksaUJBQWlCLEtBQUssU0FBUyxFQUFFO2dCQUNqQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUM1QjtZQUNELFNBQVMsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNqRCxDQUFDLENBQUMsQ0FBQztRQUVQLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sU0FBUyxDQUFDO0lBQ3JCLENBQUM7SUFVRCxxQ0FBa0IsR0FBbEIsVUFBbUIsYUFBK0MsRUFBRSxVQUFnQztRQUFwRyxpQkFrQkM7UUFqQkcsT0FBTyxJQUFJLE9BQU8sQ0FBWSxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQzFDLElBQUksU0FBb0IsQ0FBQztZQUV6QixJQUFNLFFBQVEsR0FBRyxVQUFDLEtBQVk7Z0JBQzFCLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRTtvQkFDVCxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDeEI7cUJBQU07b0JBQ0gsT0FBTyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7aUJBQzdCO1lBQ0wsQ0FBQyxDQUFDO1lBRUYsSUFBSSxDQUFDLENBQUMsVUFBVSxFQUFFO2dCQUNkLFNBQVMsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUM7YUFDdkU7aUJBQU07Z0JBQ0gsU0FBUyxHQUFHLEtBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2FBQzNEO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBTUQsb0NBQWlCLEdBQWpCLFVBQWtCLE1BQWM7UUFDNUIsT0FBTyxJQUFJLDZCQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDckMsQ0FBQztJQU1ELDBDQUF1QixHQUF2QjtRQUVJLElBQUksUUFBUSxDQUFDLGNBQWMsRUFBRSxFQUFFO1lBQzNCLE9BQU8sQ0FDSCxRQUFRLENBQUMsZUFBZSxFQUFFO2dCQUMxQixRQUFRLENBQUMscUJBQXFCLEVBQUU7Z0JBQ2hDLFFBQVEsQ0FBQyxzQkFBc0IsRUFBRTtnQkFDakMsUUFBUSxDQUFDLG9CQUFvQixFQUFFO2dCQUMvQixRQUFRLENBQUMsbUJBQW1CLEVBQUU7Z0JBQzlCLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FDeEIsQ0FBQztTQUNMO1FBR0QsT0FBTyxDQUNILFFBQVEsQ0FBQyxlQUFlLEVBQUU7WUFDMUIsUUFBUSxDQUFDLHFCQUFxQixFQUFFO1lBQ2hDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtZQUMzQixRQUFRLENBQUMsc0JBQXNCLEVBQUU7WUFDakMsUUFBUSxDQUFDLGNBQWMsRUFBRTtZQUN6QixRQUFRLENBQUMsb0JBQW9CLEVBQUU7WUFDL0IsUUFBUSxDQUFDLGFBQWEsRUFBRTtZQUN4QixRQUFRLENBQUMsbUJBQW1CLEVBQUU7WUFDOUIsUUFBUSxDQUFDLGdCQUFnQixFQUFFO1lBQzNCLFFBQVEsQ0FBQyxlQUFlLEVBQUU7WUFDMUIsUUFBUSxDQUFDLGdCQUFnQixFQUFFO1lBQzNCLFFBQVEsQ0FBQyxVQUFVLEVBQUU7WUFDckIsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUN0QixDQUFDO0lBQ04sQ0FBQztJQU1ELGlEQUE4QixHQUE5QjtRQUNJLE9BQU8sUUFBUSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3JDLENBQUM7SUFLRCw2QkFBVSxHQUFWO1FBQ0ksT0FBTyxJQUFJLE9BQU8sQ0FBVyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQ3pDLFNBQVMsQ0FBQyxZQUFZO2lCQUNqQixnQkFBZ0IsRUFBRTtpQkFDbEIsSUFBSSxDQUFDLFVBQUMsV0FBVzs7Z0JBQ2QsSUFBTSxPQUFPLEdBQWEsRUFBRSxDQUFDO2dCQUc3QixJQUFJLFFBQVEsQ0FBQyxjQUFjLEVBQUUsSUFBSSxPQUFPLE9BQU8sSUFBSSxXQUFXLEtBQUksTUFBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsT0FBTywwQ0FBRSxzQkFBc0IsQ0FBQSxFQUFFO29CQUN4RyxPQUFPLENBQUMsT0FBTyxDQUFDLHNCQUFzQixDQUFDLG1CQUFtQixFQUFFLENBQUMsSUFBSSxDQUFDLFVBQUMsYUFBdUI7d0JBQ3RGLElBQUksa0JBQWtCLEdBQWEsRUFBRSxDQUFDO3dCQUN0QyxJQUFJLFlBQVksR0FBYSxFQUFFLENBQUM7d0JBQ2hDLElBQUksWUFBWSxHQUFhLEVBQUUsQ0FBQzt3QkFDaEMsa0JBQWtCLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQyxVQUFDLE1BQWMsSUFBSyxPQUFBLE1BQU0sQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUE1QixDQUE0QixDQUFDLENBQUM7d0JBQzVGLFlBQVksR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQUMsTUFBdUIsSUFBSyxPQUFBLE1BQU0sQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUE1QixDQUE0QixDQUFRLENBQUM7d0JBQ3BHLFlBQVksR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQUMsTUFBdUIsSUFBSyxPQUFBLE1BQU0sQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUE1QixDQUE0QixDQUFRLENBQUM7d0JBQ3BHLFlBQVksQ0FBQyxPQUFPLENBQUMsVUFBQyxVQUFVLEVBQUUsS0FBSzs0QkFDbkMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUU7Z0NBQ25CLElBQUksS0FBSyxHQUFHLEVBQUUsQ0FBQztnQ0FDZixJQUFJLEtBQUssS0FBSyxDQUFDLEVBQUU7b0NBQ2IsS0FBSyxHQUFHLGNBQWMsQ0FBQztpQ0FDMUI7cUNBQU0sSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUFFO29DQUNwQixLQUFLLEdBQUcsYUFBYSxDQUFDO2lDQUN6QjtxQ0FBTTtvQ0FDSCxLQUFLLEdBQUcsZ0JBQWdCLENBQUM7aUNBQzVCO2dDQUNELE9BQU8sQ0FBQyxJQUFJLENBQUM7b0NBQ1QsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO29DQUNyQixRQUFRLEVBQUUsVUFBVSxDQUFDLFFBQVE7b0NBQzdCLEtBQUssRUFBRSxLQUFLO2lDQUNmLENBQUMsQ0FBQzs2QkFDTjtpQ0FBTTtnQ0FDSCxPQUFPLENBQUMsSUFBSSxDQUFDO29DQUNULElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtvQ0FDckIsUUFBUSxFQUFFLFVBQVUsQ0FBQyxRQUFRO29DQUM3QixLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUs7aUNBQzFCLENBQUMsQ0FBQzs2QkFDTjt3QkFDTCxDQUFDLENBQUMsQ0FBQzt3QkFDSCxZQUFZLENBQUMsT0FBTyxDQUFDLFVBQUMsVUFBVSxFQUFFLEtBQUs7NEJBQ25DLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFO2dDQUNuQixJQUFJLEtBQUssR0FBRyxFQUFFLENBQUM7Z0NBQ2YsUUFBUSxLQUFLLEVBQUU7b0NBQ1gsS0FBSyxDQUFDO3dDQUNGLEtBQUssR0FBRyxTQUFTLENBQUM7d0NBQ2xCLE1BQU07b0NBQ1YsS0FBSyxDQUFDO3dDQUNGLElBQU0sWUFBWSxHQUFHLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUF6QixDQUF5QixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7d0NBQ3BGLEtBQUssR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLHFCQUFxQixDQUFDO3dDQUNsRSxNQUFNO29DQUNWLEtBQUssQ0FBQzt3Q0FDRixJQUFNLFVBQVUsR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsVUFBQyxDQUFDLElBQUssT0FBQSxDQUFDLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBekIsQ0FBeUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dDQUNsRixJQUFJLFVBQVUsRUFBRTs0Q0FDWixLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQzt5Q0FDNUI7NkNBQU07NENBQ0gsS0FBSyxHQUFHLGtCQUFrQixDQUFDO3lDQUM5Qjt3Q0FDRCxNQUFNO29DQUNWLEtBQUssQ0FBQzt3Q0FDRixJQUFNLGFBQWEsR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsVUFBQyxDQUFDLElBQUssT0FBQSxDQUFDLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBN0IsQ0FBNkIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dDQUN6RixLQUFLLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7d0NBQ3pELE1BQU07b0NBQ1Y7d0NBQ0ksS0FBSyxHQUFHLG9CQUFvQixDQUFDO3dDQUM3QixNQUFNO2lDQUNiO2dDQUNELE9BQU8sQ0FBQyxJQUFJLENBQUM7b0NBQ1QsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO29DQUNyQixRQUFRLEVBQUUsVUFBVSxDQUFDLFFBQVE7b0NBQzdCLEtBQUssRUFBRSxLQUFLO2lDQUNmLENBQUMsQ0FBQzs2QkFDTjtpQ0FBTTtnQ0FDSCxPQUFPLENBQUMsSUFBSSxDQUFDO29DQUNULElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtvQ0FDckIsUUFBUSxFQUFFLFVBQVUsQ0FBQyxRQUFRO29DQUM3QixLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUs7aUNBQzFCLENBQUMsQ0FBQzs2QkFDTjt3QkFDTCxDQUFDLENBQUMsQ0FBQzt3QkFDSCxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDNUIsQ0FBQyxDQUFDLENBQUM7aUJBQ047cUJBQU07b0JBRUgsV0FBVyxDQUFDLE9BQU8sQ0FBQyxVQUFDLFVBQVU7d0JBQzNCLElBQUksVUFBVSxDQUFDLElBQUksS0FBSyxZQUFZLElBQUksVUFBVSxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUU7NEJBQ3RFLE9BQU8sQ0FBQyxJQUFJLENBQUM7Z0NBQ1QsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO2dDQUNyQixRQUFRLEVBQUUsVUFBVSxDQUFDLFFBQVE7Z0NBQzdCLEtBQUssRUFBRSxVQUFVLENBQUMsS0FBSzs2QkFDMUIsQ0FBQyxDQUFDO3lCQUNOO29CQUNMLENBQUMsQ0FBQyxDQUFDO29CQUNILE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2lCQUMzQjtZQUNMLENBQUMsQ0FBQztpQkFDRCxLQUFLLENBQUMsVUFBQyxLQUFLO2dCQUNULE1BQU0sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQzdDLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3pCLENBQUMsQ0FBQyxDQUFDO1FBQ1gsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBaURELCtCQUFZLEdBQVosVUFBYSxPQUE0QjtRQUF6QyxpQkFxR0M7UUFwR0csT0FBTyxJQUFJLE9BQU8sQ0FBYyxVQUFPLE9BQU8sRUFBRSxNQUFNOzs7Ozs7O3dCQUM1QyxxQkFBcUIsR0FBRyxVQUFPLG1CQUFnQyxFQUFFLFdBQW1DOzs7Ozt3Q0FDaEcsc0JBQXNCLEdBQUcsV0FBVyxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQzt3Q0FDcEYsY0FBYyxHQUEyQixFQUFFLEtBQUssRUFBRSxzQkFBc0IsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUM7Ozs7d0NBRW5FLFdBQU0sU0FBUyxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsY0FBYyxDQUFDLEVBQUE7O3dDQUEzRSxlQUFlLEdBQUcsU0FBeUQ7d0NBQ2pGLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzt3Q0FDbEUsV0FBTyxPQUFPLENBQUMsbUJBQW1CLENBQUMsRUFBQzs7O3dDQUVwQyxtQkFBbUIsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBQyxLQUFLOzRDQUMvQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7d0NBQ2pCLENBQUMsQ0FBQyxDQUFDO3dDQUNILG1CQUFtQixDQUFDLGNBQWMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFDLEtBQUs7NENBQy9DLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQzt3Q0FDakIsQ0FBQyxDQUFDLENBQUM7d0NBQ0gsV0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE9BQUssRUFBRSxjQUFjLENBQUMsQ0FBQyxFQUFDOzs7OzZCQUUzRSxDQUFDOzs7O3dCQUd3QixXQUFNLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsRUFBQTs7d0JBQTVELGFBQWEsR0FBRyxTQUE0Qzs2QkFFOUQsQ0FBQSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDOzRCQUMxRCxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsVUFBVSxJQUFJLENBQUEsTUFBQSxhQUFhLENBQUMsV0FBVywwQ0FBRSxLQUFLLE1BQUssS0FBSyxDQUFDOzRCQUMxRSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsVUFBVSxJQUFJLENBQUEsTUFBQSxhQUFhLENBQUMsV0FBVywwQ0FBRSxLQUFLLE1BQUssS0FBSyxDQUFDLENBQUEsRUFGMUUsY0FFMEU7d0JBRzFFLFdBQU8sT0FBTyxDQUFDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxhQUFhLEVBQUUsSUFBSSxXQUFXLEVBQUUsQ0FBQyxDQUFDLEVBQUM7O3dCQUtoRixJQUFJLENBQUMsQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFOzRCQUM1QixPQUFPLGFBQWEsQ0FBQyxXQUFZLENBQUMsS0FBSyxDQUFDO3lCQUMzQzt3QkFDRCxJQUFJLENBQUMsQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFOzRCQUM1QixPQUFPLGFBQWEsQ0FBQyxXQUFZLENBQUMsS0FBSyxDQUFDO3lCQUMzQzt3QkFFRyx5QkFBeUIsR0FBRyxLQUFLLENBQUM7NkJBQ2xDLENBQUEsT0FBTyxPQUFPLENBQUMsV0FBVyxLQUFLLFFBQVEsQ0FBQSxFQUF2QyxlQUF1Qzs2QkFHbkMsQ0FBQSxPQUFPLENBQUMsV0FBVyxLQUFLLFFBQVE7NEJBQ2hDLE9BQU8sQ0FBQyxXQUFXLEtBQUssUUFBUTs0QkFDaEMsQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLElBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQSxFQUZwRSxlQUVvRTt3QkFHcEUseUJBQXlCOzRCQUNyQixDQUFDLGFBQWEsQ0FBQyxVQUFVLElBQUksT0FBTyxDQUFDLFdBQVcsS0FBSyxJQUFJLElBQUksT0FBTyxDQUFDLFdBQVcsS0FBSyxLQUFLLENBQUM7NkJBQzNGLENBQUEsU0FBUyxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFBLEVBQW5FLGVBQW1FOzs7O3dCQUczQyxXQUFNLFNBQVMsQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFBOzt3QkFBOUUsV0FBVyxHQUFHLFNBQWdFO3dCQUNwRixJQUFJLENBQUMsd0JBQXdCLENBQUMsYUFBYSxFQUFFLFdBQVcsQ0FBQyxDQUFDOzZCQUN0RCx5QkFBeUIsRUFBekIsY0FBeUI7d0JBQ3pCLFdBQU0scUJBQXFCLENBQUMsV0FBVyxFQUEwQixhQUFhLENBQUMsV0FBVyxDQUFDLEVBQUE7O3dCQUEzRixTQUEyRixDQUFDO3dCQUM1RixXQUFPOzRCQUVQLFdBQU8sT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFDOzs7O3dCQUc1QixTQUFTLEdBQXNCLGlDQUFpQixDQUFDLHFCQUFxQixDQUFDO3dCQUNyRSxZQUFZLEdBQUcsT0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO3dCQUN0QyxXQUFPLE1BQU0sQ0FBQyxJQUFJLDZCQUFhLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLEVBQUM7Ozs7d0JBVXBFLGNBQWMsR0FBRyx5QkFBeUI7NEJBQzVDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxhQUFhLENBQUMsV0FBWSxDQUFDLEtBQUssRUFBRTs0QkFDN0MsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUM7Ozs7d0JBRVIsV0FBTSxTQUFTLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsRUFBQTs7d0JBQXZFLFdBQVcsR0FBRyxTQUF5RDt3QkFDN0UsSUFBSSxDQUFDLHdCQUF3QixDQUFDLGFBQWEsRUFBRSxXQUFXLENBQUMsQ0FBQzs2QkFDdEQseUJBQXlCLEVBQXpCLGVBQXlCO3dCQUN6QixXQUFNLHFCQUFxQixDQUFDLFdBQVcsRUFBMEIsYUFBYSxDQUFDLFdBQVcsQ0FBQyxFQUFBOzt3QkFBM0YsU0FBMkYsQ0FBQzs7NkJBRTVGLFdBQU8sT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFDOzs7O3dCQUc1QixTQUFTLFNBQW1CLENBQUM7d0JBQzNCLFlBQVksR0FBRyxPQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7d0JBQ3RDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLEtBQUssUUFBUSxDQUFDLEVBQUU7NEJBQ3JDLFNBQVMsR0FBRyxpQ0FBaUIsQ0FBQyxvQkFBb0IsQ0FBQzt5QkFDdEQ7NkJBQU07NEJBQ0gsU0FBUyxHQUFHLGlDQUFpQixDQUFDLHFCQUFxQixDQUFDO3lCQUN2RDt3QkFDRCxXQUFPLE1BQU0sQ0FBQyxJQUFJLDZCQUFhLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLEVBQUM7Ozs7d0JBSWxFLE1BQU0sQ0FBQyxPQUFLLENBQUMsQ0FBQzs7Ozs7YUFFckIsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQU1ELGlDQUFjLEdBQWQ7UUFDSSxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDNUIsQ0FBQztJQU1ELDJDQUF3QixHQUF4QixVQUF5QixhQUE0QztRQUNqRSxJQUFJLENBQUMscUJBQXFCLEdBQUcsYUFBYSxDQUFDO0lBQy9DLENBQUM7SUFPRCx1Q0FBb0IsR0FBcEIsVUFBcUIsT0FBTztRQUN2QixVQUFrQixDQUFDLGdCQUFnQixDQUFDLG1CQUFtQixFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFLRCxtREFBZ0MsR0FBaEMsVUFBaUMsU0FBb0IsRUFBRSxNQUF3QyxFQUFFLGFBQXFCLEVBQUUsWUFBb0I7UUFBNUksaUJBaUJDOztRQWhCRyxJQUFJLFFBQVEsR0FBRyxDQUFDLENBQUM7UUFDakIsSUFBTSxRQUFRLEdBQUcsQ0FBQSxNQUFBLE1BQUEsU0FBUyxhQUFULFNBQVMsdUJBQVQsU0FBUyxDQUFFLE1BQU0sMENBQUUsZUFBZSwwQ0FBRSxLQUFLLEtBQUksQ0FBQyxDQUFDO1FBQ2hFLElBQU0sU0FBUyxHQUFHLENBQUEsTUFBQSxNQUFBLFNBQVMsYUFBVCxTQUFTLHVCQUFULFNBQVMsQ0FBRSxNQUFNLDBDQUFFLGVBQWUsMENBQUUsTUFBTSxLQUFJLENBQUMsQ0FBQztRQUVsRSxJQUFNLDhCQUE4QixHQUFtQixXQUFXLENBQUM7WUFDL0QsUUFBUSxFQUFFLENBQUM7WUFDWCxJQUFJLFFBQVEsR0FBRyxZQUFZLEVBQUU7Z0JBQ3pCLFlBQVksQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO2FBQ2hEO1lBQ0QsU0FBUyxDQUFDLGtCQUFrQixFQUFFLENBQUMsSUFBSSxDQUFDLFVBQUMsYUFBYTtnQkFDOUMsSUFBSSxhQUFhLENBQUMsS0FBSyxLQUFLLFFBQVEsSUFBSSxhQUFhLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRTtvQkFDeEUsWUFBWSxDQUFDLDhCQUE4QixDQUFDLENBQUM7b0JBQzdDLEtBQUksQ0FBQywrQkFBK0IsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsYUFBYSxDQUFDLEtBQUssRUFBRSxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7aUJBQzNIO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDdEIsQ0FBQztJQUtELGtEQUErQixHQUEvQixVQUNJLFNBQW9CLEVBQ3BCLE1BQXdDLEVBQ3hDLFFBQWdCLEVBQ2hCLFNBQWlCLEVBQ2pCLFFBQWdCLEVBQ2hCLFNBQWlCO1FBTnJCLGlCQWdEQztRQXhDRyxTQUFTLENBQUMsTUFBTSxDQUFDLGVBQWUsR0FBRztZQUMvQixLQUFLLEVBQUUsUUFBUSxJQUFJLENBQUM7WUFDcEIsTUFBTSxFQUFFLFNBQVMsSUFBSSxDQUFDO1NBQ3pCLENBQUM7UUFDRixJQUFJLENBQUMsV0FBVyxDQUNaLHVCQUF1QixFQUN2QjtZQUNJLFFBQVEsRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVE7WUFDbkMsUUFBUSxFQUFFLGlCQUFpQjtZQUMzQixRQUFRLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQztZQUMxRCxNQUFNLFFBQUE7U0FDVCxFQUNELFVBQUMsS0FBSyxFQUFFLFFBQVE7WUFDWixJQUFJLEtBQUssRUFBRTtnQkFDUCxNQUFNLENBQUMsS0FBSyxDQUFDLDZDQUE2QyxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQ3RFO2lCQUFNO2dCQUNILEtBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFO29CQUM1QyxJQUFJLHVEQUEwQixDQUMxQixLQUFJLENBQUMsT0FBTyxFQUNaLFNBQVMsQ0FBQyxNQUFNLEVBQ2hCLGlCQUFpQixFQUNqQixTQUFTLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFDaEMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsRUFDdEMsTUFBTSxDQUNUO2lCQUNKLENBQUMsQ0FBQztnQkFDSCxTQUFTLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFO29CQUN6QyxJQUFJLHVEQUEwQixDQUMxQixTQUFTLEVBQ1QsU0FBUyxDQUFDLE1BQU0sRUFDaEIsaUJBQWlCLEVBQ2pCLFNBQVMsQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUNoQyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxFQUN0QyxNQUFNLENBQ1Q7aUJBQ0osQ0FBQyxDQUFDO2dCQUNILEtBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDO2FBQ3pDO1FBQ0wsQ0FBQyxDQUNKLENBQUM7SUFDTixDQUFDO0lBS0Qsd0NBQXFCLEdBQXJCLFVBQXNCLFNBQW9CLEVBQUUsUUFBZ0IsRUFBRSxRQUFnQixFQUFFLFlBQWlDO1FBQWpILGlCQW1DQztRQWxDRyxJQUFNLFFBQVEsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQztRQUNyQyxJQUFNLFFBQVEsR0FBRyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQztRQUNyQyxJQUFNLE1BQU0sR0FBRyxlQUFlLENBQUM7UUFFL0IsSUFBSSxTQUFTLENBQUMsTUFBTSxDQUFDLHNCQUFzQixFQUFFO1lBQ3pDLElBQUksQ0FBQyxXQUFXLENBQ1osdUJBQXVCLEVBQ3ZCO2dCQUNJLFFBQVEsRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVE7Z0JBQ25DLFFBQVEsRUFBRSxZQUFZO2dCQUN0QixRQUFRLEVBQUUsUUFBUTtnQkFDbEIsTUFBTSxRQUFBO2FBQ1QsRUFDRCxVQUFDLEtBQUssRUFBRSxRQUFRO2dCQUNaLElBQUksS0FBSyxFQUFFO29CQUNQLE1BQU0sQ0FBQyxLQUFLLENBQUMsNkNBQTZDLEVBQUUsS0FBSyxDQUFDLENBQUM7aUJBQ3RFO3FCQUFNO29CQUNILEtBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFO3dCQUM1QyxJQUFJLHVEQUEwQixDQUFDLEtBQUksQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUM7cUJBQzNHLENBQUMsQ0FBQztvQkFDSCxTQUFTLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFO3dCQUN6QyxJQUFJLHVEQUEwQixDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsTUFBTSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQztxQkFDeEcsQ0FBQyxDQUFDO2lCQUNOO1lBQ0wsQ0FBQyxDQUNKLENBQUM7U0FDTDthQUFNO1lBQ0gsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUU7Z0JBQzVDLElBQUksdURBQTBCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsTUFBTSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQzthQUMzRyxDQUFDLENBQUM7WUFDSCxTQUFTLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFO2dCQUN6QyxJQUFJLHVEQUEwQixDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsTUFBTSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQzthQUN4RyxDQUFDLENBQUM7U0FDTjtJQUNMLENBQUM7SUFLRCwyQ0FBd0IsR0FBeEIsVUFBeUIsbUJBQXdDO1FBQWpFLGlCQWtGQztRQWpGRyxPQUFPLElBQUksT0FBTyxDQUErQixVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQzdELElBQU0sYUFBYSxHQUFpQztnQkFDaEQsVUFBVSxFQUFFLFNBQVM7Z0JBQ3JCLFVBQVUsRUFBRSxTQUFTO2dCQUNyQixXQUFXLEVBQUU7b0JBQ1QsS0FBSyxFQUFFLFNBQVM7b0JBQ2hCLEtBQUssRUFBRSxTQUFTO2lCQUNuQjthQUNKLENBQUM7WUFDRixJQUFNLFdBQVcsR0FBRyxtQkFBbUIsQ0FBQyxXQUFXLENBQUM7WUFDcEQsSUFBTSxXQUFXLEdBQUcsbUJBQW1CLENBQUMsV0FBVyxDQUFDO1lBR3BELElBQUksV0FBVyxLQUFLLElBQUksSUFBSSxXQUFXLEtBQUssS0FBSyxFQUFFO2dCQUUvQyxhQUFhLENBQUMsV0FBWSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7YUFDNUM7WUFDRCxJQUFJLFdBQVcsS0FBSyxJQUFJLElBQUksV0FBVyxLQUFLLEtBQUssRUFBRTtnQkFFL0MsYUFBYSxDQUFDLFdBQVksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO2FBQzVDO1lBQ0QsSUFBSSxhQUFhLENBQUMsV0FBWSxDQUFDLEtBQUssS0FBSyxLQUFLLElBQUksYUFBYSxDQUFDLFdBQVksQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFO2dCQUUxRixPQUFPLE1BQU0sQ0FDVCxJQUFJLDZCQUFhLENBQ2IsaUNBQWlCLENBQUMsbUJBQW1CLEVBQ3JDLDRGQUE0RixDQUMvRixDQUNKLENBQUM7YUFDTDtZQUdELElBQUksT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLElBQUksV0FBVyxZQUFZLGdCQUFnQixFQUFFO2dCQUVwRixhQUFhLENBQUMsVUFBVSxHQUFHLFdBQVcsQ0FBQzthQUMxQztZQUNELElBQUksT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLElBQUksV0FBVyxZQUFZLGdCQUFnQixFQUFFO2dCQUVwRixhQUFhLENBQUMsVUFBVSxHQUFHLFdBQVcsQ0FBQzthQUMxQztZQUdELElBQUksV0FBVyxLQUFLLFNBQVMsRUFBRTtnQkFDM0IsYUFBYSxDQUFDLFdBQVksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO2FBQzNDO1lBQ0QsSUFBSSxXQUFXLEtBQUssU0FBUyxFQUFFO2dCQUMzQixhQUFhLENBQUMsV0FBWSxDQUFDLEtBQUssR0FBRztvQkFDL0IsS0FBSyxFQUFFO3dCQUNILEtBQUssRUFBRSxHQUFHO3FCQUNiO29CQUNELE1BQU0sRUFBRTt3QkFDSixLQUFLLEVBQUUsR0FBRztxQkFDYjtpQkFDSixDQUFDO2FBQ0w7WUFHRCxJQUFJLFdBQVcsS0FBSyxJQUFJLElBQUksV0FBVyxLQUFLLEtBQUssRUFBRTtnQkFDL0MsSUFBSSxDQUFDLENBQUMsbUJBQW1CLENBQUMsVUFBVSxFQUFFO29CQUNsQyxJQUFNLGNBQWMsR0FBRyxtQkFBbUIsQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUMvRSxJQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQzdDLElBQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDOUMsYUFBYSxDQUFDLFdBQVksQ0FBQyxLQUFLLEdBQUc7d0JBQy9CLEtBQUssRUFBRTs0QkFDSCxLQUFLLEVBQUUsVUFBVTt5QkFDcEI7d0JBQ0QsTUFBTSxFQUFFOzRCQUNKLEtBQUssRUFBRSxXQUFXO3lCQUNyQjtxQkFDSixDQUFDO2lCQUNMO2dCQUNELElBQUksQ0FBQyxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRTtvQkFDVCxhQUFhLENBQUMsV0FBWSxDQUFDLEtBQU0sQ0FBQyxTQUFTLEdBQUcsRUFBRSxLQUFLLEVBQUUsbUJBQW1CLENBQUMsU0FBUyxFQUFFLENBQUM7aUJBQ2xIO2FBQ0o7WUFHRCxLQUFJLENBQUMsZ0NBQWdDLENBQUMsYUFBYSxFQUFFLG1CQUFtQixFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUUzRixPQUFPLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNsQyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLRCwwQkFBTyxHQUFQLFVBQVEsZUFBdUM7UUFDM0MsSUFBTSxNQUFNLEdBQUc7WUFDWCxTQUFTLEVBQUUsSUFBSTtZQUNmLEVBQUUsRUFBRTtnQkFDQSxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssR0FBRyxhQUFhLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTO2dCQUN4RCxXQUFXLEVBQUUsZUFBZTtnQkFDNUIsWUFBWSxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNoRCxjQUFjLEVBQUUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ3BELGFBQWEsRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDbEQsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7YUFDM0Q7WUFDRCxHQUFHLEVBQUU7Z0JBQ0QsY0FBYyxFQUFFLEtBQUs7Z0JBQ3JCLHVCQUF1QixFQUFFLElBQUk7Z0JBQzdCLGlCQUFpQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7Z0JBQ3RFLG9CQUFvQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7Z0JBQzVFLHNCQUFzQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7Z0JBQ2hGLGVBQWUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUNsRSxrQkFBa0IsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUN4RSxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUNwRSxnQkFBZ0IsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUNwRSxXQUFXLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7Z0JBQ3pELHFCQUFxQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7Z0JBQzlFLHlCQUF5QixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsMkJBQTJCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7Z0JBQ3RGLDBCQUEwQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsbUNBQW1DLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7Z0JBQy9GLHFCQUFxQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7Z0JBQzlFLFlBQVksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUM5RCxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7Z0JBQ3hELDZCQUE2QixFQUFFLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUM5RSwyQkFBMkIsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUMxRixtQkFBbUIsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUMxRSx3QkFBd0IsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLDBCQUEwQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2FBQ3ZGO1NBQ0osQ0FBQztRQUNGLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBS0Qsa0RBQStCLEdBQS9CLFVBQWdDLFFBQVE7UUFDcEMsT0FBTyxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7UUFDakMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUseUJBQXlCLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBS0Qsa0NBQWUsR0FBZjtRQUNJLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUM5QyxDQUFDO0lBS0QsMEJBQU8sR0FBUDtRQUNJLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSw2QkFBNkIsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFLRCw4QkFBVyxHQUFYLFVBQVksTUFBYyxFQUFFLE1BQVcsRUFBRSxRQUFTOztRQUM5QyxJQUFJLE1BQU0sSUFBSSxNQUFNLFlBQVksUUFBUSxFQUFFO1lBQ3RDLFFBQVEsR0FBRyxNQUFNLENBQUM7WUFDbEIsTUFBTSxHQUFHLEVBQUUsQ0FBQztTQUNmO1FBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQyw0QkFBNEIsR0FBRyxNQUFNLEdBQUcsYUFBYSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDbkcsTUFBQSxJQUFJLENBQUMsYUFBYSwwQ0FBRSxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBS0QsMkJBQVEsR0FBUjtRQUNJLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUN0QixDQUFDO0lBS0QsNEJBQVMsR0FBVDtRQUNJLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBS0QsOEJBQVcsR0FBWDtRQUNJLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN6QixDQUFDO0lBS0QseUJBQU0sR0FBTjtRQUNJLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUNwQixDQUFDO0lBS0QsMkNBQXdCLEdBQXhCLFVBQXlCLEtBQUssRUFBRSxXQUFtQztRQUMvRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFO1lBRXhCLEtBQUssQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUM7U0FDdkM7UUFDRCxJQUFJLFNBQVMsRUFBRSxZQUFvQixDQUFDO1FBQ3BDLFFBQVEsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUM5QixLQUFLLGVBQWU7Z0JBQ2hCLFNBQVMsR0FBRyxpQ0FBaUIsQ0FBQyw0QkFBNEIsQ0FBQztnQkFDM0QsWUFBWSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDaEMsT0FBTyxJQUFJLDZCQUFhLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQ3RELEtBQUssaUJBQWlCO2dCQUNsQixTQUFTLEdBQUcsaUNBQWlCLENBQUMsb0JBQW9CLENBQUM7Z0JBQ25ELFlBQVksR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2hDLE9BQU8sSUFBSSw2QkFBYSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUN0RCxLQUFLLHNCQUFzQjtnQkFDdkIsSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxLQUFLLFVBQVUsRUFBRTtvQkFDL0MsU0FBUyxHQUFHLGlDQUFpQixDQUFDLDRCQUE0QixDQUFDO29CQUMzRCxZQUFZO3dCQUNSLG9DQUFvQzs0QkFDbUIsV0FBVyxDQUFDLEtBQU0sQ0FBQyxRQUFXLENBQUMsS0FBSzs0QkFDM0YsYUFBYSxDQUFDO2lCQUNyQjtxQkFBTTtvQkFDSCxTQUFTLEdBQUcsaUNBQWlCLENBQUMsMEJBQTBCLENBQUM7b0JBQ3pELFlBQVksR0FBRyxzRUFBc0UsR0FBRyxLQUFLLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQztpQkFDbEg7Z0JBQ0QsT0FBTyxJQUFJLDZCQUFhLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQ3RELEtBQUssa0JBQWtCO2dCQUNuQixTQUFTLEdBQUcsaUNBQWlCLENBQUMscUJBQXFCLENBQUM7Z0JBQ3BELFlBQVksR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2hDLE9BQU8sSUFBSSw2QkFBYSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQztZQUN0RDtnQkFDSSxPQUFPLElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQyxnQ0FBZ0MsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztTQUN0RztJQUNMLENBQUM7SUFLRCwyQ0FBd0IsR0FBeEIsVUFBeUIsYUFBMkMsRUFBRSxXQUF3QixFQUFFLE1BQWU7UUFDM0csSUFBSSxDQUFDLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRTtZQUM1QixXQUFXLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUMvQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUU7Z0JBQ1YsSUFBSSxDQUFDLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUU7b0JBQ25DLE1BQU0sQ0FBQyx5QkFBeUIsR0FBRyxhQUFhLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQztpQkFDdEU7cUJBQU07b0JBQ0gsTUFBTSxDQUFDLHlCQUF5QixHQUFHLGFBQWEsQ0FBQyxVQUFVLENBQUMsY0FBYyxFQUFFLENBQUM7aUJBQ2hGO2FBQ0o7U0FDSjtRQUNELElBQUksQ0FBQyxDQUFDLGFBQWEsQ0FBQyxVQUFVLEVBQUU7WUFDNUIsV0FBVyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDbEQ7UUFDRCxPQUFPLFdBQVcsQ0FBQztJQUN2QixDQUFDO0lBS1MsbURBQWdDLEdBQTFDLFVBQ0ksYUFBMkMsRUFDM0MsbUJBQXdDLEVBQ3hDLE9BQU8sRUFDUCxNQUFNO1FBSlYsaUJBa0pDO1FBNUlHLElBQU0sV0FBVyxHQUFHLG1CQUFtQixDQUFDLFdBQVcsQ0FBQztRQUNwRCxJQUFNLFdBQVcsR0FBRyxtQkFBbUIsQ0FBQyxXQUFXLENBQUM7UUFDcEQsSUFBSSxPQUFPLFdBQVcsS0FBSyxRQUFRLEVBQUU7WUFDakMsYUFBYSxDQUFDLFdBQVksQ0FBQyxLQUFLLEdBQUcsRUFBRSxRQUFRLEVBQUUsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLEVBQUUsQ0FBQztTQUMzRTtRQUVELElBQUksT0FBTyxXQUFXLEtBQUssUUFBUSxFQUFFO1lBQ2pDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxFQUFFO2dCQUNsQyxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsRUFBRSxXQUFXLENBQUMsQ0FBQzthQUNuRDtpQkFBTTtnQkFHSCxJQUFJLENBQUMsSUFBSSxDQUFDLDhCQUE4QixFQUFFLEVBQUU7b0JBQ3hDLElBQU0sS0FBSyxHQUFHLElBQUksNkJBQWEsQ0FDM0IsaUNBQWlCLENBQUMsNEJBQTRCLEVBQzlDLDJIQUEySDt3QkFDM0gsUUFBUSxDQUFDLE9BQU8sRUFBRTt3QkFDbEIsR0FBRzt3QkFDSCxRQUFRLENBQUMsVUFBVSxFQUFFLENBQ3hCLENBQUM7b0JBQ0YsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDcEIsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQ3hCO3FCQUFNO29CQUNILElBQUksUUFBUSxDQUFDLFVBQVUsRUFBRSxFQUFFO3dCQUN2QixJQUFNLE1BQU0sR0FBRyxTQUFTLENBQUM7d0JBQ3pCLElBQU0saUJBQWlCLEdBQVcsV0FBVyxDQUFDO3dCQUM5QyxJQUFNLGdCQUFnQixHQUFHLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO3dCQUMvRixhQUFhLENBQUMsV0FBWSxDQUFDLEtBQU0sR0FBRzs0QkFDdEMsU0FBUyxFQUFFO2dDQUNQLGlCQUFpQixFQUFFLFNBQVM7Z0NBQzVCLG1CQUFtQixFQUFFLGdCQUFnQjs2QkFDeEM7eUJBQ0osQ0FBQzt3QkFDRixPQUFPLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztxQkFDakM7eUJBQU07d0JBQ0gsSUFDSSxDQUFDLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLDBCQUEwQjs0QkFDdkQsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLFFBQVEsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDOzRCQUNuRSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsRUFDNUM7NEJBR0UsYUFBYSxDQUFDLG9CQUFvQixDQUFDLFVBQUMsS0FBSyxFQUFFLGlCQUFpQjtnQ0FDeEQsSUFDSSxDQUFDLENBQUMsS0FBSztvQ0FDUCxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLElBQUksaUJBQWlCLENBQUMsU0FBUyxDQUFDLGlCQUFpQixLQUFLLFFBQVEsQ0FBQyxFQUMvRjtvQ0FDRSxJQUFJLEtBQUssS0FBSyxtQkFBbUIsSUFBSSxLQUFLLEtBQUssdUJBQXVCLEVBQUU7d0NBQ3BFLElBQU0sT0FBSyxHQUFHLElBQUksNkJBQWEsQ0FDM0IsaUNBQWlCLENBQUMscUJBQXFCLEVBQ3ZDLHFEQUFxRCxDQUN4RCxDQUFDO3dDQUNGLE1BQU0sQ0FBQyxLQUFLLENBQUMsT0FBSyxDQUFDLENBQUM7d0NBQ3BCLE9BQU8sTUFBTSxDQUFDLE9BQUssQ0FBQyxDQUFDO3FDQUN4Qjt5Q0FBTTt3Q0FDSCxJQUFNLFdBQVcsR0FBRyxLQUFJLENBQUMscUJBQXFCOzZDQUN6QywwQkFBMkIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDOzZDQUN0QyxHQUFHLEVBQUk7NkNBQ1AsSUFBSSxFQUFFLENBQUM7d0NBQ1osYUFBYSxDQUFDLHdCQUF3QixDQUFDLFdBQVcsRUFBRSxVQUFDLE1BQU07NENBQ3ZELElBQUksTUFBTSxLQUFLLG9CQUFvQixFQUFFO2dEQUNqQyxJQUFNLE9BQUssR0FBRyxJQUFJLDZCQUFhLENBQzNCLGlDQUFpQixDQUFDLHlCQUF5QixFQUMzQyxzQ0FBc0MsQ0FDekMsQ0FBQztnREFDRixNQUFNLENBQUMsS0FBSyxDQUFDLE9BQUssQ0FBQyxDQUFDO2dEQUNwQixPQUFPLE1BQU0sQ0FBQyxPQUFLLENBQUMsQ0FBQzs2Q0FDeEI7NENBQ0QsSUFBSSxNQUFNLEtBQUssZUFBZSxFQUFFO2dEQUM1QixJQUFNLE9BQUssR0FBRyxJQUFJLDZCQUFhLENBQzNCLGlDQUFpQixDQUFDLDhCQUE4QixFQUN4QyxLQUFJLENBQUMscUJBQXFCLENBQUMsMEJBQTBCLENBQ2hFLENBQUM7Z0RBQ0YsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFLLENBQUMsQ0FBQztnREFDcEIsT0FBTyxNQUFNLENBQUMsT0FBSyxDQUFDLENBQUM7NkNBQ3hCO3dDQUNMLENBQUMsQ0FBQyxDQUFDO3dDQUNILE9BQU87cUNBQ1Y7aUNBQ0o7cUNBQU07b0NBQ0gsYUFBYSxDQUFDLFdBQVksQ0FBQyxLQUFLLEdBQUcsaUJBQWlCLENBQUM7b0NBQ3JELE9BQU8sT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO2lDQUNqQzs0QkFDTCxDQUFDLENBQUMsQ0FBQzs0QkFDSCxPQUFPO3lCQUNWOzZCQUFNOzRCQUNILElBQUksU0FBUyxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFO2dDQUUzQyxPQUFPLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQzs2QkFDakM7aUNBQU07Z0NBRUgsSUFBTSxhQUFhLEdBQ2YsUUFBUSxDQUFDLGdCQUFnQixFQUFFLElBQUksUUFBUSxDQUFDLHNCQUFzQixFQUFFO29DQUM1RCxDQUFDLENBQUMsbUJBQW1CLENBQUMsV0FBVztvQ0FDakMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQ0FFcEIsaUJBQWlCLENBQUMsV0FBVyxDQUFDLGFBQWEsRUFBRSxVQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsaUJBQWlCO29DQUM1RSxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUU7d0NBQ1QsSUFBSSxLQUFLLEtBQUssZUFBZSxFQUFFOzRDQUMzQixJQUFNLFlBQVksR0FBRyxDQUFDLENBQUMsS0FBSSxDQUFDLHFCQUFxQixDQUFDLDBCQUEwQjtnREFDeEUsQ0FBQyxDQUFDLEtBQUksQ0FBQyxxQkFBcUIsQ0FBQywwQkFBMEI7Z0RBQ3ZELENBQUMsQ0FBQyxtR0FBbUcsQ0FBQzs0Q0FDMUcsSUFBTSxHQUFHLEdBQUcsSUFBSSw2QkFBYSxDQUFDLGlDQUFpQixDQUFDLDhCQUE4QixFQUFFLFlBQVksQ0FBQyxDQUFDOzRDQUM5RixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDOzRDQUNsQixPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQzt5Q0FDdEI7NkNBQU0sSUFBSSxLQUFLLEtBQUssb0JBQW9CLEVBQUU7NENBQ3ZDLElBQU0sR0FBRyxHQUFHLElBQUksNkJBQWEsQ0FDekIsaUNBQWlCLENBQUMseUJBQXlCLEVBQzNDLHNDQUFzQyxDQUN6QyxDQUFDOzRDQUNGLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7NENBQ2xCLE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO3lDQUN0Qjs2Q0FBTSxJQUFJLEtBQUssS0FBSyxtQkFBbUIsRUFBRTs0Q0FDdEMsSUFBTSxHQUFHLEdBQUcsSUFBSSw2QkFBYSxDQUN6QixpQ0FBaUIsQ0FBQyxxQkFBcUIsRUFDdkMscURBQXFELENBQ3hELENBQUM7NENBQ0YsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQzs0Q0FDbEIsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7eUNBQ3RCOzZDQUFNOzRDQUNILElBQU0sR0FBRyxHQUFHLElBQUksNkJBQWEsQ0FDekIsaUNBQWlCLENBQUMsYUFBYSxFQUMvQiwyQ0FBMkMsQ0FDOUMsQ0FBQzs0Q0FDRixNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDOzRDQUNsQixNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDOzRDQUNwQixPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQzt5Q0FDdEI7cUNBQ0o7eUNBQU07d0NBQ0gsYUFBYSxDQUFDLFdBQVksQ0FBQyxLQUFLLEdBQUcsaUJBQWlCLENBQUMsS0FBSyxDQUFDO3dDQUMzRCxPQUFPLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztxQ0FDakM7Z0NBQ0wsQ0FBQyxDQUFDLENBQUM7Z0NBQ0gsT0FBTzs2QkFDVjt5QkFDSjtxQkFDSjtpQkFDSjthQUNKO1NBQ0o7SUFDTCxDQUFDO0lBS1MsaUNBQWMsR0FBeEIsVUFBeUIsYUFBMkMsRUFBRSxXQUFtQjtRQUNyRixJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVksQ0FBQyxLQUFLLEVBQUU7WUFDbkMsYUFBYSxDQUFDLFdBQVksQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDO1NBQ3pDO1FBQ3VCLGFBQWEsQ0FBQyxXQUFZLENBQUMsS0FBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxDQUFDO0lBQ25HLENBQUM7SUFJTyxxQ0FBa0IsR0FBMUI7UUFDSSxNQUFNLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDekMsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUU7WUFDeEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1NBQ3REO2FBQU07WUFDSCxLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztTQUNsRDtJQUNMLENBQUM7SUFFTyx1Q0FBb0IsR0FBNUI7UUFDSSxNQUFNLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsRUFBRTtZQUN6QixLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztTQUNsRDthQUFNO1lBQ0gsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQzlDO0lBQ0wsQ0FBQztJQUVPLDREQUF5QyxHQUFqRCxVQUFrRCxZQUFZO1FBQTlELGlCQXdFQztRQS9ERyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxFQUFFLFVBQUMsS0FBSyxFQUFFLFFBQVE7WUFDdEYsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFO2dCQUNULElBQUksS0FBSSxDQUFDLG1CQUFtQixFQUFFLEVBQUU7b0JBQzVCLE1BQU0sQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQztpQkFDM0M7cUJBQU07b0JBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFFcEIsSUFBTSxzQkFBb0IsR0FBRyxVQUFDLE1BQU0sRUFBRSxRQUFRO3dCQUMxQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO3dCQUN0QixLQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDO3dCQUN0QyxLQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsc0JBQXNCLEdBQUcsUUFBUSxDQUFDLENBQUM7b0JBQ3RFLENBQUMsQ0FBQztvQkFFRixJQUFNLGdCQUFnQixHQUFHO3dCQUNyQixJQUFJLEtBQUksQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUU7NEJBRWxCLHNCQUFvQixDQUNoQixtQkFBbUIsRUFDbkIsNkVBQTZFLENBQ2hGLENBQUM7eUJBQ0w7NkJBQU07NEJBSUgsS0FBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsRUFBRSxTQUFTLEVBQUUsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsRUFBRSxVQUFDLEtBQUssRUFBRSxRQUFRO2dDQUNyRixJQUFJLEtBQUssSUFBSSxJQUFJLEVBQUU7b0NBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQywrQkFBK0IsRUFBRSxLQUFLLENBQUMsQ0FBQztpQ0FDekQ7cUNBQU07b0NBQ0gsSUFBSSxLQUFJLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxJQUFJLEVBQUU7d0NBRTdCLHNCQUFvQixDQUNoQixtQkFBbUIsRUFDbkIsNkVBQTZFLENBQ2hGLENBQUM7cUNBQ0w7eUNBQU07d0NBRUgsc0JBQW9CLENBQ2hCLGFBQWEsRUFDYiw2RUFBNkUsQ0FDaEYsQ0FBQztxQ0FDTDtpQ0FDSjs0QkFDTCxDQUFDLENBQUMsQ0FBQzt5QkFDTjtvQkFDTCxDQUFDLENBQUM7b0JBRUYsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLEtBQUssSUFBSSxLQUFLLENBQUMsT0FBTyxLQUFLLG9CQUFvQixFQUFFO3dCQU1oRSxPQUFPLENBQUMsS0FBSyxDQUFDLDBFQUEwRSxDQUFDLENBQUM7d0JBQzFGLGdCQUFnQixFQUFFLENBQUM7cUJBQ3RCO3lCQUFNO3dCQUNILGdCQUFnQixFQUFFLENBQUM7cUJBQ3RCO2lCQUNKO2FBQ0o7aUJBQU07Z0JBQ0gsS0FBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDL0IsS0FBSSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO2FBQ3hDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU8sc0NBQW1CLEdBQTNCO1FBQ0ksTUFBTSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQ3JDLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxFQUFFO1lBQ3hCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFO2dCQUMzQixJQUFJLENBQUMseUNBQXlDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7YUFDeEY7aUJBQU07Z0JBQ0gsTUFBTSxDQUFDLElBQUksQ0FBQyxxRUFBcUUsQ0FBQyxDQUFDO2dCQUVuRixJQUFNLHNCQUFzQixHQUFHLElBQUksbURBQXdCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO2dCQUMvRixJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUM7Z0JBQzNFLHNCQUFzQixDQUFDLG1CQUFtQixFQUFFLENBQUM7YUFDaEQ7U0FDSjthQUFNO1lBQ0gsS0FBSyxDQUFDLHVDQUF1QyxDQUFDLENBQUM7U0FDbEQ7SUFDTCxDQUFDO0lBRU8sc0NBQW1CLEdBQTNCO1FBQ0ksT0FBTyxJQUFJLENBQUMsb0JBQW9CLENBQUM7SUFDckMsQ0FBQztJQUVPLGtDQUFlLEdBQXZCO1FBQ0ksSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsT0FBTyxZQUFZLGlCQUFPLEVBQUU7WUFDL0QsT0FBTyxJQUFJLENBQUM7U0FDZjthQUFNO1lBQ0gsTUFBTSxDQUFDLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO1lBQzFDLE9BQU8sS0FBSyxDQUFDO1NBQ2hCO0lBQ0wsQ0FBQztJQUVPLGdDQUFhLEdBQXJCLFVBQXNCLFdBQW1CO1FBQ3JDLE9BQU8sV0FBVyxLQUFLLFFBQVEsSUFBSSxXQUFXLEtBQUssUUFBUSxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxJQUFJLFdBQVcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztJQUNoSSxDQUFDO0lBQ0wsZUFBQztBQUFELENBNXNDQSxBQTRzQ0MsSUFBQTtBQTVzQ1ksNEJBQVE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2pEckIscUNBQW9DO0FBQ3BDLG1DQUFrQztBQUNsQyxpREFBZ0Q7QUFHaEQsc0VBQXFFO0FBQ3JFLG9HQUFtRztBQUNuRyx5RUFBMkY7QUFFM0YsNEVBQTJFO0FBQzNFLCtEQUFtRTtBQUNuRSxxRUFBb0U7QUFNcEUsSUFBTSxNQUFNLEdBQW1CLCtCQUFjLENBQUMsV0FBVyxFQUFFLENBQUM7QUFLNUQsSUFBSSxRQUF1QixDQUFDO0FBTzVCO0lBQStCLDZCQUFhO0lBb0N4QyxtQkFBWSxNQUF3QyxFQUFFLFVBQStCLEVBQUUsUUFBa0I7UUFBekcsWUFDSSxrQkFDSSxJQUFJLGVBQU0sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxpQkFBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFO1lBQ3RFLG1CQUFtQixFQUFFLFVBQVU7WUFDL0IsZ0JBQWdCLEVBQUUsRUFBRTtTQUN2QixDQUFDLEVBQ0YsTUFBTSxDQUNULFNBV0o7UUFsREQsbUJBQWEsR0FBRyxLQUFLLENBQUM7UUFLdEIsMEJBQW9CLEdBQUcsS0FBSyxDQUFDO1FBT3JCLGtCQUFZLEdBQUcsS0FBSyxDQUFDO1FBNEJ6QixRQUFRLEdBQUcsd0JBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN2QyxLQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixLQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUV6QixLQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsd0JBQXdCLEVBQUUsVUFBQyxNQUF5QjtZQUNsRSxLQUFJLENBQUMsTUFBTSxDQUFDLHNCQUFzQixHQUFHLEtBQUssQ0FBQztZQUMzQyxJQUFNLFdBQVcsR0FBRyxJQUFJLHlCQUFXLENBQUMsSUFBSSxFQUFFLEtBQUksRUFBRSxpQkFBaUIsRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3hGLEtBQUksQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQ2pELFdBQVcsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDOztJQUNQLENBQUM7SUFtQkQsZ0NBQVksR0FBWixVQUFhLE9BQWdCO1FBQTdCLGlCQW1DQztRQWxDRyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxLQUFLLE9BQU8sRUFBRTtZQUNyQyxJQUFNLG1CQUFtQixHQUFnQixJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRTtnQkFDbEUsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsc0NBQXVDO2dCQUNyRCxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNuQyxtQkFBbUIsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBQyxLQUFLO2dCQUMvQyxLQUFLLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztZQUM1QixDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO2dCQUMxQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQzdCLHVCQUF1QixFQUN2QjtvQkFDSSxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRO29CQUM5QixRQUFRLEVBQUUsYUFBYTtvQkFDdkIsUUFBUSxFQUFFLE9BQU87b0JBQ2pCLE1BQU0sRUFBRSxjQUFjO2lCQUN6QixFQUNELFVBQUMsS0FBSyxFQUFFLFFBQVE7b0JBQ1osSUFBSSxLQUFLLEVBQUU7d0JBQ1AsTUFBTSxDQUFDLEtBQUssQ0FBQyw2Q0FBNkMsRUFBRSxLQUFLLENBQUMsQ0FBQztxQkFDdEU7eUJBQU07d0JBQ0gsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUU7NEJBQzVDLElBQUksdURBQTBCLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxPQUFPLEVBQUUsY0FBYyxDQUFDO3lCQUM5RyxDQUFDLENBQUM7d0JBQ0gsS0FBSSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRTs0QkFDcEMsSUFBSSx1REFBMEIsQ0FBQyxLQUFJLEVBQUUsS0FBSSxDQUFDLE1BQU0sRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQzt5QkFDdEcsQ0FBQyxDQUFDO3dCQUNILEtBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLEtBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7cUJBQ3pEO2dCQUNMLENBQUMsQ0FDSixDQUFDO2FBQ0w7WUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUM7WUFDbEMsTUFBTSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxDQUFDO1NBQ25HO0lBQ0wsQ0FBQztJQTBCRCxnQ0FBWSxHQUFaLFVBQWdDLE9BQVUsRUFBRSxRQUF1RDtRQUFuRyxpQkFnR0M7UUEvRkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFPLE9BQU8sRUFBRSxNQUFNOzs7Ozs7NkJBQ2pDLENBQUEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEtBQUssT0FBTyxDQUFBLEVBQW5DLGNBQW1DO3dCQUM3Qix3QkFBbUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUU7NEJBQ2xFLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLHNDQUF1Qzs0QkFDckQsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7d0JBQy9CLDJCQUF5QixLQUFLLENBQUM7d0JBQ25DLHFCQUFtQixDQUFDLGNBQWMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFDLEtBQUs7NEJBQy9DLEtBQUssQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDOzRCQUN4QixJQUFJLENBQUMsT0FBTyxJQUFJLFFBQVEsS0FBSyxJQUFJLEVBQUU7Z0NBQy9CLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQzs2QkFDaEI7aUNBQU0sSUFBSSxPQUFPLElBQUksS0FBSyxDQUFDLFVBQVUsS0FBSyxPQUFPLEVBQUU7Z0NBRWhELHdCQUFzQixHQUFHLElBQUksQ0FBQzs2QkFDakM7d0JBQ0wsQ0FBQyxDQUFDLENBQUM7NkJBR0MsQ0FBQSxDQUFDLE9BQU8sSUFBSSxRQUFRLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFBLEVBQWxHLGNBQWtHO3dCQUNsRyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQzt3QkFDOUMsV0FBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBQTs7d0JBQXZDLFNBQXVDLENBQUM7Ozs2QkFHeEMsd0JBQXNCLEVBQXRCLGNBQXNCO3dCQUNoQixhQUFhLEdBQUcscUJBQW1CLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQzlELHFCQUFtQixDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQzt3QkFFekMsaUJBQWlCLEdBQUcsVUFBTyxFQUFvQjs7Ozs7d0NBQ2pELHFCQUFtQixDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQzs2Q0FDN0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsRUFBbEMsY0FBa0M7d0NBQ2xDLFdBQU0sSUFBSSxDQUFDLDBCQUEwQixDQUFDLEVBQUUsQ0FBQyxFQUFBOzt3Q0FBekMsU0FBeUMsQ0FBQzs7O3dDQUU5QyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRTs0Q0FDNUIsVUFBVSxDQUFDOzs7Ozs0REFDSCxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFhLENBQUMsT0FBTyxDQUFDOzREQUMxQyxjQUFjLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFhLENBQUMsY0FBYyxDQUFDOzREQUNoRSxJQUFJLENBQUMsQ0FBQyxjQUFjLElBQUksY0FBYyxDQUFDLE1BQU0sS0FBSyxRQUFRLEVBQUU7Z0VBQ3hELE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDOzZEQUMvRDs0REFDRCxXQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBYSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsRUFBQTs7NERBQXRFLFNBQXNFLENBQUM7NERBQ3ZFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUM7Ozs7aURBQ25DLEVBQUUsQ0FBQyxDQUFDLENBQUM7eUNBQ1Q7Ozs7NkJBQ0osQ0FBQzs2QkFFRSxDQUFBLENBQUMsQ0FBQyxRQUFRLElBQUksUUFBUSxZQUFZLGdCQUFnQixDQUFBLEVBQWxELGNBQWtEO3dCQUNsRCxXQUFNLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxFQUFBOzt3QkFBakMsU0FBaUMsQ0FBQzs7Ozt3QkFHVixXQUFNLFNBQVMsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDO2dDQUMxRCxLQUFLLEVBQUUsS0FBSztnQ0FDWixLQUFLLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyx5QkFBeUI7NkJBQy9DLENBQUMsRUFBQTs7d0JBSEksV0FBVyxHQUFHLFNBR2xCO3dCQUNGLFdBQU0saUJBQWlCLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUE7O3dCQUF4RCxTQUF3RCxDQUFDOzs7O3dCQUV6RCxXQUFPLE1BQU0sQ0FBQyxPQUFLLENBQUMsRUFBQzs7d0JBS2pDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFOzRCQUMxQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQzdCLHVCQUF1QixFQUN2QjtnQ0FDSSxRQUFRLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRO2dDQUM5QixRQUFRLEVBQUUsYUFBYTtnQ0FDdkIsUUFBUSxFQUFFLE9BQU87Z0NBQ2pCLE1BQU0sRUFBRSxjQUFjOzZCQUN6QixFQUNELFVBQUMsS0FBSyxFQUFFLFFBQVE7Z0NBQ1osSUFBSSxLQUFLLEVBQUU7b0NBQ1AsTUFBTSxDQUFDLEtBQUssQ0FBQyw2Q0FBNkMsRUFBRSxLQUFLLENBQUMsQ0FBQztpQ0FDdEU7cUNBQU07b0NBQ0gsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUU7d0NBQzVDLElBQUksdURBQTBCLENBQzFCLEtBQUksQ0FBQyxPQUFPLEVBQ1osS0FBSSxDQUFDLE1BQU0sRUFDWCxhQUFhLEVBQ2IsT0FBTyxFQUNQLENBQUMsT0FBTyxFQUNSLGNBQWMsQ0FDakI7cUNBQ0osQ0FBQyxDQUFDO29DQUNILEtBQUksQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUU7d0NBQ3BDLElBQUksdURBQTBCLENBQUMsS0FBSSxFQUFFLEtBQUksQ0FBQyxNQUFNLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxDQUFDLE9BQU8sRUFBRSxjQUFjLENBQUM7cUNBQ3RHLENBQUMsQ0FBQztvQ0FDSCxLQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO2lDQUN6RDs0QkFDTCxDQUFDLENBQ0osQ0FBQzt5QkFDTDt3QkFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUM7d0JBQ2xDLE1BQU0sQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLEdBQUcsbUJBQW1CLENBQUMsQ0FBQzt3QkFDaEcsV0FBTyxPQUFPLEVBQUUsRUFBQzs7OzthQUV4QixDQUFDLENBQUM7SUFDUCxDQUFDO0lBS0QscUNBQWlCLEdBQWpCLFVBQWtCLEtBQWU7UUFDN0IsS0FBSyxHQUFHLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQzNDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxLQUFLLENBQUM7UUFDbEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBS0Qsc0JBQUUsR0FBRixVQUFzQyxJQUFPLEVBQUUsT0FBOEM7UUFBN0YsaUJBdUJDO1FBdEJHLGlCQUFNLEVBQUUsWUFBTSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFN0IsSUFBSSxJQUFJLEtBQUssZUFBZSxFQUFFO1lBQzFCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsRUFBRTtnQkFDckQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxJQUFJLHlCQUFXLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDckc7aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLDZCQUE2QixFQUFFO29CQUM3QyxLQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxDQUFDLElBQUkseUJBQVcsQ0FBQyxLQUFLLEVBQUUsS0FBSSxFQUFFLGVBQWUsRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdEcsQ0FBQyxDQUFDLENBQUM7YUFDTjtTQUNKO1FBQ0QsSUFBSSxJQUFJLEtBQUssZUFBZSxFQUFFO1lBQzFCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtnQkFDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUM7YUFDdkM7U0FDSjtRQUNELElBQUksSUFBSSxLQUFLLGNBQWMsRUFBRTtZQUN6QixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2FBQ3RDO1NBQ0o7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBS0Qsd0JBQUksR0FBSixVQUF3QyxJQUFPLEVBQUUsT0FBOEM7UUFBL0YsaUJBdUJDO1FBdEJHLGlCQUFNLElBQUksWUFBTSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFL0IsSUFBSSxJQUFJLEtBQUssZUFBZSxFQUFFO1lBQzFCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsRUFBRTtnQkFDckQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxJQUFJLHlCQUFXLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDckc7aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLDZCQUE2QixFQUFFO29CQUMvQyxLQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxDQUFDLElBQUkseUJBQVcsQ0FBQyxLQUFLLEVBQUUsS0FBSSxFQUFFLGVBQWUsRUFBRSxLQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdEcsQ0FBQyxDQUFDLENBQUM7YUFDTjtTQUNKO1FBQ0QsSUFBSSxJQUFJLEtBQUssZUFBZSxFQUFFO1lBQzFCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtnQkFDcEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUM7YUFDdkM7U0FDSjtRQUNELElBQUksSUFBSSxLQUFLLGNBQWMsRUFBRTtZQUN6QixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7Z0JBQ25CLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2FBQ3RDO1NBQ0o7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBS0QsdUJBQUcsR0FBSCxVQUF1QyxJQUFPLEVBQUUsT0FBK0M7UUFDM0YsaUJBQU0sR0FBRyxZQUFNLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM5QixPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBa0JLLGdDQUFZLEdBQWxCLFVBQW1CLEtBQXVCOzs7Z0JBQ3RDLFdBQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUM7OztLQUM1QztJQU9ELDhCQUFVLEdBQVY7UUFBQSxpQkE0UkM7UUEzUkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFPLE9BQU8sRUFBRSxNQUFNOzs7Ozs7O3dCQUNqQyxXQUFXLEdBQTJCLEVBQUUsQ0FBQzt3QkFDekMsY0FBYyxHQUEyQixFQUFFLENBQUM7d0JBQzFDLGtCQUFrQixHQUFHLElBQUksQ0FBQzt3QkFHMUIsYUFBYSxHQUFHLFVBQUMsYUFBNEI7NEJBQy9DLEtBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDOzRCQUN6QixLQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQzs0QkFDM0IsTUFBTSxDQUFDLEtBQUssQ0FBQywyQ0FBb0MsYUFBYSxDQUFDLElBQUksZUFBSyxhQUFhLENBQUMsT0FBTyxDQUFFLENBQUMsQ0FBQzs0QkFDakcsT0FBTyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7d0JBQ2pDLENBQUMsQ0FBQzt3QkFFSSxlQUFlLEdBQUcsVUFBQyxXQUF3Qjs7NEJBQzdDLEtBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDOzRCQUMxQixLQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQzs0QkFFMUIsSUFBSSxPQUFPLGdCQUFnQixLQUFLLFdBQVcsSUFBSSxLQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsRUFBRTtnQ0FDcEcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQ0FDekQsV0FBVyxDQUFDLFFBQVEsQ0FBbUIsS0FBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQzs2QkFDdkU7NEJBRUQsSUFBSSxPQUFPLGdCQUFnQixLQUFLLFdBQVcsSUFBSSxLQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsWUFBWSxnQkFBZ0IsRUFBRTtnQ0FDcEcsV0FBVyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQ0FDekQsV0FBVyxDQUFDLFFBQVEsQ0FBbUIsS0FBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQzs2QkFDdkU7NEJBR0QsSUFBSSxDQUFDLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO2dDQUNuQyxJQUFNLE9BQU8sR0FDVCxLQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsS0FBSyxTQUFTLElBQUksS0FBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEtBQUssSUFBSTtvQ0FDckUsQ0FBQyxDQUFDLEtBQUksQ0FBQyxNQUFNLENBQUMsV0FBVztvQ0FDekIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQztnQ0FDNUUsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7NkJBQ3JEOzRCQUNELElBQUksQ0FBQyxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQ0FDbkMsSUFBTSxPQUFPLEdBQ1QsS0FBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEtBQUssU0FBUyxJQUFJLEtBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxLQUFLLElBQUk7b0NBQ3JFLENBQUMsQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLFdBQVc7b0NBQ3pCLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQUM7Z0NBQzVFLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDOzZCQUNyRDs0QkFHRCxLQUFvQixVQUE0QixFQUE1QixLQUFBLFdBQVcsQ0FBQyxjQUFjLEVBQUUsRUFBNUIsY0FBNEIsRUFBNUIsSUFBNEIsRUFBRTtnQ0FBN0MsSUFBTSxLQUFLLFNBQUE7Z0NBQ1osSUFBSSxDQUFDLENBQUEsTUFBQSxLQUFLLENBQUMsV0FBVywwQ0FBRSxNQUFNLENBQUEsRUFBRTtvQ0FHNUIsS0FBSyxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7b0NBQ3ZCLE1BQU0sQ0FBQyxJQUFJLENBQUMseUNBQWtDLEtBQUssQ0FBQyxXQUFXLE1BQUcsQ0FBQyxDQUFDO2lDQUN2RTs2QkFDSjs0QkFDRCxLQUFvQixVQUE0QixFQUE1QixLQUFBLFdBQVcsQ0FBQyxjQUFjLEVBQUUsRUFBNUIsY0FBNEIsRUFBNUIsSUFBNEIsRUFBRTtnQ0FBN0MsSUFBTSxLQUFLLFNBQUE7Z0NBQ1osSUFBSSxDQUFDLENBQUEsTUFBQSxLQUFLLENBQUMsV0FBVywwQ0FBRSxNQUFNLENBQUEsRUFBRTtvQ0FHNUIsUUFBUSxLQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRTt3Q0FDN0IsS0FBSyx5QkFBVyxDQUFDLE1BQU07NENBQ25CLEtBQUssQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDOzRDQUM3QixNQUFNO3dDQUNWLEtBQUsseUJBQVcsQ0FBQyxNQUFNOzRDQUNuQixNQUFNLENBQUMsSUFBSSxDQUFDLDREQUE0RCxDQUFDLENBQUM7NENBQzFFLEtBQUssQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDOzRDQUM3QixNQUFNO3dDQUNWLEtBQUsseUJBQVcsQ0FBQyxNQUFNLENBQUM7d0NBQ3hCLEtBQUsseUJBQVcsQ0FBQyxLQUFLLENBQUM7d0NBQ3ZCOzRDQUNJLEtBQUssQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDOzRDQUM3QixNQUFNO3FDQUNiO29DQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMseUNBQWtDLEtBQUssQ0FBQyxXQUFXLE1BQUcsQ0FBQyxDQUFDO2lDQUN2RTs2QkFDSjs0QkFFRCxLQUFJLENBQUMsd0JBQXdCLENBQUMsV0FBVyxDQUFDLENBQUM7NEJBRTNDLElBQUksQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxFQUFFO2dDQUdoQyxLQUFJLENBQUMsTUFBTSxDQUFDLHlCQUF5QixFQUFFLENBQUM7NkJBQzNDOzRCQUNELE9BQU8sS0FBSSxDQUFDLGlCQUFpQixDQUFDOzRCQUU5QixJQUFJLEtBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLEVBQUU7Z0NBRTNCLEtBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFDLFVBQVU7b0NBQ3RDLEtBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxHQUFHO3dDQUMxQixLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUs7d0NBQ3ZCLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTTtxQ0FDNUIsQ0FBQztvQ0FFRixJQUFJLEtBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLEVBQUU7d0NBRTVCLEtBQUksQ0FBQyx5QkFBeUIsR0FBRyxXQUFXLENBQUM7NENBQ3pDLElBQU0sUUFBUSxHQUF1QixXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7NENBQ25GLElBQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7NENBQ2hDLElBQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7NENBQ2xDLElBQU0sWUFBWSxHQUFHLFFBQVEsSUFBSSxJQUFJLElBQUksUUFBUSxLQUFLLEtBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQzs0Q0FDeEYsSUFBTSxhQUFhLEdBQUcsU0FBUyxJQUFJLElBQUksSUFBSSxTQUFTLEtBQUssS0FBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDOzRDQUM1RixJQUFJLEtBQUksQ0FBQyxNQUFNLENBQUMsc0JBQXNCLElBQUksQ0FBQyxZQUFZLElBQUksYUFBYSxDQUFDLEVBQUU7Z0RBQ3ZFLEtBQUksQ0FBQyxRQUFRLENBQUMsK0JBQStCLENBQ3pDLEtBQUksRUFDSixlQUFlLEVBQ2YsS0FBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUNqQyxLQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxNQUFNLEVBQ2xDLFFBQVEsSUFBSSxDQUFDLEVBQ2IsU0FBUyxJQUFJLENBQUMsQ0FDakIsQ0FBQzs2Q0FDTDt3Q0FDTCxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7cUNBQ1g7b0NBRUQsS0FBSSxDQUFDLE1BQU0sQ0FBQywyQkFBMkIsR0FBRyxJQUFJLENBQUM7b0NBQy9DLEtBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyx5QkFBeUIsRUFBRSxFQUFFLENBQUMsQ0FBQztnQ0FDNUQsQ0FBQyxDQUFDLENBQUM7NkJBQ047aUNBQU07Z0NBRUgsS0FBSSxDQUFDLE1BQU0sQ0FBQywyQkFBMkIsR0FBRyxJQUFJLENBQUM7Z0NBQy9DLEtBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyx5QkFBeUIsRUFBRSxFQUFFLENBQUMsQ0FBQzs2QkFDM0Q7NEJBRUQsT0FBTyxPQUFPLEVBQUUsQ0FBQzt3QkFDckIsQ0FBQyxDQUFDO3dCQUVJLGVBQWUsR0FBRyxVQUFPLFdBQXdCLEVBQUUsc0JBQXNCOzs7Ozt3Q0FDM0UsSUFBSSxDQUFDLDBCQUEwQixDQUFDLFNBQVMsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDOzZDQUMzRCxDQUFBLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQSxFQUF2RCxjQUF1RDt3Q0FFdkQsY0FBYyxDQUFDLEtBQUssR0FBRyxzQkFBc0IsQ0FBQzt3Q0FDOUMsY0FBYyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7d0NBQzdCLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7d0NBQ3ZCLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDOzs7O3dDQUd0QixXQUFNLFNBQVMsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxFQUFBOzt3Q0FBM0UsZUFBZSxHQUFHLFNBQXlEO3dDQUNqRixJQUFJLENBQUMsMEJBQTBCLENBQUMsU0FBUyxFQUFFLGtCQUFrQixDQUFDLENBQUM7d0NBQy9ELFdBQVcsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7d0NBQzFELGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQzs7Ozt3Q0FFN0IsSUFBSSxDQUFDLDBCQUEwQixDQUFDLFNBQVMsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO3dDQUMvRCxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSzs0Q0FDdkMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO3dDQUNqQixDQUFDLENBQUMsQ0FBQzt3Q0FDSCxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSzs0Q0FDdkMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO3dDQUNqQixDQUFDLENBQUMsQ0FBQzt3Q0FDSCxhQUFhLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBQyxPQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQzt3Q0FDMUUsV0FBTzs7O3dDQUdYLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQzs7Ozs7NkJBRXBDLENBQUM7d0JBRUksYUFBYSxHQUFHLFVBQU8sS0FBSzs7Ozs7d0NBQzlCLE1BQU0sQ0FBQyxLQUFLLENBQUMseUJBQWtCLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBRSxDQUFDLENBQUM7d0NBQ25ELElBQUksQ0FBQywwQkFBMEIsQ0FBQyxTQUFTLEVBQUUsa0JBQWtCLENBQUMsQ0FBQzt3Q0FDL0QsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRTs0Q0FFeEIsS0FBSyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQzt5Q0FDdkM7d0NBRU8sS0FBQSxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFBOztpREFDdkIsZUFBZSxDQUFDLENBQWhCLGNBQWU7aURBbUJmLGlCQUFpQixDQUFDLENBQWxCLGNBQWlCO2lEQU9qQixzQkFBc0IsQ0FBQyxDQUF2QixjQUFzQjtpREFxQ3RCLFlBQVksQ0FBQyxDQUFiLGVBQVk7aURBQ1osa0JBQWtCLENBQUMsQ0FBbkIsZUFBa0I7Ozs7O3dDQTlESyxXQUFNLFNBQVMsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDO2dEQUMxRCxLQUFLLEVBQUUsS0FBSztnREFDWixLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUs7NkNBQzNCLENBQUMsRUFBQTs7d0NBSEksV0FBVyxHQUFHLFNBR2xCO3dDQUNGLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBQyxLQUFLOzRDQUN2QyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7d0NBQ2pCLENBQUMsQ0FBQyxDQUFDO3dDQUNILFNBQVMsR0FBRyxpQ0FBaUIsQ0FBQyw0QkFBNEIsQ0FBQzt3Q0FDM0QsWUFBWSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQzt3Q0FDaEMsYUFBYSxDQUFDLElBQUksNkJBQWEsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQzs7Ozt3Q0FFMUQsU0FBUyxHQUFHLGlDQUFpQixDQUFDLDRCQUE0QixDQUFDO3dDQUMzRCxZQUFZLEdBQUcsT0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO3dDQUNoQyxhQUFhLENBQUMsSUFBSSw2QkFBYSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDOzs0Q0FHOUQsZUFBTTs7d0NBRU4sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFOzRDQUNsQyxDQUFDLENBQUMsaUNBQWlCLENBQUMscUJBQXFCOzRDQUN6QyxDQUFDLENBQUMsaUNBQWlCLENBQUMsb0JBQW9CLENBQUM7d0NBQzdDLFlBQVksR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7d0NBQ2hDLGFBQWEsQ0FBQyxJQUFJLDZCQUFhLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7d0NBQzFELGVBQU07Ozt3Q0FHa0IsV0FBTSxTQUFTLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQztnREFDMUQsS0FBSyxFQUFFLEtBQUs7Z0RBQ1osS0FBSyxFQUFFLFdBQVcsQ0FBQyxLQUFLOzZDQUMzQixDQUFDLEVBQUE7O3dDQUhJLFdBQVcsR0FBRyxTQUdsQjt3Q0FDRixXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSzs0Q0FDdkMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO3dDQUNqQixDQUFDLENBQUMsQ0FBQzt3Q0FDSCxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLEtBQUssVUFBVSxFQUFFOzRDQUMvQyxTQUFTLEdBQUcsaUNBQWlCLENBQUMsNEJBQTRCLENBQUM7NENBQzNELFlBQVk7Z0RBQ1Isb0NBQW9DO29EQUNtQixXQUFXLENBQUMsS0FBTSxDQUFDLFFBQVcsQ0FBQyxLQUFLO29EQUMzRixhQUFhLENBQUM7eUNBQ3JCOzZDQUFNOzRDQUNILFNBQVMsR0FBRyxpQ0FBaUIsQ0FBQywwQkFBMEIsQ0FBQzs0Q0FDekQsWUFBWTtnREFDUixzRUFBc0UsR0FBRyxLQUFLLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQzt5Q0FDdkc7d0NBQ0QsYUFBYSxDQUFDLElBQUksNkJBQWEsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUMsQ0FBQzs7Ozt3Q0FFMUQsSUFBSSxPQUFLLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxLQUFLLFVBQVUsRUFBRTs0Q0FDL0MsU0FBUyxHQUFHLGlDQUFpQixDQUFDLDRCQUE0QixDQUFDOzRDQUMzRCxZQUFZO2dEQUNSLG9DQUFvQztvREFDbUIsV0FBVyxDQUFDLEtBQU0sQ0FBQyxRQUFXLENBQUMsS0FBSztvREFDM0YsYUFBYSxDQUFDO3lDQUNyQjs2Q0FBTTs0Q0FDSCxTQUFTLEdBQUcsaUNBQWlCLENBQUMsMEJBQTBCLENBQUM7NENBQ3pELFlBQVk7Z0RBQ1Isc0VBQXNFLEdBQUcsT0FBSyxDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUM7eUNBQ3ZHO3dDQUNELGFBQWEsQ0FBQyxJQUFJLDZCQUFhLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7OzRDQUc5RCxlQUFNOzt3Q0FHTixTQUFTLEdBQUcsaUNBQWlCLENBQUMscUJBQXFCLENBQUM7d0NBQ3BELFlBQVksR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7d0NBQ2hDLGFBQWEsQ0FBQyxJQUFJLDZCQUFhLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7d0NBQzFELGVBQU07O3dDQUVOLFNBQVMsR0FBRyxpQ0FBaUIsQ0FBQyxhQUFhLENBQUM7d0NBQzVDLFlBQVksR0FBRyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7d0NBQ2hDLGFBQWEsQ0FBQyxJQUFJLDZCQUFhLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7d0NBQzFELGVBQU07Ozs7NkJBRWpCLENBQUM7Ozs7d0JBR3dCLFdBQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUE7O3dCQUE3RSxhQUFhLEdBQUcsU0FBNkQ7NkJBRS9FLENBQUEsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQzs0QkFDMUQsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLFVBQVUsSUFBSSxDQUFBLE1BQUEsYUFBYSxDQUFDLFdBQVcsMENBQUUsS0FBSyxNQUFLLEtBQUssQ0FBQzs0QkFDMUUsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLFVBQVUsSUFBSSxDQUFBLE1BQUEsYUFBYSxDQUFDLFdBQVcsMENBQUUsS0FBSyxNQUFLLEtBQUssQ0FBQyxDQUFBLEVBRjFFLGNBRTBFO3dCQUcxRSxlQUFlLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBQyxhQUFhLEVBQUUsSUFBSSxXQUFXLEVBQUUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzs7O3dCQUV2RyxXQUFXLEdBQUcsYUFBYSxDQUFDLFdBQVcsQ0FBQzt3QkFFbEMscUJBQXFCLEdBQUc7NEJBQzFCLGdCQUFnQixFQUFFLFdBQVc7NEJBQzdCLG1CQUFtQixFQUFFLElBQUksQ0FBQyxVQUFVO3lCQUN2QyxDQUFDO3dCQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsd0JBQXdCLENBQUMscUJBQXFCLENBQUMsQ0FBQzt3QkFFdEQsc0JBQXNCLEdBQUcsV0FBVyxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQzt3QkFDMUYsY0FBYyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLHNCQUFzQixDQUFDO3dCQUNuRixjQUFjLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUM7d0JBQ3pDLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7d0JBQ3ZCLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDOzs7OzZCQUcxQyxDQUFBLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLElBQUksU0FBUyxDQUFDLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFBLEVBQWpHLGNBQWlHO3dCQUM3RSxXQUFNLFNBQVMsQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFBOzt3QkFBOUUsV0FBVyxHQUFHLFNBQWdFO3dCQUNwRixJQUFJLENBQUMsUUFBUSxDQUFDLHdCQUF3QixDQUFDLGFBQWEsRUFBRSxXQUFXLENBQUMsQ0FBQzt3QkFDbkUsV0FBTSxlQUFlLENBQUMsV0FBVyxFQUFFLHNCQUFzQixDQUFDLEVBQUE7O3dCQUExRCxTQUEwRCxDQUFDOzs7d0JBRTNELElBQUksQ0FBQyxNQUFNLENBQUMseUJBQXlCLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQzt3QkFDekMsV0FBTSxTQUFTLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxjQUFjLENBQUMsRUFBQTs7d0JBQXZFLFdBQVcsR0FBRyxTQUF5RDt3QkFDN0UsSUFBSSxDQUFDLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBQyxhQUFhLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzt3QkFDaEYsV0FBTSxlQUFlLENBQUMsV0FBVyxFQUFFLHNCQUFzQixDQUFDLEVBQUE7O3dCQUExRCxTQUEwRCxDQUFDOzs7Ozt3QkFHL0QsV0FBTSxhQUFhLENBQUMsT0FBSyxDQUFDLEVBQUE7O3dCQUExQixTQUEwQixDQUFDOzs7Ozt3QkFJbkMsYUFBYSxDQUFDLE9BQUssQ0FBQyxDQUFDOzs7OzthQUU1QixDQUFDLENBQUM7SUFDUCxDQUFDO0lBS0ssbUNBQWUsR0FBckIsVUFBc0IsS0FBdUIsRUFBRSxxQkFBOEI7Ozs7Ozt3QkFFbkUseUJBQXlCLEdBQVksS0FBSyxDQUFDLE9BQU8sQ0FBQzt3QkFDekQsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRTs0QkFDeEIsS0FBSyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQzt5QkFDM0M7NkJBQU0sSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRTs0QkFDL0IsS0FBSyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQzt5QkFDM0M7Ozs7NkJBRU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsRUFBbEMsY0FBa0M7d0JBR2xDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLEVBQUUscUJBQXFCLENBQUMsQ0FBQzt3QkFDdEQsV0FBTSxJQUFJLENBQUMsMEJBQTBCLENBQUMsS0FBSyxDQUFDLEVBQUE7NEJBQW5ELFdBQU8sU0FBNEMsRUFBQzs0QkFHcEQsV0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsS0FBSyxFQUFFLHFCQUFxQixDQUFDLEVBQUM7Ozs7d0JBR3hFLEtBQUssQ0FBQyxPQUFPLEdBQUcseUJBQXlCLENBQUM7d0JBQzFDLE1BQU0sT0FBSyxDQUFDOzs7OztLQUVuQjtJQVNELHNDQUFrQixHQUFsQjtRQUFBLGlCQXNEQztRQXJERyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFFL0IsSUFBTSxvQkFBb0IsR0FBWSxRQUFRLENBQUMsVUFBVSxFQUFFLElBQUksUUFBUSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBRTFGLElBQUksc0JBQXNCLENBQUM7WUFDM0IsSUFBTSxpQkFBaUIsR0FBRztnQkFDdEIsSUFBSSxLQUFhLENBQUM7Z0JBQ2xCLElBQUksTUFBYyxDQUFDO2dCQUNuQixJQUFJLE9BQU8sS0FBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEtBQUssVUFBVSxFQUFFO29CQUNwRixJQUFNLFFBQVEsR0FBRyxLQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO29CQUNoRixLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssSUFBSSxLQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQztvQkFDekQsTUFBTSxHQUFHLFFBQVEsQ0FBQyxNQUFNLElBQUksS0FBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUM7aUJBQy9EO3FCQUFNO29CQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMsdURBQXVELEdBQUcsUUFBUSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7b0JBQ2pHLEtBQUssR0FBRyxLQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQztvQkFDdkMsTUFBTSxHQUFHLEtBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDO2lCQUM1QztnQkFFRCxJQUFJLHNCQUFzQixJQUFJLElBQUksRUFBRTtvQkFDaEMsS0FBSSxDQUFDLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxnQkFBZ0IsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO2lCQUNyRjtnQkFDRCxJQUFJLG9CQUFvQixFQUFFO29CQUN0QixRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7aUJBQ2xEO2dCQUVELE9BQU8sT0FBTyxDQUFDLEVBQUUsS0FBSyxPQUFBLEVBQUUsTUFBTSxRQUFBLEVBQUUsQ0FBQyxDQUFDO1lBQ3RDLENBQUMsQ0FBQztZQUVGLElBQUksS0FBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLElBQUksQ0FBQyxFQUFFO2dCQUdyQyxpQkFBaUIsRUFBRSxDQUFDO2FBQ3ZCO2lCQUFNO2dCQUdILHNCQUFzQixHQUFHO29CQUNyQixJQUFJLENBQUMsS0FBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUU7d0JBQ2pDLElBQUksVUFBUSxHQUFHLFdBQVcsQ0FBQzs0QkFDdkIsSUFBSSxDQUFDLENBQUMsS0FBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUU7Z0NBQ2xDLGFBQWEsQ0FBQyxVQUFRLENBQUMsQ0FBQztnQ0FDeEIsaUJBQWlCLEVBQUUsQ0FBQzs2QkFDdkI7d0JBQ0wsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO3FCQUNWO3lCQUFNO3dCQUNILGlCQUFpQixFQUFFLENBQUM7cUJBQ3ZCO2dCQUNMLENBQUMsQ0FBQztnQkFDRixLQUFJLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLGdCQUFnQixFQUFFLHNCQUFzQixDQUFDLENBQUM7Z0JBQy9FLElBQUksb0JBQW9CLEVBQUU7b0JBQ3RCLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztpQkFDbEQ7YUFDSjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELGlEQUE2QixHQUE3QjtRQUNJLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsZUFBZSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUNsRCxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztTQUNuQztJQUNMLENBQUM7SUFLRCw0Q0FBd0IsR0FBeEIsVUFBeUIsV0FBd0I7UUFDN0MsSUFBSSxDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7UUFDM0MsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUNwQyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDckMsSUFDSSxRQUFRLENBQUMsZUFBZSxFQUFFO1lBQzFCLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRTtnQkFDdEIsQ0FBQyxRQUFRLENBQUMscUJBQXFCLEVBQUU7b0JBQzdCLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRTtvQkFDOUIsUUFBUSxDQUFDLG9CQUFvQixFQUFFO29CQUMvQixRQUFRLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxDQUFDLEVBQzdDO1lBQ0UsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1NBQzFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQzFCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxFQUFtQixJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1NBQzlHO1FBQ0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUNqRSxDQUFDO0lBS0QsNkNBQXlCLEdBQXpCLFVBQTBCLEtBQXVCLEVBQUUscUJBQThCO1FBQzdFLElBQU0sV0FBVyxHQUFnQixJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRTtZQUMxRCxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxzQ0FBdUM7WUFDckQsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDbkMsSUFBSSxZQUE4QixDQUFDO1FBQ25DLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7WUFDeEIsWUFBWSxHQUFHLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMvQyxJQUFJLHFCQUFxQixFQUFFO2dCQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLHlCQUF5QixHQUFHLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUNsRTtTQUNKO2FBQU07WUFDSCxZQUFZLEdBQUcsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ2xEO1FBQ0QsWUFBWSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDN0IsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3BCLFdBQVcsQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdEMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixJQUFNLFNBQVMsR0FBRztZQUNkLFFBQVEsRUFBRSxDQUFBLFlBQVksYUFBWixZQUFZLHVCQUFaLFlBQVksQ0FBRSxLQUFLLEtBQUksRUFBRTtZQUNuQyxRQUFRLEVBQUUsQ0FBQSxLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsS0FBSyxLQUFJLEVBQUU7U0FDL0IsQ0FBQztRQUNGLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPLElBQUkscUJBQXFCLEVBQUU7WUFDakQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQ0FBZ0MsQ0FBQyxJQUFJLEVBQUUsZUFBZSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUM5RSxJQUFJLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFDaEcsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLHNCQUFzQixFQUFFO2dCQUNwQyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQ3JFO1NBQ0o7YUFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssT0FBTyxJQUFJLHFCQUFxQixFQUFFO1lBQ3hELElBQUksQ0FBQyxRQUFRLENBQUMscUJBQXFCLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsQ0FBQztTQUNuRztRQUNELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7WUFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM1QyxJQUFJLENBQUMsTUFBTSxDQUFDLCtCQUErQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ25ELElBQUksQ0FBQyxNQUFNLENBQUMsNEJBQTRCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztTQUNoQztJQUNMLENBQUM7SUFJTyw0Q0FBd0IsR0FBaEMsVUFBaUMsUUFBZ0I7UUFBakQsaUJBSUM7UUFIRyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsVUFBVSxDQUFDO1lBQ3RDLEtBQUksQ0FBQyxTQUFTLENBQUMsb0JBQW9CLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDN0MsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2pCLENBQUM7SUFFTyw4Q0FBMEIsR0FBbEMsVUFBbUMsU0FBaUIsRUFBRSxRQUFnQjtRQUNsRSxZQUFZLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7UUFDM0MsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxHQUFHLFFBQVEsRUFBRTtZQUVuQyxJQUFJLENBQUMsU0FBUyxDQUFDLG9CQUFvQixFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQzVDO0lBQ0wsQ0FBQztJQUVhLDhDQUEwQixHQUF4QyxVQUF5QyxLQUF1Qjs7Ozs7O3dCQUN0RCxPQUFPLEdBQW1CLElBQUksQ0FBQyxNQUFNLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxVQUFVLEVBQUUsQ0FBQzt3QkFFaEYsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRTs0QkFDeEIsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBQyxDQUFDLElBQUssT0FBQSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQXJDLENBQXFDLENBQUMsQ0FBQzs0QkFDcEUsSUFBSSxDQUFDLE1BQU0sRUFBRTtnQ0FDVCxNQUFNLElBQUksS0FBSyxDQUFDLHlGQUF5RixDQUFDLENBQUM7NkJBQzlHO3lCQUNKOzZCQUFNLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7NEJBQy9CLE1BQU0sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQUMsQ0FBQyxJQUFLLE9BQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFyQyxDQUFxQyxDQUFDLENBQUM7NEJBQ3BFLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0NBQ1QsTUFBTSxJQUFJLEtBQUssQ0FBQyx5RkFBeUYsQ0FBQyxDQUFDOzZCQUM5Rzt5QkFDSjs2QkFBTTs0QkFDSCxNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQzt5QkFDdkQ7d0JBQ0QsV0FBTyxNQUF1QixDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBQTs7d0JBQWxELFNBQWtELENBQUM7Ozs7O0tBQ3REO0lBQ0wsZ0JBQUM7QUFBRCxDQWh6QkEsQUFnekJDLENBaHpCOEIsNkJBQWEsR0FnekIzQztBQWh6QlksOEJBQVM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzlCdEIsMkNBQTBDO0FBQzFDLG1DQUFrQztBQUtsQywyQ0FBMEM7QUFFMUMscURBQW9EO0FBT3BELDhFQUE2RTtBQUM3RSxzRUFBcUU7QUFDckUsNEVBQTJFO0FBQzNFLGdHQUErRjtBQUMvRixzRUFBcUU7QUFDckUsa0ZBQWlGO0FBQ2pGLHNFQUFxRTtBQUNyRSxvR0FBbUc7QUFDbkcsNEdBQTJHO0FBQzNHLDhHQUE2RztBQUM3Ryx5RUFBMkY7QUFDM0YsNkVBQTRFO0FBQzVFLDRFQUEyRTtBQUMzRSwrREFBbUU7QUFLbkUsb0RBQXVEO0FBSXZELG9EQUF1RDtBQUN2RCw0RUFBK0Y7QUFLL0YsSUFBTSxNQUFNLEdBQW1CLCtCQUFjLENBQUMsV0FBVyxFQUFFLENBQUM7QUFLNUQsSUFBSSxRQUF1QixDQUFDO0FBUzVCO0lBQTZCLDJCQUFlO0lBd0R4QyxpQkFBWSxRQUFrQjtRQUE5QixZQUNJLGlCQUFPLFNBR1Y7UUE5Q0Qsb0JBQWMsR0FBb0IsRUFBRSxDQUFDO1FBWXJDLDBCQUFvQixHQUF5QixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBS3ZELHVCQUFpQixHQUE0QixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBMkJuRCxRQUFRLEdBQUcsd0JBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN2QyxLQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQzs7SUFDN0IsQ0FBQztJQWdDRCx5QkFBTyxHQUFQLFVBQVEsS0FBYSxFQUFFLFFBQWM7UUFBckMsaUJBNkJDO1FBNUJHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixLQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRXpCLElBQUksS0FBSSxDQUFDLFFBQVEsQ0FBQyx1QkFBdUIsRUFBRSxFQUFFO2dCQUV6QyxLQUFJLENBQUMsT0FBTyxHQUFHO29CQUNYLFNBQVMsRUFBRSxLQUFJLENBQUMsU0FBUztvQkFDekIsYUFBYSxFQUFFLEtBQUs7b0JBQ3BCLFFBQVEsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFJLENBQUMsb0JBQW9CLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7aUJBQ2xFLENBQUM7Z0JBQ0YsS0FBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7cUJBQ2pCLElBQUksQ0FBQyxjQUFNLE9BQUEsT0FBTyxFQUFFLEVBQVQsQ0FBUyxDQUFDO3FCQUNyQixLQUFLLENBQUMsVUFBQyxLQUFLLElBQUssT0FBQSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQWIsQ0FBYSxDQUFDLENBQUM7YUFDeEM7aUJBQU07Z0JBQ0gsT0FBTyxNQUFNLENBQ1QsSUFBSSw2QkFBYSxDQUNiLGlDQUFpQixDQUFDLHFCQUFxQixFQUN2QyxVQUFVO29CQUNWLFFBQVEsQ0FBQyxPQUFPLEVBQUU7b0JBQ2xCLFlBQVk7b0JBQ1osUUFBUSxDQUFDLFVBQVUsRUFBRTtvQkFDckIsUUFBUTtvQkFDUixRQUFRLENBQUMsU0FBUyxFQUFFO29CQUNwQiwrQkFBK0IsQ0FDbEMsQ0FDSixDQUFDO2FBQ0w7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUE2QkQsNEJBQVUsR0FBVjtRQUNJLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUErQkQsMkJBQVMsR0FBVCxVQUNJLE1BQWMsRUFDZCxhQUErQyxFQUMvQyxNQUFvRSxFQUNwRSxNQUEyQztRQUUzQyxJQUFJLFVBQVUsR0FBeUIsRUFBRSxDQUFDO1FBQzFDLElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBSSxPQUFPLE1BQU0sS0FBSyxVQUFVLEVBQUU7WUFDMUMsVUFBVSxHQUFHO2dCQUNULFVBQVUsRUFDTixPQUFPLE1BQU0sQ0FBQyxVQUFVLEtBQUssV0FBVztvQkFDcEMsQ0FBQyxDQUFDLE9BQU8sTUFBTSxDQUFDLFVBQVUsS0FBSyxRQUFRO3dCQUNuQyxDQUFDLENBQUMsaUNBQWUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO3dCQUNwQyxDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVU7b0JBQzNCLENBQUMsQ0FBQyxpQ0FBZSxDQUFDLE1BQU07Z0JBQ2hDLGdCQUFnQixFQUFFLE9BQU8sTUFBTSxDQUFDLGdCQUFnQixLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUNqRyxnQkFBZ0IsRUFBRSxPQUFPLE1BQU0sQ0FBQyxnQkFBZ0IsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsSUFBSTthQUNwRyxDQUFDO1NBQ0w7YUFBTTtZQUNILFVBQVUsR0FBRztnQkFDVCxVQUFVLEVBQUUsaUNBQWUsQ0FBQyxNQUFNO2dCQUNsQyxnQkFBZ0IsRUFBRSxJQUFJO2dCQUN0QixnQkFBZ0IsRUFBRSxJQUFJO2FBQ3pCLENBQUM7U0FDTDtRQUVELElBQUksaUJBQWlCLEdBQXFELFNBQVMsQ0FBQztRQUNwRixJQUFJLENBQUMsQ0FBQyxNQUFNLElBQUksT0FBTyxNQUFNLEtBQUssVUFBVSxFQUFFO1lBQzFDLGlCQUFpQixHQUFHLE1BQU0sQ0FBQztTQUM5QjthQUFNLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRTtZQUNqQixpQkFBaUIsR0FBRyxNQUFNLENBQUM7U0FDOUI7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUU7WUFDMUIsSUFBSSxpQkFBaUIsS0FBSyxTQUFTLEVBQUU7Z0JBQ2pDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUM7YUFDL0M7WUFDRCxNQUFNLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1NBQ2xDO1FBRUQsTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRWhFLE1BQU07YUFDRCxTQUFTLEVBQUU7YUFDWCxJQUFJLENBQUM7WUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLDBCQUEwQixHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDekUsSUFBSSxpQkFBaUIsS0FBSyxTQUFTLEVBQUU7Z0JBQ2pDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFDO2FBQ2hDO1FBQ0wsQ0FBQyxDQUFDO2FBQ0QsS0FBSyxDQUFDLFVBQUMsS0FBSztZQUNULElBQUksaUJBQWlCLEtBQUssU0FBUyxFQUFFO2dCQUNqQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUM1QjtRQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ1AsSUFBTSxVQUFVLEdBQUcsSUFBSSx1QkFBVSxDQUFDLE1BQU0sRUFBRSxhQUFhLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLGFBQWEsRUFBRTtZQUM1QixNQUFNLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQW1CLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUM3RztRQUNELE9BQU8sVUFBVSxDQUFDO0lBQ3RCLENBQUM7SUFRRCxnQ0FBYyxHQUFkLFVBQWUsTUFBYyxFQUFFLGFBQW1DLEVBQUUsVUFBaUM7UUFBckcsaUJBc0JDO1FBckJHLE9BQU8sSUFBSSxPQUFPLENBQWEsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMzQyxJQUFJLENBQUMsS0FBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUU7Z0JBQzFCLE9BQU8sTUFBTSxDQUFDLEtBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUM7YUFDM0M7WUFFRCxJQUFJLFVBQXNCLENBQUM7WUFFM0IsSUFBTSxRQUFRLEdBQUcsVUFBQyxLQUFZO2dCQUMxQixJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUU7b0JBQ1QsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQ3hCO3FCQUFNO29CQUNILE9BQU8sT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO2lCQUM5QjtZQUNMLENBQUMsQ0FBQztZQUVGLElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRTtnQkFDZCxVQUFVLEdBQUcsS0FBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQzthQUM1RTtpQkFBTTtnQkFDSCxVQUFVLEdBQUcsS0FBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2FBQ2hFO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBWUQsNkJBQVcsR0FBWCxVQUFZLFVBQXNCO1FBQWxDLGlCQTJCQztRQTFCRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBSSxDQUFDLEtBQUksQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFO2dCQUMxQixPQUFPLE1BQU0sQ0FBQyxLQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO2FBQzNDO2lCQUFNO2dCQUNILElBQU0sY0FBWSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQztnQkFFL0QsTUFBTSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxjQUFZLENBQUMsQ0FBQztnQkFFbEQsS0FBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQ3JCLHNCQUFzQixFQUN0QixFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUUsRUFDckQsVUFBQyxLQUFLLEVBQUUsUUFBUTtvQkFDWixJQUFJLEtBQUssRUFBRTt3QkFDUCxNQUFNLENBQUMsS0FBSyxDQUFDLDJCQUEyQixHQUFHLGNBQVksQ0FBQyxDQUFDO3dCQUN6RCxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztxQkFDeEI7eUJBQU07d0JBQ0gsTUFBTSxDQUFDLElBQUksQ0FBQyw4QkFBOEIsR0FBRyxjQUFZLENBQUMsQ0FBQzt3QkFDM0QsVUFBVSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7d0JBQ2xELFVBQVUsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLEVBQUUsQ0FBQzt3QkFDdEMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO3dCQUN2QyxPQUFPLE9BQU8sRUFBRSxDQUFDO3FCQUNwQjtnQkFDTCxDQUFDLENBQ0osQ0FBQzthQUNMO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBZUQseUJBQU8sR0FBUCxVQUFRLFNBQW9CO1FBQTVCLGlCQXFDQztRQXBDRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBSSxDQUFDLEtBQUksQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFO2dCQUMxQixPQUFPLE1BQU0sQ0FBQyxLQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO2FBQzNDO1lBRUQsU0FBUyxDQUFDLE9BQU8sR0FBRyxLQUFJLENBQUM7WUFDekIsU0FBUyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEdBQUcsS0FBSSxDQUFDO1lBRWhDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRTtnQkFFakMsS0FBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUM1QyxTQUFTLENBQUMsTUFBTTtxQkFDWCxPQUFPLEVBQUU7cUJBQ1QsSUFBSSxDQUFDO29CQUNGLEtBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBQzFDLE9BQU8sT0FBTyxFQUFFLENBQUM7Z0JBQ3JCLENBQUMsQ0FBQztxQkFDRCxLQUFLLENBQUMsVUFBQyxLQUFLLElBQUssT0FBQSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQWIsQ0FBYSxDQUFDLENBQUM7YUFDeEM7aUJBQU07Z0JBRUgsU0FBUztxQkFDSixVQUFVLEVBQUU7cUJBQ1osSUFBSSxDQUFDO29CQUNGLEtBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDNUMsU0FBUyxDQUFDLDZCQUE2QixFQUFFLENBQUM7b0JBQzFDLFNBQVMsQ0FBQyxNQUFNO3lCQUNYLE9BQU8sRUFBRTt5QkFDVCxJQUFJLENBQUM7d0JBQ0YsS0FBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQzt3QkFDMUMsT0FBTyxPQUFPLEVBQUUsQ0FBQztvQkFDckIsQ0FBQyxDQUFDO3lCQUNELEtBQUssQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQztnQkFDekMsQ0FBQyxDQUFDO3FCQUNELEtBQUssQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQzthQUN4QztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQXFCRCwyQkFBUyxHQUFULFVBQVUsU0FBb0I7UUFBOUIsaUJBMENDO1FBekNHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixJQUFJLENBQUMsS0FBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUU7Z0JBQzFCLE1BQU0sS0FBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7YUFDbEM7WUFFRCxJQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO1lBRWhDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFO2dCQUNwQixPQUFPLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyw0REFBNEQsQ0FBQyxDQUFDLENBQUM7YUFDMUY7aUJBQU0sSUFBSSxNQUFNLENBQUMsVUFBVSxLQUFLLEtBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQzlDLE9BQU8sTUFBTSxDQUNULElBQUksS0FBSyxDQUNMLG9GQUFvRjtvQkFDcEYsbUZBQW1GLENBQ3RGLENBQ0osQ0FBQzthQUNMO2lCQUFNO2dCQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEdBQUcsR0FBRyxDQUFDLENBQUM7Z0JBRWpGLEtBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLGdCQUFnQixFQUFFLFVBQUMsS0FBSyxFQUFFLFFBQVE7b0JBQ3hELElBQUksS0FBSyxFQUFFO3dCQUNQLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO3FCQUN4Qjt5QkFBTTt3QkFDSCxNQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUM7d0JBRTNDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO3dCQUUzQixJQUFJLE1BQU0sQ0FBQyxVQUFVLENBQUMsTUFBTSxJQUFJLE1BQU0sRUFBRTs0QkFFcEMsT0FBTyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQzt5QkFDbkM7d0JBRUQsSUFBTSxXQUFXLEdBQUcsSUFBSSx5QkFBVyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsaUJBQWlCLEVBQUUsU0FBUyxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsQ0FBQzt3QkFDdkcsU0FBUyxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7d0JBQ3RELFdBQVcsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO3dCQUVsQyxPQUFPLE9BQU8sRUFBRSxDQUFDO3FCQUNwQjtnQkFDTCxDQUFDLENBQUMsQ0FBQzthQUNOO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBbUJELGlDQUFlLEdBQWYsVUFBZ0IsVUFBc0I7UUFBdEMsaUJBMEJDO1FBekJHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixJQUFJLENBQUMsS0FBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUU7Z0JBQzFCLE9BQU8sTUFBTSxDQUFDLEtBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUM7YUFDM0M7WUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxHQUFHLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUM1RSxLQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLFlBQVksRUFBRSxVQUFVLENBQUMsWUFBWSxFQUFFLEVBQUUsVUFBQyxLQUFLLEVBQUUsUUFBUTtnQkFDcEcsSUFBSSxLQUFLLEVBQUU7b0JBQ1AsTUFBTSxDQUFDLEtBQUssQ0FBQywwQ0FBMEMsR0FBRyxVQUFVLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO29CQUMxRixJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssR0FBRyxFQUFFO3dCQUNwQixPQUFPLE1BQU0sQ0FDVCxJQUFJLDZCQUFhLENBQ2IsaUNBQWlCLENBQUMsMEJBQTBCLEVBQzVDLHFEQUFxRCxDQUN4RCxDQUNKLENBQUM7cUJBQ0w7eUJBQU07d0JBQ0gsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQ3hCO2lCQUNKO3FCQUFNO29CQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMsOENBQThDLEdBQUcsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUN0RixPQUFPLE9BQU8sRUFBRSxDQUFDO2lCQUNwQjtZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBaUJELGdDQUFjLEdBQWQsVUFBZSxNQUFjO1FBQTdCLGlCQTBCQztRQXpCRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBSSxDQUFDLEtBQUksQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFO2dCQUMxQixPQUFPLE1BQU0sQ0FBQyxLQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO2FBQzNDO1lBRUQsTUFBTSxDQUFDLElBQUksQ0FBQywrQkFBK0IsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDL0QsS0FBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLFVBQUMsS0FBSyxFQUFFLFFBQVE7Z0JBQ3ZGLElBQUksS0FBSyxFQUFFO29CQUNQLE1BQU0sQ0FBQyxLQUFLLENBQUMscUNBQXFDLEdBQUcsTUFBTSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztvQkFDN0UsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLEdBQUcsRUFBRTt3QkFDcEIsT0FBTyxNQUFNLENBQ1QsSUFBSSw2QkFBYSxDQUNiLGlDQUFpQixDQUFDLDBCQUEwQixFQUM1QyxxREFBcUQsQ0FDeEQsQ0FDSixDQUFDO3FCQUNMO3lCQUFNO3dCQUNILE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO3FCQUN4QjtpQkFDSjtxQkFBTTtvQkFDSCxNQUFNLENBQUMsSUFBSSxDQUFDLHlDQUF5QyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDekUsT0FBTyxPQUFPLEVBQUUsQ0FBQztpQkFDcEI7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQWFELHdCQUFNLEdBQU4sVUFBTyxNQUFxQjtRQUE1QixpQkE0Q0M7UUEzQ0csT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLElBQUksQ0FBQyxLQUFJLENBQUMsZ0JBQWdCLEVBQUUsRUFBRTtnQkFDMUIsT0FBTyxNQUFNLENBQUMsS0FBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQzthQUMzQztZQUVELElBQU0sYUFBYSxHQUFHLEVBQUUsQ0FBQztZQUV6QixJQUFJLE1BQU0sQ0FBQyxFQUFFLElBQUksTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUNuQyxJQUFNLGVBQWEsR0FBYSxFQUFFLENBQUM7Z0JBQ25DLE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUMsVUFBVTtvQkFDekIsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLFlBQVksRUFBRTt3QkFDM0IsZUFBYSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7cUJBQy9DO2dCQUNMLENBQUMsQ0FBQyxDQUFDO2dCQUNILGFBQWEsQ0FBQyxJQUFJLENBQUMsR0FBRyxlQUFhLENBQUM7YUFDdkM7aUJBQU07Z0JBQ0gsYUFBYSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQzthQUM1QjtZQUVELGFBQWEsQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFFdkQsSUFBSSxPQUFPLEdBQVcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO1lBQzNELElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRTtnQkFDWCxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLFNBQVMsRUFBRTtvQkFDdkMsT0FBTyxHQUFHLFNBQVMsR0FBRyxPQUFPLENBQUM7aUJBQ2pDO2FBQ0o7WUFDRCxhQUFhLENBQUMsTUFBTSxDQUFDLEdBQUcsT0FBTyxDQUFDO1lBRWhDLEtBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUNyQixhQUFhLEVBQ2I7Z0JBQ0ksT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDO2FBQ3pDLEVBQ0QsVUFBQyxLQUFLLEVBQUUsUUFBUTtnQkFDWixJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUU7b0JBQ1QsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQ3hCO3FCQUFNO29CQUNILE9BQU8sT0FBTyxFQUFFLENBQUM7aUJBQ3BCO1lBQ0wsQ0FBQyxDQUNKLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFZRCx5Q0FBdUIsR0FBdkIsVUFBd0IsTUFBYyxFQUFFLElBQVk7UUFBcEQsaUJBaUJDO1FBaEJHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixLQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FDckIseUJBQXlCLEVBQ3pCO2dCQUNJLFlBQVksRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVk7Z0JBQzVDLElBQUksTUFBQTthQUNQLEVBQ0QsVUFBQyxLQUFLLEVBQUUsUUFBUTtnQkFDWixJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUU7b0JBQ1QsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQ3hCO3FCQUFNO29CQUNILE9BQU8sT0FBTyxFQUFFLENBQUM7aUJBQ3BCO1lBQ0wsQ0FBQyxDQUNKLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFRRCw2Q0FBMkIsR0FBM0IsVUFBNEIsTUFBYztRQUExQyxpQkFnQkM7UUFmRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsS0FBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQ3JCLDZCQUE2QixFQUM3QjtnQkFDSSxZQUFZLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxZQUFZO2FBQy9DLEVBQ0QsVUFBQyxLQUFLLEVBQUUsUUFBUTtnQkFDWixJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUU7b0JBQ1QsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQ3hCO3FCQUFNO29CQUNILE9BQU8sT0FBTyxFQUFFLENBQUM7aUJBQ3BCO1lBQ0wsQ0FBQyxDQUNKLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLRCxvQkFBRSxHQUFGLFVBQW9DLElBQU8sRUFBRSxPQUE0Qzs7UUFDckYsaUJBQU0sS0FBSyxZQUFDLElBQUksRUFBRSxTQUFTLEdBQUcsSUFBSSxHQUFHLDBCQUEwQixFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRTFFLElBQUksSUFBSSxLQUFLLHdCQUF3QixFQUFFO1lBRW5DLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsVUFBQyxnQkFBZ0I7O2dCQUM1QyxJQUFJLENBQUMsQ0FBQyxDQUFBLE1BQUEsZ0JBQWdCLENBQUMsTUFBTSwwQ0FBRSxRQUFRLENBQUEsRUFBRTtvQkFDckMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLHVCQUF1QixFQUFFLENBQUM7aUJBQ3JEO1lBQ0wsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsQ0FBQyxDQUFBLE1BQUEsTUFBQSxJQUFJLENBQUMsVUFBVSwwQ0FBRSxNQUFNLDBDQUFFLFFBQVEsQ0FBQSxFQUFFO2dCQUVyQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO2FBQ3BEO1NBQ0o7UUFDRCxJQUFJLElBQUksS0FBSyx1QkFBdUIsRUFBRTtZQUVsQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLFVBQUMsZ0JBQWdCOztnQkFDNUMsSUFBSSxDQUFDLENBQUMsQ0FBQSxNQUFBLGdCQUFnQixDQUFDLE1BQU0sMENBQUUsUUFBUSxDQUFBLEVBQUU7b0JBQ3JDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyw4QkFBOEIsRUFBRSxDQUFDO2lCQUM1RDtZQUNMLENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLENBQUMsQ0FBQSxNQUFBLE1BQUEsSUFBSSxDQUFDLFVBQVUsMENBQUUsTUFBTSwwQ0FBRSxRQUFRLENBQUEsRUFBRTtnQkFFckMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsOEJBQThCLEVBQUUsQ0FBQzthQUMzRDtTQUNKO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUtELHNCQUFJLEdBQUosVUFBc0MsSUFBTyxFQUFFLE9BQTRDOztRQUN2RixpQkFBTSxPQUFPLFlBQUMsSUFBSSxFQUFFLFNBQVMsR0FBRyxJQUFJLEdBQUcsK0JBQStCLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFakYsSUFBSSxJQUFJLEtBQUssd0JBQXdCLEVBQUU7WUFFbkMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxVQUFDLGdCQUFnQjs7Z0JBQzVDLElBQUksQ0FBQyxDQUFDLENBQUEsTUFBQSxnQkFBZ0IsQ0FBQyxNQUFNLDBDQUFFLFFBQVEsQ0FBQSxFQUFFO29CQUNyQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztpQkFDekQ7WUFDTCxDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxDQUFDLENBQUEsTUFBQSxNQUFBLElBQUksQ0FBQyxVQUFVLDBDQUFFLE1BQU0sMENBQUUsUUFBUSxDQUFBLEVBQUU7Z0JBRXJDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLDJCQUEyQixFQUFFLENBQUM7YUFDeEQ7U0FDSjtRQUNELElBQUksSUFBSSxLQUFLLHVCQUF1QixFQUFFO1lBRWxDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsVUFBQyxnQkFBZ0I7O2dCQUM1QyxJQUFJLENBQUMsQ0FBQyxDQUFBLE1BQUEsZ0JBQWdCLENBQUMsTUFBTSwwQ0FBRSxRQUFRLENBQUEsRUFBRTtvQkFDckMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLGtDQUFrQyxFQUFFLENBQUM7aUJBQ2hFO1lBQ0wsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsQ0FBQyxDQUFBLE1BQUEsTUFBQSxJQUFJLENBQUMsVUFBVSwwQ0FBRSxNQUFNLDBDQUFFLFFBQVEsQ0FBQSxFQUFFO2dCQUVyQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxrQ0FBa0MsRUFBRSxDQUFDO2FBQy9EO1NBQ0o7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBS0QscUJBQUcsR0FBSCxVQUFxQyxJQUFPLEVBQUUsT0FBNkM7UUFBM0YsaUJBMENDOztRQXpDRyxpQkFBTSxNQUFNLFlBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRTVCLElBQUksSUFBSSxLQUFLLHdCQUF3QixFQUFFO1lBRW5DLElBQUksQ0FBQyxJQUFJLENBQUMsNkJBQTZCLENBQUMsd0JBQXdCLEVBQUUsS0FBSyxDQUFDLEVBQUU7Z0JBQ3RFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsVUFBQyxnQkFBZ0I7O29CQUM1QyxJQUFJLENBQUMsQ0FBQyxDQUFBLE1BQUEsZ0JBQWdCLENBQUMsTUFBTSwwQ0FBRSxhQUFhLENBQUEsRUFBRTt3QkFFMUMsSUFBSSxDQUFDLEtBQUksQ0FBQyw2QkFBNkIsQ0FBQyx3QkFBd0IsRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxFQUFFOzRCQUM3RyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLENBQUM7eUJBQzNEO3FCQUNKO2dCQUNMLENBQUMsQ0FBQyxDQUFDO2dCQUNILElBQUksQ0FBQyxDQUFDLENBQUEsTUFBQSxNQUFBLElBQUksQ0FBQyxVQUFVLDBDQUFFLE1BQU0sMENBQUUsYUFBYSxDQUFBLEVBQUU7b0JBRTFDLElBQUksQ0FBQyxJQUFJLENBQUMsNkJBQTZCLENBQUMsd0JBQXdCLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxFQUFFO3dCQUM1RyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztxQkFDMUQ7aUJBQ0o7YUFDSjtTQUNKO1FBQ0QsSUFBSSxJQUFJLEtBQUssdUJBQXVCLEVBQUU7WUFFbEMsSUFBSSxDQUFDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyx1QkFBdUIsRUFBRSxLQUFLLENBQUMsRUFBRTtnQkFDckUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxVQUFDLGdCQUFnQjs7b0JBQzVDLElBQUksQ0FBQyxDQUFDLENBQUEsTUFBQSxnQkFBZ0IsQ0FBQyxNQUFNLDBDQUFFLGFBQWEsQ0FBQSxFQUFFO3dCQUUxQyxJQUFJLENBQUMsS0FBSSxDQUFDLDZCQUE2QixDQUFDLHVCQUF1QixFQUFFLEtBQUssRUFBRSxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUU7NEJBQzVHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQywrQkFBK0IsQ0FBQyxLQUFLLENBQUMsQ0FBQzt5QkFDbEU7cUJBQ0o7Z0JBQ0wsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLENBQUMsQ0FBQSxNQUFBLE1BQUEsSUFBSSxDQUFDLFVBQVUsMENBQUUsTUFBTSwwQ0FBRSxhQUFhLENBQUEsRUFBRTtvQkFFMUMsSUFBSSxDQUFDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyx1QkFBdUIsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUU7d0JBQzNHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLCtCQUErQixDQUFDLEtBQUssQ0FBQyxDQUFDO3FCQUNqRTtpQkFDSjthQUNKO1NBQ0o7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBT0QscUNBQW1CLEdBQW5CLFVBQW9CLEtBQThCO1FBQWxELGlCQVdDO1FBVEcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQzthQUMzQixJQUFJLENBQUMsVUFBQyxVQUFVO1lBQ2IsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLEdBQUcsVUFBVSxDQUFDLFlBQVksR0FBRyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ2pHLENBQUMsQ0FBQzthQUNELEtBQUssQ0FBQyxVQUFDLGFBQWE7WUFDakIsSUFBTSxVQUFVLEdBQUcsSUFBSSx1QkFBVSxDQUFDLEtBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMvQyxLQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDakQsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxJQUFJLGlDQUFlLENBQUMsS0FBSyxFQUFFLEtBQUksRUFBRSxtQkFBbUIsRUFBRSxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BILENBQUMsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUtELG1DQUFpQixHQUFqQixVQUFrQixLQUE4RDtRQUFoRixpQkFxQkM7UUFwQkcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsbUJBQW1CLENBQUM7YUFDNUQsSUFBSSxDQUFDLFVBQUMsVUFBVTtZQUNiLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUU7Z0JBQ3JCLElBQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUM7Z0JBRWpDLElBQU0sV0FBVyxHQUFHLElBQUkseUJBQVcsQ0FBQyxJQUFJLEVBQUUsS0FBSSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ3pGLEtBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLGlCQUFpQixFQUFFLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztnQkFDcEQsV0FBVyxDQUFDLG1CQUFtQixFQUFFLENBQUM7Z0JBRWxDLEtBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ3JEO1lBQ0QsVUFBVSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3JCLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3ZELEtBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLHFCQUFxQixFQUFFO2dCQUNyQyxJQUFJLGlDQUFlLENBQUMsS0FBSyxFQUFFLEtBQUksRUFBRSxxQkFBcUIsRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQzthQUNwRixDQUFDLENBQUM7UUFDUCxDQUFDLENBQUM7YUFDRCxLQUFLLENBQUMsVUFBQyxhQUFhO1lBQ2pCLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7SUFDWCxDQUFDO0lBS0Qsd0NBQXNCLEdBQXRCLFVBQXVCLEtBQThCO1FBQXJELGlCQWlDQztRQWhDRyxJQUFNLG9CQUFvQixHQUFHLFVBQUMsVUFBVTtZQUNwQyxLQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFFaEUsSUFBSSxDQUFDLEtBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRTtnQkFLNUQsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLENBQUMsSUFBSSx5QkFBVyxDQUFDLEtBQUssRUFBRSxLQUFJLEVBQUUsZUFBZSxFQUFFLFVBQVUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQzlHO1lBRUQsS0FBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNwRSxDQUFDLENBQUM7UUFJRixJQUFJLFVBQXNCLENBQUM7UUFDM0IsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsd0JBQXdCLENBQUM7YUFFdkQsSUFBSSxDQUFDLFVBQUMsR0FBRztZQUVOLFVBQVUsR0FBRyxHQUFHLENBQUM7WUFDakIsS0FBSyxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDO1lBQzFCLFVBQVUsQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO1lBQ2pDLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDNUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDO2FBQ0QsS0FBSyxDQUFDLFVBQUMsYUFBYTtZQUVqQixVQUFVLEdBQUcsSUFBSSx1QkFBVSxDQUFDLEtBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN6QyxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUMsQ0FBQztJQUNYLENBQUM7SUFLRCwwQ0FBd0IsR0FBeEIsVUFBeUIsS0FBMEQ7UUFBbkYsaUJBdUJDO1FBdEJHLElBQUksS0FBSyxDQUFDLFlBQVksS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksRUFBRTtZQUVyRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQzFDO2FBQU07WUFDSCxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLFlBQVksRUFBRSwwQkFBMEIsQ0FBQztpQkFFbkUsSUFBSSxDQUFDLFVBQUMsVUFBVTtnQkFDYixJQUFNLFdBQVcsR0FBRyxJQUFJLHlCQUFXLENBQUMsSUFBSSxFQUFFLEtBQUksRUFBRSxpQkFBaUIsRUFBRSxVQUFVLENBQUMsTUFBTyxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDckcsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO2dCQUNwRCxXQUFXLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztnQkFHbEMsSUFBSSxVQUFVLENBQUMsTUFBTSxJQUFJLElBQUksRUFBRTtvQkFDM0IsSUFBTSxRQUFRLEdBQVcsVUFBVSxDQUFDLE1BQU8sQ0FBQyxRQUFRLENBQUM7b0JBQ3JELEtBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQzNDLFVBQVUsQ0FBQyxZQUFZLEVBQUUsQ0FBQztpQkFDN0I7WUFDTCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLFVBQUMsYUFBYTtnQkFDakIsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoQyxDQUFDLENBQUMsQ0FBQztTQUNWO0lBQ0wsQ0FBQztJQUtELHNDQUFvQixHQUFwQixVQUFxQixLQUE4RDtRQUMvRSxJQUFJLEtBQUssQ0FBQyxZQUFZLEtBQUssSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUU7WUFFckQsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFO2dCQUMvQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDbEM7U0FDSjtJQUNMLENBQUM7SUFLRCw4QkFBWSxHQUFaLFVBQWEsS0FBc0Q7UUFBbkUsaUJBaUNDO1FBaENHLE1BQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUVwRCxJQUFNLFlBQVksR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFFckYsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRTtZQUVkLElBQUksQ0FBQyxhQUFhLENBQ2QsS0FBSyxDQUFDLElBQUksRUFDVixjQUFjO2dCQUNkLEtBQUssQ0FBQyxJQUFJO2dCQUNWLDhEQUE4RDtnQkFDOUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQzdDLCtCQUErQjtnQkFDL0IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQy9CO2lCQUVJLElBQUksQ0FBQyxVQUFDLFVBQVU7Z0JBQ2IsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUMsSUFBSSx5QkFBVyxDQUFDLEtBQUksRUFBRSxZQUFZLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzNGLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUU7b0JBQ3pDLEtBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLHlCQUFXLENBQUMsS0FBSSxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDaEc7WUFDTCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLFVBQUMsYUFBYTtnQkFDakIsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoQyxDQUFDLENBQUMsQ0FBQztTQUNWO2FBQU07WUFFSCxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxJQUFJLHlCQUFXLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMxRixJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFO2dCQUN6QyxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSx5QkFBVyxDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDL0Y7U0FDSjtJQUNMLENBQUM7SUFLRCx5Q0FBdUIsR0FBdkIsVUFBd0IsS0FBeUk7UUFBakssaUJBeUVDO1FBeEVHLElBQU0sUUFBUSxHQUFHLFVBQUMsVUFBc0I7WUFDcEMsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxLQUFLLENBQUMsUUFBUSxFQUFFO2dCQUN0RSxJQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDO2dCQUNqQyxJQUFJLFFBQVEsU0FBQSxDQUFDO2dCQUNiLFFBQVEsS0FBSyxDQUFDLFFBQVEsRUFBRTtvQkFDcEIsS0FBSyxhQUFhO3dCQUNkLFFBQVEsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDO3dCQUM5QixLQUFLLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLEtBQUssTUFBTSxDQUFDO3dCQUMzQyxNQUFNLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7d0JBQ3BDLE1BQU07b0JBQ1YsS0FBSyxhQUFhO3dCQUNkLFFBQVEsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDO3dCQUM5QixLQUFLLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLEtBQUssTUFBTSxDQUFDO3dCQUMzQyxNQUFNLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7d0JBQ3BDLE1BQU07b0JBQ1YsS0FBSyxZQUFZO3dCQUNiLEtBQUssQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7d0JBQzVDLE1BQU07b0JBQ1YsS0FBSyxZQUFZO3dCQUNiLEtBQUssQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7d0JBQzVDLE1BQU07b0JBQ1YsS0FBSyxpQkFBaUI7d0JBQ2xCLFFBQVEsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDO3dCQUNsQyxLQUFLLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQzt3QkFDeEQsTUFBTSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO3dCQUN4QyxNQUFNO29CQUNWLEtBQUssUUFBUTt3QkFDVCxRQUFRLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQzt3QkFDekIsS0FBSyxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7d0JBQ3JGLElBQUksS0FBSyxDQUFDLFFBQVEsS0FBSyxTQUFTLEVBQUU7NEJBQzlCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxlQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQzs0QkFDeEUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDOzRCQUM5QixJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsY0FBYyxFQUFFO2dDQUMvQixNQUFNLENBQUMsTUFBTSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQzs2QkFDaEU7eUJBQ0o7NkJBQU07NEJBQ0gsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDO3lCQUN4Qjt3QkFDRCxLQUFLLENBQUMsUUFBUSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7d0JBQy9CLE1BQU07aUJBQ2I7Z0JBQ0QsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUU7b0JBQ3ZDLElBQUksdURBQTBCLENBQUMsS0FBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUM7aUJBQ3ZHLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFO29CQUN4QixNQUFNLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRTt3QkFDcEQsSUFBSSx1REFBMEIsQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUM7cUJBQ3ZILENBQUMsQ0FBQztpQkFDTjthQUNKO2lCQUFNO2dCQUNILE1BQU0sQ0FBQyxLQUFLLENBQ1IsMkJBQTJCO29CQUMzQixLQUFLLENBQUMsUUFBUTtvQkFDZCwwQkFBMEI7b0JBQzFCLEtBQUssQ0FBQyxZQUFZO29CQUNsQixvQ0FBb0MsQ0FDdkMsQ0FBQzthQUNMO1FBQ0wsQ0FBQyxDQUFDO1FBRUYsSUFBSSxLQUFLLENBQUMsWUFBWSxLQUFLLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBWSxFQUFFO1lBRXJELFFBQVEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDN0I7YUFBTTtZQUNILElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLHlCQUF5QixDQUFDO2lCQUNsRSxJQUFJLENBQUMsVUFBQyxVQUFVO2dCQUNiLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUN6QixDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLFVBQUMsYUFBYTtnQkFDakIsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoQyxDQUFDLENBQUMsQ0FBQztTQUNWO0lBQ0wsQ0FBQztJQUtELDZDQUEyQixHQUEzQixVQUE0QixLQUEwQztRQUNsRSxJQUFJLFFBQVEsQ0FBQztRQUNiLFFBQVEsS0FBSyxDQUFDLFFBQVEsRUFBRTtZQUNwQixLQUFLLE1BQU07Z0JBQ1AsUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN4QyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO2dCQUN0QyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQWEsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQztnQkFDcEQsTUFBTTtZQUNWLEtBQUssUUFBUTtnQkFDVCxRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUM7Z0JBQ2xDLEtBQUssQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsS0FBSyxNQUFNLENBQUM7Z0JBQzNDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7Z0JBQ3hDLElBQUksQ0FBQyxVQUFVLENBQUMsWUFBYSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO2dCQUN0RCxNQUFNO1NBQ2I7UUFDRCxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQywyQkFBMkIsRUFBRTtZQUMzQyxJQUFJLCtEQUE4QixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUM7U0FDdEcsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELHFEQUFtQyxHQUFuQyxVQUFvQyxLQUFtRTtRQUF2RyxpQkFnQkM7UUFmRyxJQUFJLEtBQUssQ0FBQyxZQUFZLEtBQUssSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUU7WUFDckQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsNEJBQTRCLEVBQUU7Z0JBQzVDLElBQUksaUVBQStCLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDO2FBQzdGLENBQUMsQ0FBQztTQUNOO2FBQU07WUFDSCxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsd0NBQXdDLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQztpQkFDaEcsSUFBSSxDQUFDLFVBQUMsVUFBc0I7Z0JBQ3pCLEtBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLDRCQUE0QixFQUFFO29CQUM1QyxJQUFJLGlFQUErQixDQUFDLEtBQUksRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDO2lCQUN4RixDQUFDLENBQUM7WUFDUCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLFVBQUMsYUFBYTtnQkFDakIsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoQyxDQUFDLENBQUMsQ0FBQztTQUNWO0lBQ0wsQ0FBQztJQUtELGtDQUFnQixHQUFoQixVQUFpQixLQU1oQjtRQUlHLElBQU0sYUFBYSxHQUF3QjtZQUN2QyxTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVM7WUFDMUIsYUFBYSxFQUFFLEtBQUssQ0FBQyxhQUFhO1lBQ2xDLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtTQUN2QixDQUFDO1FBQ0YsSUFBTSxZQUFZLEdBQUcsSUFBSSxlQUFlLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFeEQsSUFBSSxDQUFDLGFBQWEsQ0FDZCxLQUFLLENBQUMsa0JBQWtCLEVBQ3hCLHdDQUF3QztZQUN4QyxLQUFLLENBQUMsa0JBQWtCO1lBQ3hCLG1CQUFtQjtZQUNuQixLQUFLLENBQUMsWUFBWTtZQUNsQixtQ0FBbUM7WUFDbkMsWUFBWSxDQUNmO2FBQ0ksSUFBSSxDQUFDLFVBQUMsVUFBVTtZQUNiLElBQU0sTUFBTSxHQUFXLFVBQVUsQ0FBQyxNQUFPLENBQUM7WUFDMUMsTUFBTTtpQkFDRCxhQUFhLEVBQUU7aUJBQ2YsZUFBZSxDQUFDLFlBQVksQ0FBQztpQkFDN0IsS0FBSyxDQUFDLFVBQUMsS0FBSztnQkFDVCxNQUFNLENBQUMsS0FBSyxDQUNSLDZCQUE2QixHQUFHLE1BQU8sQ0FBQyxRQUFRLEdBQUcsc0JBQXNCLEdBQUcsS0FBSyxDQUFDLFlBQVksR0FBRyxJQUFJLEdBQUcsS0FBSyxDQUNoSCxDQUFDO1lBQ04sQ0FBQyxDQUFDLENBQUM7UUFDWCxDQUFDLENBQUM7YUFDRCxLQUFLLENBQUMsVUFBQyxhQUFhO1lBQ2pCLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7SUFDWCxDQUFDO0lBS0QsaUNBQWUsR0FBZixVQUFnQixHQUFHO1FBQ2YsTUFBTSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDdEQsSUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQztRQUN4QixJQUFJLENBQUMsS0FBSyxTQUFTLEVBQUU7WUFDakIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLEVBQUU7Z0JBQ2hDO29CQUNJLE9BQU8sRUFBRSxDQUFDO2lCQUNiO2FBQ0osQ0FBQyxDQUFDO1NBQ047YUFBTTtZQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMscUNBQXFDLEVBQUUsR0FBRyxDQUFDLENBQUM7U0FDM0Q7SUFDTCxDQUFDO0lBS0Qsa0NBQWdCLEdBQWhCLFVBQWlCLE1BQTZCO1FBQzFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsNkJBQTZCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRTtZQUNwRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztTQUM1QjtJQUNMLENBQUM7SUFLRCx1Q0FBcUIsR0FBckI7UUFDSSxNQUFNLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRSxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUM5QixJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUtELDhCQUFZLEdBQVosVUFBYSxLQUF3QjtRQUNqQyxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDdEQsSUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztRQUN4QixJQUFJLEdBQUcsRUFBRTtZQUNMLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRTtnQkFDN0I7b0JBQ0ksS0FBSyxFQUFFLEdBQUc7aUJBQ2I7YUFDSixDQUFDLENBQUM7U0FDTjthQUFNO1lBQ0gsTUFBTSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsRUFBRSxLQUFLLENBQUMsQ0FBQztTQUN6RDtJQUNMLENBQUM7SUFLRCxvQ0FBa0IsR0FBbEIsVUFBbUIsS0FBbUM7UUFDbEQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxJQUFJLCtCQUFjLENBQUMsSUFBSSxFQUFFLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoSCxDQUFDO0lBS0Qsb0NBQWtCLEdBQWxCLFVBQW1CLEtBQWlFO1FBQ2hGLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLGtCQUFrQixFQUFFLENBQUMsSUFBSSwrQkFBYyxDQUFDLElBQUksRUFBRSxrQkFBa0IsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5SCxDQUFDO0lBS0QseUNBQXVCLEdBQXZCLFVBQXdCLEtBQXNHO1FBQTlILGlCQXVCQztRQXRCRyxJQUFNLFlBQVksR0FBVyxLQUFLLENBQUMsWUFBWSxDQUFDO1FBQ2hELElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLHVDQUF1QyxHQUFHLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFDLFVBQVU7WUFDckcsTUFBTSxDQUFDLElBQUksQ0FBQyxpQ0FBeUIsS0FBSyxDQUFDLFNBQVMsa0JBQWMsQ0FBQyxDQUFDO1lBQ3BFLElBQU0sTUFBTSxHQUFXLFVBQVUsQ0FBQyxNQUFPLENBQUM7WUFDMUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUU7Z0JBQzNCLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FDZixpQ0FBeUIsS0FBSyxDQUFDLFNBQVMsc0NBQTJCLE1BQU0sQ0FBQyxRQUFRLDhCQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLGFBQ3pILENBQ2IsQ0FBQzthQUNMO1lBQ0QsSUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNqRSxJQUFJLENBQUMsWUFBWSxJQUFJLE9BQU8sWUFBWSxLQUFLLFVBQVUsRUFBRTtnQkFDckQsSUFBTSxjQUFjLEdBQWEsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUMzRSxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQ2YsaUNBQXlCLEtBQUssQ0FBQyxTQUFTLHFFQUEwRCxjQUFjLENBQUMsSUFBSSxDQUNqSCxHQUFHLENBQ04sQ0FBRSxDQUNOLENBQUM7YUFDTDtpQkFBTTtnQkFDSCxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUksRUFBRSxJQUFJLHlCQUFXLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO2FBQ3hGO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBS0QsK0NBQTZCLEdBQTdCLFVBQThCLEtBQW1FO1FBQWpHLGlCQThEQztRQTdERyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsS0FBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsK0JBQStCLENBQUM7aUJBQ3hFLElBQUksQ0FBQyxVQUFDLFVBQVU7Z0JBQ2IsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLE1BQU0sSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxLQUFLLENBQUMsUUFBUSxFQUFFO29CQUN0RSxJQUFNLFFBQU0sR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDO29CQUVqQyxJQUFJLFFBQU0sQ0FBQyw2QkFBNkIsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLEVBQUU7d0JBR3ZELElBQUksUUFBTSxDQUFDLHdCQUF5QixDQUFDLHdDQUF3QyxDQUFDLElBQUksSUFBSSxFQUFFOzRCQUlwRixRQUFNLENBQUMsd0JBQXlCLENBQUMsd0NBQXdDLENBQUMsR0FBRyxLQUFLLENBQUM7NEJBQ25GLE9BQU8sTUFBTSxDQUFDLHdDQUF3QyxDQUFDLENBQUM7eUJBQzNEOzZCQUFNOzRCQUlILFFBQU0sQ0FBQyx3QkFBeUIsQ0FBQyx3Q0FBd0MsQ0FBQyxHQUFHLEtBQUssQ0FBQzs0QkFDbkYsSUFBTSxVQUFRLEdBQUc7Z0NBQ2IsSUFBTSxRQUFRLEdBQUcsUUFBTSxDQUFDLHdCQUF5QixDQUFDLHdDQUF3QyxDQUFDLENBQUM7Z0NBQzVGLE9BQU8sUUFBTSxDQUFDLHdCQUF5QixDQUFDLHdDQUF3QyxDQUFDLENBQUM7Z0NBQ2xGLEtBQUksQ0FBQyw2QkFBNkIsQ0FBQyxRQUFRLENBQUMsQ0FBQzs0QkFDakQsQ0FBQyxDQUFDOzRCQUNGLFFBQU0sQ0FBQyx3QkFBeUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFO2dDQUM3QyxVQUFRLEVBQUUsQ0FBQzs0QkFDZixDQUFDLENBQUMsQ0FBQzs0QkFDSCxRQUFNLENBQUMsd0JBQXlCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtnQ0FDM0MsVUFBUSxFQUFFLENBQUM7NEJBQ2YsQ0FBQyxDQUFDLENBQUM7eUJBQ047d0JBQ0QsT0FBTztxQkFDVjtvQkFFRCxRQUFNO3lCQUNELHlCQUF5QixDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQzt5QkFDckQsSUFBSSxDQUFDLGNBQU0sT0FBQSxRQUFNLENBQUMsMkJBQTJCLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxFQUFqRCxDQUFpRCxDQUFDO3lCQUM3RCxLQUFLLENBQUMsVUFBQyxLQUFLO3dCQUNULE9BQUEsUUFBTSxDQUFDLDBCQUEwQixDQUM3QixJQUFJLEVBQ0osMERBQW1ELEtBQUssQ0FBQyxRQUFRLGVBQUssS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFFLEVBQ3hGLE1BQU0sQ0FDVDtvQkFKRCxDQUlDLENBQ0osQ0FBQztpQkFDVDtxQkFBTTtvQkFDSCxJQUFNLE1BQU0sR0FDUiwyQkFBMkI7d0JBQzNCLEtBQUssQ0FBQyxRQUFRO3dCQUNkLDBCQUEwQjt3QkFDMUIsS0FBSyxDQUFDLFlBQVk7d0JBQ2xCLG9DQUFvQyxDQUFDO29CQUN6QyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUNyQixPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztpQkFDekI7WUFDTCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLFVBQUMsYUFBYTtnQkFDakIsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDNUIsT0FBTyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDakMsQ0FBQyxDQUFDLENBQUM7UUFDWCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLRCx3Q0FBc0IsR0FBdEI7UUFDSSxNQUFNLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDcEQsSUFBSSxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFFN0IsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsOEJBQThCLEVBQUUsRUFBRTtZQUNyRixNQUFNLENBQUMsSUFBSSxDQUFDLDRCQUE0QixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzVFLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2hELGdCQUFnQixHQUFHLElBQUksQ0FBQztTQUMzQjtRQUVELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsVUFBQyxnQkFBZ0I7WUFDNUMsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxJQUFJLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyw4QkFBOEIsRUFBRSxFQUFFO2dCQUN2RixNQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDOUUsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNwRCxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7YUFDM0I7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUNuQixNQUFNLENBQUMsSUFBSSxDQUFDLHVEQUF1RCxDQUFDLENBQUM7U0FDeEU7SUFDTCxDQUFDO0lBS0ssdUNBQXFCLEdBQTNCLFVBQTRCLEtBUzNCOzs7Ozs0QkFDc0IsV0FBTSxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsdUNBQXVDLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxFQUFBOzt3QkFBdkgsVUFBVSxHQUFHLFNBQTBHO3dCQUN2SCxFQUFFLEdBQUcsSUFBSSxxQ0FBaUIsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsV0FBVyxFQUFFLEVBQUUsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ3pILElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLHFCQUFxQixFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzs7Ozs7S0FDbEQ7SUFLSyw0Q0FBMEIsR0FBaEMsVUFBaUMsS0FBMEI7OztnQkFDdkQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxJQUFJLCtCQUFjLENBQUMsSUFBSSxFQUFFLG1DQUFrQixDQUFDLDJCQUEyQixFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDOzs7O0tBQ2hJO0lBS0QsMkJBQVMsR0FBVCxVQUFVLElBQVksRUFBRSxVQUFpQjtRQUNyQyxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUtELHVCQUFLLEdBQUwsVUFBTSxNQUFlLEVBQUUsTUFBNkI7UUFBcEQsaUJBNkJDO1FBNUJHLE1BQU0sR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQ2xCLE1BQU0sQ0FBQyxJQUFJLENBQUMsMEJBQTBCLEdBQUcsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBRTlCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDbkIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUN0QyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsVUFBQyxLQUFLLEVBQUUsUUFBUTtvQkFDbkQsSUFBSSxLQUFLLEVBQUU7d0JBQ1AsTUFBTSxDQUFDLEtBQUssQ0FBQywyQkFBb0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBRSxDQUFDLENBQUM7cUJBQzdEO29CQUNELEtBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQzVCLENBQUMsQ0FBQyxDQUFDO2FBQ047aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQzthQUMzQjtZQUVELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUVqQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUU7Z0JBRTNCLElBQU0sc0JBQXNCLEdBQUcsSUFBSSxtREFBd0IsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzFFLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLHFCQUFxQixFQUFFLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO2dCQUNuRSxzQkFBc0IsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO2FBQ2hEO1NBQ0o7YUFBTTtZQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQzFFO1FBQ0QsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ25CLENBQUM7SUFLRCxrQ0FBZ0IsR0FBaEIsVUFBaUIsS0FBYTtRQUMxQixJQUFNLFVBQVUsR0FBRztZQUNmLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDM0IsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTO1lBQ3ZCLFFBQVEsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVM7WUFDN0UsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYztZQUN4QyxRQUFRLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUM5RCxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUU7WUFDakMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFO1lBQ3JDLEdBQUcsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRTtTQUM5QixDQUFDO1FBQ0YsT0FBTyxVQUFVLENBQUM7SUFDdEIsQ0FBQztJQUtELCtCQUFhLEdBQWIsVUFBYyxhQUE0QixFQUFFLGVBQTJCLEVBQUUsVUFBMkIsRUFBRSxRQUFvQjtRQUExSCxpQkFtRkM7O1FBbkYyQyxnQ0FBQSxFQUFBLG1CQUEyQjtRQUFFLDJCQUFBLEVBQUEsa0JBQTJCO1FBQUUseUJBQUEsRUFBQSxZQUFvQjtRQUN0SCxJQUNJLFFBQVEsQ0FBQyxlQUFlLEVBQUU7WUFDMUIsUUFBUSxDQUFDLHFCQUFxQixFQUFFO1lBQ2hDLFFBQVEsQ0FBQyxjQUFjLEVBQUU7WUFDekIsUUFBUSxDQUFDLG9CQUFvQixFQUFFO1lBQy9CLFFBQVEsQ0FBQyxhQUFhLEVBQUU7WUFDeEIsUUFBUSxDQUFDLG1CQUFtQixFQUFFO1lBQzlCLFFBQVEsQ0FBQyxVQUFVLEVBQUU7WUFDckIsQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDdEQsUUFBUSxDQUFDLGdCQUFnQixFQUFFO1lBQzNCLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRTtZQUMzQixRQUFRLENBQUMsY0FBYyxFQUFFO1lBQ3pCLFFBQVEsQ0FBQyxlQUFlLEVBQUUsRUFDNUI7WUFDRSxJQUFNLG9CQUFrQixHQUFHOzs7Ozs0QkFDakIsRUFBRSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztpQ0FDbkQsQ0FBQSxFQUFFLENBQUMsZUFBZSxLQUFLLFdBQVcsQ0FBQSxFQUFsQyxjQUFrQzs0QkFDakIsV0FBTSxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUE7OzRCQUE5QixRQUFRLEdBQUcsU0FBbUI7NEJBQzlCLFFBQWEsRUFBRSxDQUFDOzRCQUN0QixRQUFRLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztnQ0FDbkIsSUFBSSxZQUFZLElBQUksS0FBSyxJQUFJLGFBQWEsSUFBSSxLQUFLLElBQUksS0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7b0NBQ3JFLEtBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7aUNBQ25COzRCQUNMLENBQUMsQ0FBQyxDQUFDOzRCQUNILElBQUksS0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7Z0NBQ2hCLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUNyQixXQUFXLEVBQ1g7b0NBQ0ksTUFBTSxFQUFFLEtBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXO29DQUMxQixLQUFLLEVBQUUsS0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVU7b0NBQ3hCLFdBQVcsRUFBRSxhQUFhLENBQUMsTUFBTSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxLQUFLO29DQUNoRyxXQUFXLEVBQUUsYUFBYSxDQUFDLE1BQU0sQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsS0FBSztpQ0FDbkcsRUFDRCxVQUFDLEtBQUssRUFBRSxRQUFRO29DQUNaLElBQUksS0FBSyxFQUFFO3dDQUNQLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUNBQWlDLEVBQUUsS0FBSyxDQUFDLENBQUM7cUNBQzFEO2dDQUNMLENBQUMsQ0FDSixDQUFDOzZCQUNMOzs7OztpQkFFUixDQUFDO1lBQ0YsSUFBSSxVQUFVLEVBQUU7Z0JBQ1osSUFBSSxPQUFLLEdBQUcsQ0FBQyxDQUFDO2dCQUNkLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxXQUFXLENBQUM7b0JBQ2pDLElBQUksT0FBSyxHQUFHLFFBQVEsRUFBRTt3QkFDbEIsT0FBSyxFQUFFLENBQUM7d0JBQ1Isb0JBQWtCLEVBQUUsQ0FBQztxQkFDeEI7eUJBQU07d0JBQ0gsYUFBYSxDQUFDLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO3FCQUN6QztnQkFDTCxDQUFDLEVBQUUsZUFBZSxHQUFHLElBQUksQ0FBQyxDQUFDO2FBQzlCO2lCQUFNO2dCQUNILElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxVQUFVLENBQUMsb0JBQWtCLEVBQUUsZUFBZSxHQUFHLElBQUksQ0FBQyxDQUFDO2FBQ2xGO1NBQ0o7YUFBTSxJQUFJLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRSxJQUFJLFFBQVEsQ0FBQyxzQkFBc0IsRUFBRSxJQUFJLFFBQVEsQ0FBQyxVQUFVLEVBQUUsSUFBSSxRQUFRLENBQUMsYUFBYSxFQUFFLEVBQUU7WUFFOUgsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQ3JCLFdBQVcsRUFDWDtnQkFDSSxNQUFNLEVBQUUsQ0FBQSxNQUFBLGFBQWEsQ0FBQyxNQUFNLENBQUMsZUFBZSwwQ0FBRSxNQUFNLEtBQUksQ0FBQztnQkFDekQsS0FBSyxFQUFFLENBQUEsTUFBQSxhQUFhLENBQUMsTUFBTSxDQUFDLGVBQWUsMENBQUUsS0FBSyxLQUFJLENBQUM7Z0JBQ3ZELFdBQVcsRUFBRSxhQUFhLENBQUMsTUFBTSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxLQUFLO2dCQUNoRyxXQUFXLEVBQUUsYUFBYSxDQUFDLE1BQU0sQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsS0FBSzthQUNuRyxFQUNELFVBQUMsS0FBSyxFQUFFLFFBQVE7Z0JBQ1osSUFBSSxLQUFLLEVBQUU7b0JBQ1AsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsRUFBRSxLQUFLLENBQUMsQ0FBQztpQkFDMUQ7WUFDTCxDQUFDLENBQ0osQ0FBQztTQUNMO2FBQU07WUFDSCxNQUFNLENBQUMsS0FBSyxDQUNSLFVBQVU7Z0JBQ1YsUUFBUSxDQUFDLE9BQU8sRUFBRTtnQkFDbEIsWUFBWTtnQkFDWixRQUFRLENBQUMsVUFBVSxFQUFFO2dCQUNyQixRQUFRO2dCQUNSLFFBQVEsQ0FBQyxTQUFTLEVBQUU7Z0JBQ3BCLG1EQUFtRCxDQUN0RCxDQUFDO1NBQ0w7SUFDTCxDQUFDO0lBS0Qsa0NBQWdCLEdBQWhCO1FBQ0ksT0FBTyxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQztJQUNuQyxDQUFDO0lBS0QsbUNBQWlCLEdBQWpCO1FBQ0ksT0FBTyxJQUFJLDZCQUFhLENBQ3BCLGlDQUFpQixDQUFDLHNCQUFzQixFQUN4QyxzR0FBc0csQ0FDekcsQ0FBQztJQUNOLENBQUM7SUFLRCwrQ0FBNkIsR0FBN0IsVUFBOEIsS0FBYSxFQUFFLFFBQWlCLEVBQUUsYUFBNkI7UUFDekYsSUFBSSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNwRCxJQUFJLFFBQVEsRUFBRTtZQUNWLGlCQUFpQixHQUFHLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFDLENBQVMsQ0FBQyxJQUFJLEVBQWYsQ0FBZSxDQUFDLENBQUM7U0FDeEU7UUFDRCxJQUFJLGtCQUFrQixHQUFHLGlCQUFpQixDQUFDLE1BQU0sQ0FBQztRQUNsRCxJQUFJLGtCQUFrQixHQUFHLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUN4QyxJQUFJLHdCQUF3QixHQUFHLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsQ0FBQyxhQUFhLEVBQUU7WUFDakIsSUFBSSx1QkFBdUIsR0FBRyxhQUFhLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNuRSxJQUFJLFFBQVEsRUFBRTtnQkFDVix1QkFBdUIsR0FBRyx1QkFBdUIsQ0FBQyxNQUFNLENBQUMsVUFBQyxDQUFDLElBQUssT0FBQyxDQUFTLENBQUMsSUFBSSxFQUFmLENBQWUsQ0FBQyxDQUFDO2FBQ3BGO1lBQ0Qsd0JBQXdCLEdBQUcsdUJBQXVCLENBQUMsTUFBTSxDQUFDO1NBQzdEO1FBQ0QsT0FBTyx3QkFBd0IsR0FBRyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUtELGdDQUFjLEdBQWQsVUFBZSxLQUFhO1FBQ3hCLElBQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsNkVBQTZFLENBQUMsQ0FBQztRQUN6RyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUU7WUFDVCxJQUFNLEdBQUcsR0FBRztnQkFDUixRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDbEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ2QsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ2xCLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNkLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNsQixNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDaEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7YUFDakIsQ0FBQztZQUVGLElBQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDaEMsSUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDbkMsS0FBSyxDQUFDLEdBQUcsQ0FBQztpQkFDVixHQUFHLENBQUMsVUFBQyxLQUFLLElBQUssT0FBQSxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFoQixDQUFnQixDQUFDO2lCQUNoQyxNQUFNLENBQUMsVUFBQyxNQUFNLEVBQUUsRUFBWTtvQkFBWCxHQUFHLFFBQUEsRUFBRSxLQUFLLFFBQUE7Z0JBQ3hCLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUM7Z0JBQ3BCLE9BQU8sTUFBTSxDQUFDO1lBQ2xCLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUVYLE9BQU87Z0JBQ0gsU0FBUyxFQUFFLFdBQVcsQ0FBQyxXQUFXLENBQUM7Z0JBQ25DLE1BQU0sRUFBRSxXQUFXLENBQUMsUUFBUSxDQUFDO2dCQUM3QixRQUFRLEVBQUUsV0FBVyxDQUFDLFVBQVUsQ0FBQztnQkFDakMsR0FBRyxFQUFFLFdBQVcsQ0FBQyxLQUFLLENBQUM7Z0JBQ3ZCLG1CQUFtQixFQUFFLFdBQVcsQ0FBQyxxQkFBcUIsQ0FBQztnQkFDdkQsZUFBZSxFQUFFLFdBQVcsQ0FBQyxpQkFBaUIsQ0FBQztnQkFDL0MsT0FBTyxFQUFFLFdBQVcsQ0FBQyxTQUFTLENBQUM7Z0JBQy9CLEtBQUssRUFBRSxHQUFHLENBQUMsUUFBUSxHQUFHLEtBQUssR0FBRyxHQUFHLENBQUMsSUFBSSxHQUFHLFdBQVc7Z0JBQ3BELE9BQU8sRUFBRSxVQUFVLEdBQUcsR0FBRyxDQUFDLElBQUk7YUFDakMsQ0FBQztTQUNMO2FBQU07WUFDSCxNQUFNLElBQUksS0FBSyxDQUFDLDZCQUFxQixLQUFLLE9BQUcsQ0FBQyxDQUFDO1NBQ2xEO0lBQ0wsQ0FBQztJQUlPLDRCQUFVLEdBQWxCLFVBQW1CLEtBQWE7UUFBaEMsaUJBK0RDO1FBOURHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixLQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxVQUFDLEtBQUs7Z0JBQ3hCLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRTtvQkFDVCxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztpQkFDeEI7cUJBQU07b0JBQ0gsSUFBTSxVQUFVLEdBQUcsS0FBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUVoRCxLQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQUMsS0FBSyxFQUFFLFFBQWdDO3dCQUN0RixJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUU7NEJBQ1QsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7eUJBQ3hCOzZCQUFNOzRCQUVILEtBQUksQ0FBQyx1QkFBdUIsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7NEJBRzlDLEtBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSx1QkFBVSxDQUFDLEtBQUksRUFBRSxRQUFRLENBQUMsQ0FBQzs0QkFHakQsSUFBTSxRQUFNLEdBQUc7Z0NBQ1gsV0FBVyxFQUFFLElBQUksS0FBSyxFQUFjO2dDQUNwQyxPQUFPLEVBQUUsSUFBSSxLQUFLLEVBQVU7NkJBQy9CLENBQUM7NEJBQ0YsSUFBTSxvQkFBb0IsR0FBOEIsUUFBUSxDQUFDLEtBQUssQ0FBQzs0QkFDdkUsb0JBQW9CLENBQUMsT0FBTyxDQUFDLFVBQUMsdUJBQWdEO2dDQUMxRSxJQUFNLFVBQVUsR0FBRyxJQUFJLHVCQUFVLENBQUMsS0FBSSxFQUFFLHVCQUF1QixDQUFDLENBQUM7Z0NBQ2pFLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFlBQVksRUFBRSxVQUFVLENBQUMsQ0FBQztnQ0FDaEUsUUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7Z0NBQ3BDLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUU7b0NBQ3JCLEtBQUksQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7b0NBQ2hFLFFBQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztpQ0FDMUM7NEJBQ0wsQ0FBQyxDQUFDLENBQUM7NEJBR0gsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEVBQUU7Z0NBQ25DLElBQUksaUNBQWUsQ0FBQyxLQUFLLEVBQUUsS0FBSSxFQUFFLG1CQUFtQixFQUFFLEtBQUksQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDOzZCQUM3RSxDQUFDLENBQUM7NEJBR0gsUUFBTSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsVUFBQyxVQUFVO2dDQUNsQyxLQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxtQkFBbUIsRUFBRTtvQ0FDbkMsSUFBSSxpQ0FBZSxDQUFDLEtBQUssRUFBRSxLQUFJLEVBQUUsbUJBQW1CLEVBQUUsVUFBVSxFQUFFLEVBQUUsQ0FBQztpQ0FDeEUsQ0FBQyxDQUFDOzRCQUNQLENBQUMsQ0FBQyxDQUFDOzRCQUdILFFBQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQUMsTUFBTTtnQ0FDMUIsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLENBQUMsSUFBSSx5QkFBVyxDQUFDLEtBQUssRUFBRSxLQUFJLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7NEJBQ3BHLENBQUMsQ0FBQyxDQUFDOzRCQUVILElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxXQUFXLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQUU7Z0NBQ3BELEtBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLGtCQUFrQixFQUFFO29DQUNsQyxJQUFJLCtCQUFjLENBQUMsS0FBSSxFQUFFLGtCQUFrQixFQUFFLFFBQVEsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLGFBQWEsQ0FBQztpQ0FDN0YsQ0FBQyxDQUFDOzZCQUNOOzRCQUVELE9BQU8sT0FBTyxFQUFFLENBQUM7eUJBQ3BCO29CQUNMLENBQUMsQ0FBQyxDQUFDO2lCQUNOO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTyxxQ0FBbUIsR0FBM0IsVUFBNEIsTUFBeUI7UUFDakQsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUU7WUFFMUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUMzQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLHNCQUFzQixFQUFFO2dCQUUvQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLHdCQUF3QixFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQzthQUMzRTtTQUNKO0lBQ0wsQ0FBQztJQUVPLHdDQUFzQixHQUE5QjtRQUNJLGFBQWEsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUN0QyxZQUFZLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVPLHNDQUFvQixHQUE1QixVQUE2QixRQUFhO1FBQ3RDLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxFQUFFO1lBQzlCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUNuQzthQUFNO1lBQ0gsT0FBTyxRQUFRLENBQUM7U0FDbkI7SUFDTCxDQUFDO0lBRVMsK0JBQWEsR0FBdkIsVUFBd0IsWUFBb0IsRUFBRSxZQUFvQjtRQUFsRSxpQkFnQkM7UUFmRyxPQUFPLElBQUksT0FBTyxDQUFhLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDM0MsSUFBTSxVQUFVLEdBQUcsS0FBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUM1RCxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUU7Z0JBRWQsT0FBTyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDOUI7aUJBQU07Z0JBQ0gsSUFBSSxLQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksS0FBSyxZQUFZLEVBQUU7b0JBRS9DLE9BQU8sT0FBTyxDQUFDLEtBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztpQkFDbkM7cUJBQU07b0JBRUgsT0FBTyxNQUFNLENBQUMsSUFBSSw2QkFBYSxDQUFDLGlDQUFpQixDQUFDLGFBQWEsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO2lCQUNuRjthQUNKO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU8scUNBQW1CLEdBQTNCLFVBQTRCLFlBQW9CLEVBQUUsU0FBaUI7UUFBbkUsaUJBbUJDO1FBbEJHLE9BQU8sSUFBSSxPQUFPLENBQWEsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMzQyxJQUFNLFVBQVUsR0FBRyxLQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzVELElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRTtnQkFFZCxPQUFPLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUM5QjtpQkFBTTtnQkFFSCxJQUFNLFlBQVksR0FDZCxvQkFBb0I7b0JBQ3BCLFlBQVk7b0JBQ1osaUJBQWlCO29CQUNqQixTQUFTO29CQUNULEtBQUs7b0JBQ0wsK0JBQStCO29CQUMvQixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUNsRCxPQUFPLE1BQU0sQ0FBQyxJQUFJLDZCQUFhLENBQUMsaUNBQWlCLENBQUMsYUFBYSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7YUFDbkY7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTyw4QkFBWSxHQUFwQixVQUFxQixLQUFhO1FBQzlCLElBQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLFNBQVMsR0FBRyxXQUFXLENBQUMsU0FBUyxDQUFDO1FBRXZDLElBQUksQ0FBQyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUU7WUFDdEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQztTQUM3QztRQUNELElBQUksQ0FBQyxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUU7WUFDeEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1NBQ2pDO1FBQ0QsSUFBSSxDQUFDLENBQUMsV0FBVyxDQUFDLEdBQUcsRUFBRTtZQUNuQixJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUM7U0FDNUI7UUFDRCxJQUFJLENBQUMsQ0FBQyxXQUFXLENBQUMsbUJBQW1CLEVBQUU7WUFDbkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsR0FBRyxXQUFXLENBQUMsbUJBQW1CLENBQUM7U0FDdkU7UUFDRCxJQUFJLENBQUMsQ0FBQyxXQUFXLENBQUMsZUFBZSxFQUFFO1lBQy9CLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxHQUFHLFdBQVcsQ0FBQyxlQUFlLENBQUM7U0FDL0Q7UUFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUMsT0FBTyxLQUFLLEtBQUssSUFBSSxXQUFXLENBQUMsT0FBTyxLQUFLLFlBQVksQ0FBQztRQUNuRyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUMsT0FBTyxLQUFLLFlBQVksQ0FBQztRQUVsRSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUM7SUFDaEQsQ0FBQztJQUVPLHlDQUF1QixHQUEvQixVQUFnQyxJQUE0QixFQUFFLEtBQWE7UUFDdkUsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQzlCLElBQUksSUFBSSxDQUFDLGdCQUFnQixJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUNuRSxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7WUFDOUIsS0FBd0IsVUFBcUIsRUFBckIsS0FBQSxJQUFJLENBQUMsZ0JBQWdCLEVBQXJCLGNBQXFCLEVBQXJCLElBQXFCLEVBQUU7Z0JBQTFDLElBQU0sU0FBUyxTQUFBO2dCQUNoQixJQUFJLFlBQVksR0FBaUI7b0JBQzdCLElBQUksRUFBRSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUM7aUJBQ3hCLENBQUM7Z0JBQ0YsTUFBTSxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3BELElBQUksU0FBUyxDQUFDLFFBQVEsSUFBSSxJQUFJLElBQUksU0FBUyxDQUFDLFVBQVUsSUFBSSxJQUFJLEVBQUU7b0JBQzVELFlBQVksQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDLFFBQVEsQ0FBQztvQkFDM0MsWUFBWSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDO29CQUMvQyxNQUFNLENBQUMsR0FBRyxDQUFDLG9CQUFvQixHQUFHLFNBQVMsQ0FBQyxRQUFRLEdBQUcsR0FBRyxHQUFHLFNBQVMsQ0FBQyxVQUFVLEdBQUcsR0FBRyxDQUFDLENBQUM7aUJBQzVGO2dCQUNELElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQzthQUMvQztTQUNKO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUMvQixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQzdDLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDN0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUNuRCxJQUFJLENBQUMsWUFBWSxHQUFHO1lBQ2hCLFNBQVMsRUFBRSxJQUFJO1lBQ2YsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLFlBQVk7WUFDNUMsY0FBYyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLFdBQVc7WUFDbEQsZUFBZSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLFdBQVc7U0FDdEQsQ0FBQztRQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsMkJBQTJCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hELElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLEVBQUU7WUFDbkIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztTQUNsQztRQUNELElBQU0sZUFBZSxHQUFXLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDdEcsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxlQUFlLElBQUksQ0FBQyxJQUFJLGVBQWUsSUFBSSxDQUFDLENBQUMsRUFBRTtZQUM1SCxNQUFNLENBQUMsS0FBSyxDQUNSLDRCQUFxQixJQUFJLENBQUMsUUFBUSxDQUFDLGNBQWMsb0NBQTBCLElBQUksQ0FBQyxPQUFPLGtDQUErQjtnQkFDdEgsZ0tBQWdLLENBQ25LLENBQUM7U0FDTDthQUFNLElBQUksZUFBZSxJQUFJLENBQUMsRUFBRTtZQUM3QixNQUFNLENBQUMsSUFBSSxDQUNQLG1DQUE0QixJQUFJLENBQUMsUUFBUSxDQUFDLGNBQWMscURBQTJDLElBQUksQ0FBQyxPQUFPLE9BQUk7Z0JBQ25ILG1JQUE0SCxXQUFXLENBQ25JLElBQUksQ0FBQyxPQUFPLENBQ2YsY0FBSSxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFNO2dCQUNwQyw2Q0FBc0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLHVFQUFvRSxDQUN6SSxDQUFDO1NBQ0w7UUFHRCwrQkFBYyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBR3JELElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ3ZCLENBQUM7SUFDTCxjQUFDO0FBQUQsQ0FuckRBLEFBbXJEQyxDQW5yRDRCLGlDQUFlLEdBbXJEM0M7QUFuckRZLDBCQUFPOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN4RHBCLG1DQUFrQztBQUlsQywyQ0FBMEM7QUFHMUMsd0VBTW1EO0FBQ25ELDJFQUEwRTtBQUMxRSw0RUFBK0Y7QUFDL0YsNEZBQTJGO0FBQzNGLG9GQUFtRjtBQUNuRixvR0FBbUc7QUFDbkcseUVBQTJGO0FBQzNGLHFFQUFvRTtBQUNwRSw0RUFBMkU7QUFDM0UsK0RBQW1FO0FBRW5FLDZCQUFvQztBQUtwQywyQkFBOEI7QUFJOUIsbURBQXNEO0FBSXRELElBQU0sTUFBTSxHQUFtQiwrQkFBYyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBSzVELElBQUksUUFBdUIsQ0FBQztBQU81QjtJQW9MSSxnQkFBWSxPQUFnQixFQUFFLE9BQTBEO1FBQXhGLGlCQTREQztRQXBKTyx3QkFBbUIsR0FBRyxLQUFLLENBQUM7UUFXcEMsZ0NBQTJCLEdBQUcsS0FBSyxDQUFDO1FBSXBDLDJCQUFzQixHQUFHLEtBQUssQ0FBQztRQUkvQixrQkFBYSxHQUFHLEtBQUssQ0FBQztRQW9CdEIsd0JBQW1CLEdBQUcsS0FBSyxDQUFDO1FBSTVCLDRCQUF1QixHQUFHLEtBQUssQ0FBQztRQUloQywrQkFBMEIsR0FBRyxLQUFLLENBQUM7UUFJbkMsbUNBQThCLEdBQUcsS0FBSyxDQUFDO1FBSXZDLDRCQUF1QixHQUFHLEtBQUssQ0FBQztRQUloQyxnQ0FBMkIsR0FBRyxLQUFLLENBQUM7UUFZcEMsT0FBRSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFrQnBCLFFBQVEsR0FBRyx3QkFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBRXZCLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUU5QixJQUFJLENBQUMsaUJBQWlCLEdBQXlCLE9BQU8sQ0FBQztZQUN2RCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7WUFDMUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDO1lBQ3JELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQztZQUNoRCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLENBQUM7WUFDaEQsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNmLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFdBQVcsQ0FBQzthQUN6RDtZQUNELElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDZixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUM7Z0JBQ3RELElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUM7Z0JBQ3hHLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDO2dCQUN4RyxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxlQUFlLENBQUM7YUFDakU7WUFDRCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7Z0JBQzFGLElBQ0ksQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsY0FBYztvQkFDOUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQ3hFO29CQUNFLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUM7aUJBQ3ZEO2dCQUNELElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQzthQUMvQztTQUNKO2FBQU07WUFFSCxJQUFJLENBQUMsa0JBQWtCLEdBQTBCLE9BQU8sQ0FBQztZQUV6RCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNuQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUVuQyxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7Z0JBQ2YsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQzthQUNqRjtZQUNELElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDZixJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsWUFBWSxDQUFDO2dCQUM5RSxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLENBQUM7Z0JBQ3ZFLElBQ0ksT0FBTyxnQkFBZ0IsS0FBSyxXQUFXO29CQUN2QyxJQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsV0FBVyxZQUFZLGdCQUFnQixFQUNyRjtvQkFDRSxJQUFJLENBQUMsV0FBVyxHQUFHLHlCQUFXLENBQUMsTUFBTSxDQUFDO2lCQUN6QztxQkFBTTtvQkFDSCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUMseUJBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLHlCQUFXLENBQUMsTUFBTSxDQUFDO2lCQUNwRjthQUNKO1lBQ0QsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRTtnQkFDdEQsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDO2FBQ3BFO1NBQ0o7UUFFRCxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxxQkFBcUIsRUFBRTs7WUFDOUIsS0FBSSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxLQUFJLENBQUMsV0FBWSxDQUFDLENBQUM7WUFDeEQsTUFBTSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsSUFBRyxNQUFBLEtBQUksQ0FBQyxXQUFXLDBDQUFFLEVBQUUsQ0FBQSxHQUFHLHVCQUF1QixHQUFHLEtBQUksQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDN0csQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBV00sMEJBQVMsR0FBaEI7UUFDSSxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQVVELDRCQUFXLEdBQVgsVUFBWSxJQUFZLEVBQUUsT0FBZTtRQUF6QyxpQkFpTUM7UUFoTUcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFPLE9BQU8sRUFBRSxNQUFNOzs7O2dCQUNyQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO29CQUNmLFdBQU8sTUFBTSxDQUNULElBQUksNkJBQWEsQ0FBQyxpQ0FBaUIsQ0FBQyxhQUFhLEVBQUUsOENBQThDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUNySCxFQUFDO2lCQUNMO2dCQUVLLGtCQUFrQixHQUFHLFVBQUMsS0FBSyxFQUFFLFlBQVk7b0JBQzNDLElBQUksS0FBSyxFQUFFO3dCQUNQLE1BQU0sQ0FBQyxLQUFLLENBQUMsbUNBQW1DLEdBQUcsS0FBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQzt3QkFDekUsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLEdBQUcsRUFBRTs0QkFDcEIsT0FBTyxNQUFNLENBQ1QsSUFBSSw2QkFBYSxDQUFDLGlDQUFpQixDQUFDLDBCQUEwQixFQUFFLDhDQUE4QyxDQUFDLENBQ2xILENBQUM7eUJBQ0w7NkJBQU07NEJBQ0gsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7eUJBQ3hCO3FCQUNKO3lCQUFNO3dCQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLEdBQUcsS0FBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO3dCQUN0RSxJQUFNLFFBQVEsR0FBVyxLQUFJLENBQUMsTUFBTyxDQUFDO3dCQUN0QyxLQUFJLENBQUMsTUFBTSxHQUFHLElBQUksZUFBTSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQzt3QkFDeEMsS0FBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsS0FBSSxDQUFDO3dCQUMxQixJQUFJLFlBQVksRUFBRTs0QkFDZCxLQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRTtnQ0FDNUMsSUFBSSx1REFBMEIsQ0FBQyxLQUFJLENBQUMsT0FBTyxFQUFFLEtBQUksRUFBRSxRQUFRLEVBQUUsS0FBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsYUFBYSxDQUFDOzZCQUNyRyxDQUFDLENBQUM7NEJBQ0gsS0FBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUU7Z0NBQ2xELElBQUksdURBQTBCLENBQUMsS0FBSSxDQUFDLGFBQWEsRUFBRSxLQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLGFBQWEsQ0FBQzs2QkFDM0csQ0FBQyxDQUFDO3lCQUNOO3dCQUNELE9BQU8sT0FBTyxDQUFDLEtBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztxQkFDL0I7Z0JBQ0wsQ0FBQyxDQUFDO2dCQUVGLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRTtvQkFHeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUU7d0JBQ2hCLFdBQU8sTUFBTSxDQUNULElBQUksNkJBQWEsQ0FDYixpQ0FBaUIsQ0FBQyx3QkFBd0IsRUFDMUMsb0VBQW9FLENBQ3ZFLENBQ0osRUFBQztxQkFDTDtvQkFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO3dCQUM3RCxXQUFPLE1BQU0sQ0FDVCxJQUFJLDZCQUFhLENBQ2IsaUNBQWlCLENBQUMsd0JBQXdCLEVBQzFDLGtIQUFrSCxDQUNySCxDQUNKLEVBQUM7cUJBQ0w7b0JBR0QsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUU7d0JBQ3RCLGVBQWEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztxQkFDdEM7eUJBQU07d0JBQ0gsZUFBYSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztxQkFDcEM7b0JBQ0QsSUFBSSxDQUFDLGVBQWEsRUFBRTt3QkFDaEIsV0FBTyxNQUFNLENBQ1QsSUFBSSw2QkFBYSxDQUNiLGlDQUFpQixDQUFDLHdCQUF3QixFQUMxQyxnS0FBZ0ssQ0FDbkssQ0FDSixFQUFDO3FCQUNMO29CQUVLLGdCQUFjLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLGVBQWEsQ0FBQyxDQUFDO29CQUMvRCxJQUFJLGFBQVcsQ0FBQyxPQUFPLEtBQUssS0FBSyxJQUFJLGFBQVcsQ0FBQyxPQUFPLEtBQUssWUFBWSxFQUFFO3dCQUN2RSxXQUFPLE1BQU0sQ0FDVCxJQUFJLDZCQUFhLENBQ2IsaUNBQWlCLENBQUMsd0JBQXdCLEVBQzFDLGdGQUFnRixDQUNuRixDQUNKLEVBQUM7cUJBQ0w7b0JBRUQsZUFBYSxHQUFHLGtCQUFrQixDQUFDLElBQUksQ0FBQyxlQUFhLENBQUMsQ0FBQyxDQUFDO29CQUV4RCxNQUFNLENBQUMsSUFBSSxDQUFDLHdDQUF3QyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFFaEUsc0JBQW9COzs7Ozs7b0NBRVosRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsR0FBRyxHQUFHLElBQUEsU0FBTSxHQUFFLENBQUM7b0NBQ3BDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxXQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7b0NBQzdDLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBcUIsQ0FBQztvQ0FFM0YsVUFBVSxDQUFDLEVBQUUsR0FBRyxpQkFBaUIsQ0FBQyxpQkFBaUIsQ0FBQyxtQkFBbUIsR0FBRyxFQUFFLENBQUM7b0NBQzdFLFVBQVUsQ0FBQyxTQUFTLEdBQUcsZ0JBQWdCLENBQUM7b0NBQ3hDLFVBQVUsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO29DQUN4QixJQUFJLENBQUMsK0JBQStCLEdBQUcsRUFBRSxVQUFVLFlBQUEsRUFBRSxnQkFBZ0Isa0JBQUEsRUFBRSxDQUFDO29DQUd4RSxpQkFBaUIsQ0FBQyxpQkFBaUIsQ0FBQyxlQUFlLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO29DQUV2RSxpQkFBaUIsQ0FBQyxpQkFBaUIsQ0FBQyxrQ0FBa0MsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUM7b0NBRXZGLFdBQU0sVUFBVSxDQUFDLElBQUksRUFBRSxFQUFBOztvQ0FBdkIsU0FBdUIsQ0FBQztvQ0FHbEIsRUFBRSxHQUFHLElBQUksaUJBQWlCLENBQUMsaUJBQWlCLENBQUM7d0NBQy9DLEVBQUUsSUFBQTt3Q0FDRixpQkFBaUIsRUFBRSxJQUFJLEdBQUcsQ0FBQyxhQUFXLENBQUMsT0FBTyxDQUFDO3dDQUMvQyxhQUFhLGlCQUFBO3dDQUNiLFVBQVUsRUFBRSxVQUFVO3dDQUN0QixlQUFlLEVBQUUsUUFBUTt3Q0FDekIsZUFBZSxFQUFFLEVBQUU7cUNBQ3RCLENBQUMsQ0FBQztvQ0FFQyxhQUFhLFNBQWtCLENBQUM7b0NBQzVCLEtBQUEsSUFBSSxDQUFBOzs2Q0FDSCxTQUFTLENBQUMsQ0FBVixjQUFTOzZDQUlULFVBQVUsQ0FBQyxDQUFYLGNBQVU7Ozt3Q0FISyxXQUFNLEVBQUUsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLEVBQUE7O29DQUFoRCxhQUFhLEdBQUcsU0FBZ0MsQ0FBQztvQ0FDakQsY0FBTTt3Q0FHVSxXQUFNLEVBQUUsQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLEVBQUE7O29DQUFqRCxhQUFhLEdBQUcsU0FBaUMsQ0FBQztvQ0FDbEQsY0FBTTt3Q0FHTixNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxHQUFHLElBQUksQ0FBQyxDQUFDOztvQ0FHdEUsSUFBSSxDQUFDLDZCQUE2QixHQUFHLEVBQUUsRUFBRSxJQUFBLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxDQUFDO29DQUVsRSxVQUFVLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7b0NBRWxDLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUU7d0NBQzNCLElBQUksQ0FBQyxhQUFhLENBQUMseUJBQXlCLENBQ3ZDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxLQUFLLENBQUMsU0FBeUIsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFDdkYsS0FBSyxDQUNSLENBQUM7cUNBQ0w7eUNBQU07d0NBQ0YsSUFBSSxDQUFDLGFBQTJCLENBQUMsZUFBZSxDQUM1QyxJQUFJLENBQUMsNkJBQTZCLENBQUMsS0FBSyxDQUFDLFNBQXlCLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQ3ZGLEtBQUssQ0FDUixDQUFDO3FDQUNMO29DQUVELGtCQUFrQixDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQzs7OztvQ0FFckMsSUFBSSxPQUFLLENBQUMsSUFBSSxLQUFLLGlDQUFpQixDQUFDLHdCQUF3QixFQUFFO3dDQUMzRCxrQkFBa0IsQ0FBQyxJQUFJLDZCQUFhLENBQUMsaUNBQWlCLENBQUMsd0JBQXdCLEVBQUUsT0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO3FDQUMzRzt5Q0FBTTt3Q0FDSCxrQkFBa0IsQ0FBQyxPQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7cUNBQ3BDOzs7Ozt5QkFFUixDQUFDO29CQUdGLElBQUksT0FBTyxpQkFBaUIsS0FBSyxXQUFXLEVBQUU7d0JBQ3RDLE1BQU0sR0FBc0IsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQzt3QkFDakUsTUFBTSxDQUFDLElBQUksR0FBRyxpQkFBaUIsQ0FBQzt3QkFDaEMsTUFBTSxDQUFDLEdBQUcsR0FBRyxhQUFXLENBQUMsT0FBTyxHQUFHLG9FQUFvRSxHQUFHLGVBQWEsQ0FBQzt3QkFDeEgsTUFBTSxDQUFDLE1BQU0sR0FBRzs7Ozs7O3dDQUVSLFdBQU0sbUJBQWlCLEVBQUUsRUFBQTs7d0NBQXpCLFNBQXlCLENBQUM7d0NBQzFCLE9BQU8sQ0FBQyxJQUFJLGVBQU0sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQzs7Ozt3Q0FFbkMsTUFBTSxDQUFDLE9BQUssQ0FBQyxDQUFDOzs7Ozs2QkFFckIsQ0FBQzt3QkFDRixRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztxQkFDckM7eUJBQU07d0JBQ0gsbUJBQWlCLEVBQUU7NkJBQ2QsSUFBSSxDQUFDLGNBQU0sT0FBQSxPQUFPLENBQUMsSUFBSSxlQUFNLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDLEVBQWxDLENBQWtDLENBQUM7NkJBQzlDLEtBQUssQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQztxQkFDeEM7aUJBQ0o7cUJBQU07b0JBR0gsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsRUFBRTt3QkFDbEMsV0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLEVBQUM7cUJBQ25EO29CQUVELE1BQU0sQ0FBQyxJQUFJLENBQUMsbUNBQW1DLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUNqRSxPQUFPLEdBQUcsT0FBTyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQ3JDLGFBQWEsR0FBRyxPQUFPLENBQUM7b0JBQzVCLElBQUksT0FBTyxhQUFhLEtBQUssUUFBUSxFQUFFO3dCQUNuQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztxQkFDakQ7b0JBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUM3QixhQUFhLEVBQ2IsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLE1BQUEsRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLEVBQ3pELFVBQUMsS0FBSyxFQUFFLFFBQVE7d0JBQ1osa0JBQWtCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO29CQUNwQyxDQUFDLENBQ0osQ0FBQztpQkFDTDs7O2FBQ0osQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQU9LLDZCQUFZLEdBQWxCOzs7OzRCQUNXLFdBQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsRUFBQTs0QkFBeEMsV0FBTyxTQUFpQyxFQUFDOzs7O0tBQzVDO0lBT0QscUNBQW9CLEdBQXBCO1FBQ0ksT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBT0QsK0JBQWMsR0FBZDtRQUNJLE9BQU8sSUFBSSxDQUFDLFdBQVksQ0FBQztJQUM3QixDQUFDO0lBT0QsZ0NBQWUsR0FBZixVQUFnQixXQUFvQjtRQUFwQyxpQkF5RUM7UUF4RUcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFPLE9BQU8sRUFBRSxNQUFNOzs7Ozs7O3dCQUMvQixtQkFBbUIsR0FBRyxVQUFDLEtBQUssRUFBRSxZQUFZOzRCQUM1QyxJQUFJLEtBQUssRUFBRTtnQ0FDUCxPQUFPLEtBQUksQ0FBQyxNQUFNLENBQUM7Z0NBQ25CLE1BQU0sQ0FBQyxLQUFLLENBQUMsbUNBQW1DLEdBQUcsS0FBSSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztnQ0FDekUsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLEdBQUcsRUFBRTtvQ0FDcEIsT0FBTyxNQUFNLENBQ1QsSUFBSSw2QkFBYSxDQUFDLGlDQUFpQixDQUFDLDBCQUEwQixFQUFFLCtDQUErQyxDQUFDLENBQ25ILENBQUM7aUNBQ0w7cUNBQU07b0NBQ0gsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7aUNBQ3hCOzZCQUNKO2lDQUFNO2dDQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMsMENBQTBDLEdBQUcsS0FBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dDQUN4RSxJQUFNLFFBQVEsR0FBRyxLQUFJLENBQUMsTUFBTyxDQUFDO2dDQUM5QixPQUFPLEtBQUksQ0FBQyxNQUFNLENBQUM7Z0NBQ25CLElBQUksWUFBWSxFQUFFO29DQUNkLEtBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLHVCQUF1QixFQUFFO3dDQUM1QyxJQUFJLHVEQUEwQixDQUFDLEtBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSSxFQUFFLFFBQVEsRUFBRSxLQUFJLENBQUMsTUFBTyxFQUFFLFFBQVEsRUFBRSxhQUFhLENBQUM7cUNBQ3RHLENBQUMsQ0FBQztvQ0FDSCxLQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRTt3Q0FDbEQsSUFBSSx1REFBMEIsQ0FBQyxLQUFJLENBQUMsYUFBYSxFQUFFLEtBQUksRUFBRSxRQUFRLEVBQUUsS0FBSSxDQUFDLE1BQU8sRUFBRSxRQUFRLEVBQUUsYUFBYSxDQUFDO3FDQUM1RyxDQUFDLENBQUM7aUNBQ047Z0NBQ0QsT0FBTyxPQUFPLEVBQUUsQ0FBQzs2QkFDcEI7d0JBQ0wsQ0FBQyxDQUFDOzZCQUVFLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFiLGVBQWE7NkJBR1QsQ0FBQSxNQUFBLElBQUksQ0FBQyxNQUFNLDBDQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUEsRUFBbkMsY0FBbUM7Ozs7d0JBSXpCLGdCQUFnQixHQUFHLElBQUksQ0FBQywrQkFBZ0MsQ0FBQyxnQkFBZ0IsQ0FBQzs2QkFDNUUsQ0FBQyxXQUFXLEVBQVosY0FBWTs2QkFDUixJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBekIsY0FBeUI7d0JBQ3pCLElBQUksQ0FBQyxhQUFhLENBQUMseUJBQXlCLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7OzRCQUUxRixXQUFPLElBQUksQ0FBQyxhQUEyQixDQUFDLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsRUFBQTs7d0JBQXBHLFNBQW9HLENBQUM7Ozs7d0JBR3pHLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLEtBQUssQ0FBQyxJQUFJLEVBQUUsRUFBWixDQUFZLENBQUMsQ0FBQzs7O3dCQUdsRSxJQUFJLENBQUMsNkJBQThCLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO3dCQUVqRCxPQUFPLElBQUksQ0FBQyw2QkFBNkIsQ0FBQzt3QkFDMUMsT0FBTyxJQUFJLENBQUMsK0JBQStCLENBQUM7d0JBRTVDLFdBQU8sbUJBQW1CLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxFQUFDOzs7d0JBRTdDLFdBQU8sbUJBQW1CLENBQUMsT0FBSyxFQUFFLEtBQUssQ0FBQyxFQUFDOzs7d0JBSzdDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixFQUFFLEVBQUU7NEJBQ2xDLFdBQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxFQUFDO3lCQUNuRDt3QkFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLDRCQUE0QixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzt3QkFDMUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsVUFBQyxLQUFLLEVBQUUsUUFBUTs0QkFDM0YsT0FBTyxtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7d0JBQzVDLENBQUMsQ0FBQyxDQUFDOzs7NkJBSVAsV0FBTyxNQUFNLENBQUMsSUFBSSw2QkFBYSxDQUFDLGlDQUFpQixDQUFDLGFBQWEsRUFBRSxTQUFTLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyx3QkFBd0IsQ0FBQyxDQUFDLEVBQUM7Ozs7YUFFL0gsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELCtCQUFjLEdBQWQsVUFBZSxXQUF3QjtRQUNuQyxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztJQUNuQyxDQUFDO0lBS0QsMENBQXlCLEdBQXpCO1FBQ0ksSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMscUJBQXFCLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUtELDhCQUFhLEdBQWI7UUFDSSxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDM0IsQ0FBQztJQUtELG9DQUFtQixHQUFuQixVQUFvQixLQUFjO1FBQzlCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxLQUFLLENBQUM7SUFDckMsQ0FBQztJQUtELHlDQUF3QixHQUF4QixVQUF5QixrQkFBeUM7UUFDOUQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLGtCQUFrQixDQUFDO0lBQ2pELENBQUM7SUFLRCwwQkFBUyxHQUFUO1FBQUEsaUJBTUM7UUFMRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsS0FBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQztpQkFDNUIsSUFBSSxDQUFDLGNBQU0sT0FBQSxPQUFPLEVBQUUsRUFBVCxDQUFTLENBQUM7aUJBQ3JCLEtBQUssQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQztRQUN6QyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLRCx3QkFBTyxHQUFQO1FBQUEsaUJBY0M7UUFiRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBSSxLQUFJLENBQUMsMkJBQTJCLEVBQUU7Z0JBQ2xDLEtBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUM7cUJBQ3pCLElBQUksQ0FBQyxjQUFNLE9BQUEsT0FBTyxFQUFFLEVBQVQsQ0FBUyxDQUFDO3FCQUNyQixLQUFLLENBQUMsVUFBQyxLQUFLLElBQUssT0FBQSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQWIsQ0FBYSxDQUFDLENBQUM7YUFDeEM7aUJBQU07Z0JBQ0gsS0FBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMseUJBQXlCLEVBQUU7b0JBQ3BDLEtBQUksQ0FBQyxPQUFPLEVBQUU7eUJBQ1QsSUFBSSxDQUFDLGNBQU0sT0FBQSxPQUFPLEVBQUUsRUFBVCxDQUFTLENBQUM7eUJBQ3JCLEtBQUssQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQztnQkFDekMsQ0FBQyxDQUFDLENBQUM7YUFDTjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELGtDQUFpQixHQUFqQjtRQUNJLElBQUksUUFBUSxDQUFDO1FBQ2IsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNuQixJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQzFCLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1NBQ3RDO1FBQ0QsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sQ0FBQyxJQUFJLENBQ1AsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQztZQUN0RCw2QkFBNkI7WUFDN0IsUUFBUTtZQUNSLDJCQUEyQjtZQUMzQixJQUFJLENBQUMsUUFBUTtZQUNiLGlCQUFpQixDQUNwQixDQUFDO0lBQ04sQ0FBQztJQUtLLG1DQUFrQixHQUF4Qjs7Ozs7OzZCQUNRLENBQUEsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFBLEVBQW5ELGNBQW1EOzs7O3dCQUUvQyxXQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUE7O3dCQUFoQyxTQUFnQyxDQUFDO3dCQUNqQyxPQUFPLENBQUMsS0FBSyxDQUFDLGdFQUF5RCxJQUFJLENBQUMsUUFBUSxDQUFFLENBQUMsQ0FBQzs7Ozt3QkFFeEYsT0FBTyxDQUFDLEtBQUssQ0FBQyw4REFBdUQsSUFBSSxDQUFDLFFBQVEsQ0FBRSxFQUFFLE9BQUssQ0FBQyxDQUFDOzs7d0JBR3JHLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTs0QkFDbEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxPQUFPLENBQUMsVUFBQyxLQUFLO2dDQUM1QyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7NEJBQ2pCLENBQUMsQ0FBQyxDQUFDOzRCQUNILElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztnQ0FDNUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDOzRCQUNqQixDQUFDLENBQUMsQ0FBQzs0QkFDSCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7eUJBQzNCO3dCQUVELElBQUksSUFBSSxDQUFDLHNDQUFzQyxFQUFFOzRCQUM3QyxJQUFJLENBQUMsc0NBQXNDLENBQUMsY0FBYyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztnQ0FDdkUsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDOzRCQUNqQixDQUFDLENBQUMsQ0FBQzs0QkFDSCxJQUFJLENBQUMsc0NBQXNDLENBQUMsY0FBYyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQUMsS0FBSztnQ0FDdkUsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDOzRCQUNqQixDQUFDLENBQUMsQ0FBQzs0QkFDSCxPQUFPLElBQUksQ0FBQyxzQ0FBc0MsQ0FBQzt5QkFDdEQ7d0JBQ0QsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTs0QkFDcEIsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUU7Z0NBQ3pCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7NkJBQzNCOzRCQUNELE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQzt5QkFDM0I7d0JBQ0QsTUFBTSxDQUFDLElBQUksQ0FDUCxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEdBQUcscUNBQXFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxtQkFBbUIsQ0FDbkksQ0FBQzs7Ozs7S0FDTDtJQUtELGdDQUFlLEdBQWY7UUFDSSxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztJQUNwQyxDQUFDO0lBS0QsNEJBQVcsR0FBWDtRQUNJLE9BQU8sQ0FDSCxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQjtZQUN6QixJQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsV0FBVyxLQUFLLElBQUk7WUFDaEUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLFdBQVcsS0FBSyxLQUFLLENBQ3BFLENBQUM7SUFDTixDQUFDO0lBS0QsNEJBQVcsR0FBWDtRQUNJLE9BQU8sQ0FDSCxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQjtZQUN6QixJQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsV0FBVyxLQUFLLElBQUk7WUFDaEUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLFdBQVcsS0FBSyxLQUFLLENBQ3BFLENBQUM7SUFDTixDQUFDO0lBS0QsNkJBQVksR0FBWjtRQUNJLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLEtBQUssUUFBUSxDQUFDO1FBQ2xGLElBQUksUUFBUSxDQUFDLFVBQVUsRUFBRSxFQUFFO1lBQ3ZCLE1BQU07Z0JBQ0YsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsV0FBVyxLQUFLLFFBQVE7b0JBQzNFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ3JGO1FBQ0QsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixJQUFJLE1BQU0sQ0FBQztJQUMvQyxDQUFDO0lBS0Qsd0NBQXVCLEdBQXZCO1FBQUEsaUJBY0M7UUFiRyxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ2pELElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7WUFDaEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsVUFBVSxFQUFFO2dCQUM1QixLQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyx3QkFBd0IsRUFBRTtvQkFDN0MsSUFBSSwrQ0FBc0IsQ0FBQyxLQUFJLENBQUMsT0FBTyxFQUFFLHdCQUF3QixFQUFFLEtBQUksQ0FBQyxVQUFVLEVBQUUsS0FBSSxDQUFDLFFBQVEsQ0FBQztpQkFDckcsQ0FBQyxDQUFDO2dCQUNILEtBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLHdCQUF3QixFQUFFO29CQUNuRCxJQUFJLCtDQUFzQixDQUFDLEtBQUksQ0FBQyxhQUFhLEVBQUUsd0JBQXdCLEVBQUUsS0FBSSxDQUFDLFVBQVUsRUFBRSxLQUFJLENBQUMsUUFBUSxDQUFDO2lCQUMzRyxDQUFDLENBQUM7Z0JBQ0gsS0FBSSxDQUFDLHVCQUF1QixHQUFHLEtBQUssQ0FBQztZQUN6QyxDQUFDLENBQUMsQ0FBQztTQUNOO0lBQ0wsQ0FBQztJQUtELDRDQUEyQixHQUEzQjtRQUFBLGlCQWlCQztRQWhCRyxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLHVCQUF1QixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3JELElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUM7WUFDcEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFO2dCQUM5QixJQUFJLEtBQUksQ0FBQyx1QkFBdUIsRUFBRTtvQkFFOUIsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsd0JBQXdCLEVBQUU7d0JBQzdDLElBQUksK0NBQXNCLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxLQUFJLENBQUMsVUFBVSxFQUFFLEtBQUksQ0FBQyxRQUFRLENBQUM7cUJBQ3JHLENBQUMsQ0FBQztvQkFDSCxLQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyx3QkFBd0IsRUFBRTt3QkFDbkQsSUFBSSwrQ0FBc0IsQ0FBQyxLQUFJLENBQUMsYUFBYSxFQUFFLHdCQUF3QixFQUFFLEtBQUksQ0FBQyxVQUFVLEVBQUUsS0FBSSxDQUFDLFFBQVEsQ0FBQztxQkFDM0csQ0FBQyxDQUFDO2lCQUNOO2dCQUNELEtBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4QyxDQUFDLENBQUMsQ0FBQztTQUNOO0lBQ0wsQ0FBQztJQUtELHlDQUF3QixHQUF4QixVQUF5QixjQUF1QjtRQUM1QyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3BCLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxLQUFLLENBQUM7WUFDckMsSUFBSSxjQUFjLEVBQUU7Z0JBQ2hCLElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFO29CQUUxQixPQUFPO2lCQUNWO2FBQ0o7aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLG1CQUFtQixHQUFHLEtBQUssQ0FBQzthQUNwQztZQUVELElBQ0ksSUFBSSxDQUFDLHVCQUF1QjtnQkFDNUIsSUFBSSxDQUFDLDJCQUEyQjtnQkFDaEMsSUFBSSxDQUFDLDBCQUEwQjtnQkFDL0IsSUFBSSxDQUFDLDhCQUE4QixFQUNyQztnQkFFRSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUNwQztpQkFBTTtnQkFFSCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN4QixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7YUFDM0I7U0FDSjtJQUNMLENBQUM7SUFLRCwrQ0FBOEIsR0FBOUI7UUFBQSxpQkFjQztRQWJHLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDeEQsSUFBSSxDQUFDLDBCQUEwQixHQUFHLElBQUksQ0FBQztZQUN2QyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsRUFBRTtnQkFDcEMsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUU7b0JBQzVDLElBQUksK0NBQXNCLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxLQUFJLENBQUMsVUFBVSxFQUFFLEtBQUksQ0FBQyxRQUFRLENBQUM7aUJBQ3BHLENBQUMsQ0FBQztnQkFDSCxLQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRTtvQkFDbEQsSUFBSSwrQ0FBc0IsQ0FBQyxLQUFJLENBQUMsYUFBYSxFQUFFLHVCQUF1QixFQUFFLEtBQUksQ0FBQyxVQUFVLEVBQUUsS0FBSSxDQUFDLFFBQVEsQ0FBQztpQkFDMUcsQ0FBQyxDQUFDO2dCQUNILEtBQUksQ0FBQyw4QkFBOEIsR0FBRyxLQUFLLENBQUM7WUFDaEQsQ0FBQyxDQUFDLENBQUM7U0FDTjtJQUNMLENBQUM7SUFLRCxtREFBa0MsR0FBbEM7UUFBQSxpQkFpQkM7UUFoQkcsSUFBSSxDQUFDLDBCQUEwQixFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLElBQUksQ0FBQyw4QkFBOEIsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUM1RCxJQUFJLENBQUMsOEJBQThCLEdBQUcsSUFBSSxDQUFDO1lBQzNDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFO2dCQUN0QyxJQUFJLEtBQUksQ0FBQyw4QkFBOEIsRUFBRTtvQkFFckMsS0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUU7d0JBQzVDLElBQUksK0NBQXNCLENBQUMsS0FBSSxDQUFDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxLQUFJLENBQUMsVUFBVSxFQUFFLEtBQUksQ0FBQyxRQUFRLENBQUM7cUJBQ3BHLENBQUMsQ0FBQztvQkFDSCxLQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRTt3QkFDbEQsSUFBSSwrQ0FBc0IsQ0FBQyxLQUFJLENBQUMsYUFBYSxFQUFFLHVCQUF1QixFQUFFLEtBQUksQ0FBQyxVQUFVLEVBQUUsS0FBSSxDQUFDLFFBQVEsQ0FBQztxQkFDMUcsQ0FBQyxDQUFDO2lCQUNOO2dCQUNELEtBQUksQ0FBQywrQkFBK0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMvQyxDQUFDLENBQUMsQ0FBQztTQUNOO0lBQ0wsQ0FBQztJQUtELGdEQUErQixHQUEvQixVQUFnQyxjQUF1QjtRQUNuRCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3BCLElBQUksQ0FBQyw4QkFBOEIsR0FBRyxLQUFLLENBQUM7WUFDNUMsSUFBSSxjQUFjLEVBQUU7Z0JBQ2hCLElBQUksSUFBSSxDQUFDLDBCQUEwQixFQUFFO29CQUdqQyxPQUFPO2lCQUNWO2FBQ0o7aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLDBCQUEwQixHQUFHLEtBQUssQ0FBQzthQUMzQztZQUVELElBQ0ksSUFBSSxDQUFDLHVCQUF1QjtnQkFDNUIsSUFBSSxDQUFDLDJCQUEyQjtnQkFDaEMsSUFBSSxDQUFDLG1CQUFtQjtnQkFDeEIsSUFBSSxDQUFDLHVCQUF1QixFQUM5QjtnQkFFRSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO2FBQzVDO2lCQUFNO2dCQUVILElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3hCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQzthQUMzQjtTQUNKO0lBQ0wsQ0FBQztJQUtELDRDQUEyQixHQUEzQixVQUE0QixLQUFjO1FBQTFDLGlCQWlCQztRQWhCRyxJQUFJLElBQUksQ0FBQywwQkFBMEIsRUFBRSxFQUFFO1lBQ25DLElBQUksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLElBQUksS0FBSyxFQUFFO2dCQUN4QyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxDQUFDO2dCQUNwQyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxlQUFlLEVBQUUsVUFBQyxTQUFTO29CQUMzQyxJQUFNLFFBQVEsR0FBRyxLQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQztvQkFDakQsSUFBTSxLQUFLLEdBQUcsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFFBQVEsVUFBQSxFQUFFLENBQUM7b0JBQ2hELEtBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxHQUFHLFNBQVMsQ0FBQztvQkFDNUMsS0FBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMseUJBQXlCLEVBQUU7d0JBQ3BELElBQUksdUNBQWtCLENBQUMsS0FBSSxDQUFDLGFBQWEsRUFBRSx5QkFBeUIsRUFBRSxLQUFLLENBQUM7cUJBQy9FLENBQUMsQ0FBQztnQkFDUCxDQUFDLENBQUMsQ0FBQzthQUNOO1NBQ0o7YUFBTTtZQUVILElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUM7U0FDdkM7SUFDTCxDQUFDO0lBS0QsZ0RBQStCLEdBQS9CLFVBQWdDLEtBQWM7UUFBOUMsaUJBa0JDO1FBakJHLElBQUksSUFBSSxDQUFDLDBCQUEwQixFQUFFLEVBQUU7WUFDbkMsSUFBSSxDQUFDLElBQUksQ0FBQywyQkFBMkIsSUFBSSxLQUFLLEVBQUU7Z0JBQzVDLElBQUksQ0FBQywyQkFBMkIsR0FBRyxJQUFJLENBQUM7Z0JBQ3hDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxVQUFDLFNBQVM7b0JBQzdDLElBQU0sUUFBUSxHQUFHLEtBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDO29CQUNqRCxJQUFNLEtBQUssR0FBRyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsUUFBUSxVQUFBLEVBQUUsQ0FBQztvQkFDaEQsS0FBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDO29CQUM1QyxLQUFJLENBQUMsNEJBQTRCLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ3hDLEtBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLHlCQUF5QixFQUFFO3dCQUNwRCxJQUFJLHVDQUFrQixDQUFDLEtBQUksQ0FBQyxhQUFhLEVBQUUseUJBQXlCLEVBQUUsS0FBSyxDQUFDO3FCQUMvRSxDQUFDLENBQUM7Z0JBQ1AsQ0FBQyxDQUFDLENBQUM7YUFDTjtTQUNKO2FBQU07WUFFSCxJQUFJLENBQUMsMkJBQTJCLEdBQUcsSUFBSSxDQUFDO1NBQzNDO0lBQ0wsQ0FBQztJQUtELDZDQUE0QixHQUE1QixVQUE2QixjQUF1QjtRQUNoRCxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3BCLElBQUksQ0FBQywyQkFBMkIsR0FBRyxLQUFLLENBQUM7WUFDekMsSUFBSSxjQUFjLEVBQUU7Z0JBQ2hCLElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFO29CQUc5QixPQUFPO2lCQUNWO2FBQ0o7aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLHVCQUF1QixHQUFHLEtBQUssQ0FBQzthQUN4QztZQUVELElBQ0ksSUFBSSxDQUFDLG1CQUFtQjtnQkFDeEIsSUFBSSxDQUFDLHVCQUF1QjtnQkFDNUIsSUFBSSxDQUFDLDBCQUEwQjtnQkFDL0IsSUFBSSxDQUFDLDhCQUE4QixFQUNyQztnQkFFRSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsQ0FBQzthQUN6QztpQkFBTTtnQkFFSCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN4QixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7YUFDM0I7U0FDSjtJQUNMLENBQUM7SUFLRCx3QkFBTyxHQUFQO1FBRUksT0FBTyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDO0lBQ2hFLENBQUM7SUFLRCx3Q0FBdUIsR0FBdkI7UUFBQSxpQkFPQztRQU5HLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixLQUFJLENBQUMsV0FBVztpQkFDWCwyQkFBMkIsRUFBRTtpQkFDN0IsSUFBSSxDQUFDLFVBQUMsTUFBTSxJQUFLLE9BQUEsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFmLENBQWUsQ0FBQztpQkFDakMsS0FBSyxDQUFDLFVBQUMsS0FBSyxJQUFLLE9BQUEsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFiLENBQWEsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELDBDQUF5QixHQUF6QjtRQUNJLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxxQkFBcUIsQ0FBQztJQUNqRCxDQUFDO0lBS0QseUNBQXdCLEdBQXhCO1FBQ0ksT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDO0lBQ2hELENBQUM7SUFLRCwrQ0FBOEIsR0FBOUI7UUFDSSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLEVBQUU7WUFDdkQsT0FBTyxLQUFLLENBQUM7U0FDaEI7UUFDRCxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMscUJBQXFCLENBQUMsc0NBQXNDLEVBQUU7WUFDeEcsTUFBTSxDQUFDLElBQUksQ0FDUCx1SEFBOEcsSUFBSSxDQUFDLFFBQVEsZUFDdEgsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFlBQVksZ0NBQTZCLENBQ2hGLENBQUM7WUFDRixPQUFPLElBQUksQ0FBQztTQUNmO1FBQ0QsSUFBTSxrQkFBa0IsR0FBMEIsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsa0JBQWtCLENBQUM7UUFDakcsT0FBTyxrQkFBa0IsS0FBSyxXQUFXLElBQUksa0JBQWtCLEtBQUssV0FBVyxDQUFDO0lBQ3BGLENBQUM7SUFJTywyQ0FBMEIsR0FBbEM7UUFDSSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNuQixJQUFNLFdBQVcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVc7b0JBQ2xDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVztvQkFDbEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLDhCQUE4QixJQUFJLEVBQUUsQ0FBQztnQkFDdkYsV0FBVyxDQUFDLFFBQVEsR0FBRyxPQUFPLFdBQVcsQ0FBQyxRQUFRLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7Z0JBQzdGLFdBQVcsQ0FBQyxTQUFTLEdBQUcsT0FBTyxXQUFXLENBQUMsU0FBUyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ2hHLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsV0FBVyxDQUFDLENBQUM7YUFDMUQ7WUFDRCxPQUFPLElBQUksQ0FBQztTQUNmO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztJQUtELDhDQUE2QixHQUE3QixVQUE4QixPQUFrRCxFQUFFLE1BQThCO1FBQzVHLElBQUksSUFBSSxDQUFDLHdCQUF3QixJQUFJLFNBQVMsRUFBRTtZQUU1QyxJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNuRCxPQUFPLEtBQUssQ0FBQztTQUNoQjthQUFNO1lBRUgsT0FBTyxDQUFDLElBQUksQ0FDUixxQ0FBOEIsSUFBSSxDQUFDLFFBQVEsZUFBSyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsWUFBWSw2RUFDakIsQ0FDN0UsQ0FBQztZQUNGLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLGNBQU0sT0FBQSxPQUFPLEVBQUUsRUFBVCxDQUFTLENBQUMsQ0FBQztZQUMvRCxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxVQUFDLEtBQUssSUFBSyxPQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQztZQUN0RSxPQUFPLElBQUksQ0FBQztTQUNmO0lBQ0wsQ0FBQztJQUtELG1DQUFrQixHQUFsQixVQUFtQixTQUFrQjtRQUFyQyxpQkF1SkM7UUF0SkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNOztZQUMvQixJQUFJLFNBQVMsRUFBRTtnQkFDWCxJQUFJLEtBQUksQ0FBQyw2QkFBNkIsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLEVBQUU7b0JBRXJELE9BQU87aUJBQ1Y7YUFDSjtpQkFBTTtnQkFFSCxLQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDekI7WUFFRCxJQUFNLFlBQVksR0FBRzs7Z0JBQ2pCLElBQUksU0FBUyxFQUFFO29CQUNYLE1BQUEsS0FBSSxDQUFDLHdCQUF3QiwwQ0FBRSxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBQ3BELE9BQU8sS0FBSSxDQUFDLHdCQUF3QixDQUFDO2lCQUN4QztnQkFDRCxPQUFPLE9BQU8sRUFBRSxDQUFDO1lBQ3JCLENBQUMsQ0FBQztZQUVGLElBQU0sV0FBVyxHQUFHLFVBQUMsS0FBSzs7Z0JBQ3RCLElBQUksU0FBUyxFQUFFO29CQUNYLE1BQUEsS0FBSSxDQUFDLHdCQUF3QiwwQ0FBRSxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztvQkFDM0QsT0FBTyxLQUFJLENBQUMsd0JBQXdCLENBQUM7aUJBQ3hDO2dCQUNELE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3pCLENBQUMsQ0FBQztZQUVGLElBQU0sb0JBQW9CLEdBQUcsVUFBQyxhQUFhO2dCQUN2QyxNQUFNLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxHQUFHLEtBQUksQ0FBQyxRQUFRLEVBQUUsYUFBYSxDQUFDLENBQUM7Z0JBRWhGLElBQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQztnQkFDOUQsSUFBSSxNQUFNLENBQUM7Z0JBQ1gsSUFBSSxTQUFTLEVBQUU7b0JBQ1gsTUFBTSxHQUFHO3dCQUNMLE1BQU0sRUFBRSxLQUFJLENBQUMsUUFBUTt3QkFDckIsU0FBUyxFQUFFLGFBQWE7cUJBQzNCLENBQUM7aUJBQ0w7cUJBQU07b0JBQ0gsSUFBSSxXQUFXLFNBQUEsQ0FBQztvQkFDaEIsSUFBSSxLQUFJLENBQUMsV0FBVyxFQUFFLEVBQUU7d0JBQ3BCLFdBQVc7NEJBQ1AsT0FBTyxnQkFBZ0IsS0FBSyxXQUFXO2dDQUNuQyxLQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsV0FBVyxZQUFZLGdCQUFnQjtnQ0FDbkYsQ0FBQyxDQUFDLHlCQUFXLENBQUMsTUFBTTtnQ0FDcEIsQ0FBQyxDQUFDLEtBQUksQ0FBQyxZQUFZLEVBQUU7b0NBQ2pCLENBQUMsQ0FBQyx5QkFBVyxDQUFDLE1BQU07b0NBQ3BCLENBQUMsQ0FBQyx5QkFBVyxDQUFDLE1BQU0sQ0FBQztxQkFDcEM7b0JBQ0QsTUFBTSxHQUFHO3dCQUNMLFVBQVUsRUFBRSxLQUFJLENBQUMsZUFBZSxFQUFFLElBQUksS0FBSzt3QkFDM0MsUUFBUSxFQUFFLEtBQUksQ0FBQyxXQUFXLEVBQUU7d0JBQzVCLFFBQVEsRUFBRSxLQUFJLENBQUMsV0FBVyxFQUFFO3dCQUM1QixXQUFXLEVBQUUsS0FBSSxDQUFDLFdBQVc7d0JBQzdCLFdBQVcsRUFBRSxLQUFJLENBQUMsV0FBVzt3QkFDN0IsV0FBVyxhQUFBO3dCQUNYLFNBQVMsRUFBRSxDQUFDLENBQUMsS0FBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUNqRCxlQUFlLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFJLENBQUMsZUFBZSxDQUFDO3dCQUNyRCxNQUFNLEVBQUUsS0FBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLE1BQU07d0JBQzFELFFBQVEsRUFBRSxhQUFhO3FCQUMxQixDQUFDO2lCQUNMO2dCQUVELEtBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQUMsS0FBSyxFQUFFLFFBQVE7b0JBQzlELElBQUksS0FBSyxFQUFFO3dCQUNQLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxHQUFHLEVBQUU7NEJBQ3BCLFdBQVcsQ0FDUCxJQUFJLDZCQUFhLENBQUMsaUNBQWlCLENBQUMsMEJBQTBCLEVBQUUsdUNBQXVDLENBQUMsQ0FDM0csQ0FBQzt5QkFDTDs2QkFBTTs0QkFDSCxXQUFXLENBQUMseUJBQXlCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO3lCQUNsRTtxQkFDSjt5QkFBTTt3QkFDSCxLQUFJLENBQUMsVUFBVTs2QkFDVixtQkFBbUIsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDOzZCQUN2QyxJQUFJLENBQUM7NEJBQ0YsS0FBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsRUFBRSxDQUFDOzRCQUM1QixLQUFJLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxTQUFTLENBQUM7NEJBQ3ZDLEtBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUM7NEJBQ25DLEtBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDOzRCQUMxQixJQUFJLEtBQUksQ0FBQyxlQUFlLEVBQUUsRUFBRTtnQ0FDeEIsS0FBSSxDQUFDLHNDQUFzQyxHQUFHLEtBQUksQ0FBQyxXQUFXLENBQUM7Z0NBQy9ELEtBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxTQUFTLENBQUMsQ0FBQzs2QkFDckQ7NEJBQ0QsSUFBSSxTQUFTLEVBQUU7Z0NBQ1gsS0FBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsaUNBQWlDLEVBQUUsRUFBRSxDQUFDLENBQUM7NkJBQzVEO2lDQUFNO2dDQUNILEtBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLDZCQUE2QixFQUFFLEVBQUUsQ0FBQyxDQUFDOzZCQUN4RDs0QkFDRCxLQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7NEJBQ3ZCLE1BQU0sQ0FBQyxJQUFJLENBQ1AsZUFBZTtnQ0FDZixLQUFJLENBQUMsUUFBUTtnQ0FDYixpQkFBaUI7Z0NBQ2pCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztnQ0FDekMsYUFBYSxDQUNoQixDQUFDOzRCQUVGLFlBQVksRUFBRSxDQUFDO3dCQUNuQixDQUFDLENBQUM7NkJBQ0QsS0FBSyxDQUFDLFVBQUMsS0FBSzs0QkFDVCxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7d0JBQ3ZCLENBQUMsQ0FBQyxDQUFDO3FCQUNWO2dCQUNMLENBQUMsQ0FBQyxDQUFDO1lBQ1AsQ0FBQyxDQUFDO1lBRUYsSUFBTSxNQUFNLEdBQTRCO2dCQUNwQyxnQkFBZ0IsRUFBRTtvQkFDZCxLQUFLLEVBQUUsS0FBSSxDQUFDLFFBQVE7b0JBQ3BCLEtBQUssRUFBRSxLQUFJLENBQUMsUUFBUTtpQkFDdkI7Z0JBQ0QsU0FBUyxFQUFFLE1BQUEsS0FBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLGNBQWMsbUNBQUksS0FBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsY0FBYztnQkFDN0csY0FBYyxFQUFFLEtBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEtBQUksQ0FBQyxVQUFVLENBQUM7Z0JBQ3RFLDZCQUE2QixFQUFFLEtBQUksQ0FBQyxvQ0FBb0MsQ0FBQyxJQUFJLENBQUMsS0FBSSxDQUFDO2dCQUNuRixVQUFVLEVBQUUsS0FBSSxDQUFDLGlCQUFpQixFQUFFO2dCQUNwQyxXQUFXLEVBQUUsS0FBSSxDQUFDLFdBQVc7Z0JBQzdCLFdBQVcsRUFBRSxLQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXO2dCQUM5QyxXQUFXLEVBQUUsS0FBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMseUJBQVcsQ0FBQyxLQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7YUFDNUUsQ0FBQztZQUVGLElBQUksS0FBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxLQUFLLFdBQVcsRUFBRTtnQkFFbkQsTUFBTSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7YUFDNUI7WUFFRCxJQUFJLFNBQVMsRUFBRTtnQkFDWCxLQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQzthQUM1QjtZQUNELElBQUksS0FBSSxDQUFDLGVBQWUsRUFBRSxFQUFFO2dCQUN4QixLQUFJLENBQUMsVUFBVSxHQUFHLElBQUksK0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDcEQ7aUJBQU07Z0JBQ0gsS0FBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLCtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQ3BEO1lBQ0QsS0FBSSxDQUFDLFVBQVUsQ0FBQyxtQ0FBbUMsQ0FBQyxlQUFlLEdBQUcsS0FBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNwRyxLQUFJLENBQUMsVUFBVTtpQkFDVixXQUFXLEVBQUU7aUJBQ2IsSUFBSSxDQUFDLFVBQUMsUUFBUTtnQkFDWCxLQUFJLENBQUMsVUFBVTtxQkFDVixpQkFBaUIsQ0FBQyxRQUFRLENBQUM7cUJBQzNCLElBQUksQ0FBQztvQkFDRixvQkFBb0IsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3ZDLENBQUMsQ0FBQztxQkFDRCxLQUFLLENBQUMsVUFBQyxLQUFLO29CQUNULFdBQVcsQ0FBQyxJQUFJLEtBQUssQ0FBQywyQ0FBMkMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDaEcsQ0FBQyxDQUFDLENBQUM7WUFDWCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLFVBQUMsS0FBSztnQkFDVCxXQUFXLENBQUMsSUFBSSxLQUFLLENBQUMsb0NBQW9DLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekYsQ0FBQyxDQUFDLENBQUM7UUFDWCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLRCw0Q0FBMkIsR0FBM0IsVUFBNEIsU0FBa0IsRUFBRSxPQUFrRDs7UUFDOUYsTUFBTSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLGlCQUFpQixHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDL0csSUFBSSxDQUFDLGlDQUFpQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2QixJQUFJLFNBQVMsRUFBRTtZQUNYLE1BQUEsSUFBSSxDQUFDLHdCQUF3QiwwQ0FBRSxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDcEQsT0FBTyxJQUFJLENBQUMsd0JBQXdCLENBQUM7U0FDeEM7UUFDRCxPQUFPLE9BQU8sRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFLRCwyQ0FBMEIsR0FBMUIsVUFBMkIsU0FBa0IsRUFBRSxLQUFVLEVBQUUsTUFBOEI7O1FBQ3JGLE1BQU0sQ0FBQyxLQUFLLENBQ1IsMEJBQTBCO1lBQzFCLElBQUksQ0FBQyxRQUFRO1lBQ2Isb0JBQW9CO1lBQ3BCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztZQUN2QyxJQUFJO1lBQ0osS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUNuQixDQUFDO1FBQ0YsSUFBSSxTQUFTLEVBQUU7WUFDWCxNQUFBLElBQUksQ0FBQyx3QkFBd0IsMENBQUUsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDM0QsT0FBTyxJQUFJLENBQUMsd0JBQXdCLENBQUM7U0FDeEM7UUFDRCxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBS0Qsc0NBQXFCLEdBQXJCLFVBQXNCLFNBQWtCO1FBQXhDLGlCQXVCQztRQXRCRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBSSxTQUFTLEVBQUU7Z0JBQ1gsSUFBSSxLQUFJLENBQUMsNkJBQTZCLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxFQUFFO29CQUVyRCxPQUFPO2lCQUNWO2FBQ0o7WUFFRCxJQUFJLEtBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsS0FBSyxXQUFXLEVBQUU7Z0JBR25ELEtBQUksQ0FBQywrQkFBK0IsQ0FBQyxTQUFTLENBQUM7cUJBQzFDLElBQUksQ0FBQyxjQUFNLE9BQUEsS0FBSSxDQUFDLDJCQUEyQixDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsRUFBcEQsQ0FBb0QsQ0FBQztxQkFDaEUsS0FBSyxDQUFDLFVBQUMsS0FBSyxJQUFLLE9BQUEsS0FBSSxDQUFDLDBCQUEwQixDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEVBQXpELENBQXlELENBQUMsQ0FBQzthQUNwRjtpQkFBTTtnQkFHSCxLQUFJLENBQUMsK0JBQStCLENBQUMsU0FBUyxDQUFDO3FCQUMxQyxJQUFJLENBQUMsY0FBTSxPQUFBLEtBQUksQ0FBQywyQkFBMkIsQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLEVBQXBELENBQW9ELENBQUM7cUJBQ2hFLEtBQUssQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLEtBQUksQ0FBQywwQkFBMEIsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxFQUF6RCxDQUF5RCxDQUFDLENBQUM7YUFDcEY7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLRCxnREFBK0IsR0FBL0IsVUFBZ0MsU0FBa0I7UUFBbEQsaUJBV0M7UUFWRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsS0FBSSxDQUFDLHlCQUF5QixDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUM7aUJBQzNDLElBQUksQ0FBQyxVQUFDLFFBQVE7Z0JBQ1gsS0FBSSxDQUFDLFVBQVU7cUJBQ1YsbUJBQW1CLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQztxQkFDdkMsSUFBSSxDQUFDLGNBQU0sT0FBQSxPQUFPLEVBQUUsRUFBVCxDQUFTLENBQUM7cUJBQ3JCLEtBQUssQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQztZQUN6QyxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLFVBQUMsS0FBSyxJQUFLLE9BQUEsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFiLENBQWEsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELGdEQUErQixHQUEvQixVQUFnQyxTQUFrQjtRQUFsRCxpQkFhQztRQVpHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUUvQixLQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMseUJBQXlCLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSSxDQUFDLFFBQVEsRUFBRSxTQUFTLFdBQUEsRUFBRSxFQUFFLFVBQUMsS0FBSyxFQUFFLFFBQVE7Z0JBQy9HLElBQUksS0FBSyxFQUFFO29CQUNQLE9BQU8sTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLG9DQUFvQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2lCQUMxRjtxQkFBTTtvQkFDSCxLQUFJLENBQUMseUJBQXlCLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxRQUFRLENBQUMsUUFBUSxDQUFDO3lCQUM5RCxJQUFJLENBQUMsY0FBTSxPQUFBLE9BQU8sRUFBRSxFQUFULENBQVMsQ0FBQzt5QkFDckIsS0FBSyxDQUFDLFVBQUMsS0FBSyxJQUFLLE9BQUEsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFiLENBQWEsQ0FBQyxDQUFDO2lCQUN4QztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBS0QsMENBQXlCLEdBQXpCLFVBQTBCLFNBQWtCLEVBQUUsaUJBQTBCLEVBQUUsZ0JBQXlCO1FBQW5HLGlCQXlGQztRQXhGRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO1lBRW5ELElBQU0sZUFBZSxHQUFHLFVBQUMsU0FBaUI7Z0JBQ3RDLE1BQU0sQ0FBQyxLQUFLLENBQUMsNEJBQXFCLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLDhCQUFvQixLQUFJLENBQUMsUUFBUSxDQUFFLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBRXpILElBQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDO2dCQUNsRSxJQUFNLE1BQU0sR0FBRyxFQUFFLENBQUM7Z0JBQ2xCLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsS0FBSSxDQUFDLFFBQVEsQ0FBQztnQkFDeEQsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLEVBQUU7b0JBQ3BCLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLEdBQUcsU0FBUyxDQUFDO2lCQUM3RDtxQkFBTTtvQkFDSCxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsU0FBUyxDQUFDO2lCQUNsQztnQkFDRCxJQUFJLFNBQVMsRUFBRTtvQkFDWCxNQUFNLENBQUMsbUJBQW1CLENBQUMsR0FBRyxpQkFBaUIsQ0FBQztpQkFDbkQ7Z0JBRUQsS0FBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBQyxLQUFLLEVBQUUsUUFBUTtvQkFDOUQsSUFBSSxLQUFLLEVBQUU7d0JBQ1AsT0FBTyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsV0FBVyxHQUFHLE1BQU0sR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7cUJBQ2xGO3lCQUFNO3dCQUNILE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO3FCQUM1QjtnQkFDTCxDQUFDLENBQUMsQ0FBQztZQUNQLENBQUMsQ0FBQztZQUVGLElBQU0sTUFBTSxHQUE0QjtnQkFDcEMsZ0JBQWdCLEVBQUU7b0JBQ2QsS0FBSyxFQUFFLEtBQUksQ0FBQyxRQUFRO29CQUNwQixLQUFLLEVBQUUsS0FBSSxDQUFDLFFBQVE7aUJBQ3ZCO2dCQUNELFNBQVMsRUFBRSxLQUFLO2dCQUNoQixjQUFjLEVBQUUsS0FBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsS0FBSSxDQUFDLFVBQVUsQ0FBQztnQkFDdEUsNkJBQTZCLEVBQUUsS0FBSSxDQUFDLG9DQUFvQyxDQUFDLElBQUksQ0FBQyxLQUFJLENBQUM7Z0JBQ25GLFVBQVUsRUFBRSxLQUFJLENBQUMsaUJBQWlCLEVBQUU7Z0JBQ3BDLFdBQVcsRUFBRSxLQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXO2dCQUM5QyxXQUFXLEVBQUUsS0FBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMseUJBQVcsQ0FBQyxLQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7YUFDNUUsQ0FBQztZQUVGLElBQUksU0FBUyxFQUFFO2dCQUNYLEtBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO2FBQzVCO1lBRUQsS0FBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLCtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2pELEtBQUksQ0FBQyxVQUFVLENBQUMsbUNBQW1DLENBQUMsS0FBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRW5FLElBQUksQ0FBQyxDQUFDLGdCQUFnQixFQUFFO2dCQUNwQixLQUFJLENBQUMsVUFBVTtxQkFDVixrQkFBa0IsQ0FBQyxnQkFBZ0IsQ0FBQztxQkFDcEMsSUFBSSxDQUFDO29CQUNGLEtBQUksQ0FBQyxVQUFVO3lCQUNWLFlBQVksRUFBRTt5QkFDZCxJQUFJLENBQUMsVUFBQyxTQUFTO3dCQUNaLEtBQUksQ0FBQyxVQUFVOzZCQUNWLGtCQUFrQixDQUFDLFNBQVMsQ0FBQzs2QkFDN0IsSUFBSSxDQUFDOzRCQUNGLGVBQWUsQ0FBQyxTQUFTLENBQUMsR0FBSSxDQUFDLENBQUM7d0JBQ3BDLENBQUMsQ0FBQzs2QkFDRCxLQUFLLENBQUMsVUFBQyxLQUFLOzRCQUNULE9BQU8sTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLDhDQUE4QyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO3dCQUNyRyxDQUFDLENBQUMsQ0FBQztvQkFDWCxDQUFDLENBQUM7eUJBQ0QsS0FBSyxDQUFDLFVBQUMsS0FBSzt3QkFDVCxPQUFPLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyx1Q0FBdUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDOUYsQ0FBQyxDQUFDLENBQUM7Z0JBQ1gsQ0FBQyxDQUFDO3FCQUNELEtBQUssQ0FBQyxVQUFDLEtBQUs7b0JBQ1QsT0FBTyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsOENBQThDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JHLENBQUMsQ0FBQyxDQUFDO2FBQ1Y7aUJBQU07Z0JBQ0gsS0FBSSxDQUFDLFVBQVU7cUJBQ1YsV0FBVyxFQUFFO3FCQUNiLElBQUksQ0FBQyxVQUFDLFFBQVE7b0JBQ1gsS0FBSSxDQUFDLFVBQVU7eUJBQ1YsaUJBQWlCLENBQUMsUUFBUSxDQUFDO3lCQUMzQixJQUFJLENBQUM7d0JBQ0YsZUFBZSxDQUFDLFFBQVEsQ0FBQyxHQUFJLENBQUMsQ0FBQztvQkFDbkMsQ0FBQyxDQUFDO3lCQUNELEtBQUssQ0FBQyxVQUFDLEtBQUs7d0JBQ1QsT0FBTyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsNkNBQTZDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3BHLENBQUMsQ0FBQyxDQUFDO2dCQUNYLENBQUMsQ0FBQztxQkFDRCxLQUFLLENBQUMsVUFBQyxLQUFLO29CQUNULE9BQU8sTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLHNDQUFzQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM3RixDQUFDLENBQUMsQ0FBQzthQUNWO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBS0Qsa0RBQWlDLEdBQWpDLFVBQWtDLFNBQWtCO1FBQ2hELElBQUksU0FBUyxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxFQUFFO1lBRXZDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1NBQzdCO1FBRUQsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQ3JDLElBQUksUUFBd0IsQ0FBQztRQUM3QixLQUFpQixVQUFpQyxFQUFqQyxLQUFBLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxFQUFqQyxjQUFpQyxFQUFqQyxJQUFpQyxFQUFFO1lBQS9DLFFBQVEsU0FBQTtZQUNULElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUU7Z0JBQ2xCLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUM3QztTQUNKO1FBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFckQsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNwQixJQUFJLElBQUksQ0FBQyxhQUFhLFlBQVksdUJBQVUsRUFBRTtnQkFFMUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRTtvQkFDeEMsSUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUUsSUFBSSxDQUFDLGFBQTRCLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDO29CQUNoSCxJQUFJLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7aUJBQzFEO2dCQUNELElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ3hDLElBQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFFLElBQUksQ0FBQyxhQUE0QixDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQztvQkFDaEgsSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO2lCQUMxRDthQUNKO1lBRUQsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQ3pCO0lBQ0wsQ0FBQztJQUtELCtCQUFjLEdBQWQ7UUFDSSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBWSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBRXpDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyw2QkFBNkIsQ0FBQyx3QkFBd0IsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFO2dCQUNoRyxJQUFJLENBQUMsMkJBQTJCLEVBQUUsQ0FBQzthQUN0QztZQUNELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyw2QkFBNkIsQ0FBQyx3QkFBd0IsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFO2dCQUNqRyxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQzthQUNsQztZQUNELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyw2QkFBNkIsQ0FBQyx1QkFBdUIsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFO2dCQUMvRixJQUFJLENBQUMsa0NBQWtDLEVBQUUsQ0FBQzthQUM3QztZQUNELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyw2QkFBNkIsQ0FBQyx1QkFBdUIsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFO2dCQUNoRyxJQUFJLENBQUMsOEJBQThCLEVBQUUsQ0FBQzthQUN6QztZQUNELElBQUksSUFBSSxDQUFDLDJCQUEyQixFQUFFO2dCQUNsQyxJQUFJLENBQUMsK0JBQStCLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDOUM7WUFDRCxJQUFJLElBQUksQ0FBQyx1QkFBdUIsRUFBRTtnQkFDOUIsSUFBSSxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxDQUFDO2FBQzFDO1NBQ0o7SUFDTCxDQUFDO0lBRU8scURBQW9DLEdBQTVDLFVBQTZDLGFBQWlDLEVBQUUsT0FBZSxFQUFFLElBQVU7UUFDdkcsUUFBUSxhQUFhLEVBQUU7WUFDbkIsS0FBSyxtQ0FBa0IsQ0FBQyxxQkFBcUI7Z0JBQ3pDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO2dCQUM3QixNQUFNO1lBQ1YsS0FBSyxtQ0FBa0IsQ0FBQywyQkFBMkI7Z0JBQy9DLElBQUksQ0FBQywyQkFBMkIsRUFBRSxDQUFDO2dCQUNuQyxNQUFNO1NBQ2I7UUFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxJQUFJLCtCQUFjLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEgsQ0FBQztJQUVPLHNDQUFxQixHQUE3QjtRQUVJLE1BQU0sQ0FBQyxHQUFHLENBQ04sNEZBQXFGLElBQUksQ0FBQyxRQUFRLGVBQUssSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFlBQVksTUFDL0ksQ0FDTixDQUFDO1FBQ0YsSUFBSSxDQUFDLGdEQUFnRCxDQUFDLG1DQUFrQixDQUFDLHFCQUFxQixDQUFDLENBQUM7SUFDcEcsQ0FBQztJQUVPLDRDQUEyQixHQUFuQztRQUFBLGlCQW9DQztRQWxDRyxNQUFNLENBQUMsR0FBRyxDQUNOLHdJQUFpSSxJQUFJLENBQUMsUUFBUSxlQUN6SSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsWUFBWSxzQkFBbUIsQ0FDdEUsQ0FBQztRQUNGLElBQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLHlDQUF5QyxJQUFJLElBQUksQ0FBQztRQUM5RyxJQUFJLENBQUMsOEJBQThCLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQUMsS0FBSztZQUNwRCxRQUFRLEtBQUssRUFBRTtnQkFDWCxLQUFLLFFBQVE7b0JBRVQsTUFBTSxDQUFDLElBQUksQ0FDUCxpRUFBMEQsS0FBSSxDQUFDLFFBQVEsZUFBSyxLQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsWUFBWSxzREFDcEUsQ0FDdEQsQ0FBQztvQkFDRixNQUFNO2dCQUNWLEtBQUssV0FBVyxDQUFDO2dCQUNqQixLQUFLLFdBQVc7b0JBQ1osTUFBTSxDQUFDLEdBQUcsQ0FDTixpRUFBMEQsS0FBSSxDQUFDLFFBQVEsZUFBSyxLQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsWUFBWSx1R0FDMUIsS0FBSyxDQUFFLENBQ3ZHLENBQUM7b0JBQ0YsTUFBTTtnQkFDVixLQUFLLFFBQVEsQ0FBQztnQkFDZCxLQUFLLFVBQVUsQ0FBQztnQkFDaEIsS0FBSyxLQUFLLENBQUM7Z0JBQ1gsS0FBSyxjQUFjO29CQUVmLE1BQU0sQ0FBQyxJQUFJLENBQ1AsaUVBQTBELEtBQUksQ0FBQyxRQUFRLGVBQUssS0FBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFlBQVksZ0hBQ2pCLE9BQU8sa0JBQVEsS0FBSyxDQUFFLENBQy9ILENBQUM7b0JBQ0YsS0FBSSxDQUFDLGdEQUFnRCxDQUFDLG1DQUFrQixDQUFDLDJCQUEyQixDQUFDLENBQUM7b0JBQ3RHLE1BQU07YUFDYjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVhLGlFQUFnRCxHQUE5RCxVQUErRCxLQUFhOzs7Ozs7O3dCQUU3QixXQUFNLElBQUksQ0FBQywwQ0FBMEMsQ0FBQyxLQUFLLENBQUMsRUFBQTs7d0JBQTdGLDhCQUE4QixHQUFHLFNBQTREO3dCQUNuRyxRQUFRLDhCQUE4QixFQUFFOzRCQUNwQyxLQUFLLFdBQVcsQ0FBQzs0QkFDakIsS0FBSyxXQUFXO2dDQUNaLE1BQU0sQ0FBQyxHQUFHLENBQ04sV0FBSSxLQUFLLHNCQUFZLElBQUksQ0FBQyxRQUFRLGVBQUssSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFlBQVksOENBQzlDLEtBQUssNkNBQW1DLDhCQUE4QixDQUFFLENBQy9HLENBQUM7Z0NBQ0YsTUFBTTs0QkFDVjtnQ0FDSSxNQUFNLENBQUMsS0FBSyxDQUNSLFdBQUksS0FBSyxzQkFBWSxJQUFJLENBQUMsUUFBUSxlQUFLLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxZQUFZLHlDQUNuRCxLQUFLLDZDQUFtQyw4QkFBOEIsQ0FBRSxDQUMxRyxDQUFDO2dDQUNGLE1BQU07eUJBQ2I7Ozs7d0JBRUQsTUFBTSxDQUFDLEtBQUssQ0FDUixXQUFJLEtBQUsseUNBQStCLElBQUksQ0FBQyxRQUFRLGVBQUssSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFlBQVkscUJBQzFGLEtBQUssZUFBSyxPQUFLLENBQUUsQ0FDL0IsQ0FBQzs7Ozs7O0tBRVQ7SUFFYSwyREFBMEMsR0FBeEQsVUFBeUQsS0FBYTs7Ozs7O3dCQUNsRSxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQUksS0FBSyxtQ0FBeUIsSUFBSSxDQUFDLFFBQVEsZUFBSyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsWUFBWSwyQkFBaUIsS0FBSyxDQUFFLENBQUMsQ0FBQzs7Ozt3QkFFaEksV0FBTSxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxFQUFBOzt3QkFBakMsU0FBaUMsQ0FBQzt3QkFDNUIsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLHlDQUF5QyxJQUFJLElBQUksQ0FBQzt3QkFDOUcsV0FBTyxJQUFJLENBQUMsOEJBQThCLENBQUMsT0FBTyxDQUFDLEVBQUM7Ozt3QkFFcEQsTUFBTSxDQUFDLElBQUksQ0FDUCxXQUFJLEtBQUsseUNBQStCLElBQUksQ0FBQyxRQUFRLGVBQUssSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFlBQVksd0JBQWMsT0FBSyxDQUFFLENBQzdILENBQUM7d0JBQ0YsV0FBTyxJQUFJLENBQUMsOEJBQThCLENBQUMsQ0FBQyxDQUFDLEVBQUM7Ozs7O0tBRXJEO0lBRWEsK0NBQThCLEdBQTVDLFVBQTZDLE9BQWU7Ozs7Ozt3QkFDcEQsS0FBSyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLGtCQUFrQixDQUFDO3dCQUNyRCxRQUFRLEdBQUcsR0FBRyxDQUFDO3dCQUNmLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsQ0FBQzt3QkFDdkMsQ0FBQyxHQUFHLENBQUM7Ozs2QkFBRSxDQUFBLENBQUMsR0FBRyxTQUFTLENBQUE7d0JBQ3pCLEtBQUssR0FBRyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQzt3QkFDdkQsSUFBSSxLQUFLLEtBQUssV0FBVyxJQUFJLEtBQUssS0FBSyxXQUFXLEVBQUU7NEJBQ2hELGNBQU07eUJBQ1Q7d0JBRUQsV0FBTSxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sSUFBSyxPQUFBLFVBQVUsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLEVBQTdCLENBQTZCLENBQUMsRUFBQTs7d0JBQTdELFNBQTZELENBQUM7Ozt3QkFObkMsQ0FBQyxFQUFFLENBQUE7OzRCQVFsQyxXQUFPLEtBQUssRUFBQzs7OztLQUNoQjtJQUVhLGdDQUFlLEdBQTdCLFVBQThCLEtBQWE7Ozs7OzRCQUNqQixXQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUE7O3dCQUE1RCxhQUFhLEdBQUcsU0FBNEM7d0JBQ2xFLElBQUksYUFBYSxFQUFFOzRCQUVmLE1BQU0sQ0FBQyxHQUFHLENBQ04sV0FBSSxLQUFLLDBDQUFnQyxJQUFJLENBQUMsUUFBUSxlQUFLLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxZQUFZLGtDQUN2RSxDQUNsQyxDQUFDOzRCQUNGLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFO2dDQUNoQixXQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsRUFBQzs2QkFDeEM7aUNBQU07Z0NBQ0gsV0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLEVBQUM7NkJBQzNDO3lCQUNKOzZCQUFNOzRCQUdHLFFBQVEsR0FBRyxXQUFJLEtBQUssMENBQWdDLElBQUksQ0FBQyxRQUFRLGVBQUssSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFlBQVksc0NBQ2hGLENBQUM7NEJBQ3hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7NEJBQ3ZCLE1BQU0sS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO3lCQUN6Qjs7Ozs7S0FDSjtJQUVPLHFDQUFvQixHQUE1QixVQUE2QixLQUFhLEVBQUUsaUJBQXlCO1FBQXJFLGlCQXNCQztRQXJCRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBTSxZQUFZLEdBQUcsS0FBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDN0QsSUFBSSxZQUFZLEtBQUssQ0FBQyxFQUFFO2dCQUNwQixJQUFNLGlCQUFlLEdBQUcsVUFBVSxDQUFDO29CQUMvQixPQUFPLENBQUMsSUFBSSxDQUFDLFdBQUksS0FBSyxvQ0FBMEIsaUJBQWlCLE9BQUksQ0FBQyxDQUFDO29CQUN2RSxPQUFPLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDMUIsQ0FBQyxFQUFFLGlCQUFpQixDQUFDLENBQUM7Z0JBQ3RCLEtBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsRUFBRSxFQUFFLFVBQUMsS0FBSyxFQUFFLFFBQVE7b0JBQzFELFlBQVksQ0FBQyxpQkFBZSxDQUFDLENBQUM7b0JBQzlCLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRTt3QkFDVCxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQUksS0FBSyxnREFBc0MsS0FBSyxDQUFFLENBQUMsQ0FBQzt3QkFDckUsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7cUJBQ3pCO3lCQUFNO3dCQUNILE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO3FCQUN4QjtnQkFDTCxDQUFDLENBQUMsQ0FBQzthQUNOO2lCQUFNO2dCQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBSSxLQUFLLHVDQUE2QixZQUFZLENBQUUsQ0FBQyxDQUFDO2dCQUNuRSxPQUFPLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUN6QjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELGdDQUFlLEdBQWY7UUFDSSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUkseUJBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QyxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBa0J2QyxDQUFDO0lBRU8sZ0NBQWUsR0FBdkI7UUFDSSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLEVBQUU7WUFDcEQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztTQUN0QztJQUNMLENBQUM7SUFFTyxrQ0FBaUIsR0FBekI7UUFDSSxJQUFJLFdBQVcsQ0FBQztRQUNoQixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxVQUFVLEVBQUU7WUFDMUQsV0FBVztnQkFDUCxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxVQUFVLEtBQUssU0FBUztvQkFDaEUsQ0FBQyxDQUFDLFNBQVM7b0JBQ1gsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLFVBQVUsQ0FBQztTQUNwRTthQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFO1lBQ3pDLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUM7U0FDbEQ7YUFBTTtZQUNILFdBQVcsR0FBRyxTQUFTLENBQUM7U0FDM0I7UUFDRCxPQUFPLFdBQVcsQ0FBQztJQUN2QixDQUFDO0lBRU8sbUNBQWtCLEdBQTFCO1FBQUEsaUJBeUhDO1FBeEhHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixJQUFJLEtBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRTtnQkFHaEIsS0FBSSxDQUFDLG9CQUFvQixFQUFFO3FCQUN0QixVQUFVLEVBQUU7cUJBQ1osT0FBTyxDQUFDLFVBQUMsTUFBTTtvQkFDWixPQUFBLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBQyxRQUFRO3dCQUM1QixRQUFRLENBQUMsT0FBTyxDQUFDLFVBQUMsTUFBTTs0QkFDcEIsSUFBSSxLQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dDQUM3QixJQUFNLFdBQVcsR0FBRyxFQUFFLENBQUM7Z0NBRXZCLFdBQVcsQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO2dDQUNsQyxXQUFXLENBQUMsV0FBVyxDQUFDLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQztnQ0FDNUMsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUM7Z0NBRzlCLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxjQUFjLEVBQUU7b0NBQ2hDLFdBQVcsQ0FBQyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO29DQUNsQyxXQUFXLENBQUMsVUFBVSxDQUFDLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztvQ0FDMUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUM7b0NBQzFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDO29DQUM1QyxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQztvQ0FHcEMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRTt3Q0FDZixXQUFXLENBQUMsV0FBVyxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQztxQ0FDMUM7eUNBQU0sSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRTt3Q0FDM0IsV0FBVyxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7cUNBQy9DO3lDQUFNO3dDQUVILFdBQVcsQ0FBQyxXQUFXLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7cUNBQzFGO29DQUVELElBQUksV0FBVyxDQUFDLFdBQVcsQ0FBQyxLQUFLLE9BQU8sRUFBRTt3Q0FDdEMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxhQUFhLENBQUM7cUNBQ3ZEO29DQUVELFdBQVcsQ0FBQyxhQUFhLENBQUMsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDO29DQUNoRCxXQUFXLENBQUMsV0FBVyxDQUFDLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQztpQ0FDL0M7Z0NBR0QsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLGdCQUFnQixJQUFJLE1BQU0sQ0FBQyxrQkFBa0IsS0FBSyxTQUFTLEVBQUU7b0NBRTdFLFdBQVcsQ0FBQywwQkFBMEIsQ0FBQyxHQUFHLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQztvQ0FDMUUsV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQztvQ0FDakQsV0FBVyxDQUFDLFlBQVksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUM7aUNBQ3BGO2dDQUdELElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxvQkFBb0IsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLHFCQUFxQixFQUFFO2lDQUNsRjtnQ0FFRCxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDOzZCQUMzQjt3QkFDTCxDQUFDLENBQUMsQ0FBQztvQkFDUCxDQUFDLENBQUM7Z0JBbERGLENBa0RFLENBQ0wsQ0FBQzthQUNUO2lCQUFNO2dCQUdILEtBQUksQ0FBQyxvQkFBb0IsRUFBRTtxQkFDdEIsWUFBWSxFQUFFO3FCQUNkLE9BQU8sQ0FBQyxVQUFDLFFBQVE7b0JBQ2QsT0FBQSxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQUMsUUFBUTt3QkFDOUIsUUFBUSxDQUFDLE9BQU8sQ0FBQyxVQUFDLE1BQU07NEJBQ3BCLElBQUksS0FBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsRUFBRTtnQ0FDN0IsSUFBTSxXQUFXLEdBQUcsRUFBRSxDQUFDO2dDQUV2QixXQUFXLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQztnQ0FDbEMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7Z0NBQzVDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDO2dDQUc5QixJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssYUFBYSxFQUFFO29DQUMvQixXQUFXLENBQUMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQztvQ0FDbEMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUM7b0NBQzFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO29DQUMxQyxXQUFXLENBQUMsV0FBVyxDQUFDLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQztvQ0FDNUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUM7b0NBR3BDLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUU7d0NBQ2YsV0FBVyxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7cUNBQzFDO3lDQUFNLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUU7d0NBQzNCLFdBQVcsQ0FBQyxXQUFXLENBQUMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDO3FDQUMvQzt5Q0FBTTt3Q0FFSCxXQUFXLENBQUMsV0FBVyxDQUFDLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO3FDQUMxRjtvQ0FFRCxJQUFJLFdBQVcsQ0FBQyxXQUFXLENBQUMsS0FBSyxPQUFPLEVBQUU7d0NBQ3RDLFdBQVcsQ0FBQyxlQUFlLENBQUMsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDO3FDQUN2RDtvQ0FFRCxXQUFXLENBQUMsaUJBQWlCLENBQUMsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDO29DQUN4RCxXQUFXLENBQUMsYUFBYSxDQUFDLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQztvQ0FDaEQsV0FBVyxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7b0NBQ3RDLFdBQVcsQ0FBQyxlQUFlLENBQUMsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDO2lDQUN2RDtnQ0FHRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssZ0JBQWdCLElBQUksTUFBTSxDQUFDLGtCQUFrQixLQUFLLFNBQVMsRUFBRTtvQ0FFN0UsV0FBVyxDQUFDLDBCQUEwQixDQUFDLEdBQUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDO29DQUMxRSxXQUFXLENBQUMsS0FBSyxDQUFDLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixDQUFDO29DQUNqRCxXQUFXLENBQUMsWUFBWSxDQUFDLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztpQ0FDcEY7Z0NBR0QsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLG9CQUFvQixJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUsscUJBQXFCLEVBQUU7aUNBQ2xGO2dDQUNELE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7NkJBQzNCO3dCQUNMLENBQUMsQ0FBQyxDQUFDO29CQUNQLENBQUMsQ0FBQztnQkFuREYsQ0FtREUsQ0FDTCxDQUFDO2FBQ1Q7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTywrQkFBYyxHQUF0QixVQUF1QixNQUFXO1FBQzlCLE9BQU8sQ0FDSCxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssYUFBYSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2xELENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxjQUFjLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2xELENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxnQkFBZ0IsSUFBSSxNQUFNLENBQUMsU0FBUyxJQUFJLE1BQU0sQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQ2pGLENBQUM7SUFDTixDQUFDO0lBQ0wsYUFBQztBQUFELENBOXZEQSxBQTh2REMsSUFBQTtBQTl2RFksd0JBQU07Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2hEbkIscURBQW9EO0FBR3BELG9GQUFtRjtBQUNuRixrRkFBaUY7QUFDakYsNEVBQStGO0FBQy9GLDZFQUE0RTtBQUM1RSw0RUFBMkU7QUFDM0UsK0RBQW1FO0FBS25FLElBQU0sTUFBTSxHQUFtQiwrQkFBYyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBSzVELElBQUksUUFBdUIsQ0FBQztBQVk1QjtJQUE0QyxpQ0FBZTtJQXdEdkQsdUJBQVksTUFBYyxFQUFFLGFBQW9DO1FBQWhFLFlBQ0ksaUJBQU8sU0F3Q1Y7UUF4RkQsWUFBTSxHQUF5QixFQUFFLENBQUM7UUEwQzFCLHdDQUFrQyxHQUFHLEtBQUssQ0FBQztRQU8vQyxRQUFRLEdBQUcsd0JBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN2QyxLQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixLQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsR0FBRyxLQUFJLENBQUM7UUFDakMsS0FBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEtBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFckMsSUFBSSxDQUFDLENBQUMsYUFBYSxFQUFFO1lBQ2pCLElBQUksTUFBTSxTQUFBLENBQUM7WUFDWCxJQUFJLE9BQU8sYUFBYSxLQUFLLFFBQVEsRUFBRTtnQkFDbkMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUM7YUFDbkQ7aUJBQU0sSUFBSSxhQUFhLFlBQVksV0FBVyxFQUFFO2dCQUM3QyxNQUFNLEdBQUcsYUFBYSxDQUFDO2FBQzFCO1lBRUQsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFO2dCQUNWLEtBQUksQ0FBQyxpQkFBaUIsR0FBRztvQkFDckIsYUFBYSxFQUFFLE1BQU07b0JBQ3JCLEtBQUssRUFBRSxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQztvQkFDdEMsRUFBRSxFQUFFLEVBQUU7b0JBQ04sb0JBQW9CLEVBQUUsS0FBSztpQkFDOUIsQ0FBQztnQkFDRixJQUNJLFFBQVEsQ0FBQyxlQUFlLEVBQUU7b0JBQzFCLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRTt3QkFDdEIsQ0FBQyxRQUFRLENBQUMscUJBQXFCLEVBQUU7NEJBQzdCLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRTs0QkFDOUIsUUFBUSxDQUFDLG9CQUFvQixFQUFFOzRCQUMvQixRQUFRLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxDQUFDLEVBQzdDO29CQUNFLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztpQkFDbkQ7Z0JBQ0QsS0FBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUM7Z0JBQzVCLEtBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO2FBQ3pCO1NBQ0o7UUFFRCxLQUFJLENBQUMsZUFBZSxHQUFHO1lBQ25CLEtBQUksQ0FBQyw0Q0FBNEMsRUFBRSxDQUFDO1lBQ3BELEtBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxDQUFDLElBQUksdUNBQWtCLENBQUMsS0FBSSxFQUFFLGVBQWUsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkcsQ0FBQyxDQUFDOztJQUNOLENBQUM7SUFLRCwwQkFBRSxHQUFGLFVBQTBDLElBQU8sRUFBRSxPQUFrRDtRQUNqRyxpQkFBTSxLQUFLLFlBQUMsSUFBSSxFQUFFLFNBQVMsR0FBRyxJQUFJLEdBQUcsa0JBQWtCLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUVySCxJQUFJLElBQUksS0FBSyxxQkFBcUIsRUFBRTtZQUNoQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxrQ0FBa0MsRUFBRTtnQkFDMUQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxJQUFJLHFDQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDckgsSUFBSSxDQUFDLGtDQUFrQyxHQUFHLEtBQUssQ0FBQzthQUNuRDtTQUNKO1FBQ0QsSUFBSSxJQUFJLEtBQUssZUFBZSxFQUFFO1lBQzFCLElBQ0ksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7Z0JBQ2QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLO2dCQUNwQixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxXQUFXLEdBQUcsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLEtBQUs7Z0JBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxLQUFLO2dCQUNwQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFVLEtBQUssQ0FBQyxFQUN2QztnQkFDRSxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxJQUFJLHVDQUFrQixDQUFDLElBQUksRUFBRSxlQUFlLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ2xHO1NBQ0o7UUFDRCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO1lBQ3RCLElBQUksSUFBSSxLQUFLLHdCQUF3QixFQUFFO2dCQUNuQyxJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUF1QixFQUFFLENBQUM7YUFDekM7WUFDRCxJQUFJLElBQUksS0FBSyx1QkFBdUIsRUFBRTtnQkFDbEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyw4QkFBOEIsRUFBRSxDQUFDO2FBQ2hEO1lBQ0QsSUFBSSxJQUFJLEtBQUsseUJBQXlCLEVBQUU7Z0JBQ3BDLElBQUksQ0FBQyxNQUFNLENBQUMsMkJBQTJCLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDbEQ7U0FDSjtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFLRCw0QkFBSSxHQUFKLFVBQTRDLElBQU8sRUFBRSxPQUFrRDtRQUNuRyxpQkFBTSxPQUFPLFlBQUMsSUFBSSxFQUFFLFNBQVMsR0FBRyxJQUFJLEdBQUcsdUJBQXVCLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUU1SCxJQUFJLElBQUksS0FBSyxxQkFBcUIsRUFBRTtZQUNoQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxrQ0FBa0MsRUFBRTtnQkFDMUQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxJQUFJLHFDQUFpQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN4SDtTQUNKO1FBQ0QsSUFBSSxJQUFJLEtBQUssZUFBZSxFQUFFO1lBQzFCLElBQ0ksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7Z0JBQ2QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLO2dCQUNwQixJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxXQUFXLEdBQUcsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxLQUFLLEtBQUs7Z0JBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxLQUFLO2dCQUNwQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFVLEtBQUssQ0FBQyxFQUN2QztnQkFDRSxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxJQUFJLHVDQUFrQixDQUFDLElBQUksRUFBRSxlQUFlLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ2xHO1NBQ0o7UUFDRCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO1lBQ3RCLElBQUksSUFBSSxLQUFLLHdCQUF3QixFQUFFO2dCQUNuQyxJQUFJLENBQUMsTUFBTSxDQUFDLDJCQUEyQixFQUFFLENBQUM7YUFDN0M7WUFDRCxJQUFJLElBQUksS0FBSyx1QkFBdUIsRUFBRTtnQkFDbEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQ0FBa0MsRUFBRSxDQUFDO2FBQ3BEO1lBQ0QsSUFBSSxJQUFJLEtBQUsseUJBQXlCLEVBQUU7Z0JBQ3BDLElBQUksQ0FBQyxNQUFNLENBQUMsK0JBQStCLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDdEQ7U0FDSjtRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFLRCwyQkFBRyxHQUFILFVBQTJDLElBQU8sRUFBRSxPQUFtRDtRQUNuRyxpQkFBTSxNQUFNLFlBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRTVCLElBQUksSUFBSSxLQUFLLHdCQUF3QixFQUFFO1lBRW5DLElBQU0sb0NBQW9DLEdBQ3RDLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQztZQUN6RixJQUFJLG9DQUFvQyxLQUFLLENBQUMsRUFBRTtnQkFDNUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUMvQztTQUNKO1FBQ0QsSUFBSSxJQUFJLEtBQUssdUJBQXVCLEVBQUU7WUFFbEMsSUFBTSxtQ0FBbUMsR0FDckMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDO1lBQ3pGLElBQUksbUNBQW1DLEtBQUssQ0FBQyxFQUFFO2dCQUMzQyxJQUFJLENBQUMsTUFBTSxDQUFDLCtCQUErQixDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQ3REO1NBQ0o7UUFDRCxJQUFJLElBQUksS0FBSyx5QkFBeUIsRUFBRTtZQUVwQyxJQUFNLDZCQUE2QixHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQztZQUN4RSxJQUFJLDZCQUE2QixLQUFLLENBQUMsRUFBRTtnQkFDckMsSUFBSSxDQUFDLE1BQU0sQ0FBQyw0QkFBNEIsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUNuRDtTQUNKO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQWFELHVDQUFlLEdBQWYsVUFBZ0IsS0FBdUI7UUFDbkMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFLEVBQUU7WUFDL0MsSUFBSSxLQUFLLENBQUMsU0FBUyxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLEVBQUU7Z0JBQ2xELEtBQUssQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUNsRDtTQUNKO1FBR0QsS0FBZ0IsVUFBVyxFQUFYLEtBQUEsSUFBSSxDQUFDLE1BQU0sRUFBWCxjQUFXLEVBQVgsSUFBVyxFQUFFO1lBQXhCLElBQU0sQ0FBQyxTQUFBO1lBQ1IsSUFBSSxDQUFDLENBQUMsS0FBSyxLQUFLLEtBQUssRUFBRTtnQkFDbkIsT0FBTyxDQUFDLENBQUM7YUFDWjtTQUNKO1FBRUQsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO1FBRXJCLEtBQTRCLFVBQWtDLEVBQWxDLEtBQUEsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFsQyxjQUFrQyxFQUFsQyxJQUFrQyxFQUFFO1lBQTNELElBQU0sYUFBYSxTQUFBO1lBQ3BCLElBQUksYUFBYSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUN4QyxZQUFZLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xCLE1BQU07YUFDVDtTQUNKO1FBRUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxVQUFDLGFBQWE7WUFDckQsYUFBYSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLHlCQUF5QixDQUFDO1lBQzNCLEtBQUssT0FBQTtZQUNMLEVBQUUsRUFBRSxLQUFLLENBQUMsRUFBRTtZQUNaLG9CQUFvQixFQUFFLEtBQUs7U0FDOUIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLElBQUksQ0FBQyxrQ0FBa0MsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUV0RCxPQUFPLFlBQVksQ0FBQztJQUN4QixDQUFDO0lBY0QsMENBQWtCLEdBQWxCLFVBQW1CLGFBQW9DLEVBQUUsVUFBNEI7UUFDakYsSUFBSSxNQUFNLENBQUM7UUFDWCxJQUFJLE9BQU8sYUFBYSxLQUFLLFFBQVEsRUFBRTtZQUNuQyxNQUFNLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoRCxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUNULE1BQU0sSUFBSSxLQUFLLENBQUMseUVBQXlFLEdBQUcsYUFBYSxDQUFDLENBQUM7YUFDOUc7U0FDSjthQUFNLElBQUksYUFBYSxZQUFZLFdBQVcsRUFBRTtZQUM3QyxNQUFNLEdBQUcsYUFBYSxDQUFDO1NBQzFCO2FBQU07WUFDSCxNQUFNLElBQUksS0FBSyxDQUFDLHlFQUF5RSxHQUFHLGFBQWEsQ0FBQyxDQUFDO1NBQzlHO1FBRUQsSUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2pDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV0QyxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLGlDQUFlLENBQUMsTUFBTSxDQUFDO1FBQ2pFLFFBQVEsT0FBTyxFQUFFO1lBQ2IsS0FBSyxpQ0FBZSxDQUFDLEtBQUs7Z0JBQ3RCLE1BQU0sQ0FBQyxVQUFZLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7Z0JBQzVELE1BQU07WUFDVixLQUFLLGlDQUFlLENBQUMsTUFBTTtnQkFDdkIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDMUIsTUFBTTtZQUNWLEtBQUssaUNBQWUsQ0FBQyxNQUFNO2dCQUN2QixNQUFNLENBQUMsVUFBWSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQ2hELE1BQU07WUFDVixLQUFLLGlDQUFlLENBQUMsT0FBTztnQkFDeEIsTUFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNqRCxNQUFNO1lBQ1YsS0FBSyxpQ0FBZSxDQUFDLE9BQU87Z0JBQ3hCLE1BQU0sQ0FBQyxVQUFZLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDaEQsTUFBTTtZQUNWO2dCQUNJLE9BQU8sR0FBRyxpQ0FBZSxDQUFDLE1BQU0sQ0FBQztnQkFDakMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDMUIsTUFBTTtTQUNiO1FBRUQsSUFBTSxDQUFDLEdBQXVCO1lBQzFCLGFBQWEsRUFBRSxNQUFNO1lBQ3JCLEtBQUssT0FBQTtZQUNMLFVBQVUsRUFBRSxPQUFPO1lBQ25CLEVBQUUsRUFBRSxLQUFLLENBQUMsRUFBRTtZQUNaLG9CQUFvQixFQUFFLEtBQUs7U0FDOUIsQ0FBQztRQUNGLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVsQyxJQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLElBQUkscUNBQWlCLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEcsSUFBSSxDQUFDLGtDQUFrQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUM7UUFFbkUsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztJQVdELDREQUFvQyxHQUFwQyxVQUFxQyw4QkFBeUU7UUFDMUcsSUFBTSxrQkFBa0IsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXO1lBQ2hELENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVc7WUFDekIsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyw4QkFBOEIsSUFBSSxFQUFFLENBQUM7UUFDOUYsSUFBTSxXQUFXLEdBQ2IsT0FBTyw4QkFBOEIsQ0FBQyxRQUFRLEtBQUssUUFBUTtZQUN2RCxDQUFDLENBQUMsOEJBQThCLENBQUMsUUFBUTtZQUN6QyxDQUFDLENBQUMsT0FBTyxrQkFBa0IsQ0FBQyxRQUFRLEtBQUssUUFBUTtnQkFDakQsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLFFBQVE7Z0JBQzdCLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDZCxJQUFNLFlBQVksR0FDZCxPQUFPLDhCQUE4QixDQUFDLFNBQVMsS0FBSyxRQUFRO1lBQ3hELENBQUMsQ0FBQyw4QkFBOEIsQ0FBQyxTQUFTO1lBQzFDLENBQUMsQ0FBQyxPQUFPLGtCQUFrQixDQUFDLFNBQVMsS0FBSyxRQUFRO2dCQUNsRCxDQUFDLENBQUMsa0JBQWtCLENBQUMsU0FBUztnQkFDOUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ2QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEdBQUc7WUFDdEIsUUFBUSxFQUFFLFdBQVc7WUFDckIsU0FBUyxFQUFFLFlBQVk7U0FDMUIsQ0FBQztRQUNGLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFO1lBQzNCLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNqRCxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDdEQ7SUFDTCxDQUFDO0lBT0QsaURBQXlCLEdBQXpCLFVBQTBCLEtBQXVCO1FBQzdDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFBRSxDQUFDLEVBQUU7WUFFbEQsSUFBSSxLQUFLLENBQUMsU0FBUyxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLEVBQUU7Z0JBRWxELEtBQUssQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUNsRDtTQUNKO1FBQ0QsS0FBSyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDdEIsS0FBSyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFFdkIsSUFDSSxRQUFRLENBQUMsZUFBZSxFQUFFO1lBQzFCLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRTtnQkFDdEIsQ0FBQyxRQUFRLENBQUMscUJBQXFCLEVBQUU7b0JBQzdCLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRTtvQkFDOUIsUUFBUSxDQUFDLG9CQUFvQixFQUFFO29CQUMvQixRQUFRLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxDQUFDLEVBQzdDO1lBQ0UsS0FBSyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7U0FDNUI7UUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRTtZQUNYLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztZQUVsRixJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRTtnQkFDbEMsSUFBSSxDQUFDLEVBQUUsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDO2FBQ3RCO1NBQ0o7UUFFRCxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUU1QyxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDakM7YUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFLEVBQUU7WUFFdkQsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7WUFDbkIsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUU7Z0JBRTNGLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUNqQztpQkFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsRUFBRTtnQkFFakcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUMzQjtTQUNKO0lBQ0wsQ0FBQztJQUtELHVDQUFlLEdBQWY7UUFBQSxpQkEwQkM7UUF6QkcsS0FBSyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFO1lBQ3JFLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRTtnQkFDaEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7YUFDbkQ7U0FDSjtRQUVELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQUMsa0JBQWtCO1lBRW5DLElBQUksQ0FBQyxDQUFDLGtCQUFrQixDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLG1CQUFtQixFQUFFO2dCQUM5RSxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLEtBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQzthQUNqRjtZQUNELGtCQUFrQixDQUFDLG9CQUFvQixHQUFHLEtBQUssQ0FBQztZQUNoRCxJQUFJLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLEVBQUU7Z0JBR3BDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxVQUFXLENBQUMsV0FBVyxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMzRSxLQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyx1QkFBdUIsRUFBRTtvQkFDdkMsSUFBSSxxQ0FBaUIsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsS0FBSSxFQUFFLHVCQUF1QixDQUFDO2lCQUNqRixDQUFDLENBQUM7YUFDTjtZQUVELEtBQUksQ0FBQyxlQUFlLENBQUMsa0JBQWtCLENBQUMsQ0FBQztZQUV6QyxLQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFDLENBQUMsSUFBSyxPQUFBLENBQUMsQ0FBQyxDQUFDLGFBQWEsRUFBaEIsQ0FBZ0IsQ0FBQyxDQUFDO1FBQ2hELENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELHlDQUFpQixHQUFqQixVQUFrQixLQUF1QjtRQUNyQyxJQUFJLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFDMUIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3pDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFO2dCQUNoQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUMxRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3pCLGFBQWEsR0FBRyxJQUFJLENBQUM7Z0JBQ3JCLE1BQU0sQ0FBQyxJQUFJLENBQUMsbUNBQW1DLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3ZELE1BQU07YUFDVDtTQUNKO1FBQ0QsT0FBTyxhQUFhLENBQUM7SUFDekIsQ0FBQztJQUtELGdEQUF3QixHQUF4QjtRQUNJLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxvQkFBb0IsRUFBRTtZQUNwRixJQUFJLENBQUMsMENBQTBDLEVBQUUsQ0FBQztZQUNsRCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQ3ZFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO1NBQzlDO0lBQ0wsQ0FBQztJQUtELHlDQUFpQixHQUFqQixVQUFrQixXQUF3QjtRQUN0QyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFDLGtCQUFrQjtZQUNuQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLFdBQVcsQ0FBQztZQUNqRCxJQUFJLFFBQVEsQ0FBQyxVQUFVLEVBQUUsRUFBRTtnQkFHdkIsSUFBTSxPQUFPLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQztnQkFDdkQsSUFBTSxRQUFRLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDO2dCQUMxQyxPQUFTLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDM0Qsa0JBQWtCLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQzthQUN2QztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtELGlDQUFTLEdBQVQsVUFBVSxJQUFZLEVBQUUsVUFBaUI7UUFDckMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFLRCxtQ0FBVyxHQUFYO1FBQ0ksT0FBTyxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFLRCx1Q0FBZSxHQUFmLFVBQWdCLGtCQUFzQztRQUNsRCxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUMxQyxJQUFJLENBQUMsNENBQTRDLEVBQUUsQ0FBQztJQUN4RCxDQUFDO0lBU1MsaURBQXlCLEdBQW5DLFVBQW9DLGtCQUFzQztRQUN0RSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO1FBQ2hDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRTtZQUN6RCxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ2pEO0lBQ0wsQ0FBQztJQUVPLG1DQUFXLEdBQW5CLFVBQW9CLEtBQXVCO1FBQ3ZDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLEVBQUU7WUFDeEIsS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsaUJBQWlCLENBQUM7WUFDMUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsaUJBQWlCLENBQUM7U0FDbkQ7SUFDTCxDQUFDO0lBRU8seUNBQWlCLEdBQXpCLFVBQTBCLEtBQXVCO1FBQzdDLEtBQUssQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQztRQUNoQyxLQUFLLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUM7SUFDMUMsQ0FBQztJQUVPLHVDQUFlLEdBQXZCLFVBQXdCLEtBQXVCO1FBQzNDLE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLEtBQUssaUJBQWlCLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxlQUFlLEtBQUssaUJBQWlCLENBQUM7SUFDNUcsQ0FBQztJQUVPLGtFQUEwQyxHQUFsRDtRQUFBLGlCQTBCQztRQXpCRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUVkLE9BQU87U0FDVjtRQUNELElBQUksSUFBSSxDQUFDLGtDQUFrQyxJQUFJLElBQUksRUFBRTtZQUVqRCxPQUFPO1NBQ1Y7UUFFRCxJQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMscUJBQXFCLENBQUMsb0NBQW9DLElBQUksSUFBSSxDQUFDO1FBQ2xILElBQUksQ0FBQyxrQ0FBa0MsR0FBRyxVQUFVLENBQUM7WUFDakQsSUFBTSxHQUFHLEdBQ0wsMEJBQTBCO2dCQUMxQixLQUFJLENBQUMsTUFBTSxDQUFDLFFBQVE7Z0JBQ3BCLElBQUk7Z0JBQ0osQ0FBQyxLQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztnQkFDMUMsNkNBQTZDO2dCQUM3QyxTQUFTO2dCQUNULEtBQUssQ0FBQztZQUNWLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakIsS0FBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRTtnQkFDdkMsSUFBSSwrQkFBYyxDQUFDLEtBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLG1DQUFrQixDQUFDLHVCQUF1QixFQUFRLEtBQW1CLEVBQUUsR0FBRyxDQUFDO2FBQ3RILENBQUMsQ0FBQztZQUNILE9BQU8sS0FBSSxDQUFDLGtDQUFrQyxDQUFDO1FBQ25ELENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUNsQixDQUFDO0lBRU8sb0VBQTRDLEdBQXBEO1FBQ0ksWUFBWSxDQUFDLElBQUksQ0FBQyxrQ0FBeUMsQ0FBQyxDQUFDO1FBQzdELE9BQU8sSUFBSSxDQUFDLGtDQUFrQyxDQUFDO0lBQ25ELENBQUM7SUFDTCxvQkFBQztBQUFELENBM2pCQSxBQTJqQkMsQ0EzakIyQyxpQ0FBZSxHQTJqQjFEO0FBM2pCcUIsc0NBQWE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQy9CbkMsaURBQWdEO0FBRWhELDRFQUEyRTtBQUszRSxJQUFNLE1BQU0sR0FBbUIsK0JBQWMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztBQU81RDtJQUFnQyw4QkFBYTtJQVN6QyxvQkFBWSxNQUFjLEVBQUUsTUFBd0MsRUFBRSxVQUFnQztRQUF0RyxZQUNJLGtCQUFNLE1BQU0sRUFBRSxNQUFNLENBQUMsU0FJeEI7UUFIRyxLQUFJLENBQUMsT0FBTyxHQUFHLEtBQUksQ0FBQyxhQUFhLENBQUM7UUFDbEMsS0FBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsS0FBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7O0lBQ2pDLENBQUM7SUFNRCxxQ0FBZ0IsR0FBaEIsVUFBaUIsS0FBYztRQUMzQixJQUFJLENBQUMsTUFBTTthQUNOLGNBQWMsRUFBRTthQUNoQixjQUFjLEVBQUU7YUFDaEIsT0FBTyxDQUFDLFVBQUMsS0FBSztZQUNYLEtBQUssQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO1FBQ1AsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ2hDLE1BQU0sQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3pHLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFNRCxxQ0FBZ0IsR0FBaEIsVUFBaUIsS0FBYztRQUMzQixJQUFJLENBQUMsTUFBTTthQUNOLGNBQWMsRUFBRTthQUNoQixjQUFjLEVBQUU7YUFDaEIsT0FBTyxDQUFDLFVBQUMsS0FBSztZQUNYLEtBQUssQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO1FBQ1AsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ2hDLE1BQU0sQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3pHLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFPRCw4Q0FBeUIsR0FBekIsVUFBMEIsS0FBdUIsRUFBRSxxQkFBOEI7UUFDN0UsSUFBTSxXQUFXLEdBQWdCLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDOUQsSUFBSSxZQUE4QixDQUFDO1FBQ25DLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7WUFDeEIsWUFBWSxHQUFHLFdBQVcsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMvQyxJQUFJLHFCQUFxQixFQUFFO2dCQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLHlCQUF5QixHQUFHLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUNsRTtTQUNKO2FBQU07WUFDSCxZQUFZLEdBQUcsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ2xEO1FBQ0QsV0FBVyxDQUFDLFdBQVcsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN0QyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDcEIsV0FBVyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBQ0wsaUJBQUM7QUFBRCxDQXBFQSxBQW9FQyxDQXBFK0IsNkJBQWEsR0FvRTVDO0FBcEVZLGdDQUFVOzs7Ozs7QUNmdkIsSUFBWSxrQkFLWDtBQUxELFdBQVksa0JBQWtCO0lBQzFCLHFDQUFlLENBQUE7SUFDZiw2Q0FBdUIsQ0FBQTtJQUN2Qix1Q0FBaUIsQ0FBQTtJQUNqQiwyQ0FBcUIsQ0FBQTtBQUN6QixDQUFDLEVBTFcsa0JBQWtCLEdBQWxCLDBCQUFrQixLQUFsQiwwQkFBa0IsUUFLN0I7Ozs7OztBQ0ZELElBQVksaUJBaUdYO0FBakdELFdBQVksaUJBQWlCO0lBS3pCLG9FQUErQyxDQUFBO0lBTS9DLGtFQUE2QyxDQUFBO0lBUTdDLG9FQUErQyxDQUFBO0lBTS9DLG9FQUErQyxDQUFBO0lBTS9DLGtGQUE2RCxDQUFBO0lBTTdELHNGQUFpRSxDQUFBO0lBTWpFLDRFQUF1RCxDQUFBO0lBTXZELGtGQUE2RCxDQUFBO0lBTTdELGtGQUE2RCxDQUFBO0lBTTdELDBGQUFxRSxDQUFBO0lBTXJFLGdFQUEyQyxDQUFBO0lBTzNDLDhFQUF5RCxDQUFBO0lBTXpELDhFQUF5RCxDQUFBO0lBTXpELHNFQUFpRCxDQUFBO0lBS2pELDBFQUFxRCxDQUFBO0lBS3JELG9EQUErQixDQUFBO0FBQ25DLENBQUMsRUFqR1csaUJBQWlCLEdBQWpCLHlCQUFpQixLQUFqQix5QkFBaUIsUUFpRzVCO0FBS0Q7SUFjSSx1QkFBWSxJQUF1QixFQUFFLE9BQWU7UUFDaEQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDM0IsQ0FBQztJQUNMLG9CQUFDO0FBQUQsQ0FsQkEsQUFrQkMsSUFBQTtBQWxCWSxzQ0FBYTs7Ozs7O0FDekcxQixJQUFZLFdBS1g7QUFMRCxXQUFZLFdBQVc7SUFDbkIsZ0NBQWlCLENBQUE7SUFDakIsZ0NBQWlCLENBQUE7SUFDakIsZ0NBQWlCLENBQUE7SUFDakIsOEJBQWUsQ0FBQTtBQUNuQixDQUFDLEVBTFcsV0FBVyxHQUFYLG1CQUFXLEtBQVgsbUJBQVcsUUFLdEI7Ozs7OztBQ0ZELElBQVksZUFxQlg7QUFyQkQsV0FBWSxlQUFlO0lBSXZCLGtDQUFlLENBQUE7SUFJZixvQ0FBaUIsQ0FBQTtJQUlqQixvQ0FBaUIsQ0FBQTtJQUlqQixzQ0FBbUIsQ0FBQTtJQUluQixzQ0FBbUIsQ0FBQTtBQUN2QixDQUFDLEVBckJXLGVBQWUsR0FBZix1QkFBZSxLQUFmLHVCQUFlLFFBcUIxQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDeEJELGlDQUFnQztBQVVoQztJQUFxQyxtQ0FBSztJQXNCdEMseUJBQVksVUFBbUIsRUFBRSxNQUFlLEVBQUUsSUFBWSxFQUFFLFVBQXNCLEVBQUUsTUFBNkI7UUFBckgsWUFDSSxrQkFBTSxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxTQUdsQztRQUZHLEtBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLEtBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDOztJQUN6QixDQUFDO0lBTUQsNkNBQW1CLEdBQW5CLGNBQXdCLENBQUM7SUFDN0Isc0JBQUM7QUFBRCxDQWpDQSxBQWlDQyxDQWpDb0MsYUFBSyxHQWlDekM7QUFqQ1ksMENBQWU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ1I1QixpQ0FBZ0M7QUFXaEM7SUFBb0Qsa0RBQUs7SUF3QnJELHdDQUFZLE1BQWUsRUFBRSxVQUFzQixFQUFFLGVBQXVCLEVBQUUsUUFBZ0IsRUFBRSxRQUFnQjtRQUFoSCxZQUNJLGtCQUFNLEtBQUssRUFBRSxNQUFNLEVBQUUsMkJBQTJCLENBQUMsU0FLcEQ7UUFKRyxLQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixLQUFJLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQztRQUN2QyxLQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixLQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQzs7SUFDN0IsQ0FBQztJQU1ELDREQUFtQixHQUFuQixjQUF1QixDQUFDO0lBQzVCLHFDQUFDO0FBQUQsQ0FyQ0EsQUFxQ0MsQ0FyQ21ELGFBQUssR0FxQ3hEO0FBckNZLHdFQUE4Qjs7Ozs7O0FDVDNDO0lBd0JJLGVBQVksVUFBbUIsRUFBRSxNQUF3QyxFQUFFLElBQVk7UUFMdkYscUJBQWdCLEdBQUcsS0FBSyxDQUFDO1FBTXJCLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ3JCLENBQUM7SUFLRCxrQ0FBa0IsR0FBbEI7UUFDSSxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztJQUNqQyxDQUFDO0lBZ0JELDhCQUFjLEdBQWQ7UUFFSSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsY0FBTyxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztJQUNqQyxDQUFDO0lBTUwsWUFBQztBQUFELENBN0RBLEFBNkRDLElBQUE7QUE3RHFCLHNCQUFLOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNEM0IsaUNBQWdDO0FBS2hDLElBQVksa0JBaUVYO0FBakVELFdBQVksa0JBQWtCO0lBTTFCLGlFQUEyQyxDQUFBO0lBWTNDLHFFQUErQyxDQUFBO0lBZ0IvQyxpRkFBMkQsQ0FBQTtJQXFCM0QseUVBQW1ELENBQUE7SUFTbkQsaUZBQTJELENBQUE7QUFDL0QsQ0FBQyxFQWpFVyxrQkFBa0IsR0FBbEIsMEJBQWtCLEtBQWxCLDBCQUFrQixRQWlFN0I7QUFLRDtJQUFvQyxrQ0FBSztJQTJCckMsd0JBQVksT0FBZ0IsRUFBRSxJQUF3QixFQUFFLE1BQXFDLEVBQUUsT0FBZSxFQUFFLElBQVU7UUFBMUgsWUFDSSxrQkFBTSxLQUFLLEVBQUUsT0FBTyxFQUFFLFdBQVcsQ0FBQyxTQUtyQztRQUpHLEtBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLEtBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLEtBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLEtBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDOztJQUNyQixDQUFDO0lBTUQsNENBQW1CLEdBQW5CLGNBQXdCLENBQUM7SUFDN0IscUJBQUM7QUFBRCxDQXhDQSxBQXdDQyxDQXhDbUMsYUFBSyxHQXdDeEM7QUF4Q1ksd0NBQWM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQzlFM0IsaUNBQWdDO0FBTWhDO0lBQWlDLCtCQUFLO0lBU2xDLHFCQUFZLE1BQWMsRUFBRSxTQUFpQixFQUFFLElBQVk7UUFBM0QsWUFDSSxrQkFBTSxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxTQUVsQztRQURHLEtBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDOztJQUNyQixDQUFDO0lBTUQseUNBQW1CLEdBQW5CLGNBQXVCLENBQUM7SUFDNUIsa0JBQUM7QUFBRCxDQW5CQSxBQW1CQyxDQW5CZ0MsYUFBSyxHQW1CckM7QUFuQlksa0NBQVc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ054QixpQ0FBZ0M7QUFPaEM7SUFBcUQsbURBQUs7SUFtQnRELHlDQUFZLE1BQWUsRUFBRSxRQUFnQixFQUFFLFFBQWdCLEVBQUUsVUFBc0I7UUFBdkYsWUFDSSxrQkFBTSxLQUFLLEVBQUUsTUFBTSxFQUFFLDRCQUE0QixDQUFDLFNBSXJEO1FBSEcsS0FBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsS0FBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsS0FBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7O0lBQ2pDLENBQUM7SUFNRCw2REFBbUIsR0FBbkIsY0FBdUIsQ0FBQztJQUM1QixzQ0FBQztBQUFELENBL0JBLEFBK0JDLENBL0JvRCxhQUFLLEdBK0J6RDtBQS9CWSwwRUFBK0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ1A1QyxpQ0FBZ0M7QUFVaEM7SUFBNEMsMENBQUs7SUFjN0MsZ0NBQVksTUFBK0IsRUFBRSxJQUFZLEVBQUUsVUFBc0IsRUFBRSxRQUFnQjtRQUFuRyxZQUNJLGtCQUFNLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBSTdCO1FBSEcsS0FBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsS0FBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsS0FBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7O0lBQzdCLENBQUM7SUFNRCxvREFBbUIsR0FBbkIsY0FBdUIsQ0FBQztJQUM1Qiw2QkFBQztBQUFELENBMUJBLEFBMEJDLENBMUIyQyxhQUFLLEdBMEJoRDtBQTFCWSx3REFBc0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ1ZuQyxpQ0FBZ0M7QUFTaEM7SUFBb0Msa0NBQUs7SUE4QnJDLHdCQUFZLE1BQWUsRUFBRSxJQUFZLEVBQUUsRUFBVSxFQUFFLElBQVksRUFBRSxNQUE2QjtRQUFsRyxZQUNJLGtCQUFNLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBTTdCO1FBTEcsS0FBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUM7UUFDYixJQUFJLElBQUksS0FBSyxFQUFFLEVBQUU7WUFDYixLQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztTQUNwQjtRQUNELEtBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDOztJQUN6QixDQUFDO0lBTUQsNENBQW1CLEdBQW5CLGNBQXdCLENBQUM7SUFDN0IscUJBQUM7QUFBRCxDQTVDQSxBQTRDQyxDQTVDbUMsYUFBSyxHQTRDeEM7QUE1Q1ksd0NBQWM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ1QzQixpQ0FBZ0M7QUFFaEMsMkRBQTBEO0FBTTFELElBQU0sTUFBTSxHQUFtQiwrQkFBYyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBSzVEO0lBQThDLDRDQUFLO0lBa0IvQyxrQ0FBWSxNQUFlLEVBQUUsTUFBNkI7UUFBMUQsWUFDSSxrQkFBTSxJQUFJLEVBQUUsTUFBTSxFQUFFLHFCQUFxQixDQUFDLFNBRTdDO1FBREcsS0FBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7O0lBQ3pCLENBQUM7SUFLRCxzREFBbUIsR0FBbkI7UUFDSSxNQUFNLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxHQUFHLElBQUksQ0FBQyxJQUFJLEdBQUcsaUNBQWlDLENBQUMsQ0FBQztRQUUvRixJQUFNLE9BQU8sR0FBWSxJQUFJLENBQUMsTUFBTSxDQUFDO1FBR3JDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsVUFBQyxnQkFBZ0I7O1lBQy9DLElBQU0sWUFBWSxHQUFHLGdCQUFnQixDQUFDLFlBQVksQ0FBQztZQUNuRCxJQUFJLENBQUMsQ0FBQyxDQUFBLE1BQUEsT0FBTyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsMENBQUUsTUFBTSxDQUFBLEVBQUU7Z0JBQ3ZELE1BQUEsT0FBTyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsMENBQUUsTUFBTSxDQUFFLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3pFLE1BQUEsT0FBTyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsMENBQUUsTUFBTSxDQUFFLGtCQUFrQixFQUFFLENBQUM7Z0JBQzFFLElBQUksTUFBQSxPQUFPLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQywwQ0FBRSxNQUFNLENBQUUsYUFBYSxFQUFFO29CQUNwRSxNQUFBLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLDBDQUFFLE1BQU0sQ0FBRSxhQUFhLENBQUMsZUFBZSxFQUFFLENBQUM7aUJBQ3hGO2dCQUNELElBQU0sUUFBUSxHQUFHLE1BQUEsTUFBQSxPQUFPLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQywwQ0FBRSxNQUFNLDBDQUFFLFFBQVEsQ0FBQztnQkFDL0UsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFO29CQUNaLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7aUJBQ2pEO2dCQUNELE1BQUEsT0FBTyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsMENBQUUsT0FBTyxFQUFFLENBQUM7YUFDMUQ7WUFDRCxPQUFPLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ25ELENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUNMLCtCQUFDO0FBQUQsQ0FqREEsQUFpREMsQ0FqRDZDLGFBQUssR0FpRGxEO0FBakRZLDREQUF3Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDYnJDLGlDQUFnQztBQU9oQztJQUFpQywrQkFBSztJQXlCbEMscUJBQVksTUFBZSxFQUFFLElBQWEsRUFBRSxJQUFhLEVBQUUsSUFBaUI7UUFBNUUsWUFDSSxrQkFBTSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxTQU1qQztRQUxHLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRTtZQUNSLEtBQUksQ0FBQyxJQUFJLEdBQUcsU0FBUyxHQUFHLElBQUksQ0FBQztTQUNoQztRQUNELEtBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLEtBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDOztJQUNyQixDQUFDO0lBTUQseUNBQW1CLEdBQW5CLGNBQXVCLENBQUM7SUFDNUIsa0JBQUM7QUFBRCxDQXZDQSxBQXVDQyxDQXZDZ0MsYUFBSyxHQXVDckM7QUF2Q1ksa0NBQVc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ1B4QixpQ0FBZ0M7QUFRaEM7SUFBdUMscUNBQUs7SUFnQ3hDLDJCQUFZLE1BQWUsRUFBRSxVQUFzQixFQUFFLElBQVksRUFBRSxNQUErQixFQUFFLEdBQVcsRUFBRSxJQUFZO1FBQTdILFlBQ0ksa0JBQU0sS0FBSyxFQUFFLE1BQU0sRUFBRSxxQkFBcUIsQ0FBQyxTQU05QztRQUxHLEtBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLEtBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLEtBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLEtBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBQ2YsS0FBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7O0lBQ3JCLENBQUM7SUFNRCwrQ0FBbUIsR0FBbkIsY0FBd0IsQ0FBQztJQUM3Qix3QkFBQztBQUFELENBOUNBLEFBOENDLENBOUNzQyxhQUFLLEdBOEMzQztBQTlDWSw4Q0FBaUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ1I5QixpQ0FBZ0M7QUFDaEMsc0RBQXFEO0FBQ3JELGtEQUFpRDtBQUVqRCwyREFBMEQ7QUFNMUQsSUFBTSxNQUFNLEdBQW1CLCtCQUFjLENBQUMsV0FBVyxFQUFFLENBQUM7QUFPNUQ7SUFBaUMsK0JBQUs7SUF5QmxDLHFCQUFZLFVBQW1CLEVBQUUsTUFBMkIsRUFBRSxJQUFZLEVBQUUsTUFBYyxFQUFFLE1BQXlCO1FBQXJILFlBQ0ksa0JBQU0sVUFBVSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FHbEM7UUFGRyxLQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixLQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQzs7SUFDekIsQ0FBQztJQUtELHlDQUFtQixHQUFuQjtRQUNJLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxpQkFBaUIsRUFBRTtZQUNqQyxJQUFJLElBQUksQ0FBQyxNQUFNLFlBQVksaUJBQU8sRUFBRTtnQkFFaEMsTUFBTSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLGlDQUFpQyxDQUFDLENBQUM7Z0JBQy9GLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLEVBQUUsQ0FBQzthQUNuQztpQkFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLFlBQVkscUJBQVMsRUFBRTtnQkFFekMsTUFBTSxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLG1DQUFtQyxDQUFDLENBQUM7Z0JBQ2pHLGFBQWEsQ0FBYSxJQUFJLENBQUMsTUFBTyxDQUFDLHlCQUF5QixDQUFDLENBQUM7Z0JBQ2xFLElBQUksQ0FBQyxNQUFNLENBQUMsMkJBQTJCLEdBQUcsS0FBSyxDQUFDO2dCQUdoRCxJQUFNLGtCQUFrQixHQUFlLElBQUksQ0FBQyxNQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQztnQkFDeEUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtvQkFDaEQsSUFBSSxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsS0FBZ0IsSUFBSSxDQUFDLE1BQU0sRUFBRTt3QkFDbEQsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzt3QkFDaEMsTUFBTTtxQkFDVDtpQkFDSjthQUNKO1lBR0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBSWpDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhO2dCQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBRzNFLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBR3RFLElBQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3hHLElBQUksQ0FBQyxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUU7Z0JBQ3hELElBQU0sbUJBQW1CLEdBQUcsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQztnQkFDbkUsS0FBSyxJQUFJLENBQUMsR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUU7b0JBQ3RELElBQUksbUJBQW1CLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO3dCQUNwRCxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO3FCQUNwQztpQkFDSjthQUNKO1NBQ0o7SUFDTCxDQUFDO0lBQ0wsa0JBQUM7QUFBRCxDQTlFQSxBQThFQyxDQTlFZ0MsYUFBSyxHQThFckM7QUE5RVksa0NBQVc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2pCeEIsaUNBQWdDO0FBUWhDO0lBQXdDLHNDQUFLO0lBYXpDLDRCQUFZLE1BQXFCLEVBQUUsSUFBWSxFQUFFLEtBQXlCO1FBQTFFLFlBQ0ksa0JBQU0sS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FFN0I7UUFERyxLQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQzs7SUFDdkIsQ0FBQztJQU1ELGdEQUFtQixHQUFuQixjQUF1QixDQUFDO0lBQzVCLHlCQUFDO0FBQUQsQ0F2QkEsQUF1QkMsQ0F2QnVDLGFBQUssR0F1QjVDO0FBdkJZLGdEQUFrQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDUi9CLGlDQUFnQztBQVNoQztJQUFnRCw4Q0FBSztJQW1DakQsb0NBQ0ksTUFBK0IsRUFDL0IsTUFBYyxFQUNkLGVBQW9DLEVBQ3BDLFFBQWdCLEVBQ2hCLFFBQWdCLEVBQ2hCLE1BQXdDO1FBTjVDLFlBUUksa0JBQU0sS0FBSyxFQUFFLE1BQU0sRUFBRSx1QkFBdUIsQ0FBQyxTQU1oRDtRQUxHLEtBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLEtBQUksQ0FBQyxlQUFlLEdBQUcsZUFBZSxDQUFDO1FBQ3ZDLEtBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLEtBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLEtBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDOztJQUN6QixDQUFDO0lBTUQsd0RBQW1CLEdBQW5CLGNBQXdCLENBQUM7SUFDN0IsaUNBQUM7QUFBRCxDQXhEQSxBQXdEQyxDQXhEK0MsYUFBSyxHQXdEcEQ7QUF4RFksZ0VBQTBCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNUdkMsaUNBQWdDO0FBUWhDO0lBQXVDLHFDQUFLO0lBU3hDLDJCQUFZLE9BQXlCLEVBQUUsTUFBcUIsRUFBRSxJQUFZO1FBQTFFLFlBQ0ksa0JBQU0sS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FFN0I7UUFERyxLQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQzs7SUFDM0IsQ0FBQztJQU1ELCtDQUFtQixHQUFuQixjQUF1QixDQUFDO0lBQzVCLHdCQUFDO0FBQUQsQ0FuQkEsQUFtQkMsQ0FuQnNDLGFBQUssR0FtQjNDO0FBbkJZLDhDQUFpQjs7O0FDekI5QixTQUFTLE1BQU07SUFDWCxJQUFJLE9BQU8sR0FBRyxFQUFFLENBQUM7SUFFakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxVQUFVLFFBQVE7UUFDN0IsS0FBSyxJQUFJLEdBQUcsSUFBSSxPQUFPLEVBQUU7WUFDckIsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRTFCLEtBQUssSUFBSSxJQUFJLElBQUksTUFBTTtnQkFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7U0FDbkQ7SUFDTCxDQUFDLENBQUM7SUFFRixJQUFJLENBQUMsR0FBRyxHQUFHLFVBQVUsRUFBRSxFQUFFLE1BQU07UUFDM0IsSUFBSSxHQUFHLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzFCLElBQUksR0FBRyxJQUFJLFNBQVM7WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUV2QyxPQUFPLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNuQixDQUFDLENBQUM7SUFFRixJQUFJLENBQUMsTUFBTSxHQUFHLFVBQVUsRUFBRSxFQUFFLE1BQU07UUFDOUIsSUFBSSxHQUFHLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzFCLElBQUksR0FBRyxJQUFJLFNBQVM7WUFBRSxPQUFPO1FBRTdCLE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBR2YsS0FBSyxJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUU7WUFDZixPQUFPLEtBQUssQ0FBQztTQUNoQjtRQUVELE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzNCLENBQUMsQ0FBQztJQUVGLElBQUksQ0FBQyxHQUFHLEdBQUcsVUFBVSxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU07UUFDbEMsSUFBSSxLQUFLLElBQUksU0FBUztZQUFFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFdkQsSUFBSSxHQUFHLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzFCLElBQUksR0FBRyxJQUFJLFNBQVM7WUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUVqRCxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQ3BCLENBQUMsQ0FBQztBQUNOLENBQUM7QUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsR0FBRyxVQUFVLEVBQUUsRUFBRSxNQUFNO0lBQ3ZDLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2pDLElBQUksS0FBSyxJQUFJLFNBQVM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUV6QyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUV4QixPQUFPLEtBQUssQ0FBQztBQUNqQixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQzs7O0FDbEN4QixJQUFJLGFBQWEsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQUUvQyxPQUFPLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQzs7O0FDRnRDLElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNoQyxJQUFJLHlCQUF5QixHQUFHLE9BQU8sQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO0FBQ2xGLElBQUksY0FBYyxHQUFHLE9BQU8sQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDLGNBQWMsQ0FBQztBQUU5RSxJQUFJLENBQUMsR0FBRztJQUNKLElBQUksQ0FBQyxHQUFHO1FBQ1I7WUFDSSxPQUFPLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN2QixDQUFDLENBQUM7QUFFTixJQUFJLGFBQWEsR0FBRyxJQUFJLENBQUM7QUFFekIsSUFBSSxZQUFZLEdBQUcsY0FBYyxDQUFDO0FBQ2xDLElBQUksU0FBUyxHQUFHLFdBQVcsQ0FBQztBQUM1QixJQUFJLFlBQVksR0FBRyxjQUFjLENBQUM7QUFFbEMsSUFBSSxNQUFNLEdBQUcsY0FBYyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBcUIxQyxTQUFTLGFBQWEsQ0FBQyxhQUFhO0lBQ2hDLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQztJQUVoQixJQUFJLFFBQVEsR0FBRyxhQUFhLENBQUMsRUFBRSxDQUFDO0lBRWhDLElBQUkseUJBQXlCLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFbkMsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0lBQ3BCLElBQUksWUFBWSxHQUFHLElBQUksQ0FBQztJQUN4QixJQUFJLGVBQWUsR0FBRyxLQUFLLENBQUM7SUFDNUIsSUFBSSxZQUFZLENBQUM7SUFFakIsSUFBSSxNQUFNLEdBQUcsWUFBWSxDQUFDO0lBRTFCLElBQUksY0FBYyxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUM7SUFDN0MsSUFBSSxhQUFhLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQztJQUMzQyxJQUFJLFdBQVcsR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDO0lBQ3ZDLElBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUM7SUFFL0IsYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsVUFBVSxNQUFNLEVBQUUsT0FBTztRQUM5QyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNoQyxDQUFDLENBQUM7SUFFRixRQUFRLENBQUMsY0FBYyxHQUFHO1FBQ3RCLE1BQU0sQ0FBQyxLQUFLLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUNyRCxJQUFJLE1BQU0sS0FBSyxZQUFZLEVBQUU7WUFDekIsTUFBTSxDQUFDLEtBQUssQ0FBQyxrR0FBa0csQ0FBQyxDQUFDO1lBQ2pILE9BQU87U0FDVjtRQUVELFFBQVEsRUFBRSxDQUFDO1FBRVgsTUFBTSxHQUFHLFlBQVksQ0FBQztRQUN0QixJQUFJLGNBQWMsRUFBRTtZQUNoQixjQUFjLEVBQUUsQ0FBQztTQUNwQjtJQUNMLENBQUMsQ0FBQztJQUVGLFFBQVEsQ0FBQyxhQUFhLEdBQUc7UUFDckIsTUFBTSxDQUFDLEtBQUssQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ3BELElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRTtZQUN0QixNQUFNLENBQUMsS0FBSyxDQUFDLDhGQUE4RixDQUFDLENBQUM7WUFDN0csT0FBTztTQUNWO1FBQ0QsTUFBTSxHQUFHLFNBQVMsQ0FBQztRQUVuQiw0QkFBNEIsRUFBRSxDQUFDO1FBRS9CLElBQUksYUFBYSxFQUFFO1lBQ2YsYUFBYSxFQUFFLENBQUM7U0FDbkI7SUFDTCxDQUFDLENBQUM7SUFFRixRQUFRLENBQUMsV0FBVyxHQUFHO1FBQ25CLE1BQU0sQ0FBQyxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQztRQUNsRCxJQUFJLE1BQU0sS0FBSyxTQUFTLEVBQUU7WUFDdEIsTUFBTSxDQUFDLEtBQUssQ0FBQyw0RkFBNEYsQ0FBQyxDQUFDO1lBQzNHLE9BQU87U0FDVjtRQUNELE1BQU0sR0FBRyxTQUFTLENBQUM7UUFFbkIsWUFBWSxHQUFHLElBQUksQ0FBQztRQUNwQixPQUFPLEVBQUUsQ0FBQztRQUVWLElBQUksV0FBVyxFQUFFO1lBQ2IsV0FBVyxFQUFFLENBQUM7U0FDakI7SUFDTCxDQUFDLENBQUM7SUFFRixRQUFRLENBQUMsT0FBTyxHQUFHLFVBQVUsS0FBSztRQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixDQUFDLENBQUM7UUFFOUMsTUFBTSxHQUFHLFlBQVksQ0FBQztRQUV0QixRQUFRLEVBQUUsQ0FBQztRQUVYLElBQUksT0FBTyxFQUFFO1lBQ1QsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ2xCO0lBQ0wsQ0FBQyxDQUFDO0lBRUYsSUFBSSxFQUFFLEdBQUcsSUFBSSx5QkFBeUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUVqRCxNQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUU3RCxJQUFJLGlCQUFpQixHQUFHO1FBQ3BCLGVBQWUsRUFBRSxhQUFhLENBQUMsR0FBRyxDQUFDLGNBQWM7UUFDakQsb0JBQW9CLEVBQUUsYUFBYSxDQUFDLEdBQUcsQ0FBQyx1QkFBdUI7S0FDbEUsQ0FBQztJQUVGLElBQUksR0FBRyxHQUFHLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLEVBQUUsRUFBRSxVQUFVLE9BQU87UUFDekYsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFFN0QsSUFBSTtZQUNBLElBQUksSUFBSSxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRTdDLElBQUksSUFBSSxLQUFLLFNBQVMsRUFBRTtnQkFDcEIsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLE1BQU0sR0FBRywyQkFBMkIsQ0FBQyxDQUFDO2FBQzFFO2lCQUFNO2dCQUNILElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO2FBQ2pDO1NBQ0o7UUFBQyxPQUFPLEdBQUcsRUFBRTtZQUNWLE1BQU0sQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQ3pFLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDckI7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxJQUFJLEdBQUcsVUFBVSxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVE7UUFDMUMsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRTdCLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEtBQUssRUFBRSxNQUFNO1lBQzlDLElBQUksS0FBSyxFQUFFO2dCQUNQLElBQUk7b0JBQ0EsTUFBTSxDQUFDLEtBQUssQ0FDUixRQUFRO3dCQUNKLEtBQUssQ0FBQyxPQUFPO3dCQUNiLHNCQUFzQjt3QkFDdEIsTUFBTTt3QkFDTixVQUFVO3dCQUNWLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO3dCQUN0QixXQUFXO3dCQUNYLEtBQUssQ0FBQyxPQUFPLENBQ3BCLENBQUM7b0JBQ0YsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFO3dCQUNaLE1BQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7cUJBQzVEO2lCQUNKO2dCQUFDLE9BQU8sQ0FBQyxFQUFFLEdBQUU7Z0JBQ2QsS0FBSyxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7YUFDbkM7WUFDRCxJQUFJLFFBQVEsRUFBRTtnQkFDVixJQUFJLE1BQU0sSUFBSSxTQUFTLElBQUksTUFBTSxDQUFDLEtBQUssS0FBSyxNQUFNLEVBQUU7b0JBQ2hELE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztpQkFDdkQ7Z0JBQ0QsUUFBUSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQzthQUMzQjtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQyxDQUFDO0lBRUYsU0FBUyw0QkFBNEI7UUFDakMsTUFBTSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsR0FBRyxXQUFXLEdBQUcsUUFBUSxHQUFHLHlCQUF5QixHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ3hHLHlCQUF5QixHQUFHLFdBQVcsQ0FBQztJQUM1QyxDQUFDO0lBRUQsU0FBUyxRQUFRO1FBQ2IsSUFBSSxZQUFZLEVBQUU7WUFDZCxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUM7WUFDbEIsSUFBSSxXQUFXLElBQUksQ0FBQyxJQUFJLFdBQVcsSUFBSSx5QkFBeUIsRUFBRTtnQkFDOUQsTUFBTSxHQUFHO29CQUNMLFFBQVEsRUFBRSxhQUFhLENBQUMsU0FBUyxJQUFJLGFBQWE7aUJBQ3JELENBQUM7YUFDTDtZQUNELFdBQVcsRUFBRSxDQUFDO1lBRWQsSUFBSSxDQUFDLElBQUksQ0FDTCxNQUFNLEVBQ04sTUFBTSxFQUNOLENBQUMsVUFBVSxPQUFPO2dCQUNkLE9BQU8sVUFBVSxLQUFLLEVBQUUsTUFBTTtvQkFDMUIsSUFBSSxLQUFLLEVBQUU7d0JBQ1AsTUFBTSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsR0FBRyxPQUFPLEdBQUcsSUFBSSxHQUFHLEtBQUssQ0FBQyxPQUFPLEdBQUcsR0FBRyxDQUFDLENBQUM7d0JBQy9FLElBQUksT0FBTyxHQUFHLHlCQUF5QixFQUFFOzRCQUNyQyxZQUFZLEdBQUcsS0FBSyxDQUFDOzRCQUNyQiw0QkFBNEIsRUFBRSxDQUFDOzRCQUMvQixNQUFNLENBQUMsS0FBSyxDQUFDLDBDQUEwQyxHQUFHLE9BQU8sR0FBRyxvQkFBb0IsQ0FBQyxDQUFDOzRCQUMxRixFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7eUJBQ3BCO3FCQUNKO2dCQUNMLENBQUMsQ0FBQztZQUNOLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUNsQixDQUFDO1NBQ0w7YUFBTTtZQUNILE1BQU0sQ0FBQyxLQUFLLENBQUMsOENBQThDLENBQUMsQ0FBQztTQUNoRTtJQUNMLENBQUM7SUFNRCxTQUFTLE9BQU87UUFDWixJQUFJLENBQUMsZUFBZSxFQUFFO1lBQ2xCLE1BQU0sQ0FBQyxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQztZQUM5QyxlQUFlLEdBQUcsSUFBSSxDQUFDO1lBRXZCLElBQUksYUFBYSxDQUFDLFNBQVMsSUFBSSxTQUFTLEVBQUU7Z0JBQ3RDLFlBQVksR0FBRyxXQUFXLENBQUMsUUFBUSxFQUFFLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDOUQsUUFBUSxFQUFFLENBQUM7YUFDZDtTQUNKO0lBQ0wsQ0FBQztJQUVELFNBQVMsUUFBUTtRQUNiLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM1QixlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLFlBQVksR0FBRyxLQUFLLENBQUM7UUFDckIsV0FBVyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2pCLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRUQsSUFBSSxDQUFDLEtBQUssR0FBRyxVQUFVLElBQUksRUFBRSxNQUFNO1FBQy9CLE1BQU0sQ0FBQyxLQUFLLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxHQUFHLFlBQVksR0FBRyxNQUFNLENBQUMsQ0FBQztRQUNwRSxJQUFJLFlBQVksSUFBSSxTQUFTLEVBQUU7WUFDM0IsTUFBTSxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQ3ZDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUMvQjtRQUNELGVBQWUsR0FBRyxLQUFLLENBQUM7UUFDeEIsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUNyQixFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUMzQixDQUFDLENBQUM7SUFFRixJQUFJLENBQUMsU0FBUyxHQUFHO1FBQ2IsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JCLENBQUMsQ0FBQztJQUVGLElBQUksQ0FBQyxTQUFTLEdBQUc7UUFDYixZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLFdBQVcsR0FBRyxDQUFDLENBQUM7UUFDaEIsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDLENBQUM7SUFFRixJQUFJLENBQUMsYUFBYSxHQUFHO1FBQ2pCLE9BQU8sRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQzlCLENBQUMsQ0FBQztBQUNOLENBQUM7QUFFRCxNQUFNLENBQUMsT0FBTyxHQUFHLGFBQWEsQ0FBQzs7O0FDdFEvQixJQUFJLHlCQUF5QixHQUFHLE9BQU8sQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO0FBRXZFLE9BQU8sQ0FBQyx5QkFBeUIsR0FBRyx5QkFBeUIsQ0FBQzs7O0FDSDlELFlBQVksQ0FBQztBQUViLElBQUksY0FBYyxHQUFHLE9BQU8sQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQztBQUNqRixJQUFJLE1BQU0sR0FBRyxjQUFjLENBQUMsV0FBVyxFQUFFLENBQUM7QUFFMUMsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDO0FBQ3ZCLElBQUksYUFBYSxHQUFHLElBQUksQ0FBQztBQUV6QixJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7QUFDbkIsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO0FBQ2IsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0FBQ2hCLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztBQVdmLFNBQVMseUJBQXlCLENBQUMsTUFBTTtJQUNyQyxJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFDcEIsSUFBSSxzQkFBc0IsQ0FBQztJQUMzQixJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDO0lBQ3ZCLElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQztJQUV6QixJQUFJLEVBQUUsR0FBRyxJQUFJLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUU5QixFQUFFLENBQUMsTUFBTSxHQUFHO1FBQ1IsTUFBTSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsR0FBRyxLQUFLLENBQUMsQ0FBQztRQUNoRCxJQUFJLE1BQU0sQ0FBQyxXQUFXLEVBQUU7WUFDcEIsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDO1NBQ3hCO0lBQ0wsQ0FBQyxDQUFDO0lBRUYsRUFBRSxDQUFDLE9BQU8sR0FBRyxVQUFDLEtBQUs7UUFDZixNQUFNLENBQUMsS0FBSyxDQUFDLHVCQUF1QixHQUFHLEtBQUssR0FBRyxnQ0FBZ0MsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN4RixJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUU7WUFDaEIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN6QjtJQUNMLENBQUMsQ0FBQztJQUVGLElBQUksbUJBQW1CLEdBQUc7UUFDdEIsSUFBSSxFQUFFLENBQUMsVUFBVSxLQUFLLE1BQU0sRUFBRTtZQUMxQixJQUFJLE9BQU8sRUFBRTtnQkFDVCxNQUFNLENBQUMsS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUM7YUFDN0M7aUJBQU07Z0JBQ0gsSUFBSSxNQUFNLENBQUMsbUJBQW1CLEVBQUUsRUFBRTtvQkFDOUIsTUFBTSxDQUFDLEtBQUssQ0FBQyx3REFBd0QsQ0FBQyxDQUFDO2lCQUMxRTtxQkFBTTtvQkFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLGlEQUFpRCxDQUFDLENBQUM7b0JBQ2hFLFNBQVMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUM7aUJBQzdCO2FBQ0o7U0FDSjthQUFNO1lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxxREFBcUQsQ0FBQyxDQUFDO1NBQ3ZFO0lBQ0wsQ0FBQyxDQUFDO0lBRUYsRUFBRSxDQUFDLE9BQU8sR0FBRyxtQkFBbUIsQ0FBQztJQUVqQyxTQUFTLFNBQVMsQ0FBQyxVQUFVLEVBQUUsVUFBVTtRQUNyQyxNQUFNLENBQUMsS0FBSyxDQUFDLHNCQUFzQixHQUFHLFVBQVUsR0FBRyxRQUFRLEdBQUcsVUFBVSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ2hGLElBQUksVUFBVSxLQUFLLENBQUMsRUFBRTtZQUNsQixJQUFJLFlBQVksRUFBRTtnQkFDZCxNQUFNLENBQUMsSUFBSSxDQUFDLDhFQUE4RSxDQUFDLENBQUM7Z0JBQzVGLE9BQU87YUFDVjtpQkFBTTtnQkFDSCxZQUFZLEdBQUcsSUFBSSxDQUFDO2FBQ3ZCO1lBQ0QsSUFBSSxNQUFNLENBQUMsY0FBYyxFQUFFO2dCQUN2QixNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDM0I7U0FDSjtRQUNELFlBQVksQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVELFNBQVMsbUNBQW1DLENBQUMsU0FBUztRQUNsRCxJQUFJLFlBQVksR0FBRyxJQUFJLGVBQWUsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRTtZQUNoQyxTQUFTLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLEdBQUcsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLFNBQVMsR0FBRyxpQkFBaUIsQ0FBQztTQUNuSDtRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxTQUFTLFlBQVksQ0FBQyxVQUFVLEVBQUUsVUFBVTtRQUN4QyxNQUFNLENBQUMsS0FBSyxDQUFDLHdCQUF3QixHQUFHLFVBQVUsQ0FBQyxDQUFDO1FBQ3BELEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLG9DQUFvQyxDQUFDLENBQUM7UUFFckQsS0FBSyxHQUFHLG1DQUFtQyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25ELEVBQUUsR0FBRyxJQUFJLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUUxQixFQUFFLENBQUMsTUFBTSxHQUFHO1lBQ1IsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLEdBQUcsU0FBUyxHQUFHLFVBQVUsR0FBRyxjQUFjLENBQUMsQ0FBQztZQUNsRixZQUFZLEdBQUcsS0FBSyxDQUFDO1lBQ3JCLHNCQUFzQixFQUFFLENBQUM7WUFDekIsSUFBSSxNQUFNLENBQUMsYUFBYSxFQUFFLEVBQUU7Z0JBQ3hCLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQzthQUMxQjtZQUNELEVBQUUsQ0FBQyxPQUFPLEdBQUcsbUJBQW1CLENBQUM7UUFDckMsQ0FBQyxDQUFDO1FBRUYsRUFBRSxDQUFDLE9BQU8sR0FBRyxVQUFDLEtBQUs7WUFDZixNQUFNLENBQUMsSUFBSSxDQUFDLHNCQUFzQixFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzNDLElBQUksVUFBVSxLQUFLLFVBQVUsRUFBRTtnQkFDM0IsSUFBSSxNQUFNLENBQUMsWUFBWSxFQUFFO29CQUNyQixNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7aUJBQ3pCO2FBQ0o7aUJBQU07Z0JBQ0gsVUFBVSxDQUFDO29CQUNQLFNBQVMsQ0FBQyxVQUFVLEVBQUUsVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUMxQyxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUM7YUFDckI7UUFDTCxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQsSUFBSSxDQUFDLEtBQUssR0FBRyxVQUFDLElBQUksRUFBRSxNQUFNO1FBQ3RCLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDZixFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUMzQixDQUFDLENBQUM7SUFFRixJQUFJLENBQUMsV0FBVyxHQUFHO1FBQ2YsTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUM1QixTQUFTLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzlCLENBQUMsQ0FBQztJQUVGLElBQUksQ0FBQyxJQUFJLEdBQUcsVUFBQyxPQUFPO1FBQ2hCLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDckIsQ0FBQyxDQUFDO0lBRUYsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFVBQUMsSUFBSSxFQUFFLFFBQVE7UUFDbkMsc0JBQXNCLEdBQUc7WUFDckIsRUFBRSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN4QyxDQUFDLENBQUM7UUFDRixzQkFBc0IsRUFBRSxDQUFDO0lBQzdCLENBQUMsQ0FBQztJQUVGLElBQUksQ0FBQyxhQUFhLEdBQUc7UUFDakIsT0FBTyxFQUFFLENBQUMsVUFBVSxDQUFDO0lBQ3pCLENBQUMsQ0FBQztBQUNOLENBQUM7QUFFRCxNQUFNLENBQUMsT0FBTyxHQUFHLHlCQUF5QixDQUFDOzs7QUMvSTNDLElBQUksa0JBQWtCLEdBQUcsS0FBSyxDQUFDO0FBQy9CLElBQUksTUFBTSxDQUFDLGNBQWMsRUFBRTtJQUN2QixJQUFJO1FBQ0EsTUFBTSxDQUFDLGNBQWMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0tBQ3RDO0lBQUMsT0FBTyxDQUFDLEVBQUU7UUFDUixrQkFBa0IsR0FBRyxJQUFJLENBQUM7S0FDN0I7Q0FDSjtBQUdELElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRTtJQUMxQixRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxVQUFVLEtBQUs7UUFDckMsSUFBSSxPQUFPLElBQUksS0FBSyxVQUFVLEVBQUU7WUFHNUIsTUFBTSxJQUFJLFNBQVMsQ0FBQyxzRUFBc0UsQ0FBQyxDQUFDO1NBQy9GO1FBRUQsSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsRUFDaEQsT0FBTyxHQUFHLElBQUksRUFDZCxJQUFJLEdBQUcsY0FBYSxDQUFDLEVBQ3JCLE1BQU0sR0FBRztZQUNMLE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLFlBQVksSUFBSSxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVILENBQUMsQ0FBQztRQUVOLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUNoQyxNQUFNLENBQUMsU0FBUyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFFOUIsT0FBTyxNQUFNLENBQUM7SUFDbEIsQ0FBQyxDQUFDO0NBQ0w7QUFFRCxJQUFJLFlBQVksR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsWUFBWSxDQUFDO0FBRWxELElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUVuQyxJQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDbkMsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBRWpDLElBQUksWUFBWSxHQUFHLElBQUksQ0FBQztBQUV4QixTQUFTLG9CQUFvQixDQUFDLGVBQWU7SUFDekMsSUFBSSxDQUFDLGVBQWU7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUVoQyxLQUFLLElBQUksR0FBRyxJQUFJLGVBQWUsRUFBRTtRQUM3QixJQUFJLEtBQUssR0FBRyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFakMsSUFBSSxPQUFPLEtBQUssSUFBSSxRQUFRO1lBQ3hCLGVBQWUsQ0FBQyxHQUFHLENBQUMsR0FBRztnQkFDbkIsUUFBUSxFQUFFLEtBQUs7YUFDbEIsQ0FBQztLQUNUO0lBRUQsT0FBTyxlQUFlLENBQUM7QUFDM0IsQ0FBQztBQUVELFNBQVMsY0FBYyxDQUFDLFNBQVM7SUFDN0IsSUFBSSxDQUFDLFNBQVM7UUFBRSxPQUFPO0lBR3ZCLElBQUksU0FBUyxZQUFZLFFBQVE7UUFDN0IsT0FBTztZQUNILElBQUksRUFBRSxTQUFTO1NBQ2xCLENBQUM7SUFHTixJQUFJLFNBQVMsQ0FBQyxJQUFJLFlBQVksUUFBUTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBR3pELElBQUksU0FBUyxDQUFDLFdBQVcsWUFBWSxRQUFRLEVBQUU7UUFDM0MsU0FBUyxDQUFDLElBQUksR0FBRyxTQUFTLENBQUMsV0FBVyxDQUFDO1FBQ3ZDLE9BQU8sU0FBUyxDQUFDO0tBQ3BCO0lBR0QsSUFBSSxTQUFTLENBQUMsS0FBSyxZQUFZLFFBQVEsRUFBRTtRQUNyQyxTQUFTLENBQUMsSUFBSSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDakMsT0FBTyxTQUFTLENBQUM7S0FDcEI7SUFHRCxJQUFJLFNBQVMsQ0FBQyxTQUFTLEtBQUssU0FBUztRQUFFLE9BQU87SUFDOUMsSUFBSSxTQUFTLENBQUMsS0FBSyxZQUFZLFFBQVE7UUFBRSxPQUFPO0lBRWhELE1BQU0sSUFBSSxXQUFXLENBQUMsZ0RBQWdELENBQUMsQ0FBQztBQUM1RSxDQUFDO0FBWUQsU0FBUyxlQUFlLENBQUMsTUFBTSxFQUFFLE1BQU07SUFDbkMsSUFBSSxrQkFBa0IsRUFBRTtRQUNwQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztLQUN4QjtTQUFNO1FBQ0gsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFO1lBQ2xDLEtBQUssRUFBRSxNQUFNO1lBQ2IsVUFBVSxFQUFFLElBQUk7U0FDbkIsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFO1lBQ2xDLEtBQUssRUFBRSxNQUFNO1lBQ2IsVUFBVSxFQUFFLElBQUk7U0FDbkIsQ0FBQyxDQUFDO0tBQ047QUFDTCxDQUFDO0FBZUQsU0FBUyxVQUFVLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUztJQUNyRCxJQUFJLElBQUksR0FBRyxJQUFJLENBQUM7SUFFaEIsSUFBSSxDQUFDLE1BQU07UUFBRSxNQUFNLElBQUksV0FBVyxDQUFDLHVCQUF1QixDQUFDLENBQUM7SUFFNUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTTtRQUFFLE1BQU0sSUFBSSxXQUFXLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUUvRSxJQUFJLGVBQWUsR0FBRyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7SUFFbkUsSUFBSSxPQUFPLFlBQVksUUFBUSxFQUFFO1FBQzdCLElBQUksU0FBUyxJQUFJLFNBQVM7WUFBRSxNQUFNLElBQUksV0FBVyxDQUFDLDJDQUEyQyxDQUFDLENBQUM7UUFFL0YsU0FBUyxHQUFHLE9BQU8sQ0FBQztRQUNwQixTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQ3RCLE9BQU8sR0FBRyxTQUFTLENBQUM7S0FDdkI7SUFFRCxJQUFJLE9BQU8sSUFBSSxPQUFPLENBQUMsSUFBSSxZQUFZLFFBQVEsRUFBRTtRQUM3QyxJQUFJLFNBQVMsSUFBSSxDQUFDLENBQUMsU0FBUyxZQUFZLFFBQVEsQ0FBQztZQUFFLE1BQU0sSUFBSSxXQUFXLENBQUMsd0NBQXdDLENBQUMsQ0FBQztRQUVuSCxTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQ3RCLFNBQVMsR0FBRyxPQUFPLENBQUM7UUFDcEIsT0FBTyxHQUFHLFNBQVMsQ0FBQztLQUN2QjtJQUVELElBQUksU0FBUyxZQUFZLFFBQVEsRUFBRTtRQUMvQixJQUFJLFNBQVMsSUFBSSxTQUFTO1lBQUUsTUFBTSxJQUFJLFdBQVcsQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO1FBRS9GLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDdEIsU0FBUyxHQUFHLFNBQVMsQ0FBQztLQUN6QjtJQUVELElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxJQUFJLFlBQVksUUFBUTtRQUMvQyxJQUFJLFNBQVMsSUFBSSxDQUFDLENBQUMsU0FBUyxZQUFZLFFBQVEsQ0FBQztZQUFFLE1BQU0sSUFBSSxXQUFXLENBQUMsd0NBQXdDLENBQUMsQ0FBQztJQUV2SCxPQUFPLEdBQUcsT0FBTyxJQUFJLEVBQUUsQ0FBQztJQUV4QixZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRXhCLElBQUksU0FBUztRQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBRTdDLElBQUksa0JBQWtCO1FBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDOztRQUVqRCxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUU7WUFDbEMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxNQUFNO1NBQ3hCLENBQUMsQ0FBQztJQUVQLElBQUksV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksQ0FBQyxDQUFDO0lBRTNDLFNBQVMsZ0JBQWdCLENBQUMsS0FBSztRQUMzQixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVELElBQUksQ0FBQyxZQUFZLEdBQUc7UUFDaEIsT0FBTyxTQUFTLENBQUM7SUFDckIsQ0FBQyxDQUFDO0lBQ0YsSUFBSSxDQUFDLFlBQVksR0FBRyxVQUFVLEtBQUs7UUFFL0IsSUFBSSxTQUFTLEVBQUU7WUFFWCxJQUFJLFNBQVMsQ0FBQyxtQkFBbUI7Z0JBQUUsU0FBUyxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO2lCQUV6RixJQUFJLFNBQVMsQ0FBQyxjQUFjO2dCQUFFLFNBQVMsQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLGdCQUFnQixDQUFDLENBQUM7U0FDekY7UUFHRCxJQUFJLEtBQUssRUFBRTtZQUVQLElBQUksS0FBSyxDQUFDLGdCQUFnQjtnQkFBRSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLGdCQUFnQixDQUFDLENBQUM7aUJBRTNFLElBQUksS0FBSyxDQUFDLFdBQVc7Z0JBQUUsS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztTQUMzRTtRQUVELFNBQVMsR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdEMsQ0FBQyxDQUFDO0lBRUYsSUFBSSxDQUFDLGtCQUFrQjtRQUNuQixNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUU7WUFDckMsR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztZQUNqQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1NBQ3BDLENBQUMsQ0FBQztJQUVQLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFN0IsSUFBSSxlQUFlLEdBQUcsT0FBTyxDQUFDLGVBQWUsSUFBSSxZQUFZLENBQUM7SUFDOUQsSUFBSSxvQkFBb0IsR0FBRyxPQUFPLENBQUMsb0JBQW9CLElBQUksZUFBZSxDQUFDO0lBQzNFLElBQUksZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixJQUFJLFlBQVksQ0FBQztJQUNoRSxJQUFJLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsSUFBSSxZQUFZLENBQUM7SUFFcEUsSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBRWxCLElBQUksUUFBUSxHQUFHLElBQUksTUFBTSxFQUFFLENBQUM7SUFDNUIsSUFBSSxTQUFTLEdBQUcsSUFBSSxNQUFNLEVBQUUsQ0FBQztJQUM3QixJQUFJLGtCQUFrQixHQUFHLElBQUksTUFBTSxFQUFFLENBQUM7SUFFdEMsSUFBSSxXQUFXLEdBQUcsRUFBRSxDQUFDO0lBS3JCLFNBQVMsYUFBYSxDQUFDLE9BQU8sRUFBRSxFQUFFLEVBQUUsSUFBSTtRQUNwQyxJQUFJLFFBQVEsR0FBRztZQUNYLE9BQU8sRUFBRSxPQUFPO1lBRWhCLE9BQU8sRUFBRSxVQUFVLENBQUM7Z0JBQ2hCLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQy9CLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQztTQUN2QixDQUFDO1FBRUYsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFLRCxTQUFTLHNCQUFzQixDQUFDLEdBQUcsRUFBRSxJQUFJO1FBQ3JDLElBQUksT0FBTyxHQUFHLFVBQVUsQ0FBQztZQUNyQixrQkFBa0IsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3pDLENBQUMsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1FBRXZCLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFlRCxTQUFTLFVBQVUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUztRQUNuRCxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFM0MsSUFBSSxDQUFDLFlBQVksR0FBRztZQUNoQixPQUFPLFNBQVMsQ0FBQztRQUNyQixDQUFDLENBQUM7UUFDRixJQUFJLENBQUMsWUFBWSxHQUFHLFVBQVUsS0FBSztZQUMvQixTQUFTLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3RDLENBQUMsQ0FBQztRQUVGLElBQUksQ0FBQyxrQkFBa0I7WUFDbkIsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFO2dCQUNyQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNqQyxHQUFHLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2FBQ3BDLENBQUMsQ0FBQztRQUVQLElBQUksUUFBUSxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBS3ZDLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsRUFBRTtZQUNyQyxJQUFJLGtCQUFrQjtnQkFBRSxJQUFJLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQzs7Z0JBRXhELE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRTtvQkFDdEMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUM7aUJBQzNCLENBQUMsQ0FBQztTQUNWO1FBRUQsSUFBSSxjQUFjLEdBQUcsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTdDLElBQUksQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztRQVUvQyxJQUFJLENBQUMsS0FBSyxHQUFHLFVBQVUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTO1lBRTNDLElBQUksS0FBSyxZQUFZLFFBQVEsSUFBSSxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsSUFBSSxZQUFZLFFBQVEsQ0FBQyxFQUFFO2dCQUN4RSxJQUFJLE1BQU0sSUFBSSxTQUFTO29CQUFFLE1BQU0sSUFBSSxXQUFXLENBQUMsMENBQTBDLENBQUMsQ0FBQztnQkFFM0YsU0FBUyxHQUFHLEtBQUssQ0FBQztnQkFDbEIsTUFBTSxHQUFHLElBQUksQ0FBQztnQkFDZCxLQUFLLEdBQUcsU0FBUyxDQUFDO2FBQ3JCO2lCQUFNLElBQUksTUFBTSxZQUFZLFFBQVEsSUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsSUFBSSxZQUFZLFFBQVEsQ0FBQyxFQUFFO2dCQUNsRixJQUFJLFNBQVMsSUFBSSxTQUFTO29CQUFFLE1BQU0sSUFBSSxXQUFXLENBQUMsMENBQTBDLENBQUMsQ0FBQztnQkFFOUYsU0FBUyxHQUFHLE1BQU0sQ0FBQztnQkFDbkIsTUFBTSxHQUFHLElBQUksQ0FBQzthQUNqQjtZQUVELFNBQVMsR0FBRyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUM7WUFHdEMsSUFBSSxRQUFRO2dCQUFFLFlBQVksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFN0MsSUFBSSxJQUFJLElBQUksU0FBUyxFQUFFO2dCQUNuQixJQUFJLEtBQUs7b0JBQUUsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7Z0JBRTdCLElBQUksTUFBTTtvQkFBRSxNQUFNLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQzthQUNsQztZQUVELElBQUksT0FBTyxDQUFDO1lBR1osSUFBSSxLQUFLLElBQUksTUFBTSxJQUFJLFNBQVMsRUFBRTtnQkFDOUIsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLFNBQVMsRUFBRTtvQkFDMUIsSUFBSSxLQUFLO3dCQUFFLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQzs7d0JBQy9CLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztpQkFDbEM7Z0JBR0QsSUFBSSxjQUFjLEVBQUU7b0JBQ2hCLElBQUksY0FBYyxDQUFDLEtBQUssSUFBSSxTQUFTLElBQUksS0FBSzt3QkFDMUMsT0FBTyxHQUFHOzRCQUNOLEtBQUssRUFBRSxLQUFLO3lCQUNmLENBQUM7eUJBQ0Q7d0JBQ0QsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDO3dCQUVwRSxPQUFPLEdBQUc7NEJBQ04sTUFBTSxFQUFFLE1BQU07NEJBQ2QsTUFBTSxFQUFFLEtBQUssSUFBSSxNQUFNO3lCQUMxQixDQUFDO3FCQUNMO2lCQUNKOztvQkFDRyxPQUFPLEdBQUc7d0JBQ04sS0FBSyxFQUFFLEtBQUs7d0JBQ1osTUFBTSxFQUFFLE1BQU07cUJBQ2pCLENBQUM7Z0JBRU4sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2FBQ3RDO2lCQUdJLElBQUksUUFBUTtnQkFBRSxPQUFPLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQzs7Z0JBRzFDLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUNqQjtvQkFDSSxNQUFNLEVBQUUsSUFBSTtpQkFDZixFQUNELEVBQUUsQ0FDTCxDQUFDO1lBR04sYUFBYSxDQUFDLE9BQU8sRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFHakMsU0FBUyxHQUFHLFNBQVMsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBRXBFLElBQUksU0FBUztnQkFBRSxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFFOUMsT0FBTyxPQUFPLENBQUM7UUFDbkIsQ0FBQyxDQUFDO0lBQ04sQ0FBQztJQUNELFFBQVEsQ0FBQyxVQUFVLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFFdEMsU0FBUyxNQUFNLENBQUMsT0FBTztRQUNuQixJQUFJLEdBQUcsR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLEdBQUc7WUFBRSxPQUFPO1FBRWpCLE9BQU8sV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTVCLElBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0MsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBRXJCLFlBQVksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFHOUIsc0JBQXNCLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQU9ELElBQUksQ0FBQyxNQUFNLEdBQUcsVUFBVSxPQUFPO1FBQzNCLElBQUksT0FBTztZQUFFLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXBDLEtBQUssSUFBSSxPQUFPLElBQUksV0FBVztZQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNyRCxDQUFDLENBQUM7SUFFRixJQUFJLENBQUMsS0FBSyxHQUFHO1FBRVQsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BDLElBQUksU0FBUyxJQUFJLFNBQVMsQ0FBQyxLQUFLO1lBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztRQUcxRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFZCxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7UUFHekMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxVQUFVLFFBQVE7WUFDaEMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuQyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUMsQ0FBQztJQWNGLElBQUksQ0FBQyxNQUFNLEdBQUcsVUFBVSxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsUUFBUTtRQUU3RCxJQUFJLE1BQU0sWUFBWSxRQUFRLEVBQUU7WUFDNUIsSUFBSSxJQUFJLElBQUksU0FBUztnQkFBRSxNQUFNLElBQUksV0FBVyxDQUFDLDBDQUEwQyxDQUFDLENBQUM7WUFFekYsUUFBUSxHQUFHLE1BQU0sQ0FBQztZQUNsQixTQUFTLEdBQUcsU0FBUyxDQUFDO1lBQ3RCLElBQUksR0FBRyxTQUFTLENBQUM7WUFDakIsTUFBTSxHQUFHLFNBQVMsQ0FBQztTQUN0QjthQUFNLElBQUksSUFBSSxZQUFZLFFBQVEsRUFBRTtZQUNqQyxJQUFJLFNBQVMsSUFBSSxTQUFTO2dCQUFFLE1BQU0sSUFBSSxXQUFXLENBQUMsMENBQTBDLENBQUMsQ0FBQztZQUU5RixRQUFRLEdBQUcsSUFBSSxDQUFDO1lBQ2hCLFNBQVMsR0FBRyxTQUFTLENBQUM7WUFDdEIsSUFBSSxHQUFHLFNBQVMsQ0FBQztTQUNwQjthQUFNLElBQUksU0FBUyxZQUFZLFFBQVEsRUFBRTtZQUN0QyxJQUFJLFFBQVEsSUFBSSxTQUFTO2dCQUFFLE1BQU0sSUFBSSxXQUFXLENBQUMsMENBQTBDLENBQUMsQ0FBQztZQUU3RixRQUFRLEdBQUcsU0FBUyxDQUFDO1lBQ3JCLFNBQVMsR0FBRyxTQUFTLENBQUM7U0FDekI7UUFFRCxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksU0FBUyxFQUFFO1lBQzFCLE1BQU0sR0FBRyxNQUFNLElBQUksRUFBRSxDQUFDO1lBRXRCLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztTQUM3QjtRQUVELElBQUksSUFBSSxJQUFJLFNBQVMsRUFBRTtZQUNuQixNQUFNLEdBQUcsTUFBTSxJQUFJLEVBQUUsQ0FBQztZQUV0QixNQUFNLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztTQUN0QjtRQUdELElBQUksT0FBTyxHQUFHO1lBQ1YsTUFBTSxFQUFFLE1BQU07WUFDZCxNQUFNLEVBQUUsTUFBTTtTQUNqQixDQUFDO1FBRUYsSUFBSSxRQUFRLEVBQUU7WUFDVixJQUFJLEVBQUUsR0FBRyxTQUFTLEVBQUUsQ0FBQztZQUNyQixJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7WUFFaEIsT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBRW5DLFNBQVMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLE1BQU07Z0JBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBRXJCLFFBQVEsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDNUIsQ0FBQztZQUVELElBQUksT0FBTyxHQUFHO2dCQUNWLE9BQU8sRUFBRSxPQUFPO2dCQUNoQixRQUFRLEVBQUUsZ0JBQWdCO2dCQUMxQixlQUFlLEVBQUUsZUFBZSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUU7YUFDakQsQ0FBQztZQUVGLElBQUksZ0JBQWdCLEdBQUcsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRWpELFNBQVMsV0FBVyxDQUFDLFNBQVM7Z0JBQzFCLElBQUksRUFBRSxHQUFHLE1BQU0sS0FBSyxNQUFNLENBQUMsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUM7Z0JBQ3BFLE9BQU8sQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLE9BQU8sRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNuRSxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUc7b0JBQ25CLEVBQUUsRUFBRSxFQUFFO29CQUNOLElBQUksRUFBRSxJQUFJO2lCQUNiLENBQUM7Z0JBQ0YsUUFBUSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUVoQyxTQUFTLEdBQUcsU0FBUyxJQUFJLGdCQUFnQixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDakUsSUFBSSxTQUFTO29CQUFFLE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFFOUMsT0FBTyxPQUFPLENBQUM7WUFDbkIsQ0FBQztZQUVELFNBQVMsS0FBSyxDQUFDLFNBQVM7Z0JBQ3BCLFNBQVMsR0FBRyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBRXRDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxHQUFHLDZCQUE2QixFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUUvRCxJQUFJLE9BQU8sR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUMvQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBRXRCLE9BQU8sV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ2xDLENBQUM7WUFFRCxTQUFTLE9BQU87Z0JBQ1osSUFBSSxPQUFPLEdBQUcsV0FBVztvQkFBRSxPQUFPLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFFbkQsSUFBSSxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsdUJBQXVCLENBQUMsQ0FBQztnQkFDL0MsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7Z0JBRXhCLEtBQUssQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO2dCQUVwQixnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM1QixDQUFDO1lBRUQsT0FBTyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDakM7UUFHRCxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUUvQixTQUFTLEdBQUcsU0FBUyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUM3QyxJQUFJLFNBQVM7WUFBRSxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFOUMsT0FBTyxPQUFPLENBQUM7SUFDbkIsQ0FBQyxDQUFDO0lBYUYsSUFBSSxDQUFDLE1BQU0sR0FBRyxVQUFVLE9BQU8sRUFBRSxTQUFTO1FBQ3RDLElBQUksQ0FBQyxPQUFPO1lBQUUsTUFBTSxJQUFJLFNBQVMsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBRTVELElBQUk7WUFDQSxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUNwQztRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBRVIsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQztTQUNwQztRQUVELElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDcEIsSUFBSSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUN0QixJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBQzVCLElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDO1FBRWxDLElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFDdkIsSUFBSSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQztRQUd2QixJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksU0FBUyxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU87UUFHNUQsSUFBSSxFQUFFLElBQUksU0FBUyxJQUFJLEdBQUcsSUFBSSxTQUFTLEVBQUU7WUFDckMsSUFBSSxZQUFZLEdBQUcsSUFBSSxlQUFlLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBRXZELElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDO2dCQUFFLE9BQU87WUFDL0MsT0FBTyxZQUFZLENBQUM7U0FDdkI7UUFFRCxTQUFTLGNBQWM7WUFFbkIsU0FBUyxHQUFHLGNBQWMsQ0FBQyxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDN0QsSUFBSSxTQUFTLEVBQUU7Z0JBQ1gsSUFBSSxRQUFRLEdBQUcsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3ZDLElBQUksUUFBUTtvQkFBRSxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ3pEO1lBRUQsSUFBSSxLQUFLLEdBQUcsRUFBRSxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDdkMsSUFBSSxPQUFPLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBRXJFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDO2dCQUFFLE9BQU87WUFDMUMsT0FBTyxPQUFPLENBQUM7UUFDbkIsQ0FBQztRQUVELFNBQVMsZUFBZSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTTtZQUMzQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNwQyxDQUFDO1FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxPQUFPO1lBQy9CLE9BQU8sQ0FBQyxJQUFJLENBQUMsNEJBQTRCLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFHcEQsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RCLHNCQUFzQixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBR0QsSUFBSSxNQUFNLEVBQUU7WUFFUixJQUFJLElBQUksSUFBSSxTQUFTLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQzFDLElBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUN0QyxJQUFJLE9BQU8sRUFBRTtvQkFDVCxJQUFJLGVBQWUsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDO29CQUU5QyxJQUFJLE1BQU0sSUFBSSxlQUFlLENBQUMsS0FBSzt3QkFBRSxPQUFPLGVBQWUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7b0JBRTdFLElBQUksTUFBTSxJQUFJLGVBQWUsQ0FBQyxRQUFRO3dCQUFFLE9BQU8sZUFBZSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7b0JBRXRGLE9BQU8sY0FBYyxFQUFFLENBQUM7aUJBQzNCO2dCQUVELElBQUksU0FBUyxHQUFHLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ2xELElBQUksU0FBUztvQkFBRSxPQUFPLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDO2FBQ3ZEO1lBR0QsT0FBTyxjQUFjLEVBQUUsQ0FBQztTQUMzQjtRQUVELElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFDMUIsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUc1QixJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPO1FBQzdELElBQUksTUFBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksTUFBTSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU87UUFHaEUsSUFBSSxPQUFPLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNWLElBQUksU0FBUyxHQUFHLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDbEQsSUFBSSxTQUFTO2dCQUFFLE9BQU8sa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFFcEQsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1NBQzVFO1FBR0QsZUFBZSxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDNUMsQ0FBQyxDQUFDO0FBQ04sQ0FBQztBQUNELFFBQVEsQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLENBQUM7QUFFbkMsVUFBVSxDQUFDLGVBQWUsR0FBRyxlQUFlLENBQUM7QUFFN0MsTUFBTSxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUM7QUFFNUIsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ25DLElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0FBRWpELFVBQVUsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0FBQzdCLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztBQUMzQyxVQUFVLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQzs7O0FDbHFCN0IsU0FBUyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUU7SUFDckIsSUFBSSxNQUFNLEdBQUc7UUFDVCxPQUFPLEVBQUUsS0FBSztLQUNqQixDQUFDO0lBR0YsSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFO1FBQ2hCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUUvQixJQUFJLE9BQU8sQ0FBQyxNQUFNO1lBQUUsTUFBTSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBR25ELElBQUksRUFBRSxJQUFJLFNBQVM7WUFBRSxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztLQUN2QztTQUdJLElBQUksRUFBRSxJQUFJLFNBQVMsRUFBRTtRQUN0QixJQUFJLE9BQU8sQ0FBQyxLQUFLLEVBQUU7WUFDZixJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssU0FBUztnQkFBRSxNQUFNLElBQUksU0FBUyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7WUFFM0YsTUFBTSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDO1NBQ2hDO2FBQU0sSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLFNBQVM7WUFBRSxNQUFNLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7O1lBQ25FLE1BQU0sSUFBSSxTQUFTLENBQUMsK0JBQStCLENBQUMsQ0FBQztRQUUxRCxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztLQUNsQjtJQUVELE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNsQyxDQUFDO0FBV0QsU0FBUyxNQUFNLENBQUMsT0FBTztJQUNuQixJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUM7SUFFckIsSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLElBQUksT0FBTyxZQUFZLE1BQU0sRUFBRTtRQUMxRCxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztLQUNoQztJQUlELElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUM7SUFDN0IsSUFBSSxPQUFPLEtBQUssS0FBSztRQUFFLE1BQU0sSUFBSSxTQUFTLENBQUMsMkJBQTJCLEdBQUcsT0FBTyxHQUFHLEtBQUssR0FBRyxPQUFPLENBQUMsQ0FBQztJQUdwRyxJQUFJLE1BQU0sQ0FBQyxNQUFNLElBQUksU0FBUyxFQUFFO1FBQzVCLElBQUksTUFBTSxDQUFDLEVBQUUsSUFBSSxTQUFTO1lBQUUsTUFBTSxJQUFJLFNBQVMsQ0FBQyxtQkFBbUIsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUvRSxJQUFJLGNBQWMsR0FBRyxNQUFNLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQztRQUNqRCxJQUFJLGFBQWEsR0FBRyxNQUFNLENBQUMsS0FBSyxLQUFLLFNBQVMsQ0FBQztRQUcvQyxJQUFJLGNBQWMsSUFBSSxhQUFhO1lBQUUsTUFBTSxJQUFJLFNBQVMsQ0FBQyxxQ0FBcUMsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUxRyxJQUFJLENBQUMsY0FBYyxJQUFJLENBQUMsYUFBYTtZQUFFLE1BQU0sSUFBSSxTQUFTLENBQUMsaUNBQWlDLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFeEcsTUFBTSxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQ3ZCLE9BQU8sTUFBTSxDQUFDLEVBQUUsQ0FBQztLQUNwQjtJQUdELE9BQU8sTUFBTSxDQUFDO0FBQ2xCLENBQUM7QUFFRCxPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNwQixPQUFPLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQzs7O0FDcEZ4QixTQUFTLElBQUksQ0FBQyxPQUFPO0lBQ2pCLE1BQU0sSUFBSSxTQUFTLENBQUMscUJBQXFCLENBQUMsQ0FBQztBQUMvQyxDQUFDO0FBRUQsU0FBUyxNQUFNLENBQUMsT0FBTztJQUNuQixNQUFNLElBQUksU0FBUyxDQUFDLHFCQUFxQixDQUFDLENBQUM7QUFDL0MsQ0FBQztBQUVELE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ3BCLE9BQU8sQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDOzs7QUNUeEIsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ25DLElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUVqQyxPQUFPLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztBQUMxQixPQUFPLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQzs7Ozs7O0FDSHhCO0lBK0JJLHVCQUFZLE9BQWdCO1FBQ3hCLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDO1FBQ3RCLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDO1lBQ3BCLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQzFCLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDO1lBQzVCLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQzFCLENBQUMsSUFBSSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUNMLG9CQUFDO0FBQUQsQ0F2Q0EsQUF1Q0MsSUFBQTtBQXZDWSxzQ0FBYTs7Ozs7O0FDRDFCLGlDQUE0QjtBQUU1QixpREFBZ0Q7QUFDaEQsNkVBQTRFO0FBRTVFO0lBQUE7UUFHWSxlQUFVLEdBQVcscUNBQXFDLENBQUM7UUFDM0Qsa0NBQTZCLEdBQVcsR0FBRyxDQUFDO1FBQzVDLGdDQUEyQixHQUFXLElBQUksQ0FBQztRQUMzQywyQkFBc0IsR0FBVyxJQUFJLENBQUM7UUFFdEMseUJBQW9CLEdBQWtCLElBQUksNkJBQWEsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7UUFJNUUsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUNuQixrQkFBYSxHQUFHLEtBQUssQ0FBQztJQTBRbEMsQ0FBQztJQWpRVSw4QkFBZSxHQUF0QixVQUF1QixRQUFrQixFQUFFLEtBQWE7UUFBeEQsaUJBNEdDO1FBM0dHLElBQUk7WUFFQSxJQUNJLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQztnQkFFaEMsQ0FBQyxJQUFJLENBQUMsUUFBUTtvQkFDVixRQUFRLENBQUMsWUFBWTtvQkFFckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQ0FBZ0MsQ0FBQyxRQUFRLENBQUM7b0JBRXhELElBQUksQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUNoRTtnQkFJRSxJQUFJLFFBQVEsQ0FBQyxlQUFlLEtBQUsseURBQTJCLENBQUMsU0FBUyxFQUFFO29CQUNwRSxJQUFJLENBQUMsUUFBUSxDQUFDLG9CQUFvQixFQUFFLENBQUM7aUJBQ3hDO2dCQUdELElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztnQkFDcEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQztnQkFFM0MsSUFBTSxhQUFXLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQztnQkFDekMsSUFBTSxXQUFTLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7Z0JBRTdDLElBQU0sa0JBQWtCLEdBQUcsVUFBQyxHQUFHO29CQUczQixJQUFNLHdCQUF3QixHQUFHLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQztvQkFDeEQsR0FBRyxDQUFDLGtCQUFrQixHQUFHO3dCQUNyQixJQUFJLEtBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsRUFBRTs0QkFDN0IsTUFBTSxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsWUFBWSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7NEJBQ3ZELE1BQU0sQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDOzRCQUVyRCxLQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsRUFBRSxDQUFDO3lCQUNqQzt3QkFDRCx3QkFBd0IsRUFBRSxDQUFDO29CQUMvQixDQUFDLENBQUM7b0JBR0YsR0FBRyxDQUFDLGdCQUFnQixDQUFDLGVBQWUsRUFBRSxRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQUcsYUFBVyxnQkFBTSxXQUFTLENBQUUsR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztvQkFDdEcsR0FBRyxDQUFDLGdCQUFnQixDQUFDLGtCQUFrQixFQUFFLGdCQUFnQixDQUFDLENBQUM7b0JBRTNELEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxrQkFBa0IsRUFBRSxhQUFXLENBQUMsQ0FBQztvQkFDdEQsR0FBRyxDQUFDLGdCQUFnQixDQUFDLGVBQWUsRUFBRSxXQUFTLENBQUMsQ0FBQztvQkFDakQsR0FBRyxDQUFDLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDNUMsQ0FBQyxDQUFDO2dCQUdGLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxHQUFHLFdBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxtQkFBWSxhQUFXLGNBQUksV0FBUyxDQUFFLENBQUMsQ0FBQztnQkFDOUYsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDO29CQUNyQyxVQUFVLEVBQUUsa0JBQWtCO29CQUM5QixZQUFZLEVBQUUsSUFBSTtvQkFDbEIsU0FBUyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsNkJBQTZCO29CQUN0RCxZQUFZLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQywyQkFBMkI7aUJBQzFELENBQUMsQ0FBQztnQkFHSCxJQUFNLGFBQWEsR0FBRyxVQUFDLEdBQUc7b0JBQ3RCLElBQU0sbUJBQW1CLEdBQUc7d0JBQ3hCLElBQU0sSUFBSSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7d0JBQzNCLE9BQU8sVUFBQyxHQUFHLEVBQUUsS0FBSzs0QkFDZCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLElBQUksSUFBSSxFQUFFO2dDQUM1QyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxJQUFJLEtBQUssWUFBWSxXQUFXLENBQUMsRUFBRTtvQ0FDN0UsT0FBTztpQ0FDVjtnQ0FDRCxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDOzZCQUNuQjs0QkFDRCxPQUFPLEtBQUssQ0FBQzt3QkFDakIsQ0FBQyxDQUFDO29CQUNOLENBQUMsQ0FBQztvQkFHRixJQUFJLGFBQWEsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxtQkFBbUIsRUFBRSxDQUFDLENBQUM7b0JBQy9ELElBQUksYUFBYSxDQUFDLE1BQU0sR0FBRyxLQUFJLENBQUMsUUFBUSxDQUFDLHNCQUFzQixFQUFFO3dCQUM3RCxhQUFhLEdBQUcsVUFBRyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxLQUFJLENBQUMsUUFBUSxDQUFDLHNCQUFzQixDQUFDLFFBQUssQ0FBQztxQkFDNUY7b0JBRUQsSUFBSSxVQUFVLENBQUMsb0JBQW9CLENBQUMsRUFBRTt3QkFDbEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztxQkFDOUI7b0JBRUQsT0FBTyxhQUFhLENBQUM7Z0JBQ3pCLENBQUMsQ0FBQztnQkFHRixXQUFFLENBQUMsVUFBVSxDQUFDO29CQUNWLGNBQWMsRUFBRSxRQUFRLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVTtvQkFDM0QsU0FBUyxFQUFFLGFBQWE7b0JBQ3hCLE9BQU8sRUFBRSxJQUFJO2lCQUNoQixDQUFDLENBQUM7Z0JBQ0gsSUFBQSxXQUFFLEdBQUUsQ0FBQyxVQUFVLENBQUM7b0JBQ1osU0FBUyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUM7aUJBQzdDLENBQUMsQ0FBQztnQkFFSCxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEdBQUcsV0FBUyxDQUFDO2dCQUMzQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO2FBQzVDO1NBQ0o7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUVSLE9BQU8sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLENBQUMsQ0FBQztZQUM1QyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRWpCLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxFQUFFLENBQUM7U0FDakM7SUFDTCxDQUFDO0lBS00sMEJBQVcsR0FBbEI7UUFDSSxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRTtZQUMxQixjQUFjLENBQUMsUUFBUSxHQUFHLElBQUksY0FBYyxFQUFFLENBQUM7U0FDbEQ7UUFDRCxPQUFPLGNBQWMsQ0FBQyxRQUFRLENBQUM7SUFDbkMsQ0FBQztJQUVjLGdDQUFpQixHQUFoQyxVQUFpQyxHQUFtQjtRQUNoRCxPQUFPLEdBQUcsQ0FBQyxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDO0lBQzFGLENBQUM7SUFFTywyQ0FBa0IsR0FBMUIsVUFBMkIsUUFBa0IsRUFBRSxNQUFzQjtRQUNqRSxPQUFPLFFBQVEsQ0FBQyxPQUFPLENBQUMsU0FBUyxJQUFJLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztJQUNqRSxDQUFDO0lBRU8seURBQWdDLEdBQXhDLFVBQXlDLFFBQWtCO1FBQ3ZELE9BQU8sQ0FDSCxRQUFRLENBQUMsZUFBZSxLQUFLLHlEQUEyQixDQUFDLEtBQUs7WUFDOUQsUUFBUSxDQUFDLGVBQWUsS0FBSyx5REFBMkIsQ0FBQyxTQUFTLENBQ3JFLENBQUM7SUFDTixDQUFDO0lBR08sNkNBQW9CLEdBQTVCO1FBQ0ksT0FBTyxDQUFDLFVBQVUsY0FBOEI7WUFDNUMsT0FBTztnQkFDSCxHQUFHLEVBQUU7b0JBQVUsY0FBTzt5QkFBUCxVQUFPLEVBQVAscUJBQU8sRUFBUCxJQUFPO3dCQUFQLHlCQUFPOztvQkFDbEIsY0FBYyxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztvQkFDckcsSUFBSSxjQUFjLENBQUMsYUFBYSxFQUFFO3dCQUM5QixJQUFBLFdBQUUsR0FBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztxQkFDeEI7Z0JBQ0wsQ0FBQztnQkFDRCxJQUFJLEVBQUU7b0JBQVUsY0FBTzt5QkFBUCxVQUFPLEVBQVAscUJBQU8sRUFBUCxJQUFPO3dCQUFQLHlCQUFPOztvQkFDbkIsY0FBYyxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztvQkFDdEcsSUFBSSxjQUFjLENBQUMsYUFBYSxFQUFFO3dCQUM5QixJQUFBLFdBQUUsR0FBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztxQkFDeEI7Z0JBQ0wsQ0FBQztnQkFDRCxLQUFLLEVBQUU7b0JBQVUsY0FBTzt5QkFBUCxVQUFPLEVBQVAscUJBQU8sRUFBUCxJQUFPO3dCQUFQLHlCQUFPOztvQkFDcEIsY0FBYyxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDM0csQ0FBQztnQkFDRCxJQUFJLEVBQUU7b0JBQVUsY0FBTzt5QkFBUCxVQUFPLEVBQVAscUJBQU8sRUFBUCxJQUFPO3dCQUFQLHlCQUFPOztvQkFDbkIsY0FBYyxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztvQkFDdEcsSUFBSSxjQUFjLENBQUMsYUFBYSxFQUFFO3dCQUM5QixJQUFBLFdBQUUsR0FBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztxQkFDeEI7Z0JBQ0wsQ0FBQztnQkFDRCxLQUFLLEVBQUU7b0JBQVUsY0FBTzt5QkFBUCxVQUFPLEVBQVAscUJBQU8sRUFBUCxJQUFPO3dCQUFQLHlCQUFPOztvQkFDcEIsY0FBYyxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztvQkFDdkcsSUFBSSxjQUFjLENBQUMsYUFBYSxFQUFFO3dCQUM5QixJQUFBLFdBQUUsR0FBRSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztxQkFDekI7Z0JBQ0wsQ0FBQzthQUNKLENBQUM7UUFDTixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNiLENBQUM7SUFFTyw2Q0FBb0IsR0FBNUI7UUFDSSxVQUFVLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUM7UUFDdEQsVUFBVSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsR0FBRyxDQUFDO1FBQ3pELFVBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLElBQUksQ0FBQztRQUMzRCxVQUFVLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxLQUFLLENBQUM7UUFDN0QsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsSUFBSSxDQUFDO1FBQzNELFVBQVUsQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLEtBQUssQ0FBQztJQUNqRSxDQUFDO0lBRU8sc0NBQWEsR0FBckI7UUFDSSxXQUFFLENBQUMsVUFBVSxDQUFDLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFDM0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFNBQVMsQ0FBQztRQUNsQyxJQUFJLENBQUMsZUFBZSxHQUFHLFNBQVMsQ0FBQztRQUNqQyxVQUFVLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUM7UUFDdEQsVUFBVSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQztRQUN2RCxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDO1FBQ3pELFVBQVUsQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUM7UUFDM0QsVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQztRQUN6RCxVQUFVLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDO0lBQy9ELENBQUM7SUFLRCw0QkFBRyxHQUFIO1FBQUksY0FBYzthQUFkLFVBQWMsRUFBZCxxQkFBYyxFQUFkLElBQWM7WUFBZCx5QkFBYzs7UUFDZCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNsQixJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQ3BGO1FBQ0QsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3BCLElBQUEsV0FBRSxHQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ3hCO0lBQ0wsQ0FBQztJQUtELDhCQUFLLEdBQUw7UUFBTSxjQUFjO2FBQWQsVUFBYyxFQUFkLHFCQUFjLEVBQWQsSUFBYztZQUFkLHlCQUFjOztRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNsQixJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1NBQ3RGO0lBQ0wsQ0FBQztJQUtELDZCQUFJLEdBQUo7UUFBSyxjQUFjO2FBQWQsVUFBYyxFQUFkLHFCQUFjLEVBQWQsSUFBYztZQUFkLHlCQUFjOztRQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2xCLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7U0FDckY7UUFDRCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDcEIsSUFBQSxXQUFFLEdBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDeEI7SUFDTCxDQUFDO0lBS0QsNkJBQUksR0FBSjtRQUFLLGNBQWM7YUFBZCxVQUFjLEVBQWQscUJBQWMsRUFBZCxJQUFjO1lBQWQseUJBQWM7O1FBQ2YsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNsRixJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDcEIsSUFBQSxXQUFFLEdBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDeEI7SUFDTCxDQUFDO0lBS0QsOEJBQUssR0FBTDtRQUFNLGNBQWM7YUFBZCxVQUFjLEVBQWQscUJBQWMsRUFBZCxJQUFjO1lBQWQseUJBQWM7O1FBQ2hCLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDbkYsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3BCLElBQUEsV0FBRSxHQUFFLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ3pCO0lBQ0wsQ0FBQztJQUtELDhCQUFLLEdBQUw7UUFDSSxJQUFJLElBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJLEVBQUU7WUFDcEQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztTQUNwQztJQUNMLENBQUM7SUFFRCx1Q0FBYyxHQUFkO1FBQ0ksSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDM0IsQ0FBQztJQUNMLHFCQUFDO0FBQUQsQ0F2UkEsQUF1UkMsSUFBQTtBQXZSWSx3Q0FBYzs7Ozs7O0FDTDNCLElBQVksMkJBSVg7QUFKRCxXQUFZLDJCQUEyQjtJQUNuQyxvREFBcUIsQ0FBQTtJQUNyQiw4Q0FBZSxDQUFBO0lBQ2Ysc0RBQXVCLENBQUE7QUFDM0IsQ0FBQyxFQUpXLDJCQUEyQixHQUEzQixtQ0FBMkIsS0FBM0IsbUNBQTJCLFFBSXRDOzs7QUNxQkQsVUFBVSxDQUFDLFdBQVcsR0FBRyxVQUFVLGFBQWEsRUFBRSxRQUFRLEVBQUUsZ0JBQWdCO0lBQ3hFLElBQUksU0FBUyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEVBQUU7UUFFeEcsUUFBUSxDQUFDO1lBQ0wsS0FBSyxFQUFFLElBQUk7U0FDZCxDQUFDLENBQUM7UUFDSCxPQUFPO0tBQ1Y7SUFLRCxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFO1FBQzdCLFFBQVEsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFO1lBQ3RCLEtBQUssRUFBRTtnQkFDSCxjQUFjLEVBQUUsYUFBYTtnQkFDN0IsV0FBVyxFQUFFLGFBQWE7YUFDN0I7U0FDSixDQUFDLENBQUM7UUFDSCxPQUFPO0tBQ1Y7SUFFRCxVQUFVLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLGdCQUFnQixDQUFDLENBQUM7SUFFekQsU0FBUyxnQkFBZ0IsQ0FBQyxLQUFLO1FBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTtZQUFFLE9BQU87UUFFeEIsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFO1lBQ2hDLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsS0FBSyx1QkFBdUIsRUFBRTtnQkFDNUQsUUFBUSxDQUFDLG1CQUFtQixDQUFDLENBQUM7YUFDakM7aUJBQU07Z0JBQ0gsUUFBUSxDQUNKLElBQUksRUFDSixLQUFLLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUM5QixvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQzlGLENBQUM7YUFDTDtZQUdELFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztTQUMvRDtRQUVELElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBRTtZQUNsQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxJQUFJLEVBQUUsb0JBQW9CLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUM7WUFHekcsVUFBVSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1NBQy9EO0lBQ0wsQ0FBQztJQUVELElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtRQUNuQixVQUFVLENBQUMsc0JBQXNCLEVBQUUsR0FBRyxDQUFDLENBQUM7S0FDM0M7U0FBTTtRQUNILFVBQVUsQ0FBQztZQUNQLHNCQUFzQixDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDN0MsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0tBQ1g7QUFDTCxDQUFDLENBQUM7QUFFRixTQUFTLG9CQUFvQixDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsb0JBQW9CO0lBQy9ELElBQUksa0JBQWtCLEdBQUc7UUFDckIsS0FBSyxFQUFFLEtBQUs7UUFDWixLQUFLLEVBQUU7WUFDSCxTQUFTLEVBQUU7Z0JBQ1AsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQy9DLFFBQVEsRUFBRSxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUN6RSxTQUFTLEVBQUUsVUFBVSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSTthQUMvRTtZQUNELFFBQVEsRUFBRSxFQUFFO1NBQ2Y7S0FDSixDQUFDO0lBRUYsSUFBSSxDQUFDLENBQUMsb0JBQW9CLEVBQUU7UUFDeEIsa0JBQWtCLENBQUMsS0FBSyxHQUFHO1lBQ3ZCLFNBQVMsRUFBRTtnQkFDUCxpQkFBaUIsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUzthQUVsRDtZQUNELFFBQVEsRUFBRSxFQUFFO1NBQ2YsQ0FBQztLQUNMO0lBRUQsSUFBSSxRQUFRLEVBQUU7UUFDVixrQkFBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLG1CQUFtQixHQUFHLFFBQVEsQ0FBQztRQUVsRSxJQUFJLGtCQUFrQixDQUFDLEtBQUssSUFBSSxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFO1lBQ2hFLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEdBQUcsUUFBUSxDQUFDO1NBQ3JFO0tBQ0o7SUFFRCxPQUFPLGtCQUFrQixDQUFDO0FBQzlCLENBQUM7QUFFRCxTQUFTLHNCQUFzQixDQUFDLGdCQUFnQjtJQUM1QyxJQUFJLENBQUMsTUFBTSxFQUFFO1FBQ1QsVUFBVSxDQUFDO1lBQ1Asc0JBQXNCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztRQUNILE9BQU87S0FDVjtJQUVELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO1FBQ2xCLFVBQVUsQ0FBQztZQUNQLHNCQUFzQixDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDN0MsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ1IsT0FBTztLQUNWO0lBRUQsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1FBQ25CLE1BQU0sQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUM1QjtZQUNJLGVBQWUsRUFBRSxJQUFJO1NBQ3hCLEVBQ0QsR0FBRyxDQUNOLENBQUM7S0FDTDtTQUFNLElBQUksQ0FBQyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRTtRQUNuQyxNQUFNLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FDNUI7WUFDSSxxQkFBcUIsRUFBRSxnQkFBZ0I7U0FDMUMsRUFDRCxHQUFHLENBQ04sQ0FBQztLQUNMO1NBQU07UUFDSCxNQUFNLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FDNUI7WUFDSSx3QkFBd0IsRUFBRSxJQUFJO1NBQ2pDLEVBQ0QsR0FBRyxDQUNOLENBQUM7S0FDTDtBQUNMLENBQUM7QUFFRCxJQUFJLE1BQU0sQ0FBQztBQUdYLFVBQVUsQ0FBQyxvQkFBb0IsR0FBRyxVQUFVLFFBQVE7SUFDaEQsVUFBVSxDQUFDO1FBQ1AsV0FBVyxDQUFDLFVBQVUsS0FBSyxFQUFFLFFBQVEsRUFBRSxrQkFBa0I7WUFDckQsSUFBSSxDQUFDLGtCQUFrQixFQUFFO2dCQUNyQixrQkFBa0IsR0FBRztvQkFDakIsS0FBSyxFQUFFLElBQUk7aUJBQ2QsQ0FBQzthQUNMO1lBRUQsUUFBUSxDQUFDLEtBQUssRUFBRSxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyxDQUFDO0FBRUYsU0FBUyxVQUFVLENBQUMsWUFBWTtJQUM1QixJQUFJLE1BQU0sRUFBRTtRQUNSLFlBQVksRUFBRSxDQUFDO1FBQ2YsT0FBTztLQUNWO0lBRUQsTUFBTSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDMUMsTUFBTSxDQUFDLE1BQU0sR0FBRztRQUNaLE1BQU0sQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLFlBQVksRUFBRSxDQUFDO0lBQ25CLENBQUMsQ0FBQztJQUNGLE1BQU0sQ0FBQyxHQUFHLEdBQUcsc0VBQXNFLENBQUM7SUFDcEYsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO0lBQzlCLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3BFLENBQUM7QUFFRCxVQUFVLENBQUMsd0JBQXdCLEdBQUcsVUFBVSxRQUFRO0lBRXBELElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUU7UUFDN0IsUUFBUSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDOUIsT0FBTztLQUNWO0lBRUQsVUFBVSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0lBRXpELFNBQVMsZ0JBQWdCLENBQUMsS0FBSztRQUMzQixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUk7WUFBRSxPQUFPO1FBRXhCLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBRTtZQUNsQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1lBRzNDLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztTQUMvRDtJQUNMLENBQUM7SUFFRCxVQUFVLENBQUMsbUNBQW1DLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDekQsQ0FBQyxDQUFDO0FBRUYsU0FBUyxtQ0FBbUM7SUFDeEMsSUFBSSxDQUFDLE1BQU0sRUFBRTtRQUNULFVBQVUsQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO1FBQ2hELE9BQU87S0FDVjtJQUVELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO1FBQ2xCLFVBQVUsQ0FBQyxtQ0FBbUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNyRCxPQUFPO0tBQ1Y7SUFFRCxNQUFNLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FDNUI7UUFDSSx3QkFBd0IsRUFBRSxJQUFJO0tBQ2pDLEVBQ0QsR0FBRyxDQUNOLENBQUM7QUFDTixDQUFDO0FBRUQsT0FBTyxDQUFDLFdBQVcsR0FBRyxVQUFVLENBQUMsV0FBVyxDQUFDOzs7QUN2TzdDLElBQUksaUJBQWlCLEdBQUcsUUFBUSxDQUFDO0FBQ2pDLElBQUksUUFBUSxDQUFDO0FBQ2IsSUFBSSxjQUFjLENBQUM7QUFFbkIsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLElBQUksT0FBTyxTQUFTLEtBQUssV0FBVyxJQUFJLE9BQU8sU0FBUyxDQUFDLFNBQVMsS0FBSyxXQUFXLEVBQUU7SUFDakgsSUFBSSxTQUFTLEdBQUcsT0FBTyxNQUFNLENBQUMsY0FBYyxLQUFLLFdBQVcsQ0FBQztJQUM3RCxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxTQUFTLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUUsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUM7SUFFM0MsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxVQUFVLEtBQUs7UUFDOUMsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFO1lBQ3hDLE9BQU87U0FDVjtRQUNELGlCQUFpQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsQyxDQUFDLENBQUMsQ0FBQztDQUNOO0FBR0QsU0FBUyxpQkFBaUIsQ0FBQyxJQUFJO0lBRTNCLElBQUksSUFBSSxJQUFJLHVCQUF1QixFQUFFO1FBQ2pDLElBQUksY0FBYztZQUFFLE9BQU8sY0FBYyxDQUFDLHVCQUF1QixDQUFDLENBQUM7O1lBQzlELE1BQU0sSUFBSSxLQUFLLENBQUMsdUJBQXVCLENBQUMsQ0FBQztLQUNqRDtJQUVELElBQUksSUFBSSxJQUFJLHFDQUFxQyxFQUFFO1FBQy9DLGlCQUFpQixHQUFHLFNBQVMsQ0FBQztLQUNqQztJQUVELElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxjQUFjLEVBQUU7UUFDakMsY0FBYyxDQUFDLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLENBQUMsb0JBQW9CLEtBQUssSUFBSSxDQUFDLENBQUM7S0FDbEY7QUFDTCxDQUFDO0FBR0QsU0FBUywwQkFBMEIsQ0FBQyxRQUFRO0lBQ3hDLElBQUksQ0FBQyxRQUFRO1FBQUUsT0FBTztJQUN0QixJQUFJLGlCQUFpQixJQUFJLFNBQVM7UUFBRSxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUcxRCxNQUFNLENBQUMsV0FBVyxDQUFDLGVBQWUsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUN6QyxVQUFVLENBQUM7UUFDUCxJQUFJLGlCQUFpQixJQUFJLFFBQVEsRUFBRTtZQUMvQixRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDbkI7O1lBQU0sUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNiLENBQUM7QUFHRCxTQUFTLFdBQVcsQ0FBQyxRQUFRO0lBQ3pCLElBQUksQ0FBQyxRQUFRO1FBQUUsTUFBTSxvQ0FBb0MsQ0FBQztJQUMxRCxJQUFJLFFBQVE7UUFBRSxPQUFPLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN4QyxjQUFjLEdBQUcsUUFBUSxDQUFDO0lBQzFCLE1BQU0sQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzVDLENBQUM7QUFHRCxTQUFTLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxRQUFRO0lBQ3BDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTztRQUFFLE1BQU0sdURBQXVELENBQUM7SUFDeEYsSUFBSSxDQUFDLFFBQVE7UUFBRSxNQUFNLG9DQUFvQyxDQUFDO0lBRTFELElBQUksUUFBUTtRQUFFLE9BQU8sUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRXhDLGNBQWMsR0FBRyxRQUFRLENBQUM7SUFDMUIsTUFBTSxDQUFDLFdBQVcsQ0FDZDtRQUNJLHFCQUFxQixFQUFFLEdBQUc7S0FDN0IsRUFDRCxHQUFHLENBQ04sQ0FBQztBQUNOLENBQUM7QUFHRCxTQUFTLG9CQUFvQixDQUFDLFFBQVE7SUFDbEMsSUFBSSxDQUFDLFFBQVE7UUFBRSxNQUFNLG9DQUFvQyxDQUFDO0lBQzFELElBQUksUUFBUTtRQUFFLE9BQU8sUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRXhDLGNBQWMsR0FBRyxRQUFRLENBQUM7SUFDMUIsTUFBTSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUM5QyxDQUFDO0FBRUQsU0FBUyx3QkFBd0IsQ0FBQyxXQUFXLEVBQUUsUUFBUTtJQUNuRCxJQUFJLFNBQVM7UUFBRSxPQUFPLFFBQVEsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUM3QyxJQUFJLFNBQVMsQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFO1FBQ3ZCLFFBQVEsR0FBRyxXQUFXLENBQUM7UUFDdkIsV0FBVyxHQUFHLGtDQUFrQyxDQUFDO0tBQ3BEO0lBQ0QsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQyxLQUFLLENBQUMsR0FBRyxHQUFHLHFCQUFxQixHQUFHLFdBQVcsR0FBRyxXQUFXLENBQUM7SUFDOUQsS0FBSyxDQUFDLE1BQU0sR0FBRztRQUNYLGlCQUFpQixHQUFHLFFBQVEsQ0FBQztRQUM3QixNQUFNLENBQUMsV0FBVyxDQUFDLGVBQWUsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN6QyxVQUFVLENBQUM7WUFDUCxJQUFJLGlCQUFpQixJQUFJLFFBQVEsRUFBRTtnQkFDL0IsUUFBUSxDQUFDLG9CQUFvQixDQUFDLENBQUM7YUFDbEM7O2dCQUFNLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNiLENBQUMsQ0FBQztJQUNGLEtBQUssQ0FBQyxPQUFPLEdBQUc7UUFDWixRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDOUIsQ0FBQyxDQUFDO0FBQ04sQ0FBQztBQUVELFNBQVMsNkJBQTZCLENBQUMsUUFBUTtJQUMzQyxvQkFBb0IsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDekMsQ0FBQztBQUdELFNBQVMsb0JBQW9CLENBQUMsUUFBUSxFQUFFLHdCQUF3QjtJQUM1RCxRQUFRLEdBQUcsRUFBRSxDQUFDO0lBQ2QsSUFBSSx3QkFBd0IsR0FBRztRQUMzQixjQUFjLEVBQUUsUUFBUTtRQUN4QixXQUFXLEVBQUUsUUFBUTtLQUN4QixDQUFDO0lBQ0YsSUFBSSxTQUFTO1FBQUUsT0FBTyxRQUFRLENBQUMsSUFBSSxFQUFFLHdCQUF3QixDQUFDLENBQUM7SUFHL0QsSUFBSSxrQkFBa0IsR0FBRztRQUNyQixTQUFTLEVBQUU7WUFDUCxpQkFBaUIsRUFBRSxpQkFBaUI7WUFDcEMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJO1lBQ25ELFNBQVMsRUFBRSxNQUFNLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSTtTQUN6RDtRQUNELFFBQVEsRUFBRSxFQUFFO0tBQ2YsQ0FBQztJQUlGLElBQUksaUJBQWlCLElBQUksU0FBUyxJQUFJLENBQUMsUUFBUSxFQUFFO1FBQzdDLElBQUksd0JBQXdCLEVBQUU7WUFDMUIsb0JBQW9CLENBQUMsVUFBVSxRQUFRLEVBQUUsb0JBQW9CO2dCQUN6RCxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEdBQUcsUUFBUSxDQUFDO2dCQUU1RCxJQUFJLG9CQUFvQixFQUFFO29CQUN0QixrQkFBa0IsQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7aUJBQ2xEO2dCQUNELFFBQVEsQ0FBQyxRQUFRLElBQUksdUJBQXVCLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLGtCQUFrQixDQUFDLENBQUM7WUFDeEYsQ0FBQyxDQUFDLENBQUM7U0FDTjthQUFNO1lBQ0gsV0FBVyxDQUFDLFVBQVUsUUFBUTtnQkFDMUIsa0JBQWtCLENBQUMsU0FBUyxDQUFDLG1CQUFtQixHQUFHLFFBQVEsQ0FBQztnQkFDNUQsUUFBUSxDQUFDLFFBQVEsSUFBSSx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztZQUN4RixDQUFDLENBQUMsQ0FBQztTQUNOO1FBQ0QsT0FBTztLQUNWO0lBR0QsSUFBSSxpQkFBaUIsSUFBSSxTQUFTLEVBQUU7UUFDaEMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLG1CQUFtQixHQUFHLFFBQVEsQ0FBQztLQUMvRDtJQUdELFFBQVEsQ0FBQyxJQUFJLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztBQUN2QyxDQUFDO0FBRUQsT0FBTyxDQUFDLG9CQUFvQixHQUFHLG9CQUFvQixDQUFDO0FBQ3BELE9BQU8sQ0FBQyw2QkFBNkIsR0FBRyw2QkFBNkIsQ0FBQztBQUN0RSxPQUFPLENBQUMsMEJBQTBCLEdBQUcsMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxDQUFDLHdCQUF3QixHQUFHLHdCQUF3QixDQUFDO0FBQzVELE9BQU8sQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDOzs7Ozs7QUNqS2xDLG1DQUFzQztBQUV0QztJQUVJO0lBQWUsQ0FBQztJQUVULHlCQUFXLEdBQWxCO1FBQ0ksSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDaEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLGFBQWEsRUFBRSxDQUFDO1NBQ3ZDO1FBQ0QsT0FBTyxhQUFhLENBQUMsUUFBUSxDQUFDO0lBQ2xDLENBQUM7SUFFTSx1Q0FBZSxHQUF0QjtRQUNJLE9BQU8sUUFBUSxDQUFDLElBQUksS0FBSyxRQUFRLENBQUM7SUFDdEMsQ0FBQztJQUtNLHVDQUFlLEdBQXRCO1FBQ0ksT0FBTyxRQUFRLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQztJQUN0QyxDQUFDO0lBS00sNkNBQXFCLEdBQTVCO1FBQ0ksT0FBTyxRQUFRLENBQUMsSUFBSSxLQUFLLGVBQWUsQ0FBQztJQUM3QyxDQUFDO0lBS00sd0NBQWdCLEdBQXZCO1FBQ0ksT0FBTyxRQUFRLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQztJQUN2QyxDQUFDO0lBS00sOENBQXNCLEdBQTdCO1FBQ0ksT0FBTyxRQUFRLENBQUMsSUFBSSxLQUFLLGdCQUFnQixJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssaUJBQWlCLENBQUM7SUFDckYsQ0FBQztJQUtNLHNDQUFjLEdBQXJCO1FBQ0ksT0FBTyxRQUFRLENBQUMsSUFBSSxLQUFLLE9BQU8sQ0FBQztJQUNyQyxDQUFDO0lBS00sNENBQW9CLEdBQTNCO1FBQ0ksT0FBTyxRQUFRLENBQUMsSUFBSSxLQUFLLGNBQWMsQ0FBQztJQUM1QyxDQUFDO0lBS00scUNBQWEsR0FBcEI7UUFDSSxJQUFNLE9BQU8sR0FBRyxDQUFBLFFBQVEsYUFBUixRQUFRLHVCQUFSLFFBQVEsQ0FBRSxPQUFPLEVBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLE9BQU8sUUFBUSxDQUFDLElBQUksS0FBSyxnQkFBZ0IsSUFBSSxPQUFPLElBQUksRUFBRSxDQUFDO0lBQy9ELENBQUM7SUFLTSwyQ0FBbUIsR0FBMUI7O1FBQ0ksSUFBTSxPQUFPLEdBQUcsQ0FBQSxRQUFRLGFBQVIsUUFBUSx1QkFBUixRQUFRLENBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0RSxPQUFPLFFBQVEsQ0FBQyxJQUFJLEtBQUssZ0JBQWdCLElBQUksQ0FBQyxDQUFBLE1BQUEsUUFBUSxDQUFDLEVBQUUsMENBQUUsTUFBTSxNQUFLLFNBQVMsSUFBSSxDQUFBLE1BQUEsUUFBUSxDQUFDLEVBQUUsMENBQUUsTUFBTSxNQUFLLEtBQUssQ0FBQyxJQUFJLE9BQU8sR0FBRyxFQUFFLENBQUM7SUFDdEksQ0FBQztJQUtNLHdDQUFnQixHQUF2QjtRQUNJLE9BQU8sUUFBUSxDQUFDLElBQUksS0FBSyxpQkFBaUIsQ0FBQztJQUMvQyxDQUFDO0lBS00sa0NBQVUsR0FBakI7UUFDSSxPQUFPLFFBQVEsQ0FBQyxJQUFJLEtBQUssVUFBVSxDQUFDO0lBQ3hDLENBQUM7SUFLTSxnQ0FBUSxHQUFmO1FBQ0ksT0FBTyxRQUFRLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQztJQUN2QyxDQUFDO0lBS00sd0NBQWdCLEdBQXZCO1FBQ0ksT0FBTyxRQUFRLENBQUMsSUFBSSxLQUFLLHlCQUF5QixJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssa0JBQWtCLENBQUM7SUFDL0YsQ0FBQztJQUtNLHNDQUFjLEdBQXJCO1FBQ0ksSUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUM7UUFDcEUsSUFBTSxXQUFXLEdBQUcsWUFBWSxJQUFJLFFBQVEsQ0FBQztRQUM3QyxJQUFNLE1BQU0sR0FBRyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksV0FBVyxDQUFDO1FBQ3RFLElBQU0sUUFBUSxHQUFHLG9CQUFvQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksV0FBVyxDQUFDO1FBQzdHLE9BQU8sTUFBTSxJQUFJLFFBQVEsQ0FBQztJQUM5QixDQUFDO0lBS00sdUNBQWUsR0FBdEI7UUFDSSxJQUFNLFNBQVMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQztRQUNwRSxPQUFPLENBQ0gsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUNyQixtQkFBbUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztZQUMxQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3BDLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUNwQyxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FDdkMsQ0FBQztJQUNOLENBQUM7SUFLTSxrQ0FBVSxHQUFqQjtRQUNJLE9BQU8sSUFBSSxDQUFDLGNBQWMsRUFBRSxJQUFJLFFBQVEsQ0FBQyxFQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQzNFLENBQUM7SUFLTSxzQ0FBYyxHQUFyQjtRQUNJLE9BQU8sUUFBUSxDQUFDLEVBQUksQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLFFBQVEsQ0FBQyxJQUFJLElBQUksaUJBQWlCLENBQUM7SUFDcEYsQ0FBQztJQUtNLHNDQUFjLEdBQXJCO1FBQ0ksT0FBTyxRQUFRLENBQUMsRUFBSSxDQUFDLE1BQU0sS0FBSyxLQUFLLElBQUksUUFBUSxDQUFDLEVBQUksQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDO0lBQ2hGLENBQUM7SUFLTSxxQ0FBYSxHQUFwQjtRQUNJLE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7SUFLTSxrQ0FBVSxHQUFqQjtRQUNJLE9BQU8sQ0FDSCxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQ3RCLElBQUksQ0FBQyxxQkFBcUIsRUFBRTtZQUM1QixJQUFJLENBQUMsY0FBYyxFQUFFO1lBQ3JCLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtZQUMzQixJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ3BCLElBQUksQ0FBQyxtQkFBbUIsRUFBRTtZQUMxQixJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDdkIsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUNyQixJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2pCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FDcEIsQ0FBQztJQUNOLENBQUM7SUFLTSxzQ0FBYyxHQUFyQjtRQUNJLElBQU0sT0FBTyxHQUFHLENBQUEsUUFBUSxhQUFSLFFBQVEsdUJBQVIsUUFBUSxDQUFFLE9BQU8sRUFBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFdEUsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUU7WUFDdkIsT0FBTyxLQUFLLENBQUM7U0FDaEI7UUFDRCxPQUFPLENBQ0gsSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUN0QixJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDdkIsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUNyQixJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2pCLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDcEIsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLElBQUksT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUM1QyxDQUFDO0lBQ04sQ0FBQztJQUtNLCtCQUFPLEdBQWQ7UUFDSSxPQUFPLFFBQVEsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFLTSxrQ0FBVSxHQUFqQjtRQUNJLE9BQU8sUUFBUSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUM7SUFDbEMsQ0FBQztJQUtNLGlDQUFTLEdBQWhCO1FBQ0ksT0FBTyxRQUFRLENBQUMsRUFBSSxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUM7SUFDdEMsQ0FBQztJQUtNLHNDQUFjLEdBQXJCO1FBQ0ksT0FBTyxRQUFRLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQztJQUN0QyxDQUFDO0lBQ0wsb0JBQUM7QUFBRCxDQTFOQSxBQTBOQyxJQUFBO0FBMU5ZLHNDQUFhOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2UxQixpQ0FBb0M7QUFDcEMsNkJBQW9DO0FBRXBDLDJEQUE4RDtBQUM5RCwyREFBMEQ7QUFDMUQsOENBQWtEO0FBS2xELElBQU0sTUFBTSxHQUFtQiwrQkFBYyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBSTVELElBQUksUUFBdUIsQ0FBQztBQWtCNUI7SUFXSSxvQkFBWSxhQUFzQztRQUFsRCxpQkEwQ0M7UUFuREQsMEJBQXFCLEdBQXNCLEVBQUUsQ0FBQztRQUM5Qyx5QkFBb0IsR0FBc0IsRUFBRSxDQUFDO1FBS3JDLHFCQUFnQixHQUFzQixFQUFFLENBQUM7UUFDekMsMkJBQXNCLEdBQUcsS0FBSyxDQUFDO1FBR25DLFFBQVEsR0FBRyx3QkFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRXZDLElBQUksQ0FBQyxhQUFhLHlCQUNYLGFBQWEsS0FDaEIsVUFBVSxFQUFFLENBQUMsQ0FBQyxhQUFhLENBQUMsVUFBVSxJQUFJLGFBQWEsQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQ3BILFdBQVcsRUFBRSxhQUFhLENBQUMsV0FBVyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUN2RixJQUFJLEVBQUUsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFDNUQsRUFBRSxFQUFFLENBQUMsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsR0FDdEUsQ0FBQztRQUVGLE1BQU0sQ0FBQyxLQUFLLENBQUMsdUNBQWdDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUUsQ0FBQyxDQUFDO1FBRTVGLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFFL0UsSUFBSSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLEVBQUUsVUFBQyxLQUFnQztZQUN0RSxJQUFJLEtBQUssQ0FBQyxTQUFTLEtBQUssSUFBSSxFQUFFO2dCQU8xQixJQUFNLGFBQWEsR0FBd0IsS0FBSyxDQUFDLFNBQWdDLENBQUM7Z0JBQ2xGLElBQU0sWUFBWSxHQUFHLElBQUksZUFBZSxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUV4RCxLQUFJLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsQ0FBQztnQkFDaEQsSUFBSSxZQUFZLENBQUMsU0FBUyxLQUFLLEVBQUUsRUFBRTtvQkFDL0IsS0FBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztpQkFDaEQ7YUFDSjtRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxzQkFBc0IsRUFBRTtZQUM3QyxJQUFJLEtBQUksQ0FBQyxFQUFFLENBQUMsY0FBYyxLQUFLLFFBQVEsRUFBRTtnQkFFckMsT0FBTyxLQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtvQkFDckMsSUFBSSxTQUFTLEdBQUcsS0FBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO29CQUM5QyxLQUFJLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBa0IsU0FBUyxDQUFDLENBQUM7aUJBQ3ZEO2FBQ0o7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCwwQkFBSyxHQUFMO1FBQ0ksT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBS0QsNEJBQU8sR0FBUDtRQUNJLE1BQU0sQ0FBQyxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUNyQyxJQUFJLElBQUksQ0FBQyxFQUFFLEVBQUU7WUFDVCxJQUFJLElBQUksQ0FBQyxFQUFFLENBQUMsY0FBYyxLQUFLLFFBQVEsRUFBRTtnQkFDckMsT0FBTzthQUNWO1lBQ0QsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUMscUJBQXFCLEdBQUcsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUM7U0FDbEM7SUFDTCxDQUFDO0lBS08sc0NBQWlCLEdBQXpCO1FBQ0ksSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUU7WUFDbEMsSUFBSSxDQUFDLGdDQUFnQyxFQUFFLENBQUM7U0FDM0M7UUFFRCxJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQztRQUMzRCxJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQztRQUUzRCxJQUFNLE9BQU8sR0FBb0I7WUFDN0IsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEtBQUssVUFBVSxJQUFJLFFBQVE7WUFDdkUsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEtBQUssVUFBVSxJQUFJLFFBQVE7U0FDMUUsQ0FBQztRQUVGLE1BQU0sQ0FBQyxLQUFLLENBQUMsOERBQThELEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBRXRHLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQU1LLGdDQUFXLEdBQWpCOzs7Ozs7O3dCQUdJLElBQUksQ0FBQyxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRTs0QkFDaEMsTUFBTSxDQUFDLElBQUksQ0FDUCxvSEFBb0gsQ0FDdkgsQ0FBQzs0QkFDRixXQUFPLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxFQUFDO3lCQUNuQzs2QkFBTTs0QkFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLGdGQUFnRixDQUFDLENBQUM7eUJBQ2xHOzZCQUlHLENBQUEsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEtBQUssVUFBVSxDQUFBLEVBQXRDLGNBQXNDO3dCQUl0QyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUU7NEJBQ2pDLE1BQU0sSUFBSSxLQUFLLENBQ1gsaURBQTBDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSwrQ0FBNEMsQ0FDaEgsQ0FBQzt5QkFDTDs4QkFFNkQsRUFBMUMsS0FBQSxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUU7Ozs2QkFBMUMsQ0FBQSxjQUEwQyxDQUFBO3dCQUFuRCxLQUFLO3dCQUNOLE1BQU0sR0FBMEI7NEJBQ2xDLFNBQVMsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUk7NEJBQ2xDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO3lCQUM1QyxDQUFDO3dCQUVGLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUU7NEJBRWxELGFBQWEsR0FBRyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7NEJBQ3BDLFdBQVcsR0FBRyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7NEJBRXJDLFVBQVUsR0FDWixNQUFBLE1BQUEsTUFBQSxhQUFhLENBQUMsS0FBSyxtQ0FBSyxXQUFXLENBQUMsS0FBNkIsQ0FBQyxLQUFLLG1DQUFLLFdBQVcsQ0FBQyxLQUFnQixtQ0FBSSxDQUFDLENBQUM7NEJBQzVHLFdBQVcsR0FDYixNQUFBLE1BQUEsTUFBQSxhQUFhLENBQUMsTUFBTSxtQ0FBSyxXQUFXLENBQUMsTUFBOEIsQ0FBQyxLQUFLLG1DQUFLLFdBQVcsQ0FBQyxNQUFpQixtQ0FBSSxDQUFDLENBQUM7NEJBQ3JILE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0RBQXlDLFVBQVUsY0FBSSxXQUFXLENBQUUsQ0FBQyxDQUFDOzRCQUU1RSxXQUFXLEdBQUcsVUFBVSxHQUFHLFdBQVcsQ0FBQzs0QkFDekMsU0FBUyxHQUFHLENBQUMsQ0FBQzs0QkFDbEIsSUFBSSxXQUFXLElBQUksR0FBRyxHQUFHLEdBQUcsRUFBRTtnQ0FDMUIsU0FBUyxHQUFHLENBQUMsQ0FBQzs2QkFDakI7aUNBQU0sSUFBSSxXQUFXLElBQUksR0FBRyxHQUFHLEdBQUcsRUFBRTtnQ0FDakMsU0FBUyxHQUFHLENBQUMsQ0FBQzs2QkFDakI7aUNBQU07Z0NBQ0gsU0FBUyxHQUFHLENBQUMsQ0FBQzs2QkFDakI7NEJBRUQsTUFBTSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUM7NEJBQzFCLEtBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsU0FBUyxFQUFFLENBQUMsRUFBRSxFQUFFO2dDQUMxQixRQUFRLEdBQUcsU0FBQSxDQUFDLEVBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBLENBQUM7Z0NBRXBDLFFBQVEsR0FBNkI7b0NBQ3ZDLEdBQUcsRUFBRSxNQUFNLEdBQUcsUUFBUSxDQUFDLFFBQVEsRUFBRTtvQ0FHakMsZUFBZSxFQUFFLE1BQU07aUNBQzFCLENBQUM7Z0NBRUYsSUFBSSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxFQUFFO29DQUVoRCxRQUFRLENBQUMscUJBQXFCLEdBQUcsR0FBRyxDQUFDO29DQUdyQyxRQUFRLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDO2lDQUNyRDtxQ0FBTTtvQ0FDSCxRQUFRLENBQUMscUJBQXFCLEdBQUcsUUFBUSxDQUFDO2lDQUM3QztnQ0FFRCxNQUFNLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzs2QkFDdkM7eUJBQ0o7d0JBRUssRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQzs2QkFFN0MsQ0FBQSxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sQ0FBQSxFQUF0QixjQUFzQjt3QkFDbEIsVUFBVSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUM7d0JBQ3ZDLGFBQWEsR0FBRyxLQUFLLENBQUM7d0JBRTFCLElBQUksQ0FBQyxDQUFBLE1BQUEsVUFBVSxDQUFDLHFCQUFxQiwwQ0FBRSxNQUFNLENBQUEsRUFBRTs0QkFHM0MsSUFBSSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxFQUFFO2dDQUNoRCxVQUFVLENBQUMscUJBQXFCLEdBQUcscUJBQXFCLENBQUM7NkJBQzVEO2lDQUFNO2dDQUNILFVBQVUsQ0FBQyxxQkFBcUIsR0FBRyxVQUFVLENBQUM7NkJBQ2pEOzRCQUVELE1BQU0sQ0FBQyxJQUFJLENBQUMsaUVBQTBELFVBQVUsQ0FBQyxxQkFBcUIsQ0FBRSxDQUFDLENBQUM7NEJBSzFHLGFBQWEsR0FBRyxJQUFJLENBQUM7eUJBQ3hCO3dCQWFELElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUU7NEJBQzlCLElBQUksQ0FBQSxNQUFBLFVBQVUsQ0FBQyxTQUFTLDBDQUFFLE1BQU0sTUFBSyxNQUFNLENBQUMsYUFBYyxDQUFDLE1BQU0sRUFBRTtnQ0FDL0QsVUFBVSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUMsYUFBYyxDQUFDO2dDQUU3QyxhQUFhLEdBQUcsSUFBSSxDQUFDOzZCQUN4Qjt5QkFDSjs2QkFFRyxhQUFhLEVBQWIsY0FBYTt3QkFDYixNQUFNLENBQUMsS0FBSyxDQUFDLGdFQUFnRSxDQUFDLENBQUM7Ozs7d0JBRTNFLFdBQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLEVBQUE7O3dCQUF6QyxTQUF5QyxDQUFDOzs7O3dCQUV0QyxPQUFPLEdBQUcsMEVBQTBFLENBQUM7d0JBQ3pGLElBQUksT0FBSyxZQUFZLEtBQUssRUFBRTs0QkFDeEIsT0FBTyxJQUFJLFlBQUssT0FBSyxDQUFDLE9BQU8sQ0FBRSxDQUFDO3lCQUNuQzt3QkFDRCxNQUFNLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDOzt3QkF2R3JCLElBQTBDLENBQUE7Ozs7d0JBNkg5RCxXQUFxQyxFQUFsQixNQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsRUFBbEIsY0FBa0IsRUFBbEIsSUFBa0IsRUFBRTs0QkFBNUIsSUFBSTs0QkFFWCxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsRUFBRTtnQ0FDNUMsU0FBUzs2QkFDWjs0QkFFRCxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDOzRCQUNuRCxJQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUU7Z0NBQ3pCLFNBQVMsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUk7Z0NBQ2xDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDOzZCQUM1QyxDQUFDLENBQUM7eUJBQ047Ozs7d0JBS1UsV0FBTSxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxFQUFBOzt3QkFBdEMsUUFBUSxHQUFHLFNBQTJCLENBQUM7Ozs7d0JBRW5DLE9BQU8sR0FBRywrREFBK0QsQ0FBQzt3QkFDOUUsSUFBSSxPQUFLLFlBQVksS0FBSyxFQUFFOzRCQUN4QixPQUFPLElBQUksWUFBSyxPQUFLLENBQUMsT0FBTyxDQUFFLENBQUM7eUJBQ25DO3dCQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7NkJBRzdCLFdBQU8sUUFBUSxFQUFDOzs7O0tBQ25CO0lBRUQscURBQWdDLEdBQWhDO1FBQ0ksS0FBb0IsVUFBMkMsRUFBM0MsS0FBQSxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVksQ0FBQyxTQUFTLEVBQUUsRUFBM0MsY0FBMkMsRUFBM0MsSUFBMkMsRUFBRTtZQUE1RCxJQUFNLEtBQUssU0FBQTtZQUNaLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVksQ0FBQyxDQUFDO1NBQzVEO0lBQ0wsQ0FBQztJQU1ELGlDQUFZLEdBQVo7UUFBQSxpQkF3REM7UUF2REcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBRy9CLElBQUksaUJBQWlCLElBQUksS0FBSSxDQUFDLEVBQUUsRUFBRTtnQkFDOUIsTUFBTSxDQUFDLEtBQUssQ0FBQyxrRkFBa0YsQ0FBQyxDQUFDO3dDQU90RixJQUFJO29CQUVYLElBQUksQ0FBQyxLQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFOztxQkFFL0M7b0JBRUQsSUFBSSxFQUFFLEdBQUcsS0FBSSxDQUFDLEVBQUUsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBQyxFQUFFLElBQUssT0FBQSxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssSUFBSSxFQUEvQixDQUErQixDQUFDLENBQUM7b0JBRWpGLElBQUksRUFBRSxFQUFFO3dCQUVKLEVBQUUsQ0FBQyxTQUFTLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUM7cUJBQzFDO3lCQUFNO3dDQUNJLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxVQUFHLElBQUksdUVBQW9FLENBQUMsQ0FBQztxQkFDeEc7O2dCQWJMLEtBQW1CLFVBQWtCLEVBQWxCLE1BQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxFQUFsQixjQUFrQixFQUFsQixJQUFrQjtvQkFBaEMsSUFBTSxJQUFJLFNBQUE7MENBQUosSUFBSTs7O2lCQWNkO2dCQUVELEtBQUksQ0FBQyxFQUFFO3FCQUNGLFlBQVksRUFBRTtxQkFDZCxJQUFJLENBQUMsVUFBQyxTQUFTLElBQUssT0FBQSxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQWxCLENBQWtCLENBQUM7cUJBQ3ZDLEtBQUssQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQzthQUN4QztpQkFBTTtnQkFJSCxJQUFJLFVBQVUsU0FBQSxFQUNWLFVBQVUsR0FBRyxJQUFJLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyxDQUFDLEtBQUksQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLEVBQUU7b0JBQ3ZDLFVBQVU7d0JBQ04sT0FBTyxLQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUksQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ3RILFVBQVU7d0JBQ04sT0FBTyxLQUFJLENBQUMsYUFBYSxDQUFDLGdCQUFnQixDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUksQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ3RILElBQU0sV0FBVyxHQUFvQjt3QkFDakMsbUJBQW1CLEVBQUUsVUFBVTt3QkFDL0IsbUJBQW1CLEVBQUUsVUFBVTtxQkFDbEMsQ0FBQztvQkFDRixLQUFJLENBQUMsRUFBRyxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUM7eUJBQzdCLElBQUksQ0FBQyxVQUFDLFNBQVMsSUFBSyxPQUFBLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBbEIsQ0FBa0IsQ0FBQzt5QkFDdkMsS0FBSyxDQUFDLFVBQUMsS0FBSyxJQUFLLE9BQUEsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFiLENBQWEsQ0FBQyxDQUFDO2lCQUN4QzthQUNKO1FBSUwsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBS0Qsc0NBQWlCLEdBQWpCLFVBQWtCLEtBQWdDO1FBQWxELGlCQWVDO1FBZEcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLEtBQUksQ0FBQyxFQUFFO2lCQUNGLG1CQUFtQixDQUFDLEtBQUssQ0FBQztpQkFDMUIsSUFBSSxDQUFDO2dCQUNGLElBQU0sZ0JBQWdCLEdBQUcsS0FBSSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQztnQkFDbEQsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLEVBQUU7b0JBQ3BCLE1BQU0sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEVBQUUsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQzVELE9BQU8sT0FBTyxFQUFFLENBQUM7aUJBQ3BCO3FCQUFNO29CQUNILE9BQU8sTUFBTSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7aUJBQ3JEO1lBQ0wsQ0FBQyxDQUFDO2lCQUNELEtBQUssQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQztRQUN6QyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLRCx1Q0FBa0IsR0FBbEIsVUFBbUIsUUFBZ0I7UUFBbkMsaUJBZUM7UUFkRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07WUFDL0IsSUFBTSxLQUFLLEdBQThCO2dCQUNyQyxJQUFJLEVBQUUsT0FBTztnQkFDYixHQUFHLEVBQUUsUUFBUTthQUNoQixDQUFDO1lBQ0YsTUFBTSxDQUFDLEtBQUssQ0FBQyxnREFBZ0QsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUV0RSxJQUFJLEtBQUksQ0FBQyxFQUFFLENBQUMsY0FBYyxLQUFLLFFBQVEsRUFBRTtnQkFDckMsT0FBTyxNQUFNLENBQUMsbUVBQW1FLENBQUMsQ0FBQzthQUN0RjtZQUNELEtBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUM7aUJBQzNCLElBQUksQ0FBQyxjQUFNLE9BQUEsT0FBTyxFQUFFLEVBQVQsQ0FBUyxDQUFDO2lCQUNyQixLQUFLLENBQUMsVUFBQyxLQUFLLElBQUssT0FBQSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQWIsQ0FBYSxDQUFDLENBQUM7UUFDekMsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBS0QsdUNBQWtCLEdBQWxCLFVBQW1CLE1BQWlDO1FBQXBELGlCQVdDO1FBVkcsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQy9CLE1BQU0sQ0FBQyxLQUFLLENBQUMsK0NBQStDLENBQUMsQ0FBQztZQUM5RCxJQUFJLEtBQUksQ0FBQyxFQUFFLENBQUMsY0FBYyxLQUFLLFFBQVEsRUFBRTtnQkFDckMsT0FBTyxNQUFNLENBQUMsa0VBQWtFLENBQUMsQ0FBQzthQUNyRjtZQUNELEtBQUksQ0FBQyxFQUFFO2lCQUNGLG1CQUFtQixDQUFDLE1BQU0sQ0FBQztpQkFDM0IsSUFBSSxDQUFDLGNBQU0sT0FBQSxPQUFPLEVBQUUsRUFBVCxDQUFTLENBQUM7aUJBQ3JCLEtBQUssQ0FBQyxVQUFDLEtBQUssSUFBSyxPQUFBLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBYixDQUFhLENBQUMsQ0FBQztRQUN6QyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLRCx3Q0FBbUIsR0FBbkIsVUFBb0IsU0FBaUI7UUFBckMsaUJBd0JDO1FBdkJHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixJQUFNLE1BQU0sR0FBOEI7Z0JBQ3RDLElBQUksRUFBRSxRQUFRO2dCQUNkLEdBQUcsRUFBRSxTQUFTO2FBQ2pCLENBQUM7WUFDRixNQUFNLENBQUMsS0FBSyxDQUFDLGlEQUFpRCxDQUFDLENBQUM7WUFFaEUsSUFBSSxLQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsS0FBSyxRQUFRLEVBQUU7Z0JBQ3JDLE9BQU8sTUFBTSxDQUFDLG1FQUFtRSxDQUFDLENBQUM7YUFDdEY7WUFDRCxLQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDO2lCQUM1QixJQUFJLENBQUM7Z0JBUUYsT0FBTyxFQUFFLENBQUM7WUFDZCxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLFVBQUMsS0FBSyxJQUFLLE9BQUEsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFiLENBQWEsQ0FBQyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUtLLHlDQUFvQixHQUExQixVQUEyQixHQUE4Qjs7O2dCQUNyRCxXQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLEVBQUM7OztLQUM1QztJQUtELG9DQUFlLEdBQWYsVUFBZ0IsWUFBNkI7UUFBN0MsaUJBd0JDO1FBdkJHLE9BQU8sSUFBSSxPQUFPLENBQUMsVUFBQyxPQUFPLEVBQUUsTUFBTTtZQUMvQixNQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQzVELEtBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDOUMsUUFBUSxLQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsRUFBRTtnQkFDNUIsS0FBSyxRQUFRO29CQUNULE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3JELE1BQU07Z0JBQ1YsS0FBSyxRQUFRO29CQUNULElBQUksQ0FBQyxDQUFDLEtBQUksQ0FBQyxFQUFFLENBQUMsaUJBQWlCLEVBQUU7d0JBQzdCLEtBQUksQ0FBQyxFQUFFOzZCQUNGLGVBQWUsQ0FBQyxZQUFZLENBQUM7NkJBQzdCLElBQUksQ0FBQyxjQUFNLE9BQUEsT0FBTyxFQUFFLEVBQVQsQ0FBUyxDQUFDOzZCQUNyQixLQUFLLENBQUMsVUFBQyxLQUFLLElBQUssT0FBQSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQWIsQ0FBYSxDQUFDLENBQUM7cUJBQ3hDO3lCQUFNO3dCQUNILEtBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7d0JBQ3pDLE9BQU8sRUFBRSxDQUFDO3FCQUNiO29CQUNELE1BQU07Z0JBQ1Y7b0JBQ0ksS0FBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztvQkFDekMsT0FBTyxFQUFFLENBQUM7YUFDakI7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCx3REFBbUMsR0FBbkMsVUFBb0MsT0FBZTtRQUFuRCxpQkE2Q0M7UUE1Q0csSUFBSSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQywwQkFBMEIsRUFBRTtZQUNqRCxJQUFNLGtCQUFrQixHQUEwQixLQUFJLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDO1lBQzdFLFFBQVEsa0JBQWtCLEVBQUU7Z0JBQ3hCLEtBQUssY0FBYztvQkFFZixJQUFNLElBQUksR0FDTiwwQ0FBMEM7d0JBQzFDLEtBQUksQ0FBQyxhQUFhLENBQUMsRUFBRTt3QkFDckIsSUFBSTt3QkFDSixPQUFPO3dCQUNQLDREQUE0RCxDQUFDO29CQUNqRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUNsQixLQUFJLENBQUMsYUFBYSxDQUFDLDZCQUE2QixDQUFDLG1DQUFrQixDQUFDLDJCQUEyQixFQUFFLElBQUksQ0FBQyxDQUFDO29CQUN2RyxNQUFNO2dCQUNWLEtBQUssUUFBUTtvQkFDVCxJQUFNLElBQUksR0FBRywwQ0FBMEMsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsR0FBRyxJQUFJLEdBQUcsT0FBTyxHQUFHLGVBQWUsQ0FBQztvQkFDbkgsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDbkIsS0FBSSxDQUFDLGFBQWEsQ0FBQyw2QkFBNkIsQ0FBQyxtQ0FBa0IsQ0FBQyxxQkFBcUIsRUFBRSxJQUFJLENBQUMsQ0FBQztvQkFDakcsTUFBTTtnQkFDVixLQUFLLFFBQVE7b0JBQ1QsTUFBTSxDQUFDLEdBQUcsQ0FDTiwwQ0FBMEMsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsR0FBRyxJQUFJLEdBQUcsT0FBTyxHQUFHLHNCQUFzQixDQUMvRyxDQUFDO29CQUNGLE1BQU07Z0JBQ1YsS0FBSyxLQUFLO29CQUNOLE1BQU0sQ0FBQyxHQUFHLENBQUMsMENBQTBDLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEdBQUcsSUFBSSxHQUFHLE9BQU8sR0FBRyxtQkFBbUIsQ0FBQyxDQUFDO29CQUN0SCxNQUFNO2dCQUNWLEtBQUssVUFBVTtvQkFDWCxNQUFNLENBQUMsR0FBRyxDQUNOLDBDQUEwQyxHQUFHLEtBQUksQ0FBQyxhQUFhLENBQUMsRUFBRSxHQUFHLElBQUksR0FBRyxPQUFPLEdBQUcsd0JBQXdCLENBQ2pILENBQUM7b0JBQ0YsTUFBTTtnQkFDVixLQUFLLFdBQVc7b0JBQ1osTUFBTSxDQUFDLEdBQUcsQ0FDTiwwQ0FBMEMsR0FBRyxLQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsR0FBRyxJQUFJLEdBQUcsT0FBTyxHQUFHLHlCQUF5QixDQUNsSCxDQUFDO29CQUNGLE1BQU07Z0JBQ1YsS0FBSyxXQUFXO29CQUNaLE1BQU0sQ0FBQyxHQUFHLENBQ04sMENBQTBDLEdBQUcsS0FBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEdBQUcsSUFBSSxHQUFHLE9BQU8sR0FBRyx5QkFBeUIsQ0FDbEgsQ0FBQztvQkFDRixNQUFNO2FBQ2I7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFLRCxxQ0FBZ0IsR0FBaEI7UUFDSSxPQUFPLElBQUEsU0FBTSxHQUFFLENBQUM7SUFDcEIsQ0FBQztJQUNMLGlCQUFDO0FBQUQsQ0F0Z0JBLEFBc2dCQyxJQUFBO0FBdGdCWSxnQ0FBVTtBQXdnQnZCO0lBQXdDLHNDQUFVO0lBQzlDLDRCQUFZLGFBQXNDO1FBQWxELGlCQUdDO1FBRkcsYUFBYSxDQUFDLElBQUksR0FBRyxVQUFVLENBQUM7UUFDaEMsUUFBQSxrQkFBTSxhQUFhLENBQUMsU0FBQzs7SUFDekIsQ0FBQztJQUNMLHlCQUFDO0FBQUQsQ0FMQSxBQUtDLENBTHVDLFVBQVUsR0FLakQ7QUFMWSxnREFBa0I7QUFPL0I7SUFBd0Msc0NBQVU7SUFDOUMsNEJBQVksYUFBc0M7UUFBbEQsaUJBR0M7UUFGRyxhQUFhLENBQUMsSUFBSSxHQUFHLFVBQVUsQ0FBQztRQUNoQyxRQUFBLGtCQUFNLGFBQWEsQ0FBQyxTQUFDOztJQUN6QixDQUFDO0lBQ0wseUJBQUM7QUFBRCxDQUxBLEFBS0MsQ0FMdUMsVUFBVSxHQUtqRDtBQUxZLGdEQUFrQjtBQU8vQjtJQUF3QyxzQ0FBVTtJQUM5Qyw0QkFBWSxhQUFzQztRQUFsRCxpQkFHQztRQUZHLGFBQWEsQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDO1FBQ2hDLFFBQUEsa0JBQU0sYUFBYSxDQUFDLFNBQUM7O0lBQ3pCLENBQUM7SUFDTCx5QkFBQztBQUFELENBTEEsQUFLQyxDQUx1QyxVQUFVLEdBS2pEO0FBTFksZ0RBQWtCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNuakIvQiwyREFBMEQ7QUFDMUQsOENBQWtEO0FBSWxELElBQU0sTUFBTSxHQUFtQiwrQkFBYyxDQUFDLFdBQVcsRUFBRSxDQUFDO0FBSTVELElBQUksUUFBdUIsQ0FBQztBQTZFNUI7SUFRSSxxQkFBb0IsTUFBYztRQUFkLFdBQU0sR0FBTixNQUFNLENBQVE7UUFQakIsb0JBQWUsR0FBRyxxQkFBcUIsQ0FBQztRQUVqRCx1QkFBa0IsR0FBRyxLQUFLLENBQUM7UUFFM0Isa0JBQWEsR0FBRyxDQUFDLENBQUM7UUFJdEIsUUFBUSxHQUFHLHdCQUFhLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDM0MsQ0FBQztJQUVNLCtCQUFTLEdBQWhCO1FBQ0ksT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUM7SUFDbkMsQ0FBQztJQUVNLHFDQUFlLEdBQXRCO1FBQUEsaUJBcUJDO1FBcEJHLElBQU0sU0FBUyxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRTdELElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRTtZQUNiLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7WUFDL0IsSUFBTSxpQkFBaUIsR0FBc0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUVuRSxNQUFNLENBQUMsSUFBSSxDQUNQLGtDQUFrQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLGlCQUFpQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FDdEgsQ0FBQztZQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7WUFFdkUsSUFBSSxDQUFDLFFBQVEsR0FBRyxpQkFBaUIsQ0FBQyxZQUFZLENBQUM7WUFDL0MsSUFBSSxDQUFDLGFBQWEsR0FBRyxpQkFBaUIsQ0FBQyxRQUFRLENBQUM7WUFFaEQsSUFBSSxDQUFDLHFCQUFxQixHQUFHLFdBQVcsQ0FBQzs7O2dDQUNyQyxXQUFNLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxFQUFBOzs0QkFBcEMsU0FBb0MsQ0FBQzs7OztpQkFDeEMsRUFBRSxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxDQUFDO1NBQ2pDO2FBQU07WUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7U0FDNUM7SUFDTCxDQUFDO0lBc0VNLGlEQUEyQixHQUFsQztRQUFBLGlCQWtGQztRQWpGRyxPQUFPLElBQUksT0FBTyxDQUFDLFVBQU8sT0FBTyxFQUFFLE1BQU07Ozs7NEJBQ1osV0FBTSxJQUFJLENBQUMsTUFBTSxDQUFDLG9CQUFvQixFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUE7O3dCQUF0RSxXQUFXLEdBQVEsU0FBbUQ7d0JBRXRFLGNBQWMsR0FBcUIsSUFBSSxHQUFHLEVBQUUsQ0FBQzt3QkFDN0MsZUFBZSxHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFDO3dCQUM5QyxnQkFBZ0IsR0FBcUIsSUFBSSxHQUFHLEVBQUUsQ0FBQzt3QkFDckQsV0FBVyxDQUFDLE9BQU8sQ0FBQyxVQUFDLElBQVM7NEJBQzFCLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxXQUFXLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLElBQUksUUFBUSxDQUFDLGVBQWUsRUFBRSxJQUFJLFFBQVEsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxFQUFFO2dDQUNoSCxhQUFhLEdBQUcsSUFBSSxDQUFDOzZCQUN4Qjs0QkFDRCxRQUFRLElBQUksQ0FBQyxJQUFJLEVBQUU7Z0NBQ2YsS0FBSyxnQkFBZ0I7b0NBQ2pCLGNBQWMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztvQ0FDbEMsTUFBTTtnQ0FDVixLQUFLLGlCQUFpQjtvQ0FDbEIsZUFBZSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO29DQUNuQyxNQUFNO2dDQUNWLEtBQUssa0JBQWtCO29DQUNuQixnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztvQ0FDcEMsTUFBTTs2QkFDYjt3QkFDTCxDQUFDLENBQUMsQ0FBQzt3QkFFSCxJQUFJLGFBQWEsSUFBSSxJQUFJLEVBQUU7NEJBQ2pCLHVCQUF1QixHQUFHLGFBQWEsQ0FBQyx1QkFBdUIsQ0FBQzs0QkFDdEUscUJBQXFCLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO3lCQUN2RTs2QkFBTTs0QkFFRyxXQUFTLGNBQWMsQ0FBQyxJQUFJLENBQUM7NEJBQzdCLFFBQVEsR0FBRyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUM7NEJBQ3pDLEtBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO2dDQUN2QixhQUFhLEdBQUcsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQztnQ0FDNUMsSUFBSSxhQUFhLENBQUMsVUFBVSxDQUFDLEVBQUU7b0NBQzNCLHFCQUFxQixHQUFHLGFBQWEsQ0FBQztvQ0FDdEMsTUFBTTtpQ0FDVDs2QkFDSjt5QkFDSjt3QkFDSyxnQkFBZ0IsR0FBRyxxQkFBcUIsQ0FBQyxnQkFBZ0IsQ0FBQzt3QkFDMUQsaUJBQWlCLEdBQUcscUJBQXFCLENBQUMsaUJBQWlCLENBQUM7d0JBQzlELG1CQUFtQixHQUFHLGVBQWUsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsQ0FBQzt3QkFDaEUsSUFBSSxDQUFDLENBQUMsbUJBQW1CLEVBQUU7NEJBQ2pCLFFBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLHdCQUF3QixFQUFFLENBQUM7NEJBQ2xELElBQUksR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQUMsQ0FBa0I7Z0NBQzVDLE9BQU8sQ0FDSCxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7b0NBQ2IsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO29DQUMzRyxDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQ3JELENBQUM7NEJBQ04sQ0FBQyxDQUFDLENBQUM7NEJBQ0gsbUJBQW1CLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQzs0QkFDN0IsV0FBa0IsRUFBSixhQUFJLEVBQUosa0JBQUksRUFBSixJQUFJLEVBQUU7Z0NBQVgsQ0FBQztnQ0FDTixtQkFBbUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQzs2QkFDN0M7eUJBQ0o7NkJBQU07NEJBQ0gsbUJBQW1CLEdBQUcsc0VBQXNFLENBQUM7eUJBQ2hHO3dCQUVHLG9CQUFvQixHQUFHLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO3dCQUNuRSxJQUFJLENBQUMsQ0FBQyxvQkFBb0IsRUFBRTs0QkFDbEIsUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMseUJBQXlCLEVBQUUsQ0FBQzs0QkFDbkQsSUFBSSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBQyxDQUFrQjtnQ0FDNUMsT0FBTyxDQUNILENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztvQ0FDYixDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7b0NBQzdHLENBQUMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FDdEQsQ0FBQzs0QkFDTixDQUFDLENBQUMsQ0FBQzs0QkFDSCxvQkFBb0IsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDOzRCQUM5QixXQUFrQixFQUFKLGFBQUksRUFBSixrQkFBSSxFQUFKLElBQUksRUFBRTtnQ0FBWCxDQUFDO2dDQUNOLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDOzZCQUM5Qzt5QkFDSjs2QkFBTTs0QkFDSCxvQkFBb0IsR0FBRyx1RUFBdUUsQ0FBQzt5QkFDbEc7d0JBRUQsV0FBTyxPQUFPLENBQUM7Z0NBQ1gsY0FBYyxFQUFFLG1CQUFtQjtnQ0FDbkMsZUFBZSxFQUFFLG9CQUFvQjs2QkFDeEMsQ0FBQyxFQUFDOzs7YUFDTixDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU0scUNBQWUsR0FBdEI7UUFDSSxJQUFJLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUN6QixhQUFhLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUM7WUFDMUMsTUFBTSxDQUFDLElBQUksQ0FDUCwyQ0FBMkMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQy9ILENBQUM7U0FDTDtJQUNMLENBQUM7SUFFYSwrQkFBUyxHQUF2QixVQUF3QixHQUFXLEVBQUUsUUFBMkI7Ozs7Ozs7d0JBRWxELGFBQWEsR0FBZ0I7NEJBQy9CLE9BQU8sRUFBRTtnQ0FDTCxjQUFjLEVBQUUsa0JBQWtCOzZCQUNyQzs0QkFDRCxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUM7NEJBQzlCLE1BQU0sRUFBRSxNQUFNO3lCQUNqQixDQUFDO3dCQUNGLFdBQU0sS0FBSyxDQUFDLEdBQUcsRUFBRSxhQUFhLENBQUMsRUFBQTs7d0JBQS9CLFNBQStCLENBQUM7Ozs7d0JBRWhDLE1BQU0sQ0FBQyxLQUFLLENBQUMsMkJBQW9CLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBSyxDQUFDLENBQUUsQ0FBQyxDQUFDOzs7Ozs7S0FFakU7SUFFYSw2Q0FBdUIsR0FBckM7Ozs7Ozs7d0JBRTBDLFdBQU0sSUFBSSxDQUFDLGNBQWMsRUFBRSxFQUFBOzt3QkFBdkQsV0FBVyxHQUFpQixTQUEyQjt3QkFDdkQsUUFBUSxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxXQUFXLENBQUMsQ0FBQzt3QkFDN0QsV0FBTSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLEVBQUE7O3dCQUE3QyxTQUE2QyxDQUFDOzs7O3dCQUU5QyxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQUssQ0FBQyxDQUFDOzs7Ozs7S0FFekI7SUFpQ1ksb0NBQWMsR0FBM0I7Ozs7Z0JBQ0ksV0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFPLE9BQU8sRUFBRSxNQUFNOzs7Ozs7O29DQUVSLFdBQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRSxDQUFDLFFBQVEsRUFBRSxFQUFBOztvQ0FBdEUsV0FBVyxHQUFRLFNBQW1EO29DQUN0RSxhQUF5QixJQUFJLENBQUMsNkJBQTZCLEVBQUUsQ0FBQztvQ0FDOUQsb0JBQWtCLENBQUMsZ0JBQWdCLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsWUFBWSxDQUFDLENBQUM7b0NBQ2pHLHVCQUFxQixDQUFDLDBCQUEwQixFQUFFLHNCQUFzQixDQUFDLENBQUM7b0NBRWhGLFdBQVcsQ0FBQyxPQUFPLENBQUMsVUFBQyxJQUFTO3dDQUMxQixJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQzt3Q0FDcEUsSUFBTSxPQUFPLEdBQUcsVUFBQyxTQUFpQixFQUFFLEdBQVc7NENBQzNDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksSUFBSSxVQUFRLENBQUMsU0FBUyxDQUFDLElBQUksSUFBSSxFQUFFO2dEQUNsRCxJQUFJLENBQUMsU0FBUyxJQUFJLGlCQUFlLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFO29EQUNqRCxTQUFTLEdBQUcsT0FBTyxDQUFDO2lEQUN2QjtnREFDRCxJQUFJLFNBQVMsSUFBSSxJQUFJLElBQUksU0FBUyxJQUFJLElBQUksSUFBSSxHQUFHLElBQUksSUFBSSxJQUFJLFVBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxJQUFJLEVBQUU7b0RBQ2pHLFVBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7aURBQzNEO3FEQUFNLElBQUksU0FBUyxJQUFJLElBQUksSUFBSSxHQUFHLElBQUksSUFBSSxJQUFJLG9CQUFrQixDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRTtvREFFN0UsVUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztpREFDaEQ7NkNBQ0o7d0NBQ0wsQ0FBQyxDQUFDO3dDQUVGLFFBQVEsSUFBSSxDQUFDLElBQUksRUFBRTs0Q0FDZixLQUFLLGNBQWM7Z0RBQ2YsT0FBTyxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMsQ0FBQztnREFDakMsT0FBTyxDQUFDLFVBQVUsRUFBRSxhQUFhLENBQUMsQ0FBQztnREFDbkMsT0FBTyxDQUFDLFVBQVUsRUFBRSxlQUFlLENBQUMsQ0FBQztnREFDckMsT0FBTyxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMsQ0FBQztnREFDakMsT0FBTyxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztnREFDaEMsT0FBTyxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztnREFDaEMsT0FBTyxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztnREFDN0IsTUFBTTs0Q0FDVixLQUFLLGFBQWE7Z0RBQ2QsT0FBTyxDQUFDLFNBQVMsRUFBRSxlQUFlLENBQUMsQ0FBQztnREFDcEMsT0FBTyxDQUFDLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO2dEQUN0QyxPQUFPLENBQUMsU0FBUyxFQUFFLGFBQWEsQ0FBQyxDQUFDO2dEQUNsQyxPQUFPLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dEQUM3QixPQUFPLENBQUMsU0FBUyxFQUFFLGVBQWUsQ0FBQyxDQUFDO2dEQUNwQyxPQUFPLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDO2dEQUNoQyxPQUFPLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dEQUMvQixPQUFPLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dEQUMvQixNQUFNOzRDQUNWLEtBQUssT0FBTztnREFDUixPQUFPLENBQUMsU0FBUyxFQUFFLG1CQUFtQixDQUFDLENBQUM7Z0RBQ3hDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztnREFDckMsT0FBTyxDQUFDLFVBQVUsRUFBRSxlQUFlLENBQUMsQ0FBQztnREFDckMsT0FBTyxDQUFDLFVBQVUsRUFBRSxZQUFZLENBQUMsQ0FBQztnREFDbEMsT0FBTyxDQUFDLEtBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFFLGFBQWEsQ0FBQyxDQUFDO2dEQUN2RSxPQUFPLENBQUMsS0FBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLENBQUM7Z0RBQ3RFLE1BQU07NENBQ1YsS0FBSyxnQkFBZ0I7Z0RBQ2pCLE9BQU8sQ0FBQyxlQUFlLEVBQUUsc0JBQXNCLENBQUMsQ0FBQztnREFDakQsT0FBTyxDQUFDLGVBQWUsRUFBRSwwQkFBMEIsQ0FBQyxDQUFDO2dEQUNyRCxNQUFNO3lDQUNiO29DQUNMLENBQUMsQ0FBQyxDQUFDO29DQUdILElBQUksQ0FBQyxDQUFBLFVBQVEsYUFBUixVQUFRLHVCQUFSLFVBQVEsQ0FBRSxhQUFhLENBQUEsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFTLFVBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO3dDQUN0RixPQUFPLFVBQVEsQ0FBQyxhQUFhLENBQUM7cUNBQ2pDO29DQUVELFdBQU8sT0FBTyxDQUFDLFVBQVEsQ0FBQyxFQUFDOzs7b0NBRXpCLE1BQU0sQ0FBQyxLQUFLLENBQUMsOEJBQThCLEVBQUUsT0FBSyxDQUFDLENBQUM7b0NBQ3BELFdBQU8sTUFBTSxDQUFDLE9BQUssQ0FBQyxFQUFDOzs7O3lCQUU1QixDQUFDLEVBQUM7OztLQUNOO0lBRU8sK0NBQXlCLEdBQWpDLFVBQWtDLEtBQW1CO1FBQ2pELE9BQU87WUFDSCxZQUFZLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7WUFDdEMsY0FBYyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUk7WUFDM0MsVUFBVSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVM7WUFDekMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxPQUFPLEVBQUU7WUFDNUIsb0JBQW9CLEVBQUUsUUFBUSxDQUFDLGNBQWMsRUFBRTtZQUMvQyxNQUFNLEVBQUUsUUFBUTtZQUNoQixZQUFZLEVBQUUsS0FBSztTQUN0QixDQUFDO0lBQ04sQ0FBQztJQUVPLG1EQUE2QixHQUFyQztRQUNJLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUN2QixPQUFPO2dCQUNILFFBQVEsRUFBRTtvQkFDTixLQUFLLEVBQUUsRUFBRTtvQkFDVCxLQUFLLEVBQUUsRUFBRTtpQkFDWjtnQkFDRCxhQUFhLEVBQUUsRUFBRTthQUNwQixDQUFDO1NBQ0w7YUFBTTtZQUNILE9BQU87Z0JBQ0gsT0FBTyxFQUFFO29CQUNMLEtBQUssRUFBRSxFQUFFO29CQUNULEtBQUssRUFBRSxFQUFFO2lCQUNaO2FBQ0osQ0FBQztTQUNMO0lBQ0wsQ0FBQztJQUNMLGtCQUFDO0FBQUQsQ0F0V0EsQUFzV0MsSUFBQTtBQXRXWSxrQ0FBVyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcihlLG4sdCl7ZnVuY3Rpb24gbyhpLGYpe2lmKCFuW2ldKXtpZighZVtpXSl7dmFyIGM9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZTtpZighZiYmYylyZXR1cm4gYyhpLCEwKTtpZih1KXJldHVybiB1KGksITApO3ZhciBhPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIraStcIidcIik7dGhyb3cgYS5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGF9dmFyIHA9bltpXT17ZXhwb3J0czp7fX07ZVtpXVswXS5jYWxsKHAuZXhwb3J0cyxmdW5jdGlvbihyKXt2YXIgbj1lW2ldWzFdW3JdO3JldHVybiBvKG58fHIpfSxwLHAuZXhwb3J0cyxyLGUsbix0KX1yZXR1cm4gbltpXS5leHBvcnRzfWZvcih2YXIgdT1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlLGk9MDtpPHQubGVuZ3RoO2krKylvKHRbaV0pO3JldHVybiBvfXJldHVybiByfSkoKSIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4ndXNlIHN0cmljdCc7XG5cbnZhciBSID0gdHlwZW9mIFJlZmxlY3QgPT09ICdvYmplY3QnID8gUmVmbGVjdCA6IG51bGxcbnZhciBSZWZsZWN0QXBwbHkgPSBSICYmIHR5cGVvZiBSLmFwcGx5ID09PSAnZnVuY3Rpb24nXG4gID8gUi5hcHBseVxuICA6IGZ1bmN0aW9uIFJlZmxlY3RBcHBseSh0YXJnZXQsIHJlY2VpdmVyLCBhcmdzKSB7XG4gICAgcmV0dXJuIEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseS5jYWxsKHRhcmdldCwgcmVjZWl2ZXIsIGFyZ3MpO1xuICB9XG5cbnZhciBSZWZsZWN0T3duS2V5c1xuaWYgKFIgJiYgdHlwZW9mIFIub3duS2V5cyA9PT0gJ2Z1bmN0aW9uJykge1xuICBSZWZsZWN0T3duS2V5cyA9IFIub3duS2V5c1xufSBlbHNlIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7XG4gIFJlZmxlY3RPd25LZXlzID0gZnVuY3Rpb24gUmVmbGVjdE93bktleXModGFyZ2V0KSB7XG4gICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRhcmdldClcbiAgICAgIC5jb25jYXQoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyh0YXJnZXQpKTtcbiAgfTtcbn0gZWxzZSB7XG4gIFJlZmxlY3RPd25LZXlzID0gZnVuY3Rpb24gUmVmbGVjdE93bktleXModGFyZ2V0KSB7XG4gICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRhcmdldCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIFByb2Nlc3NFbWl0V2FybmluZyh3YXJuaW5nKSB7XG4gIGlmIChjb25zb2xlICYmIGNvbnNvbGUud2FybikgY29uc29sZS53YXJuKHdhcm5pbmcpO1xufVxuXG52YXIgTnVtYmVySXNOYU4gPSBOdW1iZXIuaXNOYU4gfHwgZnVuY3Rpb24gTnVtYmVySXNOYU4odmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICBFdmVudEVtaXR0ZXIuaW5pdC5jYWxsKHRoaXMpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG5tb2R1bGUuZXhwb3J0cy5vbmNlID0gb25jZTtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHNDb3VudCA9IDA7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbnZhciBkZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbmZ1bmN0aW9uIGNoZWNrTGlzdGVuZXIobGlzdGVuZXIpIHtcbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIEZ1bmN0aW9uLiBSZWNlaXZlZCB0eXBlICcgKyB0eXBlb2YgbGlzdGVuZXIpO1xuICB9XG59XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudEVtaXR0ZXIsICdkZWZhdWx0TWF4TGlzdGVuZXJzJywge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkZWZhdWx0TWF4TGlzdGVuZXJzO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uKGFyZykge1xuICAgIGlmICh0eXBlb2YgYXJnICE9PSAnbnVtYmVyJyB8fCBhcmcgPCAwIHx8IE51bWJlcklzTmFOKGFyZykpIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdUaGUgdmFsdWUgb2YgXCJkZWZhdWx0TWF4TGlzdGVuZXJzXCIgaXMgb3V0IG9mIHJhbmdlLiBJdCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIG51bWJlci4gUmVjZWl2ZWQgJyArIGFyZyArICcuJyk7XG4gICAgfVxuICAgIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBhcmc7XG4gIH1cbn0pO1xuXG5FdmVudEVtaXR0ZXIuaW5pdCA9IGZ1bmN0aW9uKCkge1xuXG4gIGlmICh0aGlzLl9ldmVudHMgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgdGhpcy5fZXZlbnRzID09PSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykuX2V2ZW50cykge1xuICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICB9XG5cbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn07XG5cbi8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuLy8gdGhhdCB0byBiZSBpbmNyZWFzZWQuIFNldCB0byB6ZXJvIGZvciB1bmxpbWl0ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uIHNldE1heExpc3RlbmVycyhuKSB7XG4gIGlmICh0eXBlb2YgbiAhPT0gJ251bWJlcicgfHwgbiA8IDAgfHwgTnVtYmVySXNOYU4obikpIHtcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVGhlIHZhbHVlIG9mIFwiblwiIGlzIG91dCBvZiByYW5nZS4gSXQgbXVzdCBiZSBhIG5vbi1uZWdhdGl2ZSBudW1iZXIuIFJlY2VpdmVkICcgKyBuICsgJy4nKTtcbiAgfVxuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSBuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIF9nZXRNYXhMaXN0ZW5lcnModGhhdCkge1xuICBpZiAodGhhdC5fbWF4TGlzdGVuZXJzID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICByZXR1cm4gdGhhdC5fbWF4TGlzdGVuZXJzO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmdldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uIGdldE1heExpc3RlbmVycygpIHtcbiAgcmV0dXJuIF9nZXRNYXhMaXN0ZW5lcnModGhpcyk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiBlbWl0KHR5cGUpIHtcbiAgdmFyIGFyZ3MgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIGFyZ3MucHVzaChhcmd1bWVudHNbaV0pO1xuICB2YXIgZG9FcnJvciA9ICh0eXBlID09PSAnZXJyb3InKTtcblxuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICBpZiAoZXZlbnRzICE9PSB1bmRlZmluZWQpXG4gICAgZG9FcnJvciA9IChkb0Vycm9yICYmIGV2ZW50cy5lcnJvciA9PT0gdW5kZWZpbmVkKTtcbiAgZWxzZSBpZiAoIWRvRXJyb3IpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKGRvRXJyb3IpIHtcbiAgICB2YXIgZXI7XG4gICAgaWYgKGFyZ3MubGVuZ3RoID4gMClcbiAgICAgIGVyID0gYXJnc1swXTtcbiAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgLy8gTm90ZTogVGhlIGNvbW1lbnRzIG9uIHRoZSBgdGhyb3dgIGxpbmVzIGFyZSBpbnRlbnRpb25hbCwgdGhleSBzaG93XG4gICAgICAvLyB1cCBpbiBOb2RlJ3Mgb3V0cHV0IGlmIHRoaXMgcmVzdWx0cyBpbiBhbiB1bmhhbmRsZWQgZXhjZXB0aW9uLlxuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgfVxuICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdVbmhhbmRsZWQgZXJyb3IuJyArIChlciA/ICcgKCcgKyBlci5tZXNzYWdlICsgJyknIDogJycpKTtcbiAgICBlcnIuY29udGV4dCA9IGVyO1xuICAgIHRocm93IGVycjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgfVxuXG4gIHZhciBoYW5kbGVyID0gZXZlbnRzW3R5cGVdO1xuXG4gIGlmIChoYW5kbGVyID09PSB1bmRlZmluZWQpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIFJlZmxlY3RBcHBseShoYW5kbGVyLCB0aGlzLCBhcmdzKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgUmVmbGVjdEFwcGx5KGxpc3RlbmVyc1tpXSwgdGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIF9hZGRMaXN0ZW5lcih0YXJnZXQsIHR5cGUsIGxpc3RlbmVyLCBwcmVwZW5kKSB7XG4gIHZhciBtO1xuICB2YXIgZXZlbnRzO1xuICB2YXIgZXhpc3Rpbmc7XG5cbiAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG5cbiAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gIGlmIChldmVudHMgPT09IHVuZGVmaW5lZCkge1xuICAgIGV2ZW50cyA9IHRhcmdldC5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB0YXJnZXQuX2V2ZW50c0NvdW50ID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09PSBcIm5ld0xpc3RlbmVyXCIhIEJlZm9yZVxuICAgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgICBpZiAoZXZlbnRzLm5ld0xpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRhcmdldC5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsXG4gICAgICAgICAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA/IGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gICAgICAvLyBSZS1hc3NpZ24gYGV2ZW50c2AgYmVjYXVzZSBhIG5ld0xpc3RlbmVyIGhhbmRsZXIgY291bGQgaGF2ZSBjYXVzZWQgdGhlXG4gICAgICAvLyB0aGlzLl9ldmVudHMgdG8gYmUgYXNzaWduZWQgdG8gYSBuZXcgb2JqZWN0XG4gICAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgICB9XG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV07XG4gIH1cblxuICBpZiAoZXhpc3RpbmcgPT09IHVuZGVmaW5lZCkge1xuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIGV4aXN0aW5nID0gZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gICAgKyt0YXJnZXQuX2V2ZW50c0NvdW50O1xuICB9IGVsc2Uge1xuICAgIGlmICh0eXBlb2YgZXhpc3RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPVxuICAgICAgICBwcmVwZW5kID8gW2xpc3RlbmVyLCBleGlzdGluZ10gOiBbZXhpc3RpbmcsIGxpc3RlbmVyXTtcbiAgICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICB9IGVsc2UgaWYgKHByZXBlbmQpIHtcbiAgICAgIGV4aXN0aW5nLnVuc2hpZnQobGlzdGVuZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBleGlzdGluZy5wdXNoKGxpc3RlbmVyKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICAgIG0gPSBfZ2V0TWF4TGlzdGVuZXJzKHRhcmdldCk7XG4gICAgaWYgKG0gPiAwICYmIGV4aXN0aW5nLmxlbmd0aCA+IG0gJiYgIWV4aXN0aW5nLndhcm5lZCkge1xuICAgICAgZXhpc3Rpbmcud2FybmVkID0gdHJ1ZTtcbiAgICAgIC8vIE5vIGVycm9yIGNvZGUgZm9yIHRoaXMgc2luY2UgaXQgaXMgYSBXYXJuaW5nXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXhcbiAgICAgIHZhciB3ID0gbmV3IEVycm9yKCdQb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5IGxlYWsgZGV0ZWN0ZWQuICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZy5sZW5ndGggKyAnICcgKyBTdHJpbmcodHlwZSkgKyAnIGxpc3RlbmVycyAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FkZGVkLiBVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJ2luY3JlYXNlIGxpbWl0Jyk7XG4gICAgICB3Lm5hbWUgPSAnTWF4TGlzdGVuZXJzRXhjZWVkZWRXYXJuaW5nJztcbiAgICAgIHcuZW1pdHRlciA9IHRhcmdldDtcbiAgICAgIHcudHlwZSA9IHR5cGU7XG4gICAgICB3LmNvdW50ID0gZXhpc3RpbmcubGVuZ3RoO1xuICAgICAgUHJvY2Vzc0VtaXRXYXJuaW5nKHcpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiBhZGRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kTGlzdGVuZXIgPVxuICAgIGZ1bmN0aW9uIHByZXBlbmRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIF9hZGRMaXN0ZW5lcih0aGlzLCB0eXBlLCBsaXN0ZW5lciwgdHJ1ZSk7XG4gICAgfTtcblxuZnVuY3Rpb24gb25jZVdyYXBwZXIoKSB7XG4gIGlmICghdGhpcy5maXJlZCkge1xuICAgIHRoaXMudGFyZ2V0LnJlbW92ZUxpc3RlbmVyKHRoaXMudHlwZSwgdGhpcy53cmFwRm4pO1xuICAgIHRoaXMuZmlyZWQgPSB0cnVlO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKVxuICAgICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuY2FsbCh0aGlzLnRhcmdldCk7XG4gICAgcmV0dXJuIHRoaXMubGlzdGVuZXIuYXBwbHkodGhpcy50YXJnZXQsIGFyZ3VtZW50cyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX29uY2VXcmFwKHRhcmdldCwgdHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIHN0YXRlID0geyBmaXJlZDogZmFsc2UsIHdyYXBGbjogdW5kZWZpbmVkLCB0YXJnZXQ6IHRhcmdldCwgdHlwZTogdHlwZSwgbGlzdGVuZXI6IGxpc3RlbmVyIH07XG4gIHZhciB3cmFwcGVkID0gb25jZVdyYXBwZXIuYmluZChzdGF0ZSk7XG4gIHdyYXBwZWQubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgc3RhdGUud3JhcEZuID0gd3JhcHBlZDtcbiAgcmV0dXJuIHdyYXBwZWQ7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UodHlwZSwgbGlzdGVuZXIpIHtcbiAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG4gIHRoaXMub24odHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5wcmVwZW5kT25jZUxpc3RlbmVyID1cbiAgICBmdW5jdGlvbiBwcmVwZW5kT25jZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICBjaGVja0xpc3RlbmVyKGxpc3RlbmVyKTtcbiAgICAgIHRoaXMucHJlcGVuZExpc3RlbmVyKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuLy8gRW1pdHMgYSAncmVtb3ZlTGlzdGVuZXInIGV2ZW50IGlmIGFuZCBvbmx5IGlmIHRoZSBsaXN0ZW5lciB3YXMgcmVtb3ZlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICB2YXIgbGlzdCwgZXZlbnRzLCBwb3NpdGlvbiwgaSwgb3JpZ2luYWxMaXN0ZW5lcjtcblxuICAgICAgY2hlY2tMaXN0ZW5lcihsaXN0ZW5lcik7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmIChldmVudHMgPT09IHVuZGVmaW5lZClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGxpc3QgPSBldmVudHNbdHlwZV07XG4gICAgICBpZiAobGlzdCA9PT0gdW5kZWZpbmVkKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgaWYgKGxpc3QgPT09IGxpc3RlbmVyIHx8IGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0Lmxpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGlzdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwb3NpdGlvbiA9IC0xO1xuXG4gICAgICAgIGZvciAoaSA9IGxpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHwgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsTGlzdGVuZXIgPSBsaXN0W2ldLmxpc3RlbmVyO1xuICAgICAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgICBpZiAocG9zaXRpb24gPT09IDApXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBzcGxpY2VPbmUobGlzdCwgcG9zaXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGxpc3QubGVuZ3RoID09PSAxKVxuICAgICAgICAgIGV2ZW50c1t0eXBlXSA9IGxpc3RbMF07XG5cbiAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKVxuICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBvcmlnaW5hbExpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vZmYgPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlQWxsTGlzdGVuZXJzKHR5cGUpIHtcbiAgICAgIHZhciBsaXN0ZW5lcnMsIGV2ZW50cywgaTtcblxuICAgICAgZXZlbnRzID0gdGhpcy5fZXZlbnRzO1xuICAgICAgaWYgKGV2ZW50cyA9PT0gdW5kZWZpbmVkKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnRzW3R5cGVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1t0eXBlXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGV2ZW50cyk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfVxuXG4gICAgICBsaXN0ZW5lcnMgPSBldmVudHNbdHlwZV07XG5cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXJzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzKTtcbiAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXJzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gTElGTyBvcmRlclxuICAgICAgICBmb3IgKGkgPSBsaXN0ZW5lcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuZnVuY3Rpb24gX2xpc3RlbmVycyh0YXJnZXQsIHR5cGUsIHVud3JhcCkge1xuICB2YXIgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG5cbiAgaWYgKGV2ZW50cyA9PT0gdW5kZWZpbmVkKVxuICAgIHJldHVybiBbXTtcblxuICB2YXIgZXZsaXN0ZW5lciA9IGV2ZW50c1t0eXBlXTtcbiAgaWYgKGV2bGlzdGVuZXIgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gW107XG5cbiAgaWYgKHR5cGVvZiBldmxpc3RlbmVyID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiB1bndyYXAgPyBbZXZsaXN0ZW5lci5saXN0ZW5lciB8fCBldmxpc3RlbmVyXSA6IFtldmxpc3RlbmVyXTtcblxuICByZXR1cm4gdW53cmFwID9cbiAgICB1bndyYXBMaXN0ZW5lcnMoZXZsaXN0ZW5lcikgOiBhcnJheUNsb25lKGV2bGlzdGVuZXIsIGV2bGlzdGVuZXIubGVuZ3RoKTtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbiBsaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCB0cnVlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmF3TGlzdGVuZXJzID0gZnVuY3Rpb24gcmF3TGlzdGVuZXJzKHR5cGUpIHtcbiAgcmV0dXJuIF9saXN0ZW5lcnModGhpcywgdHlwZSwgZmFsc2UpO1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIGlmICh0eXBlb2YgZW1pdHRlci5saXN0ZW5lckNvdW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGVtaXR0ZXIubGlzdGVuZXJDb3VudCh0eXBlKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbGlzdGVuZXJDb3VudC5jYWxsKGVtaXR0ZXIsIHR5cGUpO1xuICB9XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVyQ291bnQgPSBsaXN0ZW5lckNvdW50O1xuZnVuY3Rpb24gbGlzdGVuZXJDb3VudCh0eXBlKSB7XG4gIHZhciBldmVudHMgPSB0aGlzLl9ldmVudHM7XG5cbiAgaWYgKGV2ZW50cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG5cbiAgICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSBpZiAoZXZsaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZXZsaXN0ZW5lci5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIDA7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZXZlbnROYW1lcyA9IGZ1bmN0aW9uIGV2ZW50TmFtZXMoKSB7XG4gIHJldHVybiB0aGlzLl9ldmVudHNDb3VudCA+IDAgPyBSZWZsZWN0T3duS2V5cyh0aGlzLl9ldmVudHMpIDogW107XG59O1xuXG5mdW5jdGlvbiBhcnJheUNsb25lKGFyciwgbikge1xuICB2YXIgY29weSA9IG5ldyBBcnJheShuKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyArK2kpXG4gICAgY29weVtpXSA9IGFycltpXTtcbiAgcmV0dXJuIGNvcHk7XG59XG5cbmZ1bmN0aW9uIHNwbGljZU9uZShsaXN0LCBpbmRleCkge1xuICBmb3IgKDsgaW5kZXggKyAxIDwgbGlzdC5sZW5ndGg7IGluZGV4KyspXG4gICAgbGlzdFtpbmRleF0gPSBsaXN0W2luZGV4ICsgMV07XG4gIGxpc3QucG9wKCk7XG59XG5cbmZ1bmN0aW9uIHVud3JhcExpc3RlbmVycyhhcnIpIHtcbiAgdmFyIHJldCA9IG5ldyBBcnJheShhcnIubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXQubGVuZ3RoOyArK2kpIHtcbiAgICByZXRbaV0gPSBhcnJbaV0ubGlzdGVuZXIgfHwgYXJyW2ldO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIG9uY2UoZW1pdHRlciwgbmFtZSkge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGZ1bmN0aW9uIGVycm9yTGlzdGVuZXIoZXJyKSB7XG4gICAgICBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyKG5hbWUsIHJlc29sdmVyKTtcbiAgICAgIHJlamVjdChlcnIpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlc29sdmVyKCkge1xuICAgICAgaWYgKHR5cGVvZiBlbWl0dGVyLnJlbW92ZUxpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgZXJyb3JMaXN0ZW5lcik7XG4gICAgICB9XG4gICAgICByZXNvbHZlKFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKSk7XG4gICAgfTtcblxuICAgIGV2ZW50VGFyZ2V0QWdub3N0aWNBZGRMaXN0ZW5lcihlbWl0dGVyLCBuYW1lLCByZXNvbHZlciwgeyBvbmNlOiB0cnVlIH0pO1xuICAgIGlmIChuYW1lICE9PSAnZXJyb3InKSB7XG4gICAgICBhZGRFcnJvckhhbmRsZXJJZkV2ZW50RW1pdHRlcihlbWl0dGVyLCBlcnJvckxpc3RlbmVyLCB7IG9uY2U6IHRydWUgfSk7XG4gICAgfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gYWRkRXJyb3JIYW5kbGVySWZFdmVudEVtaXR0ZXIoZW1pdHRlciwgaGFuZGxlciwgZmxhZ3MpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLm9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgZXZlbnRUYXJnZXRBZ25vc3RpY0FkZExpc3RlbmVyKGVtaXR0ZXIsICdlcnJvcicsIGhhbmRsZXIsIGZsYWdzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBldmVudFRhcmdldEFnbm9zdGljQWRkTGlzdGVuZXIoZW1pdHRlciwgbmFtZSwgbGlzdGVuZXIsIGZsYWdzKSB7XG4gIGlmICh0eXBlb2YgZW1pdHRlci5vbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGlmIChmbGFncy5vbmNlKSB7XG4gICAgICBlbWl0dGVyLm9uY2UobmFtZSwgbGlzdGVuZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbWl0dGVyLm9uKG5hbWUsIGxpc3RlbmVyKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIGVtaXR0ZXIuYWRkRXZlbnRMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIC8vIEV2ZW50VGFyZ2V0IGRvZXMgbm90IGhhdmUgYGVycm9yYCBldmVudCBzZW1hbnRpY3MgbGlrZSBOb2RlXG4gICAgLy8gRXZlbnRFbWl0dGVycywgd2UgZG8gbm90IGxpc3RlbiBmb3IgYGVycm9yYCBldmVudHMgaGVyZS5cbiAgICBlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIobmFtZSwgZnVuY3Rpb24gd3JhcExpc3RlbmVyKGFyZykge1xuICAgICAgLy8gSUUgZG9lcyBub3QgaGF2ZSBidWlsdGluIGB7IG9uY2U6IHRydWUgfWAgc3VwcG9ydCBzbyB3ZVxuICAgICAgLy8gaGF2ZSB0byBkbyBpdCBtYW51YWxseS5cbiAgICAgIGlmIChmbGFncy5vbmNlKSB7XG4gICAgICAgIGVtaXR0ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihuYW1lLCB3cmFwTGlzdGVuZXIpO1xuICAgICAgfVxuICAgICAgbGlzdGVuZXIoYXJnKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgXCJlbWl0dGVyXCIgYXJndW1lbnQgbXVzdCBiZSBvZiB0eXBlIEV2ZW50RW1pdHRlci4gUmVjZWl2ZWQgdHlwZSAnICsgdHlwZW9mIGVtaXR0ZXIpO1xuICB9XG59XG4iLCIvKiBqc2hpbnQgbm9kZTogdHJ1ZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgbm9ybWFsaWNlID0gcmVxdWlyZSgnbm9ybWFsaWNlJyk7XG5cbi8qKlxuICAjIGZyZWVpY2VcblxuICBUaGUgYGZyZWVpY2VgIG1vZHVsZSBpcyBhIHNpbXBsZSB3YXkgb2YgZ2V0dGluZyByYW5kb20gU1RVTiBvciBUVVJOIHNlcnZlclxuICBmb3IgeW91ciBXZWJSVEMgYXBwbGljYXRpb24uICBUaGUgbGlzdCBvZiBzZXJ2ZXJzIChqdXN0IFNUVU4gYXQgdGhpcyBzdGFnZSlcbiAgd2VyZSBzb3VyY2VkIGZyb20gdGhpcyBbZ2lzdF0oaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20venppdW5pLzM3NDE5MzMpLlxuXG4gICMjIEV4YW1wbGUgVXNlXG5cbiAgVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHlvdSBjYW4gdXNlIGBmcmVlaWNlYCB3aXRoXG4gIFtydGMtcXVpY2tjb25uZWN0XShodHRwczovL2dpdGh1Yi5jb20vcnRjLWlvL3J0Yy1xdWlja2Nvbm5lY3QpOlxuXG4gIDw8PCBleGFtcGxlcy9xdWlja2Nvbm5lY3QuanNcblxuICBBcyB0aGUgYGZyZWVpY2VgIG1vZHVsZSBnZW5lcmF0ZXMgaWNlIHNlcnZlcnMgaW4gYSBsaXN0IGNvbXBsaWFudCB3aXRoIHRoZVxuICBXZWJSVEMgc3BlYyB5b3Ugd2lsbCBiZSBhYmxlIHRvIHVzZSBpdCB3aXRoIHJhdyBgUlRDUGVlckNvbm5lY3Rpb25gXG4gIGNvbnN0cnVjdG9ycyBhbmQgb3RoZXIgV2ViUlRDIGxpYnJhcmllcy5cblxuICAjIyBIZXksIGRvbid0IHVzZSBteSBTVFVOL1RVUk4gc2VydmVyIVxuXG4gIElmIGZvciBzb21lIHJlYXNvbiB5b3VyIGZyZWUgU1RVTiBvciBUVVJOIHNlcnZlciBlbmRzIHVwIGluIHRoZVxuICBsaXN0IG9mIHNlcnZlcnMgKFtzdHVuXShodHRwczovL2dpdGh1Yi5jb20vRGFtb25PZWhsbWFuL2ZyZWVpY2UvYmxvYi9tYXN0ZXIvc3R1bi5qc29uKSBvclxuICBbdHVybl0oaHR0cHM6Ly9naXRodWIuY29tL0RhbW9uT2VobG1hbi9mcmVlaWNlL2Jsb2IvbWFzdGVyL3R1cm4uanNvbikpXG4gIHRoYXQgaXMgdXNlZCBpbiB0aGlzIG1vZHVsZSwgeW91IGNhbiBmZWVsXG4gIGZyZWUgdG8gb3BlbiBhbiBpc3N1ZSBvbiB0aGlzIHJlcG9zaXRvcnkgYW5kIHRob3NlIHNlcnZlcnMgd2lsbCBiZSByZW1vdmVkXG4gIHdpdGhpbiAyNCBob3VycyAob3Igc29vbmVyKS4gIFRoaXMgaXMgdGhlIHF1aWNrZXN0IGFuZCBwcm9iYWJseSB0aGUgbW9zdFxuICBwb2xpdGUgd2F5IHRvIGhhdmUgc29tZXRoaW5nIHJlbW92ZWQgKGFuZCBwcm92aWRlcyB1cyBzb21lIHZpc2liaWxpdHlcbiAgaWYgc29tZW9uZSBvcGVucyBhIHB1bGwgcmVxdWVzdCByZXF1ZXN0aW5nIHRoYXQgYSBzZXJ2ZXIgaXMgYWRkZWQpLlxuXG4gICMjIFBsZWFzZSBhZGQgbXkgc2VydmVyIVxuXG4gIElmIHlvdSBoYXZlIGEgc2VydmVyIHRoYXQgeW91IHdpc2ggdG8gYWRkIHRvIHRoZSBsaXN0LCB0aGF0J3MgYXdlc29tZSEgSSdtXG4gIHN1cmUgSSBzcGVhayBvbiBiZWhhbGYgb2YgYSB3aG9sZSBwaWxlIG9mIFdlYlJUQyBkZXZlbG9wZXJzIHdobyBzYXkgdGhhbmtzLlxuICBUbyBnZXQgaXQgaW50byB0aGUgbGlzdCwgZmVlbCBmcmVlIHRvIGVpdGhlciBvcGVuIGEgcHVsbCByZXF1ZXN0IG9yIGlmIHlvdVxuICBmaW5kIHRoYXQgcHJvY2VzcyBhIGJpdCBkYXVudGluZyB0aGVuIGp1c3QgY3JlYXRlIGFuIGlzc3VlIHJlcXVlc3RpbmdcbiAgdGhlIGFkZGl0aW9uIG9mIHRoZSBzZXJ2ZXIgKG1ha2Ugc3VyZSB5b3UgcHJvdmlkZSBhbGwgdGhlIGRldGFpbHMsIGFuZCBpZlxuICB5b3UgaGF2ZSBhIFRlcm1zIG9mIFNlcnZpY2UgdGhlbiBpbmNsdWRpbmcgdGhhdCBpbiB0aGUgUFIvaXNzdWUgd291bGQgYmVcbiAgYXdlc29tZSkuXG5cbiAgIyMgSSBrbm93IG9mIGEgZnJlZSBzZXJ2ZXIsIGNhbiBJIGFkZCBpdD9cblxuICBTdXJlLCBpZiB5b3UgZG8geW91ciBob21ld29yayBhbmQgbWFrZSBzdXJlIGl0IGlzIG9rIHRvIHVzZSAoSSdtIGN1cnJlbnRseVxuICBpbiB0aGUgcHJvY2VzcyBvZiByZXZpZXdpbmcgdGhlIHRlcm1zIG9mIHRob3NlIFNUVU4gc2VydmVycyBpbmNsdWRlZCBmcm9tXG4gIHRoZSBvcmlnaW5hbCBsaXN0KS4gIElmIGl0J3Mgb2sgdG8gZ28sIHRoZW4gcGxlYXNlIHNlZSB0aGUgcHJldmlvdXMgZW50cnlcbiAgZm9yIGhvdyB0byBhZGQgaXQuXG5cbiAgIyMgQ3VycmVudCBMaXN0IG9mIFNlcnZlcnNcblxuICAqIGN1cnJlbnQgYXMgYXQgdGhlIHRpbWUgb2YgbGFzdCBgUkVBRE1FLm1kYCBmaWxlIGdlbmVyYXRpb25cblxuICAjIyMgU1RVTlxuXG4gIDw8PCBzdHVuLmpzb25cblxuICAjIyMgVFVSTlxuXG4gIDw8PCB0dXJuLmpzb25cblxuKiovXG5cbnZhciBmcmVlaWNlID0gZnVuY3Rpb24ob3B0cykge1xuICAvLyBpZiBhIGxpc3Qgb2Ygc2VydmVycyBoYXMgYmVlbiBwcm92aWRlZCwgdGhlbiB1c2UgaXQgaW5zdGVhZCBvZiBkZWZhdWx0c1xuICB2YXIgc2VydmVycyA9IHtcbiAgICBzdHVuOiAob3B0cyB8fCB7fSkuc3R1biB8fCByZXF1aXJlKCcuL3N0dW4uanNvbicpLFxuICAgIHR1cm46IChvcHRzIHx8IHt9KS50dXJuIHx8IHJlcXVpcmUoJy4vdHVybi5qc29uJylcbiAgfTtcblxuICB2YXIgc3R1bkNvdW50ID0gKG9wdHMgfHwge30pLnN0dW5Db3VudCB8fCAyO1xuICB2YXIgdHVybkNvdW50ID0gKG9wdHMgfHwge30pLnR1cm5Db3VudCB8fCAwO1xuICB2YXIgc2VsZWN0ZWQ7XG5cbiAgZnVuY3Rpb24gZ2V0U2VydmVycyh0eXBlLCBjb3VudCkge1xuICAgIHZhciBvdXQgPSBbXTtcbiAgICB2YXIgaW5wdXQgPSBbXS5jb25jYXQoc2VydmVyc1t0eXBlXSk7XG4gICAgdmFyIGlkeDtcblxuICAgIHdoaWxlIChpbnB1dC5sZW5ndGggJiYgb3V0Lmxlbmd0aCA8IGNvdW50KSB7XG4gICAgICBpZHggPSAoTWF0aC5yYW5kb20oKSAqIGlucHV0Lmxlbmd0aCkgfCAwO1xuICAgICAgb3V0ID0gb3V0LmNvbmNhdChpbnB1dC5zcGxpY2UoaWR4LCAxKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dC5tYXAoZnVuY3Rpb24odXJsKSB7XG4gICAgICAgIC8vSWYgaXQncyBhIG5vdCBhIHN0cmluZywgZG9uJ3QgdHJ5IHRvIFwibm9ybWFsaWNlXCIgaXQgb3RoZXJ3aXNlIHVzaW5nIHR5cGU6dXJsIHdpbGwgc2NyZXcgaXQgdXBcbiAgICAgICAgaWYgKCh0eXBlb2YgdXJsICE9PSAnc3RyaW5nJykgJiYgKCEgKHVybCBpbnN0YW5jZW9mIFN0cmluZykpKSB7XG4gICAgICAgICAgICByZXR1cm4gdXJsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGljZSh0eXBlICsgJzonICsgdXJsKTtcbiAgICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gYWRkIHN0dW4gc2VydmVyc1xuICBzZWxlY3RlZCA9IFtdLmNvbmNhdChnZXRTZXJ2ZXJzKCdzdHVuJywgc3R1bkNvdW50KSk7XG5cbiAgaWYgKHR1cm5Db3VudCkge1xuICAgIHNlbGVjdGVkID0gc2VsZWN0ZWQuY29uY2F0KGdldFNlcnZlcnMoJ3R1cm4nLCB0dXJuQ291bnQpKTtcbiAgfVxuXG4gIHJldHVybiBzZWxlY3RlZDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZWljZTsiLCJtb2R1bGUuZXhwb3J0cz1bXG4gIFwic3R1bi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMS5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMi5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuMy5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuNC5sLmdvb2dsZS5jb206MTkzMDJcIixcbiAgXCJzdHVuLmVraWdhLm5ldFwiLFxuICBcInN0dW4uaWRlYXNpcC5jb21cIixcbiAgXCJzdHVuLnNjaGx1bmQuZGVcIixcbiAgXCJzdHVuLnN0dW5wcm90b2NvbC5vcmc6MzQ3OFwiLFxuICBcInN0dW4udm9pcGFyb3VuZC5jb21cIixcbiAgXCJzdHVuLnZvaXBidXN0ZXIuY29tXCIsXG4gIFwic3R1bi52b2lwc3R1bnQuY29tXCIsXG4gIFwic3R1bi52b3hncmF0aWEub3JnXCJcbl1cbiIsIm1vZHVsZS5leHBvcnRzPVtdXG4iLCJ2YXIgV2lsZEVtaXR0ZXIgPSByZXF1aXJlKCd3aWxkZW1pdHRlcicpO1xuXG5mdW5jdGlvbiBnZXRNYXhWb2x1bWUgKGFuYWx5c2VyLCBmZnRCaW5zKSB7XG4gIHZhciBtYXhWb2x1bWUgPSAtSW5maW5pdHk7XG4gIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShmZnRCaW5zKTtcblxuICBmb3IodmFyIGk9NCwgaWk9ZmZ0Qmlucy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgaWYgKGZmdEJpbnNbaV0gPiBtYXhWb2x1bWUgJiYgZmZ0Qmluc1tpXSA8IDApIHtcbiAgICAgIG1heFZvbHVtZSA9IGZmdEJpbnNbaV07XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBtYXhWb2x1bWU7XG59XG5cblxudmFyIGF1ZGlvQ29udGV4dFR5cGU7XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgYXVkaW9Db250ZXh0VHlwZSA9IHdpbmRvdy5BdWRpb0NvbnRleHQgfHwgd2luZG93LndlYmtpdEF1ZGlvQ29udGV4dDtcbn1cbi8vIHVzZSBhIHNpbmdsZSBhdWRpbyBjb250ZXh0IGR1ZSB0byBoYXJkd2FyZSBsaW1pdHNcbnZhciBhdWRpb0NvbnRleHQgPSBudWxsO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzdHJlYW0sIG9wdGlvbnMpIHtcbiAgdmFyIGhhcmtlciA9IG5ldyBXaWxkRW1pdHRlcigpO1xuXG4gIC8vIG1ha2UgaXQgbm90IGJyZWFrIGluIG5vbi1zdXBwb3J0ZWQgYnJvd3NlcnNcbiAgaWYgKCFhdWRpb0NvbnRleHRUeXBlKSByZXR1cm4gaGFya2VyO1xuXG4gIC8vQ29uZmlnXG4gIHZhciBvcHRpb25zID0gb3B0aW9ucyB8fCB7fSxcbiAgICAgIHNtb290aGluZyA9IChvcHRpb25zLnNtb290aGluZyB8fCAwLjEpLFxuICAgICAgaW50ZXJ2YWwgPSAob3B0aW9ucy5pbnRlcnZhbCB8fCA1MCksXG4gICAgICB0aHJlc2hvbGQgPSBvcHRpb25zLnRocmVzaG9sZCxcbiAgICAgIHBsYXkgPSBvcHRpb25zLnBsYXksXG4gICAgICBoaXN0b3J5ID0gb3B0aW9ucy5oaXN0b3J5IHx8IDEwLFxuICAgICAgcnVubmluZyA9IHRydWU7XG5cbiAgLy8gRW5zdXJlIHRoYXQganVzdCBhIHNpbmdsZSBBdWRpb0NvbnRleHQgaXMgaW50ZXJuYWxseSBjcmVhdGVkXG4gIGF1ZGlvQ29udGV4dCA9IG9wdGlvbnMuYXVkaW9Db250ZXh0IHx8IGF1ZGlvQ29udGV4dCB8fCBuZXcgYXVkaW9Db250ZXh0VHlwZSgpO1xuXG4gIHZhciBzb3VyY2VOb2RlLCBmZnRCaW5zLCBhbmFseXNlcjtcblxuICBhbmFseXNlciA9IGF1ZGlvQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICBhbmFseXNlci5mZnRTaXplID0gNTEyO1xuICBhbmFseXNlci5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSBzbW9vdGhpbmc7XG4gIGZmdEJpbnMgPSBuZXcgRmxvYXQzMkFycmF5KGFuYWx5c2VyLmZyZXF1ZW5jeUJpbkNvdW50KTtcblxuICBpZiAoc3RyZWFtLmpxdWVyeSkgc3RyZWFtID0gc3RyZWFtWzBdO1xuICBpZiAoc3RyZWFtIGluc3RhbmNlb2YgSFRNTEF1ZGlvRWxlbWVudCB8fCBzdHJlYW0gaW5zdGFuY2VvZiBIVE1MVmlkZW9FbGVtZW50KSB7XG4gICAgLy9BdWRpbyBUYWdcbiAgICBzb3VyY2VOb2RlID0gYXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShzdHJlYW0pO1xuICAgIGlmICh0eXBlb2YgcGxheSA9PT0gJ3VuZGVmaW5lZCcpIHBsYXkgPSB0cnVlO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH0gZWxzZSB7XG4gICAgLy9XZWJSVEMgU3RyZWFtXG4gICAgc291cmNlTm9kZSA9IGF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgIHRocmVzaG9sZCA9IHRocmVzaG9sZCB8fCAtNTA7XG4gIH1cblxuICBzb3VyY2VOb2RlLmNvbm5lY3QoYW5hbHlzZXIpO1xuICBpZiAocGxheSkgYW5hbHlzZXIuY29ubmVjdChhdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuXG4gIGhhcmtlci5zcGVha2luZyA9IGZhbHNlO1xuXG4gIGhhcmtlci5zdXNwZW5kID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF1ZGlvQ29udGV4dC5zdXNwZW5kKCk7XG4gIH1cbiAgaGFya2VyLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQucmVzdW1lKCk7XG4gIH1cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGhhcmtlciwgJ3N0YXRlJywgeyBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhdWRpb0NvbnRleHQuc3RhdGU7XG4gIH19KTtcbiAgYXVkaW9Db250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcbiAgICBoYXJrZXIuZW1pdCgnc3RhdGVfY2hhbmdlJywgYXVkaW9Db250ZXh0LnN0YXRlKTtcbiAgfVxuXG4gIGhhcmtlci5zZXRUaHJlc2hvbGQgPSBmdW5jdGlvbih0KSB7XG4gICAgdGhyZXNob2xkID0gdDtcbiAgfTtcblxuICBoYXJrZXIuc2V0SW50ZXJ2YWwgPSBmdW5jdGlvbihpKSB7XG4gICAgaW50ZXJ2YWwgPSBpO1xuICB9O1xuXG4gIGhhcmtlci5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgcnVubmluZyA9IGZhbHNlO1xuICAgIGhhcmtlci5lbWl0KCd2b2x1bWVfY2hhbmdlJywgLTEwMCwgdGhyZXNob2xkKTtcbiAgICBpZiAoaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICBoYXJrZXIuc3BlYWtpbmcgPSBmYWxzZTtcbiAgICAgIGhhcmtlci5lbWl0KCdzdG9wcGVkX3NwZWFraW5nJyk7XG4gICAgfVxuICAgIGFuYWx5c2VyLmRpc2Nvbm5lY3QoKTtcbiAgICBzb3VyY2VOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgfTtcbiAgaGFya2VyLnNwZWFraW5nSGlzdG9yeSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGhpc3Rvcnk7IGkrKykge1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDApO1xuICB9XG5cbiAgLy8gUG9sbCB0aGUgYW5hbHlzZXIgbm9kZSB0byBkZXRlcm1pbmUgaWYgc3BlYWtpbmdcbiAgLy8gYW5kIGVtaXQgZXZlbnRzIGlmIGNoYW5nZWRcbiAgdmFyIGxvb3BlciA9IGZ1bmN0aW9uKCkge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cbiAgICAgIC8vY2hlY2sgaWYgc3RvcCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgIGlmKCFydW5uaW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGN1cnJlbnRWb2x1bWUgPSBnZXRNYXhWb2x1bWUoYW5hbHlzZXIsIGZmdEJpbnMpO1xuXG4gICAgICBoYXJrZXIuZW1pdCgndm9sdW1lX2NoYW5nZScsIGN1cnJlbnRWb2x1bWUsIHRocmVzaG9sZCk7XG5cbiAgICAgIHZhciBoaXN0b3J5ID0gMDtcbiAgICAgIGlmIChjdXJyZW50Vm9sdW1lID4gdGhyZXNob2xkICYmICFoYXJrZXIuc3BlYWtpbmcpIHtcbiAgICAgICAgLy8gdHJpZ2dlciBxdWlja2x5LCBzaG9ydCBoaXN0b3J5XG4gICAgICAgIGZvciAodmFyIGkgPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aCAtIDM7IGkgPCBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaGlzdG9yeSArPSBoYXJrZXIuc3BlYWtpbmdIaXN0b3J5W2ldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoaXN0b3J5ID49IDIpIHtcbiAgICAgICAgICBoYXJrZXIuc3BlYWtpbmcgPSB0cnVlO1xuICAgICAgICAgIGhhcmtlci5lbWl0KCdzcGVha2luZycpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRWb2x1bWUgPCB0aHJlc2hvbGQgJiYgaGFya2VyLnNwZWFraW5nKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGhpc3RvcnkgKz0gaGFya2VyLnNwZWFraW5nSGlzdG9yeVtpXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaGlzdG9yeSA9PSAwKSB7XG4gICAgICAgICAgaGFya2VyLnNwZWFraW5nID0gZmFsc2U7XG4gICAgICAgICAgaGFya2VyLmVtaXQoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5zaGlmdCgpO1xuICAgICAgaGFya2VyLnNwZWFraW5nSGlzdG9yeS5wdXNoKDAgKyAoY3VycmVudFZvbHVtZSA+IHRocmVzaG9sZCkpO1xuXG4gICAgICBsb29wZXIoKTtcbiAgICB9LCBpbnRlcnZhbCk7XG4gIH07XG4gIGxvb3BlcigpO1xuXG4gIHJldHVybiBoYXJrZXI7XG59XG4iLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZVxuICAgICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gICAgfVxuICB9XG59XG4iLCIvKiBcclxuICogSlNOTG9nIDIuMzAuMFxyXG4gKiBPcGVuIHNvdXJjZSB1bmRlciB0aGUgTUlUIExpY2Vuc2UuXHJcbiAqIENvcHlyaWdodCAyMDEyLTIwMTcgTWF0dGlqcyBQZXJkZWNrIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbiAqL1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICAgICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5mdW5jdGlvbiBKTChsb2dnZXJOYW1lKSB7XHJcbiAgICAvLyBJZiBuYW1lIGlzIGVtcHR5LCByZXR1cm4gdGhlIHJvb3QgbG9nZ2VyXHJcbiAgICBpZiAoIWxvZ2dlck5hbWUpIHtcclxuICAgICAgICByZXR1cm4gSkwuX187XHJcbiAgICB9XHJcbiAgICAvLyBJbXBsZW1lbnRzIEFycmF5LnJlZHVjZS4gSlNOTG9nIHN1cHBvcnRzIElFOCsgYW5kIHJlZHVjZSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoYXQgYnJvd3Nlci5cclxuICAgIC8vIFNhbWUgaW50ZXJmYWNlIGFzIHRoZSBzdGFuZGFyZCByZWR1Y2UsIGV4Y2VwdCB0aGF0IFxyXG4gICAgaWYgKCFBcnJheS5wcm90b3R5cGUucmVkdWNlKSB7XHJcbiAgICAgICAgQXJyYXkucHJvdG90eXBlLnJlZHVjZSA9IGZ1bmN0aW9uIChjYWxsYmFjaywgaW5pdGlhbFZhbHVlKSB7XHJcbiAgICAgICAgICAgIHZhciBwcmV2aW91c1ZhbHVlID0gaW5pdGlhbFZhbHVlO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIHByZXZpb3VzVmFsdWUgPSBjYWxsYmFjayhwcmV2aW91c1ZhbHVlLCB0aGlzW2ldLCBpLCB0aGlzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gcHJldmlvdXNWYWx1ZTtcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG4gICAgdmFyIGFjY3VtdWxhdGVkTG9nZ2VyTmFtZSA9ICcnO1xyXG4gICAgdmFyIGxvZ2dlciA9ICgnLicgKyBsb2dnZXJOYW1lKS5zcGxpdCgnLicpLnJlZHVjZShmdW5jdGlvbiAocHJldiwgY3VyciwgaWR4LCBhcnIpIHtcclxuICAgICAgICAvLyBpZiBsb2dnZXJuYW1lIGlzIGEuYi5jLCB0aGFuIGN1cnJlbnRMb2dnZXIgd2lsbCBiZSBzZXQgdG8gdGhlIGxvZ2dlcnNcclxuICAgICAgICAvLyByb290ICAgKHByZXY6IEpMLCBjdXJyOiAnJylcclxuICAgICAgICAvLyBhICAgICAgKHByZXY6IEpMLl9fLCBjdXJyOiAnYScpXHJcbiAgICAgICAgLy8gYS5iICAgIChwcmV2OiBKTC5fXy5fX2EsIGN1cnI6ICdiJylcclxuICAgICAgICAvLyBhLmIuYyAgKHByZXY6IEpMLl9fLl9fYS5fX2EuYiwgY3VycjogJ2MnKVxyXG4gICAgICAgIC8vIE5vdGUgdGhhdCB3aGVuIGEgbmV3IGxvZ2dlciBuYW1lIGlzIGVuY291bnRlcmVkIChzdWNoIGFzICdhLmIuYycpLFxyXG4gICAgICAgIC8vIGEgbmV3IGxvZ2dlciBvYmplY3QgaXMgY3JlYXRlZCBhbmQgYWRkZWQgYXMgYSBwcm9wZXJ0eSB0byB0aGUgcGFyZW50ICgnYS5iJykuXHJcbiAgICAgICAgLy8gVGhlIHJvb3QgbG9nZ2VyIGlzIGFkZGVkIGFzIGEgcHJvcGVydHkgb2YgdGhlIEpMIG9iamVjdCBpdHNlbGYuXHJcbiAgICAgICAgLy8gSXQgaXMgZXNzZW50aWFsIHRoYXQgdGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IGNvbnRhaW5pbmcgdGhlIGNoaWxkIGxvZ2dlclxyXG4gICAgICAgIC8vIGNvbnRhaW5zIHRoZSBmdWxsICdwYXRoJyBuYW1lIG9mIHRoZSBjaGlsZCBsb2dnZXIgKCdhLmIuYycpIGluc3RlYWQgb2ZcclxuICAgICAgICAvLyBqdXN0IHRoZSBiaXQgYWZ0ZXIgdGhlIGxhc3QgcGVyaW9kICgnYycpLlxyXG4gICAgICAgIC8vIFRoaXMgaXMgYmVjYXVzZSB0aGUgcGFyZW50IGluaGVyaXRzIHByb3BlcnRpZXMgZnJvbSBpdHMgYW5jZXN0b3JzLlxyXG4gICAgICAgIC8vIFNvIGlmIHRoZSByb290IGhhcyBhIGNoaWxkIGxvZ2dlciAnYycgKHN0b3JlZCBpbiBhIHByb3BlcnR5ICdjJyBvZiB0aGUgcm9vdCBsb2dnZXIpLFxyXG4gICAgICAgIC8vIHRoZW4gbG9nZ2VyICdhLmInIGhhcyB0aGF0IHNhbWUgcHJvcGVydHkgJ2MnIHRocm91Z2ggaW5oZXJpdGFuY2UuXHJcbiAgICAgICAgLy8gVGhlIG5hbWVzIG9mIHRoZSBsb2dnZXIgcHJvcGVydGllcyBzdGFydCB3aXRoIF9fLCBzbyB0aGUgcm9vdCBsb2dnZXIgXHJcbiAgICAgICAgLy8gKHdoaWNoIGhhcyBuYW1lICcnKSwgaGFzIGEgbmljZSBwcm9wZXJ0eSBuYW1lICdfXycuICAgICAgICAgICAgICBcclxuICAgICAgICAvLyBhY2N1bXVsYXRlZExvZ2dlck5hbWUgZXZhbHVhdGVzIGZhbHNlICgnJyBpcyBmYWxzeSkgaW4gZmlyc3QgaXRlcmF0aW9uIHdoZW4gcHJldiBpcyB0aGUgcm9vdCBsb2dnZXIuXHJcbiAgICAgICAgLy8gYWNjdW11bGF0ZWRMb2dnZXJOYW1lIHdpbGwgYmUgdGhlIGxvZ2dlciBuYW1lIGNvcnJlc3BvbmRpbmcgd2l0aCB0aGUgbG9nZ2VyIGluIGN1cnJlbnRMb2dnZXIuXHJcbiAgICAgICAgLy8gS2VlcCBpbiBtaW5kIHRoYXQgdGhlIGN1cnJlbnRMb2dnZXIgbWF5IG5vdCBiZSBkZWZpbmVkIHlldCwgc28gY2FuJ3QgZ2V0IHRoZSBuYW1lIGZyb21cclxuICAgICAgICAvLyB0aGUgY3VycmVudExvZ2dlciBvYmplY3QgaXRzZWxmLiBcclxuICAgICAgICBpZiAoYWNjdW11bGF0ZWRMb2dnZXJOYW1lKSB7XHJcbiAgICAgICAgICAgIGFjY3VtdWxhdGVkTG9nZ2VyTmFtZSArPSAnLicgKyBjdXJyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgYWNjdW11bGF0ZWRMb2dnZXJOYW1lID0gY3VycjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGN1cnJlbnRMb2dnZXIgPSBwcmV2WydfXycgKyBhY2N1bXVsYXRlZExvZ2dlck5hbWVdO1xyXG4gICAgICAgIC8vIElmIHRoZSBjdXJyZW50TG9nZ2VyIChvciB0aGUgYWN0dWFsIGxvZ2dlciBiZWluZyBzb3VnaHQpIGRvZXMgbm90IHlldCBleGlzdCwgXHJcbiAgICAgICAgLy8gY3JlYXRlIGl0IG5vdy5cclxuICAgICAgICBpZiAoY3VycmVudExvZ2dlciA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIC8vIFNldCB0aGUgcHJvdG90eXBlIG9mIHRoZSBMb2dnZXIgY29uc3RydWN0b3IgZnVuY3Rpb24gdG8gdGhlIHBhcmVudCBvZiB0aGUgbG9nZ2VyXHJcbiAgICAgICAgICAgIC8vIHRvIGJlIGNyZWF0ZWQuIFRoaXMgd2F5LCBfX3Byb3RvIG9mIHRoZSBuZXcgbG9nZ2VyIG9iamVjdCB3aWxsIHBvaW50IGF0IHRoZSBwYXJlbnQuXHJcbiAgICAgICAgICAgIC8vIFdoZW4gbG9nZ2VyLmxldmVsIGlzIGV2YWx1YXRlZCBhbmQgaXMgbm90IHByZXNlbnQsIHRoZSBKYXZhU2NyaXB0IHJ1bnRpbWUgd2lsbCBcclxuICAgICAgICAgICAgLy8gd2FsayBkb3duIHRoZSBwcm90b3R5cGUgY2hhaW4gdG8gZmluZCB0aGUgZmlyc3QgYW5jZXN0b3Igd2l0aCBhIGxldmVsIHByb3BlcnR5LlxyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBOb3RlIHRoYXQgcHJldiBhdCB0aGlzIHBvaW50IHJlZmVycyB0byB0aGUgcGFyZW50IGxvZ2dlci5cclxuICAgICAgICAgICAgSkwuTG9nZ2VyLnByb3RvdHlwZSA9IHByZXY7XHJcbiAgICAgICAgICAgIGN1cnJlbnRMb2dnZXIgPSBuZXcgSkwuTG9nZ2VyKGFjY3VtdWxhdGVkTG9nZ2VyTmFtZSk7XHJcbiAgICAgICAgICAgIHByZXZbJ19fJyArIGFjY3VtdWxhdGVkTG9nZ2VyTmFtZV0gPSBjdXJyZW50TG9nZ2VyO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gY3VycmVudExvZ2dlcjtcclxuICAgIH0sIEpMLl9fKTtcclxuICAgIHJldHVybiBsb2dnZXI7XHJcbn1cclxuKGZ1bmN0aW9uIChKTCkge1xyXG4gICAgLy8gSW5pdGlhbGlzZSByZXF1ZXN0SWQgdG8gZW1wdHkgc3RyaW5nLiBJZiB5b3UgZG9uJ3QgZG8gdGhpcyBhbmQgdGhlIHVzZXJcclxuICAgIC8vIGRvZXMgbm90IHNldCBpdCB2aWEgc2V0T3B0aW9ucywgdGhlbiB0aGUgSlNOTG9nLVJlcXVlc3RJZCBoZWFkZXIgd2lsbFxyXG4gICAgLy8gaGF2ZSB2YWx1ZSBcInVuZGVmaW5lZFwiLCB3aGljaCBkb2Vzbid0IGxvb2sgZ29vZCBpbiBhIGxvZy5cclxuICAgIC8vXHJcbiAgICAvLyBOb3RlIHRoYXQgeW91IGFsd2F5cyB3YW50IHRvIHNlbmQgYSByZXF1ZXN0SWQgYXMgcGFydCBvZiBsb2cgcmVxdWVzdHMsXHJcbiAgICAvLyBvdGhlcndpc2UgdGhlIHNlcnZlciBzaWRlIGNvbXBvbmVudCBkb2Vzbid0IGtub3cgdGhpcyBpcyBhIGxvZyByZXF1ZXN0XHJcbiAgICAvLyBhbmQgbWF5IGNyZWF0ZSBhIG5ldyByZXF1ZXN0IGlkIGZvciB0aGUgbG9nIHJlcXVlc3QsIGNhdXNpbmcgY29uZnVzaW9uXHJcbiAgICAvLyBpbiB0aGUgbG9nLlxyXG4gICAgSkwucmVxdWVzdElkID0gJyc7XHJcbiAgICAvLyBOdW1iZXIgdW5pcXVlbHkgaWRlbnRpZnlpbmcgZXZlcnkgbG9nIGVudHJ5IHdpdGhpbiB0aGUgcmVxdWVzdC5cclxuICAgIEpMLmVudHJ5SWQgPSAwO1xyXG4gICAgLy8gQWxsb3cgcHJvcGVydHkgaW5qZWN0aW9uIG9mIHRoZXNlIGNsYXNzZXMsIHRvIGVuYWJsZSB1bml0IHRlc3RpbmdcclxuICAgIEpMLl9jcmVhdGVYTUxIdHRwUmVxdWVzdCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdCgpOyB9O1xyXG4gICAgSkwuX2dldFRpbWUgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAobmV3IERhdGUpLmdldFRpbWUoKTsgfTtcclxuICAgIEpMLl9jb25zb2xlID0gY29uc29sZTtcclxuICAgIC8vIC0tLS0tIHByaXZhdGUgdmFyaWFibGVzXHJcbiAgICBKTC5fYXBwZW5kZXJOYW1lcyA9IFtdO1xyXG4gICAgLyoqXHJcbiAgICBDb3BpZXMgdGhlIHZhbHVlIG9mIGEgcHJvcGVydHkgZnJvbSBvbmUgb2JqZWN0IHRvIHRoZSBvdGhlci5cclxuICAgIFRoaXMgaXMgdXNlZCB0byBjb3B5IHByb3BlcnR5IHZhbHVlcyBhcyBwYXJ0IG9mIHNldE9wdGlvbiBmb3IgbG9nZ2VycyBhbmQgYXBwZW5kZXJzLlxyXG5cclxuICAgIEJlY2F1c2UgbG9nZ2VycyBpbmhlcml0IHByb3BlcnR5IHZhbHVlcyBmcm9tIHRoZWlyIHBhcmVudHMsIGl0IGlzIGltcG9ydGFudCBuZXZlciB0b1xyXG4gICAgY3JlYXRlIGEgcHJvcGVydHkgb24gYSBsb2dnZXIgaWYgdGhlIGludGVudCBpcyB0byBpbmhlcml0IGZyb20gdGhlIHBhcmVudC5cclxuXHJcbiAgICBDb3B5aW5nIHJ1bGVzOlxyXG4gICAgMSkgaWYgdGhlIGZyb20gcHJvcGVydHkgaXMgdW5kZWZpbmVkIChmb3IgZXhhbXBsZSwgbm90IG1lbnRpb25lZCBpbiBhIEpTT04gb2JqZWN0KSwgdGhlXHJcbiAgICAgICB0byBwcm9wZXJ0eSBpcyBub3QgYWZmZWN0ZWQgYXQgYWxsLlxyXG4gICAgMikgaWYgdGhlIGZyb20gcHJvcGVydHkgaXMgbnVsbCwgdGhlIHRvIHByb3BlcnR5IGlzIGRlbGV0ZWQgKHNvIHRoZSBsb2dnZXIgd2lsbCBpbmhlcml0IGZyb21cclxuICAgICAgIGl0cyBwYXJlbnQpLlxyXG4gICAgMykgT3RoZXJ3aXNlLCB0aGUgZnJvbSBwcm9wZXJ0eSBpcyBjb3BpZWQgdG8gdGhlIHRvIHByb3BlcnR5LlxyXG4gICAgKi9cclxuICAgIGZ1bmN0aW9uIGNvcHlQcm9wZXJ0eShwcm9wZXJ0eU5hbWUsIGZyb20sIHRvKSB7XHJcbiAgICAgICAgaWYgKGZyb21bcHJvcGVydHlOYW1lXSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGZyb21bcHJvcGVydHlOYW1lXSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICBkZWxldGUgdG9bcHJvcGVydHlOYW1lXTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0b1twcm9wZXJ0eU5hbWVdID0gZnJvbVtwcm9wZXJ0eU5hbWVdO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICBSZXR1cm5zIHRydWUgaWYgYSBsb2cgc2hvdWxkIGdvIGFoZWFkLlxyXG4gICAgRG9lcyBub3QgY2hlY2sgbGV2ZWwuXHJcblxyXG4gICAgQHBhcmFtIGZpbHRlcnNcclxuICAgICAgICBGaWx0ZXJzIHRoYXQgZGV0ZXJtaW5lIHdoZXRoZXIgYSBsb2cgY2FuIGdvIGFoZWFkLlxyXG4gICAgKi9cclxuICAgIGZ1bmN0aW9uIGFsbG93KGZpbHRlcnMpIHtcclxuICAgICAgICAvLyBJZiBlbmFibGVkIGlzIG5vdCBudWxsIG9yIHVuZGVmaW5lZCwgdGhlbiBpZiBpdCBpcyBmYWxzZSwgdGhlbiByZXR1cm4gZmFsc2VcclxuICAgICAgICAvLyBOb3RlIHRoYXQgdW5kZWZpbmVkPT1udWxsICghKVxyXG4gICAgICAgIGlmICghKEpMLmVuYWJsZWQgPT0gbnVsbCkpIHtcclxuICAgICAgICAgICAgaWYgKCFKTC5lbmFibGVkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gSWYgdGhlIHJlZ2V4IGNvbnRhaW5zIGEgYnVnLCB0aGF0IHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uLlxyXG4gICAgICAgIC8vIElnbm9yZSB0aGlzLCBhbmQgcGFzcyB0aGUgbG9nIGl0ZW0gKGJldHRlciB0b28gbXVjaCB0aGFuIHRvbyBsaXR0bGUpLlxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmaWx0ZXJzLnVzZXJBZ2VudFJlZ2V4KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIW5ldyBSZWdFeHAoZmlsdGVycy51c2VyQWdlbnRSZWdleCkudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkgeyB9XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGZpbHRlcnMuaXBSZWdleCAmJiBKTC5jbGllbnRJUCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFuZXcgUmVnRXhwKGZpbHRlcnMuaXBSZWdleCkudGVzdChKTC5jbGllbnRJUCkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY2F0Y2ggKGUpIHsgfVxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICBSZXR1cm5zIHRydWUgaWYgYSBsb2cgc2hvdWxkIGdvIGFoZWFkLCBiYXNlZCBvbiB0aGUgbWVzc2FnZS5cclxuXHJcbiAgICBAcGFyYW0gZmlsdGVyc1xyXG4gICAgICAgIEZpbHRlcnMgdGhhdCBkZXRlcm1pbmUgd2hldGhlciBhIGxvZyBjYW4gZ28gYWhlYWQuXHJcblxyXG4gICAgQHBhcmFtIG1lc3NhZ2VcclxuICAgICAgICBNZXNzYWdlIHRvIGJlIGxvZ2dlZC5cclxuICAgICovXHJcbiAgICBmdW5jdGlvbiBhbGxvd01lc3NhZ2UoZmlsdGVycywgbWVzc2FnZSkge1xyXG4gICAgICAgIC8vIElmIHRoZSByZWdleCBjb250YWlucyBhIGJ1ZywgdGhhdCB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbi5cclxuICAgICAgICAvLyBJZ25vcmUgdGhpcywgYW5kIHBhc3MgdGhlIGxvZyBpdGVtIChiZXR0ZXIgdG9vIG11Y2ggdGhhbiB0b28gbGl0dGxlKS5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZmlsdGVycy5kaXNhbGxvdykge1xyXG4gICAgICAgICAgICAgICAgaWYgKG5ldyBSZWdFeHAoZmlsdGVycy5kaXNhbGxvdykudGVzdChtZXNzYWdlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkgeyB9XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgICAvLyBJZiBsb2dPYmplY3QgaXMgYSBmdW5jdGlvbiwgdGhlIGZ1bmN0aW9uIGlzIGV2YWx1YXRlZCAod2l0aG91dCBwYXJhbWV0ZXJzKVxyXG4gICAgLy8gYW5kIHRoZSByZXN1bHQgcmV0dXJuZWQuXHJcbiAgICAvLyBPdGhlcndpc2UsIGxvZ09iamVjdCBpdHNlbGYgaXMgcmV0dXJuZWQuXHJcbiAgICBmdW5jdGlvbiBzdHJpbmdpZnlMb2dPYmplY3RGdW5jdGlvbihsb2dPYmplY3QpIHtcclxuICAgICAgICBpZiAodHlwZW9mIGxvZ09iamVjdCA9PSBcImZ1bmN0aW9uXCIpIHtcclxuICAgICAgICAgICAgaWYgKGxvZ09iamVjdCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGxvZ09iamVjdC50b1N0cmluZygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGxvZ09iamVjdCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBsb2dPYmplY3Q7XHJcbiAgICB9XHJcbiAgICB2YXIgU3RyaW5naWZpZWRMb2dPYmplY3QgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gKiBtc2cgLSBcclxuICAgICAgICAvLyAgICAgIGlmIHRoZSBsb2dPYmplY3QgaXMgYSBzY2FsYXIgKGFmdGVyIHBvc3NpYmxlIGZ1bmN0aW9uIGV2YWx1YXRpb24pLCB0aGlzIGlzIHNldCB0b1xyXG4gICAgICAgIC8vICAgICAgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgc2NhbGFyLiBPdGhlcndpc2UgaXQgaXMgbGVmdCB1bmRlZmluZWQuXHJcbiAgICAgICAgLy8gKiBtZXRhIC1cclxuICAgICAgICAvLyAgICAgIGlmIHRoZSBsb2dPYmplY3QgaXMgYW4gb2JqZWN0IChhZnRlciBwb3NzaWJsZSBmdW5jdGlvbiBldmFsdWF0aW9uKSwgdGhpcyBpcyBzZXQgdG9cclxuICAgICAgICAvLyAgICAgIHRoYXQgb2JqZWN0LiBPdGhlcndpc2UgaXQgaXMgbGVmdCB1bmRlZmluZWQuXHJcbiAgICAgICAgLy8gKiBmaW5hbFN0cmluZyAtXHJcbiAgICAgICAgLy8gICAgICBUaGlzIGlzIHNldCB0byB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGxvZ09iamVjdCAoYWZ0ZXIgcG9zc2libGUgZnVuY3Rpb24gZXZhbHVhdGlvbiksXHJcbiAgICAgICAgLy8gICAgICByZWdhcmRsZXNzIG9mIHdoZXRoZXIgaXQgaXMgYW4gc2NhbGFyIG9yIGFuIG9iamVjdC4gQW4gb2JqZWN0IGlzIHN0cmluZ2lmaWVkIHRvIGEgSlNPTiBzdHJpbmcuXHJcbiAgICAgICAgLy8gICAgICBOb3RlIHRoYXQgeW91IGNhbid0IGNhbGwgdGhpcyBmaWVsZCBcImZpbmFsXCIsIGJlY2F1c2UgYXMgc29tZSBwb2ludCB0aGlzIHdhcyBhIHJlc2VydmVkXHJcbiAgICAgICAgLy8gICAgICBKYXZhU2NyaXB0IGtleXdvcmQgYW5kIHVzaW5nIGZpbmFsIHRyaXBzIHVwIHNvbWUgbWluaWZpZXJzLlxyXG4gICAgICAgIGZ1bmN0aW9uIFN0cmluZ2lmaWVkTG9nT2JqZWN0KG1zZywgbWV0YSwgZmluYWxTdHJpbmcpIHtcclxuICAgICAgICAgICAgdGhpcy5tc2cgPSBtc2c7XHJcbiAgICAgICAgICAgIHRoaXMubWV0YSA9IG1ldGE7XHJcbiAgICAgICAgICAgIHRoaXMuZmluYWxTdHJpbmcgPSBmaW5hbFN0cmluZztcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIFN0cmluZ2lmaWVkTG9nT2JqZWN0O1xyXG4gICAgfSgpKTtcclxuICAgIC8vIFRha2VzIGEgbG9nT2JqZWN0LCB3aGljaCBjYW4gYmUgXHJcbiAgICAvLyAqIGEgc2NhbGFyXHJcbiAgICAvLyAqIGFuIG9iamVjdFxyXG4gICAgLy8gKiBhIHBhcmFtZXRlcmxlc3MgZnVuY3Rpb24sIHdoaWNoIHJldHVybnMgdGhlIHNjYWxhciBvciBvYmplY3QgdG8gbG9nLlxyXG4gICAgLy8gUmV0dXJucyBhIHN0cmluZ2lmaWVkTG9nT2JqZWN0XHJcbiAgICBmdW5jdGlvbiBzdHJpbmdpZnlMb2dPYmplY3QobG9nT2JqZWN0KSB7XHJcbiAgICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgd29ya3MgaWYgbG9nT2JqZWN0IGlzIG51bGwuXHJcbiAgICAgICAgLy8gdHlwZW9mIG51bGwgaXMgb2JqZWN0LlxyXG4gICAgICAgIC8vIEpTT04uc3RyaW5naWZ5KG51bGwpIHJldHVybnMgXCJudWxsXCIuXHJcbiAgICAgICAgdmFyIGFjdHVhbExvZ09iamVjdCA9IHN0cmluZ2lmeUxvZ09iamVjdEZ1bmN0aW9uKGxvZ09iamVjdCk7XHJcbiAgICAgICAgdmFyIGZpbmFsU3RyaW5nO1xyXG4gICAgICAgIC8vIE5vdGUgdGhhdCB0eXBlb2YgYWN0dWFsTG9nT2JqZWN0IHNob3VsZCBub3QgYmUgXCJmdW5jdGlvblwiLCBiZWNhdXNlIHRoYXQgaGFzIFxyXG4gICAgICAgIC8vIGJlZW4gcmVzb2x2ZWQgd2l0aCBzdHJpbmdpZnlMb2dPYmplY3RGdW5jdGlvbi5cclxuICAgICAgICBzd2l0Y2ggKHR5cGVvZiBhY3R1YWxMb2dPYmplY3QpIHtcclxuICAgICAgICAgICAgY2FzZSBcInN0cmluZ1wiOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdpZmllZExvZ09iamVjdChhY3R1YWxMb2dPYmplY3QsIG51bGwsIGFjdHVhbExvZ09iamVjdCk7XHJcbiAgICAgICAgICAgIGNhc2UgXCJudW1iZXJcIjpcclxuICAgICAgICAgICAgICAgIGZpbmFsU3RyaW5nID0gYWN0dWFsTG9nT2JqZWN0LnRvU3RyaW5nKCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZ2lmaWVkTG9nT2JqZWN0KGZpbmFsU3RyaW5nLCBudWxsLCBmaW5hbFN0cmluZyk7XHJcbiAgICAgICAgICAgIGNhc2UgXCJib29sZWFuXCI6XHJcbiAgICAgICAgICAgICAgICBmaW5hbFN0cmluZyA9IGFjdHVhbExvZ09iamVjdC50b1N0cmluZygpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdpZmllZExvZ09iamVjdChmaW5hbFN0cmluZywgbnVsbCwgZmluYWxTdHJpbmcpO1xyXG4gICAgICAgICAgICBjYXNlIFwidW5kZWZpbmVkXCI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZ2lmaWVkTG9nT2JqZWN0KFwidW5kZWZpbmVkXCIsIG51bGwsIFwidW5kZWZpbmVkXCIpO1xyXG4gICAgICAgICAgICBjYXNlIFwib2JqZWN0XCI6XHJcbiAgICAgICAgICAgICAgICBpZiAoKGFjdHVhbExvZ09iamVjdCBpbnN0YW5jZW9mIFJlZ0V4cCkgfHxcclxuICAgICAgICAgICAgICAgICAgICAoYWN0dWFsTG9nT2JqZWN0IGluc3RhbmNlb2YgU3RyaW5nKSB8fFxyXG4gICAgICAgICAgICAgICAgICAgIChhY3R1YWxMb2dPYmplY3QgaW5zdGFuY2VvZiBOdW1iZXIpIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgKGFjdHVhbExvZ09iamVjdCBpbnN0YW5jZW9mIEJvb2xlYW4pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmluYWxTdHJpbmcgPSBhY3R1YWxMb2dPYmplY3QudG9TdHJpbmcoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFN0cmluZ2lmaWVkTG9nT2JqZWN0KGZpbmFsU3RyaW5nLCBudWxsLCBmaW5hbFN0cmluZyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIEpMLnNlcmlhbGl6ZSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFN0cmluZyA9IEpMLnNlcmlhbGl6ZS5jYWxsKHRoaXMsIGFjdHVhbExvZ09iamVjdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFN0cmluZyA9IEpTT04uc3RyaW5naWZ5KGFjdHVhbExvZ09iamVjdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIFNldCB0aGUgbXNnIGZpZWxkIHRvIFwiXCIgaW5zdGVhZCBvZiBudWxsLiBTb21lIFdpbnN0b24gdHJhbnNwb3J0c1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGFzc3VtZSB0aGF0IHRoZSBtc2cgZmllbGQgaXMgbm90IG51bGwuXHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmdpZmllZExvZ09iamVjdChcIlwiLCBhY3R1YWxMb2dPYmplY3QsIGZpbmFsU3RyaW5nKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU3RyaW5naWZpZWRMb2dPYmplY3QoXCJ1bmtub3duXCIsIG51bGwsIFwidW5rbm93blwiKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiBzZXRPcHRpb25zKG9wdGlvbnMpIHtcclxuICAgICAgICBjb3B5UHJvcGVydHkoXCJlbmFibGVkXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgIGNvcHlQcm9wZXJ0eShcIm1heE1lc3NhZ2VzXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgIGNvcHlQcm9wZXJ0eShcImRlZmF1bHRBamF4VXJsXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgIGNvcHlQcm9wZXJ0eShcImNsaWVudElQXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgIGNvcHlQcm9wZXJ0eShcInJlcXVlc3RJZFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICBjb3B5UHJvcGVydHkoXCJkZWZhdWx0QmVmb3JlU2VuZFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICBjb3B5UHJvcGVydHkoXCJzZXJpYWxpemVcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcbiAgICBKTC5zZXRPcHRpb25zID0gc2V0T3B0aW9ucztcclxuICAgIGZ1bmN0aW9uIGdldEFsbExldmVsKCkgeyByZXR1cm4gLTIxNDc0ODM2NDg7IH1cclxuICAgIEpMLmdldEFsbExldmVsID0gZ2V0QWxsTGV2ZWw7XHJcbiAgICBmdW5jdGlvbiBnZXRUcmFjZUxldmVsKCkgeyByZXR1cm4gMTAwMDsgfVxyXG4gICAgSkwuZ2V0VHJhY2VMZXZlbCA9IGdldFRyYWNlTGV2ZWw7XHJcbiAgICBmdW5jdGlvbiBnZXREZWJ1Z0xldmVsKCkgeyByZXR1cm4gMjAwMDsgfVxyXG4gICAgSkwuZ2V0RGVidWdMZXZlbCA9IGdldERlYnVnTGV2ZWw7XHJcbiAgICBmdW5jdGlvbiBnZXRJbmZvTGV2ZWwoKSB7IHJldHVybiAzMDAwOyB9XHJcbiAgICBKTC5nZXRJbmZvTGV2ZWwgPSBnZXRJbmZvTGV2ZWw7XHJcbiAgICBmdW5jdGlvbiBnZXRXYXJuTGV2ZWwoKSB7IHJldHVybiA0MDAwOyB9XHJcbiAgICBKTC5nZXRXYXJuTGV2ZWwgPSBnZXRXYXJuTGV2ZWw7XHJcbiAgICBmdW5jdGlvbiBnZXRFcnJvckxldmVsKCkgeyByZXR1cm4gNTAwMDsgfVxyXG4gICAgSkwuZ2V0RXJyb3JMZXZlbCA9IGdldEVycm9yTGV2ZWw7XHJcbiAgICBmdW5jdGlvbiBnZXRGYXRhbExldmVsKCkgeyByZXR1cm4gNjAwMDsgfVxyXG4gICAgSkwuZ2V0RmF0YWxMZXZlbCA9IGdldEZhdGFsTGV2ZWw7XHJcbiAgICBmdW5jdGlvbiBnZXRPZmZMZXZlbCgpIHsgcmV0dXJuIDIxNDc0ODM2NDc7IH1cclxuICAgIEpMLmdldE9mZkxldmVsID0gZ2V0T2ZmTGV2ZWw7XHJcbiAgICBmdW5jdGlvbiBsZXZlbFRvU3RyaW5nKGxldmVsKSB7XHJcbiAgICAgICAgaWYgKGxldmVsIDw9IDEwMDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIFwidHJhY2VcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGxldmVsIDw9IDIwMDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIFwiZGVidWdcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGxldmVsIDw9IDMwMDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIFwiaW5mb1wiO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAobGV2ZWwgPD0gNDAwMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gXCJ3YXJuXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChsZXZlbCA8PSA1MDAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcImVycm9yXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBcImZhdGFsXCI7XHJcbiAgICB9XHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAgIHZhciBFeGNlcHRpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gZGF0YSByZXBsYWNlcyBtZXNzYWdlLiBJdCB0YWtlcyBub3QganVzdCBzdHJpbmdzLCBidXQgYWxzbyBvYmplY3RzIGFuZCBmdW5jdGlvbnMsIGp1c3QgbGlrZSB0aGUgbG9nIGZ1bmN0aW9uLlxyXG4gICAgICAgIC8vIGludGVybmFsbHksIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gaXMgc3RvcmVkIGluIHRoZSBtZXNzYWdlIHByb3BlcnR5IChpbmhlcml0ZWQgZnJvbSBFcnJvcilcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIGlubmVyOiBpbm5lciBleGNlcHRpb24uIENhbiBiZSBudWxsIG9yIHVuZGVmaW5lZC4gXHJcbiAgICAgICAgZnVuY3Rpb24gRXhjZXB0aW9uKGRhdGEsIGlubmVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaW5uZXIgPSBpbm5lcjtcclxuICAgICAgICAgICAgdGhpcy5uYW1lID0gXCJKTC5FeGNlcHRpb25cIjtcclxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlID0gc3RyaW5naWZ5TG9nT2JqZWN0KGRhdGEpLmZpbmFsU3RyaW5nO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gRXhjZXB0aW9uO1xyXG4gICAgfSgpKTtcclxuICAgIEpMLkV4Y2VwdGlvbiA9IEV4Y2VwdGlvbjtcclxuICAgIC8vIERlcml2ZSBFeGNlcHRpb24gZnJvbSBFcnJvciAoYSBIb3N0IG9iamVjdCksIHNvIGJyb3dzZXJzXHJcbiAgICAvLyBhcmUgbW9yZSBsaWtlbHkgdG8gcHJvZHVjZSBhIHN0YWNrIHRyYWNlIGZvciBpdCBpbiB0aGVpciBjb25zb2xlLlxyXG4gICAgLy9cclxuICAgIC8vIE5vdGUgdGhhdCBpbnN0YW5jZW9mIGFnYWluc3QgYW4gb2JqZWN0IGNyZWF0ZWQgd2l0aCB0aGlzIGNvbnN0cnVjdG9yXHJcbiAgICAvLyB3aWxsIHJldHVybiB0cnVlIGluIHRoZXNlIGNhc2VzOlxyXG4gICAgLy8gPG9iamVjdD4gaW5zdGFuY2VvZiBKTC5FeGNlcHRpb24pO1xyXG4gICAgLy8gPG9iamVjdD4gaW5zdGFuY2VvZiBFcnJvcik7XHJcbiAgICBFeGNlcHRpb24ucHJvdG90eXBlID0gbmV3IEVycm9yKCk7XHJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAgIHZhciBMb2dJdGVtID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIGw6IGxldmVsXHJcbiAgICAgICAgLy8gbTogbWVzc2FnZVxyXG4gICAgICAgIC8vIG46IGxvZ2dlciBuYW1lXHJcbiAgICAgICAgLy8gdCAodGltZVN0YW1wKSBpcyBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHNpbmNlIDEgSmFudWFyeSAxOTcwIDAwOjAwOjAwIFVUQ1xyXG4gICAgICAgIC8vIHU6IG51bWJlciB1bmlxdWVseSBpZGVudGlmeWluZyB0aGlzIGVudHJ5IGZvciB0aGlzIHJlcXVlc3QuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBLZWVwaW5nIHRoZSBwcm9wZXJ0eSBuYW1lcyByZWFsbHkgc2hvcnQsIGJlY2F1c2UgdGhleSB3aWxsIGJlIHNlbnQgaW4gdGhlXHJcbiAgICAgICAgLy8gSlNPTiBwYXlsb2FkIHRvIHRoZSBzZXJ2ZXIuXHJcbiAgICAgICAgZnVuY3Rpb24gTG9nSXRlbShsLCBtLCBuLCB0LCB1KSB7XHJcbiAgICAgICAgICAgIHRoaXMubCA9IGw7XHJcbiAgICAgICAgICAgIHRoaXMubSA9IG07XHJcbiAgICAgICAgICAgIHRoaXMubiA9IG47XHJcbiAgICAgICAgICAgIHRoaXMudCA9IHQ7XHJcbiAgICAgICAgICAgIHRoaXMudSA9IHU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBMb2dJdGVtO1xyXG4gICAgfSgpKTtcclxuICAgIEpMLkxvZ0l0ZW0gPSBMb2dJdGVtO1xyXG4gICAgZnVuY3Rpb24gbmV3TG9nSXRlbShsZXZlbE5iciwgbWVzc2FnZSwgbG9nZ2VyTmFtZSkge1xyXG4gICAgICAgIEpMLmVudHJ5SWQrKztcclxuICAgICAgICByZXR1cm4gbmV3IExvZ0l0ZW0obGV2ZWxOYnIsIG1lc3NhZ2UsIGxvZ2dlck5hbWUsIEpMLl9nZXRUaW1lKCksIEpMLmVudHJ5SWQpO1xyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gY2xlYXJUaW1lcih0aW1lcikge1xyXG4gICAgICAgIGlmICh0aW1lci5pZCkge1xyXG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIuaWQpO1xyXG4gICAgICAgICAgICB0aW1lci5pZCA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZnVuY3Rpb24gc2V0VGltZXIodGltZXIsIHRpbWVvdXRNcywgY2FsbGJhY2spIHtcclxuICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XHJcbiAgICAgICAgaWYgKCF0aW1lci5pZCkge1xyXG4gICAgICAgICAgICB0aW1lci5pZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgLy8gdXNlIGNhbGwgdG8gZW5zdXJlIHRoYXQgdGhlIHRoaXMgYXMgdXNlZCBpbnNpZGUgc2VuZEJhdGNoIHdoZW4gaXQgcnVucyBpcyB0aGVcclxuICAgICAgICAgICAgICAgIC8vIHNhbWUgdGhpcyBhdCB0aGlzIHBvaW50LlxyXG4gICAgICAgICAgICAgICAgY2FsbGJhY2suY2FsbCh0aGF0KTtcclxuICAgICAgICAgICAgfSwgdGltZW91dE1zKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICB2YXIgQXBwZW5kZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gc2VuZExvZ0l0ZW1zIHRha2VzIGFuIGFycmF5IG9mIGxvZyBpdGVtcy4gSXQgd2lsbCBiZSBjYWxsZWQgd2hlblxyXG4gICAgICAgIC8vIHRoZSBhcHBlbmRlciBoYXMgaXRlbXMgdG8gcHJvY2VzcyAoc3VjaCBhcywgc2VuZCB0byB0aGUgc2VydmVyKS5cclxuICAgICAgICAvLyBzZW5kTG9nSXRlbXMgd2lsbCBjYWxsIHN1Y2Nlc3NDYWxsYmFjayBhZnRlciB0aGUgaXRlbXMgaGF2ZSBiZWVuIHN1Y2Nlc3NmdWxseSBzZW50LlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gTm90ZSB0aGF0IGFmdGVyIHNlbmRMb2dJdGVtcyByZXR1cm5zLCB0aGUgYXBwZW5kZXIgbWF5IHRydW5jYXRlXHJcbiAgICAgICAgLy8gdGhlIExvZ0l0ZW0gYXJyYXksIHNvIHRoZSBmdW5jdGlvbiBoYXMgdG8gY29weSB0aGUgY29udGVudCBvZiB0aGUgYXJyYXlcclxuICAgICAgICAvLyBpbiBzb21lIGZhc2hpb24gKGVnLiBzZXJpYWxpemUpIGJlZm9yZSByZXR1cm5pbmcuXHJcbiAgICAgICAgZnVuY3Rpb24gQXBwZW5kZXIoYXBwZW5kZXJOYW1lLCBzZW5kTG9nSXRlbXMpIHtcclxuICAgICAgICAgICAgdGhpcy5hcHBlbmRlck5hbWUgPSBhcHBlbmRlck5hbWU7XHJcbiAgICAgICAgICAgIHRoaXMuc2VuZExvZ0l0ZW1zID0gc2VuZExvZ0l0ZW1zO1xyXG4gICAgICAgICAgICB0aGlzLmxldmVsID0gSkwuZ2V0VHJhY2VMZXZlbCgpO1xyXG4gICAgICAgICAgICAvLyBzZXQgdG8gc3VwZXIgaGlnaCBsZXZlbCwgc28gaWYgdXNlciBpbmNyZWFzZXMgbGV2ZWwsIGxldmVsIGlzIHVubGlrZWx5IHRvIGdldCBcclxuICAgICAgICAgICAgLy8gYWJvdmUgc2VuZFdpdGhCdWZmZXJMZXZlbFxyXG4gICAgICAgICAgICB0aGlzLnNlbmRXaXRoQnVmZmVyTGV2ZWwgPSAyMTQ3NDgzNjQ3O1xyXG4gICAgICAgICAgICB0aGlzLnN0b3JlSW5CdWZmZXJMZXZlbCA9IC0yMTQ3NDgzNjQ4O1xyXG4gICAgICAgICAgICB0aGlzLmJ1ZmZlclNpemUgPSAwOyAvLyBidWZmZXJpbmcgc3dpdGNoIG9mZiBieSBkZWZhdWx0XHJcbiAgICAgICAgICAgIHRoaXMuYmF0Y2hTaXplID0gMTtcclxuICAgICAgICAgICAgdGhpcy5tYXhCYXRjaFNpemUgPSAyMDtcclxuICAgICAgICAgICAgdGhpcy5iYXRjaFRpbWVvdXQgPSAyMTQ3NDgzNjQ3O1xyXG4gICAgICAgICAgICB0aGlzLnNlbmRUaW1lb3V0ID0gNTAwMDtcclxuICAgICAgICAgICAgLy8gSG9sZHMgYWxsIGxvZyBpdGVtcyB3aXRoIGxldmVscyBoaWdoZXIgdGhhbiBzdG9yZUluQnVmZmVyTGV2ZWwgXHJcbiAgICAgICAgICAgIC8vIGJ1dCBsb3dlciB0aGFuIGxldmVsLiBUaGVzZSBpdGVtcyBtYXkgbmV2ZXIgYmUgc2VudC5cclxuICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBbXTtcclxuICAgICAgICAgICAgLy8gSG9sZHMgYWxsIGl0ZW1zIHRoYXQgd2UgZG8gd2FudCB0byBzZW5kLCB1bnRpbCB3ZSBoYXZlIGEgZnVsbFxyXG4gICAgICAgICAgICAvLyBiYXRjaCAoYXMgZGV0ZXJtaW5lZCBieSBiYXRjaFNpemUpLlxyXG4gICAgICAgICAgICB0aGlzLmJhdGNoQnVmZmVyID0gW107XHJcbiAgICAgICAgICAgIC8vIEhvbGRzIHRoZSBpZCBvZiB0aGUgdGltZXIgaW1wbGVtZW50aW5nIHRoZSBiYXRjaCB0aW1lb3V0LlxyXG4gICAgICAgICAgICAvLyBDYW4gYmUgbnVsbC5cclxuICAgICAgICAgICAgLy8gVGhpcyBpcyBhbiBvYmplY3QsIHNvIGl0IGNhbiBiZSBwYXNzZWQgdG8gYSBtZXRob2QgdGhhdCB1cGRhdGVkIHRoZSB0aW1lciB2YXJpYWJsZS5cclxuICAgICAgICAgICAgdGhpcy5iYXRjaFRpbWVvdXRUaW1lciA9IHsgaWQ6IG51bGwgfTtcclxuICAgICAgICAgICAgLy8gSG9sZHMgdGhlIGlkIG9mIHRoZSB0aW1lciBpbXBsZW1lbnRpbmcgdGhlIHNlbmQgdGltZW91dC5cclxuICAgICAgICAgICAgLy8gQ2FuIGJlIG51bGwuXHJcbiAgICAgICAgICAgIHRoaXMuc2VuZFRpbWVvdXRUaW1lciA9IHsgaWQ6IG51bGwgfTtcclxuICAgICAgICAgICAgLy8gTnVtYmVyIG9mIGxvZyBpdGVtcyB0aGF0IGhhcyBiZWVuIHNraXBwZWQgZHVlIHRvIGJhdGNoIGJ1ZmZlciBhdCBtYXggc2l6ZSxcclxuICAgICAgICAgICAgLy8gc2luY2UgYXBwZW5kZXIgY3JlYXRpb24gb3Igc2luY2UgY3JlYXRpb24gb2YgdGhlIGxhc3QgXCJza2lwcGVkXCIgd2FybmluZyBsb2cgZW50cnkuXHJcbiAgICAgICAgICAgIHRoaXMubmJyTG9nSXRlbXNTa2lwcGVkID0gMDtcclxuICAgICAgICAgICAgLy8gV2lsbCBiZSAwIGlmIG5vIGxvZyByZXF1ZXN0IGlzIG91dHN0YW5kaW5nIGF0IHRoZSBtb21lbnQuXHJcbiAgICAgICAgICAgIC8vIE90aGVyd2lzZSB0aGUgbnVtYmVyIG9mIGxvZyBpdGVtcyBpbiB0aGUgb3V0c3RhbmRpbmcgcmVxdWVzdC5cclxuICAgICAgICAgICAgdGhpcy5uYnJMb2dJdGVtc0JlaW5nU2VudCA9IDA7XHJcbiAgICAgICAgICAgIHZhciBlbXB0eU5hbWVFcnJvck1lc3NhZ2UgPSBcIlRyeWluZyB0byBjcmVhdGUgYW4gYXBwZW5kZXIgd2l0aG91dCBhIG5hbWUgb3Igd2l0aCBhbiBlbXB0eSBuYW1lXCI7XHJcbiAgICAgICAgICAgIC8vIFRoaXMgZXZhbHVhdGVzIHRvIHRydWUgaWYgYXBwZW5kZXJOYW1lIGlzIGVpdGhlciBudWxsIG9yIHVuZGVmaW5lZCFcclxuICAgICAgICAgICAgLy8gRG8gbm90IGNoZWNrIGhlcmUgaWYgdGhlIG5hbWUgaXMgXCJcIiwgYmVjYXVzZSB0aGF0IHdvdWxkIHN0b3AgeW91IGNyZWF0aW5nIHRoZSBcclxuICAgICAgICAgICAgLy8gZGVmYXVsdCBhcHBlbmRlci5cclxuICAgICAgICAgICAgaWYgKGFwcGVuZGVyTmFtZSA9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IGVtcHR5TmFtZUVycm9yTWVzc2FnZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoSkwuX2FwcGVuZGVyTmFtZXMuaW5kZXhPZihhcHBlbmRlck5hbWUpICE9IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBJZiB1c2VyIHBhc3NlZCBpbiBcIlwiLCB0aGF0IHdpbGwgbm93IGhhdmUgYmVlbiBwaWNrZWQgdXAgYXMgYSBkdXBsaWNhdGVcclxuICAgICAgICAgICAgICAgIC8vIGJlY2F1c2UgZGVmYXVsdCBhcHBlbmRlciBhbHNvIHVzZXMgXCJcIi5cclxuICAgICAgICAgICAgICAgIGlmICghYXBwZW5kZXJOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZW1wdHlOYW1lRXJyb3JNZXNzYWdlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhyb3cgXCJNdWx0aXBsZSBhcHBlbmRlcnMgdXNlIHRoZSBzYW1lIG5hbWUgXCIgKyBhcHBlbmRlck5hbWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgSkwuX2FwcGVuZGVyTmFtZXMucHVzaChhcHBlbmRlck5hbWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBBcHBlbmRlci5wcm90b3R5cGUuYWRkTG9nSXRlbXNUb0J1ZmZlciA9IGZ1bmN0aW9uIChsb2dJdGVtcykge1xyXG4gICAgICAgICAgICAvLyBJZiB0aGUgYmF0Y2ggYnVmZmVyIGhhcyByZWFjaGVkIGl0cyBtYXhpbXVtIGxpbWl0LCBcclxuICAgICAgICAgICAgLy8gc2tpcCB0aGUgbG9nIGl0ZW0gYW5kIGluY3JlYXNlIHRoZSBcInNraXBwZWQgaXRlbXNcIiBjb3VudGVyLlxyXG4gICAgICAgICAgICBpZiAodGhpcy5iYXRjaEJ1ZmZlci5sZW5ndGggPj0gdGhpcy5tYXhCYXRjaFNpemUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubmJyTG9nSXRlbXNTa2lwcGVkICs9IGxvZ0l0ZW1zLmxlbmd0aDtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBJZiBtYXhNZXNzYWdlcyBpcyBub3QgbnVsbCBvciB1bmRlZmluZWQsIHRoZW4gZGVjcmVhc2UgaXQgYnkgdGhlIGJhdGNoIHNpemUuXHJcbiAgICAgICAgICAgIC8vIFRoaXMgY2FuIHJlc3VsdCBpbiBhIG5lZ2F0aXZlIG1heE1lc3NhZ2VzLlxyXG4gICAgICAgICAgICAvLyBOb3RlIHRoYXQgdW5kZWZpbmVkPT1udWxsICghKVxyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBOb3RlIHRoYXQgd2UgbWF5IGJlIHNlbmRpbmcgbW9yZSBtZXNzYWdlcyB0aGFuIHRoZSBtYXhNZXNzYWdlcyBsaW1pdCBhbGxvd3MsXHJcbiAgICAgICAgICAgIC8vIGlmIHdlIHN0b3JlZCB0cmFjZSBtZXNzYWdlcy4gUmF0aW9uYWxlIGlzIHRoZSBidWZmZXIgZm9yIHRyYWNlIG1lc3NhZ2VzIGlzIGxpbWl0ZWQsXHJcbiAgICAgICAgICAgIC8vIGFuZCBpZiB3ZSBjdXQgb2ZmIGF0IGV4YWN0bHkgbWF4TWVzc2FnZXMsIHdlJ2QgYWxzbyBsb29zZSB0aGUgaGlnaCBzZXZlcml0eSBtZXNzYWdlXHJcbiAgICAgICAgICAgIC8vIHRoYXQgY2F1c2VkIHRoZSB0cmFjZSBtZXNzYWdlcyB0byBiZSBzZW50ICh1bmxlc3Mgd2UgY2F0ZXIgZm9yIHRoaXMgc3BlY2lmaWNhbGx5LCB3aGljaFxyXG4gICAgICAgICAgICAvLyBpcyBtb3JlIGNvbXBsZXhpdHkpLlxyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgYXBwZW5kZXJzIHNlbmRpbmcgdGhlIHNhbWUgbWVzc2FnZSwgbWF4TWVzc2FnZSB3aWxsIGJlIGRlY3JlYXNlZFxyXG4gICAgICAgICAgICAvLyBieSBlYWNoIGFwcGVuZGVyIGZvciB0aGUgc2FtZSBtZXNzYWdlLiBUaGlzIGlzOlxyXG4gICAgICAgICAgICAvLyAxKSBvbmx5IGFwcGVuZGVycyBrbm93IHdoZXRoZXIgYSBtZXNzYWdlIHdpbGwgYWN0dWFsbHkgYmUgc2VudCAoYmFzZWQgb24gc3RvcmVJbkJ1ZmZlckxldmVsKSxcclxuICAgICAgICAgICAgLy8gICAgc28gdGhlIGxvZ2dlcnMgY291bGRuJ3QgZG8gdGhpcyB1cGRhdGU7XHJcbiAgICAgICAgICAgIC8vIDIpIGlmIHlvdSBoYXZlIG11bHRpcGxlIGFwcGVuZGVycyBoaXR0aW5nIHRoZSBzYW1lIHNlcnZlciwgdGhpcyBtYXkgYmUgd2hhdCB5b3Ugd2FudC5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gSW4gbW9zdCBjYXNlcyB0aGVyZSBpcyBvbmx5IDEgYXBwZW5kZXIsIHNvIHRoaXMgdGhlbiBkb2Vzbid0IG1hdHRlci5cclxuICAgICAgICAgICAgaWYgKCEoSkwubWF4TWVzc2FnZXMgPT0gbnVsbCkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChKTC5tYXhNZXNzYWdlcyA8IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBKTC5tYXhNZXNzYWdlcyAtPSBsb2dJdGVtcy5sZW5ndGg7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5iYXRjaEJ1ZmZlciA9IHRoaXMuYmF0Y2hCdWZmZXIuY29uY2F0KGxvZ0l0ZW1zKTtcclxuICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyB0aGUgZmlyc3QgaXRlbSBpbiB0aGUgYnVmZmVyLCBzZXQgdGhlIHRpbWVyXHJcbiAgICAgICAgICAgIC8vIHRvIGVuc3VyZSBpdCB3aWxsIGJlIHNlbnQgd2l0aGluIHRoZSB0aW1lb3V0IHBlcmlvZC5cclxuICAgICAgICAgICAgLy8gSWYgaXQgaXMgbm90IHRoZSBmaXJzdCBpdGVtLCBsZWF2ZSB0aGUgdGltZXIgYWxvbmUgc28gdG8gbm90IHRvIFxyXG4gICAgICAgICAgICAvLyBpbmNyZWFzZSB0aGUgdGltZW91dCBmb3IgdGhlIGZpcnN0IGl0ZW0uXHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgIC8vIFRvIGRldGVybWluZSBpZiB0aGlzIGlzIHRoZSBmaXJzdCBpdGVtLCBsb29rIGF0IHRoZSB0aW1lciB2YXJpYWJsZS5cclxuICAgICAgICAgICAgLy8gRG8gbm90IGxvb2sgYXQgdGhlIGJ1ZmZlciBsZW5ndGgsIGJlY2F1c2Ugd2UgYWxzbyBwdXQgaXRlbXMgaW4gdGhlIGJ1ZmZlclxyXG4gICAgICAgICAgICAvLyB2aWEgYSBjb25jYXQgKGJ5cGFzc2luZyB0aGlzIGZ1bmN0aW9uKS5cclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gVGhlIHNldFRpbWVyIG1ldGhvZCBvbmx5IHNldHMgdGhlIHRpbWVyIGlmIGl0IGlzIG5vdCBhbHJlYWR5IHJ1bm5pbmcuXHJcbiAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcztcclxuICAgICAgICAgICAgc2V0VGltZXIodGhpcy5iYXRjaFRpbWVvdXRUaW1lciwgdGhpcy5iYXRjaFRpbWVvdXQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHRoYXQuc2VuZEJhdGNoLmNhbGwodGhhdCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgO1xyXG4gICAgICAgIEFwcGVuZGVyLnByb3RvdHlwZS5iYXRjaEJ1ZmZlckhhc092ZXJkdWVNZXNzYWdlcyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmJhdGNoQnVmZmVyLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbWVzc2FnZUFnZU1zID0gSkwuX2dldFRpbWUoKSAtIHRoaXMuYmF0Y2hCdWZmZXJbaV0udDtcclxuICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlQWdlTXMgPiB0aGlzLmJhdGNoVGltZW91dCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBubyBtb3JlIG1lc3NhZ2Ugd2lsbCBldmVyIGJlIGFkZGVkIHRvIHRoZSBiYXRjaCBidWZmZXIsXHJcbiAgICAgICAgLy8gYnV0IHRoZSBiYXRjaCBidWZmZXIgaGFzIG1lc3NhZ2VzIG5vdyAtIHNvIGlmIHRoZXJlIGFyZSBub3QgZW5vdWdoIHRvIG1ha2UgdXAgYSBiYXRjaCxcclxuICAgICAgICAvLyBhbmQgdGhlcmUgaXMgbm8gYmF0Y2ggdGltZW91dCwgdGhlbiB0aGV5IHdpbGwgbmV2ZXIgYmUgc2VudC4gVGhpcyBpcyBlc3BlY2lhbGx5IGltcG9ydGFudCBpZiBcclxuICAgICAgICAvLyBtYXhNZXNzYWdlcyB3YXMgcmVhY2hlZCB3aGlsZSBqc25sb2cuanMgd2FzIHJldHJ5aW5nIHNlbmRpbmcgbWVzc2FnZXMgdG8gdGhlIHNlcnZlci5cclxuICAgICAgICBBcHBlbmRlci5wcm90b3R5cGUuYmF0Y2hCdWZmZXJIYXNTdHJhbmRlZE1lc3NhZ2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAoIShKTC5tYXhNZXNzYWdlcyA9PSBudWxsKSkgJiYgKEpMLm1heE1lc3NhZ2VzIDwgMSkgJiYgKHRoaXMuYmF0Y2hCdWZmZXIubGVuZ3RoID4gMCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBBcHBlbmRlci5wcm90b3R5cGUuc2VuZEJhdGNoSWZDb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKCh0aGlzLmJhdGNoQnVmZmVyLmxlbmd0aCA+PSB0aGlzLmJhdGNoU2l6ZSkgfHxcclxuICAgICAgICAgICAgICAgIHRoaXMuYmF0Y2hCdWZmZXJIYXNPdmVyZHVlTWVzc2FnZXMoKSB8fFxyXG4gICAgICAgICAgICAgICAgdGhpcy5iYXRjaEJ1ZmZlckhhc1N0cmFuZGVkTWVzc2FnZSgpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNlbmRCYXRjaCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBBcHBlbmRlci5wcm90b3R5cGUub25TZW5kaW5nRW5kZWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNsZWFyVGltZXIodGhpcy5zZW5kVGltZW91dFRpbWVyKTtcclxuICAgICAgICAgICAgdGhpcy5uYnJMb2dJdGVtc0JlaW5nU2VudCA9IDA7XHJcbiAgICAgICAgICAgIHRoaXMuc2VuZEJhdGNoSWZDb21wbGV0ZSgpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgQXBwZW5kZXIucHJvdG90eXBlLnNldE9wdGlvbnMgPSBmdW5jdGlvbiAob3B0aW9ucykge1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJsZXZlbFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwiaXBSZWdleFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwidXNlckFnZW50UmVnZXhcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImRpc2FsbG93XCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJzZW5kV2l0aEJ1ZmZlckxldmVsXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJzdG9yZUluQnVmZmVyTGV2ZWxcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImJ1ZmZlclNpemVcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcImJhdGNoU2l6ZVwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwibWF4QmF0Y2hTaXplXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJiYXRjaFRpbWVvdXRcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcInNlbmRUaW1lb3V0XCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBpZiAodGhpcy5idWZmZXJTaXplIDwgdGhpcy5idWZmZXIubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmJ1ZmZlci5sZW5ndGggPSB0aGlzLmJ1ZmZlclNpemU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHRoaXMubWF4QmF0Y2hTaXplIDwgdGhpcy5iYXRjaFNpemUpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBKTC5FeGNlcHRpb24oe1xyXG4gICAgICAgICAgICAgICAgICAgIFwibWVzc2FnZVwiOiBcIm1heEJhdGNoU2l6ZSBjYW5ub3QgYmUgc21hbGxlciB0aGFuIGJhdGNoU2l6ZVwiLFxyXG4gICAgICAgICAgICAgICAgICAgIFwibWF4QmF0Y2hTaXplXCI6IHRoaXMubWF4QmF0Y2hTaXplLFxyXG4gICAgICAgICAgICAgICAgICAgIFwiYmF0Y2hTaXplXCI6IHRoaXMuYmF0Y2hTaXplXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgIENhbGxlZCBieSBhIGxvZ2dlciB0byBsb2cgYSBsb2cgaXRlbS5cclxuICAgICAgICBJZiBpbiByZXNwb25zZSB0byB0aGlzIGNhbGwgb25lIG9yIG1vcmUgbG9nIGl0ZW1zIG5lZWQgdG8gYmUgcHJvY2Vzc2VkXHJcbiAgICAgICAgKGVnLiwgc2VudCB0byB0aGUgc2VydmVyKSwgdGhpcyBtZXRob2QgY2FsbHMgdGhpcy5zZW5kTG9nSXRlbXNcclxuICAgICAgICB3aXRoIGFuIGFycmF5IHdpdGggYWxsIGl0ZW1zIHRvIGJlIHByb2Nlc3NlZC5cclxuXHJcbiAgICAgICAgTm90ZSB0aGF0IHRoZSBuYW1lIGFuZCBwYXJhbWV0ZXJzIG9mIHRoaXMgZnVuY3Rpb24gbXVzdCBtYXRjaCB0aG9zZSBvZiB0aGUgbG9nIGZ1bmN0aW9uIG9mXHJcbiAgICAgICAgYSBXaW5zdG9uIHRyYW5zcG9ydCBvYmplY3QsIHNvIHRoYXQgdXNlcnMgY2FuIHVzZSB0aGVzZSB0cmFuc3BvcnRzIGFzIGFwcGVuZGVycy5cclxuICAgICAgICBUaGF0IGlzIHdoeSB0aGVyZSBhcmUgbWFueSBwYXJhbWV0ZXJzIHRoYXQgYXJlIG5vdCBhY3R1YWxseSB1c2VkIGJ5IHRoaXMgZnVuY3Rpb24uXHJcblxyXG4gICAgICAgIGxldmVsIC0gc3RyaW5nIHdpdGggdGhlIGxldmVsIChcInRyYWNlXCIsIFwiZGVidWdcIiwgZXRjLikgT25seSB1c2VkIGJ5IFdpbnN0b24gdHJhbnNwb3J0cy5cclxuICAgICAgICBtc2cgLSBodW1hbiByZWFkYWJsZSBtZXNzYWdlLiBVbmRlZmluZWQgaWYgdGhlIGxvZyBpdGVtIGlzIGFuIG9iamVjdC4gT25seSB1c2VkIGJ5IFdpbnN0b24gdHJhbnNwb3J0cy5cclxuICAgICAgICBtZXRhIC0gbG9nIG9iamVjdC4gQWx3YXlzIGRlZmluZWQsIGJlY2F1c2UgYXQgbGVhc3QgaXQgY29udGFpbnMgdGhlIGxvZ2dlciBuYW1lLiBPbmx5IHVzZWQgYnkgV2luc3RvbiB0cmFuc3BvcnRzLlxyXG4gICAgICAgIGNhbGxiYWNrIC0gZnVuY3Rpb24gdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGUgbG9nIGl0ZW0gaGFzIGJlZW4gbG9nZ2VkLiBPbmx5IHVzZWQgYnkgV2luc3RvbiB0cmFuc3BvcnRzLlxyXG4gICAgICAgIGxldmVsTmJyIC0gbGV2ZWwgYXMgYSBudW1iZXIuIE5vdCB1c2VkIGJ5IFdpbnN0b24gdHJhbnNwb3J0cy5cclxuICAgICAgICBtZXNzYWdlIC0gbG9nIGl0ZW0uIElmIHRoZSB1c2VyIGxvZ2dlZCBhbiBvYmplY3QsIHRoaXMgaXMgdGhlIEpTT04gc3RyaW5nLiAgTm90IHVzZWQgYnkgV2luc3RvbiB0cmFuc3BvcnRzLlxyXG4gICAgICAgIGxvZ2dlck5hbWU6IG5hbWUgb2YgdGhlIGxvZ2dlci4gIE5vdCB1c2VkIGJ5IFdpbnN0b24gdHJhbnNwb3J0cy5cclxuICAgICAgICAqL1xyXG4gICAgICAgIEFwcGVuZGVyLnByb3RvdHlwZS5sb2cgPSBmdW5jdGlvbiAobGV2ZWwsIG1zZywgbWV0YSwgY2FsbGJhY2ssIGxldmVsTmJyLCBtZXNzYWdlLCBsb2dnZXJOYW1lKSB7XHJcbiAgICAgICAgICAgIHZhciBsb2dJdGVtO1xyXG4gICAgICAgICAgICBpZiAoIWFsbG93KHRoaXMpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCFhbGxvd01lc3NhZ2UodGhpcywgbWVzc2FnZSkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAobGV2ZWxOYnIgPCB0aGlzLnN0b3JlSW5CdWZmZXJMZXZlbCkge1xyXG4gICAgICAgICAgICAgICAgLy8gSWdub3JlIHRoZSBsb2cgaXRlbSBjb21wbGV0ZWx5XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbG9nSXRlbSA9IG5ld0xvZ0l0ZW0obGV2ZWxOYnIsIG1lc3NhZ2UsIGxvZ2dlck5hbWUpO1xyXG4gICAgICAgICAgICBpZiAobGV2ZWxOYnIgPCB0aGlzLmxldmVsKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBTdG9yZSBpbiB0aGUgaG9sZCBidWZmZXIuIERvIG5vdCBzZW5kLlxyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuYnVmZmVyU2l6ZSA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1ZmZlci5wdXNoKGxvZ0l0ZW0pO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIElmIHdlIGV4Y2VlZGVkIG1heCBidWZmZXIgc2l6ZSwgcmVtb3ZlIG9sZGVzdCBpdGVtXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuYnVmZmVyLmxlbmd0aCA+IHRoaXMuYnVmZmVyU2l6ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1ZmZlci5zaGlmdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBXYW50IHRvIHNlbmQgdGhlIGl0ZW1cclxuICAgICAgICAgICAgdGhpcy5hZGRMb2dJdGVtc1RvQnVmZmVyKFtsb2dJdGVtXSk7XHJcbiAgICAgICAgICAgIGlmIChsZXZlbE5iciA+PSB0aGlzLnNlbmRXaXRoQnVmZmVyTGV2ZWwpIHtcclxuICAgICAgICAgICAgICAgIC8vIFdhbnQgdG8gc2VuZCB0aGUgY29udGVudHMgb2YgdGhlIGJ1ZmZlci5cclxuICAgICAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgICAgICAvLyBTZW5kIHRoZSBidWZmZXIgQUZURVIgc2VuZGluZyB0aGUgaGlnaCBwcmlvcml0eSBpdGVtLlxyXG4gICAgICAgICAgICAgICAgLy8gSWYgeW91IHdlcmUgdG8gc2VuZCB0aGUgaGlnaCBwcmlvcml0eSBpdGVtIGFmdGVyIHRoZSBidWZmZXIsXHJcbiAgICAgICAgICAgICAgICAvLyBpZiB3ZSdyZSBjbG9zZSB0byBtYXhNZXNzYWdlcyBvciBtYXhCYXRjaFNpemUsXHJcbiAgICAgICAgICAgICAgICAvLyB0aGVuIHRoZSB0cmFjZSBtZXNzYWdlcyBpbiB0aGUgYnVmZmVyIGNvdWxkIGNyb3dkIG91dCB0aGUgYWN0dWFsIGhpZ2ggcHJpb3JpdHkgaXRlbS5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZExvZ0l0ZW1zVG9CdWZmZXIodGhpcy5idWZmZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYnVmZmVyLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5zZW5kQmF0Y2hJZkNvbXBsZXRlKCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICA7XHJcbiAgICAgICAgLy8gUHJvY2Vzc2VzIHRoZSBiYXRjaCBidWZmZXJcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIE1ha2UgdGhpcyBwdWJsaWMsIHNvIGl0IGNhbiBiZSBjYWxsZWQgZnJvbSBvdXRzaWRlIHRoZSBsaWJyYXJ5LFxyXG4gICAgICAgIC8vIHdoZW4gdGhlIHBhZ2UgaXMgdW5sb2FkZWQuXHJcbiAgICAgICAgQXBwZW5kZXIucHJvdG90eXBlLnNlbmRCYXRjaCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gRG8gbm90IGNsZWFyIHRoZSBiYXRjaCB0aW1lciBpZiB5b3UgZG9uJ3QgZ28gYWhlYWQgaGVyZSBiZWNhdXNlXHJcbiAgICAgICAgICAgIC8vIGEgc2VuZCBpcyBhbHJlYWR5IGluIHByb2dyZXNzLiBPdGhlcndpc2UgdGhlIG1lc3NhZ2VzIHRoYXQgd2VyZSBzdG9wcGVkIGZyb20gZ29pbmcgb3V0XHJcbiAgICAgICAgICAgIC8vIG1heSBnZXQgaWdub3JlZCBiZWNhdXNlIHRoZSBiYXRjaCB0aW1lciBuZXZlciB3ZW50IG9mZi5cclxuICAgICAgICAgICAgaWYgKHRoaXMubmJyTG9nSXRlbXNCZWluZ1NlbnQgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2xlYXJUaW1lcih0aGlzLmJhdGNoVGltZW91dFRpbWVyKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuYmF0Y2hCdWZmZXIubGVuZ3RoID09IDApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBEZWNpZGVkIGF0IHRoaXMgcG9pbnQgdG8gc2VuZCBjb250ZW50cyBvZiB0aGUgYnVmZmVyXHJcbiAgICAgICAgICAgIHRoaXMubmJyTG9nSXRlbXNCZWluZ1NlbnQgPSB0aGlzLmJhdGNoQnVmZmVyLmxlbmd0aDtcclxuICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzO1xyXG4gICAgICAgICAgICBzZXRUaW1lcih0aGlzLnNlbmRUaW1lb3V0VGltZXIsIHRoaXMuc2VuZFRpbWVvdXQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHRoYXQub25TZW5kaW5nRW5kZWQuY2FsbCh0aGF0KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuc2VuZExvZ0l0ZW1zKHRoaXMuYmF0Y2hCdWZmZXIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIC8vIExvZyBlbnRyaWVzIGhhdmUgYmVlbiBzdWNjZXNzZnVsbHkgc2VudCB0byBzZXJ2ZXJcclxuICAgICAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgZmlyc3QgKG5ickxvZ0l0ZW1zQmVpbmdTZW50KSBpdGVtcyBpbiB0aGUgYmF0Y2ggYnVmZmVyLCBiZWNhdXNlIHRoZXkgYXJlIHRoZSBvbmVzXHJcbiAgICAgICAgICAgICAgICAvLyB0aGF0IHdlcmUgc2VudC5cclxuICAgICAgICAgICAgICAgIHRoYXQuYmF0Y2hCdWZmZXIuc3BsaWNlKDAsIHRoYXQubmJyTG9nSXRlbXNCZWluZ1NlbnQpO1xyXG4gICAgICAgICAgICAgICAgLy8gSWYgaXRlbXMgaGFkIHRvIGJlIHNraXBwZWQsIGFkZCBhIFdBUk4gbWVzc2FnZVxyXG4gICAgICAgICAgICAgICAgaWYgKHRoYXQubmJyTG9nSXRlbXNTa2lwcGVkID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoYXQuYmF0Y2hCdWZmZXIucHVzaChuZXdMb2dJdGVtKGdldFdhcm5MZXZlbCgpLCBcIkxvc3QgXCIgKyB0aGF0Lm5ickxvZ0l0ZW1zU2tpcHBlZCArIFwiIG1lc3NhZ2VzLiBFaXRoZXIgY29ubmVjdGlvbiB3aXRoIHRoZSBzZXJ2ZXIgd2FzIGRvd24gb3IgbG9nZ2luZyB3YXMgZGlzYWJsZWQgdmlhIHRoZSBlbmFibGVkIG9wdGlvbi4gUmVkdWNlIGxvc3QgbWVzc2FnZXMgYnkgaW5jcmVhc2luZyB0aGUgYWpheEFwcGVuZGVyIG9wdGlvbiBtYXhCYXRjaFNpemUuXCIsIHRoYXQuYXBwZW5kZXJOYW1lKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5uYnJMb2dJdGVtc1NraXBwZWQgPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhhdC5vblNlbmRpbmdFbmRlZC5jYWxsKHRoYXQpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHJldHVybiBBcHBlbmRlcjtcclxuICAgIH0oKSk7XHJcbiAgICBKTC5BcHBlbmRlciA9IEFwcGVuZGVyO1xyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICB2YXIgQWpheEFwcGVuZGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgICAgIF9fZXh0ZW5kcyhBamF4QXBwZW5kZXIsIF9zdXBlcik7XHJcbiAgICAgICAgZnVuY3Rpb24gQWpheEFwcGVuZGVyKGFwcGVuZGVyTmFtZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gX3N1cGVyLmNhbGwodGhpcywgYXBwZW5kZXJOYW1lLCBBamF4QXBwZW5kZXIucHJvdG90eXBlLnNlbmRMb2dJdGVtc0FqYXgpIHx8IHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIEFqYXhBcHBlbmRlci5wcm90b3R5cGUuc2V0T3B0aW9ucyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcInVybFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwiYmVmb3JlU2VuZFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5zZXRPcHRpb25zLmNhbGwodGhpcywgb3B0aW9ucyk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgQWpheEFwcGVuZGVyLnByb3RvdHlwZS5zZW5kTG9nSXRlbXNBamF4ID0gZnVuY3Rpb24gKGxvZ0l0ZW1zLCBzdWNjZXNzQ2FsbGJhY2spIHtcclxuICAgICAgICAgICAgLy8gSlNPTi5zdHJpbmdpZnkgaXMgb25seSBzdXBwb3J0ZWQgb24gSUU4K1xyXG4gICAgICAgICAgICAvLyBVc2UgdHJ5LWNhdGNoIGluIGNhc2Ugd2UgZ2V0IGFuIGV4Y2VwdGlvbiBoZXJlLlxyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBUaGUgXCJyXCIgZmllbGQgaXMgbm93IG9ic29sZXRlLiBXaGVuIHdyaXRpbmcgYSBzZXJ2ZXIgc2lkZSBjb21wb25lbnQsIFxyXG4gICAgICAgICAgICAvLyByZWFkIHRoZSBIVFRQIGhlYWRlciBcIkpTTkxvZy1SZXF1ZXN0SWRcIlxyXG4gICAgICAgICAgICAvLyB0byBnZXQgdGhlIHJlcXVlc3QgaWQuXHJcbiAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgIC8vIFRoZSAuTmV0IHNlcnZlciBzaWRlIGNvbXBvbmVudFxyXG4gICAgICAgICAgICAvLyBub3cgdXNlcyB0aGUgSlNOTG9nLVJlcXVlc3RJZCBIVFRQIEhlYWRlciwgYmVjYXVzZSB0aGlzIGFsbG93cyBpdCB0b1xyXG4gICAgICAgICAgICAvLyBkZXRlY3Qgd2hldGhlciB0aGUgaW5jb21pbmcgcmVxdWVzdCBoYXMgYSByZXF1ZXN0IGlkLlxyXG4gICAgICAgICAgICAvLyBJZiB0aGUgcmVxdWVzdCBpZCB3ZXJlIGluIHRoZSBqc29uIHBheWxvYWQsIGl0IHdvdWxkIGhhdmUgdG8gcmVhZCB0aGUganNvblxyXG4gICAgICAgICAgICAvLyBmcm9tIHRoZSBzdHJlYW0sIGludGVyZmVyaW5nIHdpdGggbm9ybWFsIG5vbi1sb2dnaW5nIHJlcXVlc3RzLlxyXG4gICAgICAgICAgICAvL1xyXG4gICAgICAgICAgICAvLyBUbyBzZWUgd2hhdCBjaGFyYWN0ZXJzIHlvdSBjYW4gdXNlIGluIHRoZSBIVFRQIGhlYWRlciwgdmlzaXQ6XHJcbiAgICAgICAgICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzU2MTM4MS9jdXN0b20taHR0cC1oZWFkZXJzLW5hbWluZy1jb252ZW50aW9ucy8zNTYxMzk5IzM1NjEzOTlcclxuICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgLy8gSXQgbmVlZHMgdGhpcyBhYmlsaXR5LCBzbyB1c2VycyBvZiBOTG9nIGNhbiBzZXQgYSByZXF1ZXN0SWQgdmFyaWFibGUgaW4gTkxvZ1xyXG4gICAgICAgICAgICAvLyBiZWZvcmUgdGhlIHNlcnZlciBzaWRlIGNvbXBvbmVudCB0cmllcyB0byBsb2cgdGhlIGNsaWVudCBzaWRlIGxvZyBtZXNzYWdlXHJcbiAgICAgICAgICAgIC8vIHRocm91Z2ggYW4gTkxvZyBsb2dnZXIuXHJcbiAgICAgICAgICAgIC8vIFVubGlrZSBMb2c0TmV0LCBOTG9nIGRvZXNuJ3QgYWxsb3cgeW91IHRvIHJlZ2lzdGVyIGFuIG9iamVjdCB3aG9zZSBUb1N0cmluZygpXHJcbiAgICAgICAgICAgIC8vIGlzIG9ubHkgY2FsbGVkIHdoZW4gaXQgdHJpZXMgdG8gbG9nIHNvbWV0aGluZywgc28gdGhlIHJlcXVlc3RJZCBoYXMgdG8gYmUgXHJcbiAgICAgICAgICAgIC8vIGRldGVybWluZWQgcmlnaHQgYXQgdGhlIHN0YXJ0IG9mIHJlcXVlc3QgcHJvY2Vzc2luZy5cclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIC8vIERvIG5vdCBzZW5kIGxvZ3MsIGlmIEpMLmVuYWJsZWQgaXMgc2V0IHRvIGZhbHNlLlxyXG4gICAgICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgICAgIC8vIERvIG5vdCBjYWxsIHN1Y2Nlc3NDYWxsYmFjayBoZXJlLiBBZnRlciBlYWNoIHRpbWVvdXQsIGpzbmxvZyB3aWxsIHJldHJ5IHNlbmRpbmcgdGhlIG1lc3NhZ2UuXHJcbiAgICAgICAgICAgICAgICAvLyBJZiBqc25sb2cgZ2V0cyByZS1lbmFibGVkLCBpdCB3aWxsIHRoZW4gbG9nIHRoZSBudW1iZXIgb2YgbWVzc2FnZXMgbG9nZ2VkLlxyXG4gICAgICAgICAgICAgICAgLy8gSWYgaXQgZG9lc24ndCBnZXQgcmUtZW5hYmxlZCwgYW1vdW50IG9mIGNwdSBjeWNsZXMgd2FzdGVkIGlzIG1pbmltYWwuXHJcbiAgICAgICAgICAgICAgICBpZiAoIWFsbG93KHRoaXMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gSWYgYSByZXF1ZXN0IGlzIGluIHByb2dyZXNzLCBhYm9ydCBpdC5cclxuICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgaXQgbWF5IGNhbGwgdGhlIHN1Y2Nlc3MgY2FsbGJhY2ssIHdoaWNoIHdpbGwgYmUgdmVyeSBjb25mdXNpbmcuXHJcbiAgICAgICAgICAgICAgICAvLyBJdCBtYXkgYWxzbyBzdG9wIHRoZSBpbmZsaWdodCByZXF1ZXN0IGZyb20gcmVzdWx0aW5nIGluIGEgbG9nIGF0IHRoZSBzZXJ2ZXIuXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy54aHIgJiYgKHRoaXMueGhyLnJlYWR5U3RhdGUgIT0gMCkgJiYgKHRoaXMueGhyLnJlYWR5U3RhdGUgIT0gNCkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnhoci5hYm9ydCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gQmVjYXVzZSBhIHJlYWN0LW5hdGl2ZSBYTUxIdHRwUmVxdWVzdCBjYW5ub3QgYmUgcmV1c2VkIGl0IG5lZWRzIHRvIGJlIHJlY3JlYXRlZCB3aXRoIGVhY2ggcmVxdWVzdFxyXG4gICAgICAgICAgICAgICAgdGhpcy54aHIgPSBKTC5fY3JlYXRlWE1MSHR0cFJlcXVlc3QoKTtcclxuICAgICAgICAgICAgICAgIC8vIE9ubHkgZGV0ZXJtaW5lIHRoZSB1cmwgcmlnaHQgYmVmb3JlIHlvdSBzZW5kIGEgbG9nIHJlcXVlc3QuXHJcbiAgICAgICAgICAgICAgICAvLyBEbyBub3Qgc2V0IHRoZSB1cmwgd2hlbiBjb25zdHJ1Y3RpbmcgdGhlIGFwcGVuZGVyLlxyXG4gICAgICAgICAgICAgICAgLy9cclxuICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYmVjYXVzZSB0aGUgc2VydmVyIHNpZGUgY29tcG9uZW50IHNldHMgZGVmYXVsdEFqYXhVcmxcclxuICAgICAgICAgICAgICAgIC8vIGluIGEgY2FsbCB0byBzZXRPcHRpb25zLCBBRlRFUiB0aGUgSkwgb2JqZWN0IGFuZCB0aGUgZGVmYXVsdCBhcHBlbmRlclxyXG4gICAgICAgICAgICAgICAgLy8gaGF2ZSBiZWVuIGNyZWF0ZWQuIFxyXG4gICAgICAgICAgICAgICAgdmFyIGFqYXhVcmwgPSBcIi9qc25sb2cubG9nZ2VyXCI7XHJcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGV2YWx1YXRlcyB0byB0cnVlIGlmIGRlZmF1bHRBamF4VXJsIGlzIG51bGwgb3IgdW5kZWZpbmVkXHJcbiAgICAgICAgICAgICAgICBpZiAoIShKTC5kZWZhdWx0QWpheFVybCA9PSBudWxsKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGFqYXhVcmwgPSBKTC5kZWZhdWx0QWpheFVybDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnVybCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGFqYXhVcmwgPSB0aGlzLnVybDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMueGhyLm9wZW4oJ1BPU1QnLCBhamF4VXJsKTtcclxuICAgICAgICAgICAgICAgIHRoaXMueGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICdhcHBsaWNhdGlvbi9qc29uJyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnhoci5zZXRSZXF1ZXN0SGVhZGVyKCdKU05Mb2ctUmVxdWVzdElkJywgSkwucmVxdWVzdElkKTtcclxuICAgICAgICAgICAgICAgIHZhciB0aGF0ID0gdGhpcztcclxuICAgICAgICAgICAgICAgIHRoaXMueGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBPbiBtb3N0IGJyb3dzZXJzLCBpZiB0aGUgcmVxdWVzdCBmYWlscyAoZWcuIGludGVybmV0IGlzIGdvbmUpLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGl0IHdpbGwgc2V0IHhoci5yZWFkeVN0YXRlID09IDQgYW5kIHhoci5zdGF0dXMgIT0gMjAwICgwIGlmIHJlcXVlc3QgY291bGQgbm90IGJlIHNlbnQpIGltbWVkaWF0ZWx5LlxyXG4gICAgICAgICAgICAgICAgICAgIC8vIEhvd2V2ZXIsIEVkZ2UgYW5kIElFIHdpbGwgbm90IGNoYW5nZSB0aGUgcmVhZHlTdGF0ZSBhdCBhbGwgaWYgdGhlIGludGVybmV0IGdvZXMgYXdheSB3aGlsZSB3YWl0aW5nXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZm9yIGEgcmVzcG9uc2UuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gU29tZSBzZXJ2ZXJzIHdpbGwgcmV0dXJuIGEgMjA0IChzdWNjZXNzLCBubyBjb250ZW50KSB3aGVuIHRoZSBKU05Mb2cgZW5kcG9pbnRcclxuICAgICAgICAgICAgICAgICAgICAvLyByZXR1cm5zIHRoZSBlbXB0eSByZXNwb25zZS4gU28gY2hlY2sgb24gYW55IGNvZGUgaW4gdGhlIDIuLiByYW5nZSwgbm90IGp1c3QgMjAwLlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICgodGhhdC54aHIucmVhZHlTdGF0ZSA9PSA0KSAmJiAodGhhdC54aHIuc3RhdHVzID49IDIwMCAmJiB0aGF0Lnhoci5zdGF0dXMgPCAzMDApKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjaygpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB2YXIganNvbiA9IHtcclxuICAgICAgICAgICAgICAgICAgICByOiBKTC5yZXF1ZXN0SWQsXHJcbiAgICAgICAgICAgICAgICAgICAgbGc6IGxvZ0l0ZW1zXHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgLy8gY2FsbCBiZWZvcmVTZW5kIGNhbGxiYWNrXHJcbiAgICAgICAgICAgICAgICAvLyBmaXJzdCB0cnkgdGhlIGNhbGxiYWNrIG9uIHRoZSBhcHBlbmRlclxyXG4gICAgICAgICAgICAgICAgLy8gdGhlbiB0aGUgZ2xvYmFsIGRlZmF1bHRCZWZvcmVTZW5kIGNhbGxiYWNrXHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMuYmVmb3JlU2VuZCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYmVmb3JlU2VuZC5jYWxsKHRoaXMsIHRoaXMueGhyLCBqc29uKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBKTC5kZWZhdWx0QmVmb3JlU2VuZCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICAgICAgICAgIEpMLmRlZmF1bHRCZWZvcmVTZW5kLmNhbGwodGhpcywgdGhpcy54aHIsIGpzb24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIGZpbmFsbXNnID0gSlNPTi5zdHJpbmdpZnkoanNvbik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnhoci5zZW5kKGZpbmFsbXNnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXRjaCAoZSkgeyB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gQWpheEFwcGVuZGVyO1xyXG4gICAgfShBcHBlbmRlcikpO1xyXG4gICAgSkwuQWpheEFwcGVuZGVyID0gQWpheEFwcGVuZGVyO1xyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICB2YXIgQ29uc29sZUFwcGVuZGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgICAgIF9fZXh0ZW5kcyhDb25zb2xlQXBwZW5kZXIsIF9zdXBlcik7XHJcbiAgICAgICAgZnVuY3Rpb24gQ29uc29sZUFwcGVuZGVyKGFwcGVuZGVyTmFtZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gX3N1cGVyLmNhbGwodGhpcywgYXBwZW5kZXJOYW1lLCBDb25zb2xlQXBwZW5kZXIucHJvdG90eXBlLnNlbmRMb2dJdGVtc0NvbnNvbGUpIHx8IHRoaXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIENvbnNvbGVBcHBlbmRlci5wcm90b3R5cGUuY2xvZyA9IGZ1bmN0aW9uIChsb2dFbnRyeSkge1xyXG4gICAgICAgICAgICBKTC5fY29uc29sZS5sb2cobG9nRW50cnkpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgQ29uc29sZUFwcGVuZGVyLnByb3RvdHlwZS5jZXJyb3IgPSBmdW5jdGlvbiAobG9nRW50cnkpIHtcclxuICAgICAgICAgICAgaWYgKEpMLl9jb25zb2xlLmVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICBKTC5fY29uc29sZS5lcnJvcihsb2dFbnRyeSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNsb2cobG9nRW50cnkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBDb25zb2xlQXBwZW5kZXIucHJvdG90eXBlLmN3YXJuID0gZnVuY3Rpb24gKGxvZ0VudHJ5KSB7XHJcbiAgICAgICAgICAgIGlmIChKTC5fY29uc29sZS53YXJuKSB7XHJcbiAgICAgICAgICAgICAgICBKTC5fY29uc29sZS53YXJuKGxvZ0VudHJ5KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2xvZyhsb2dFbnRyeSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIENvbnNvbGVBcHBlbmRlci5wcm90b3R5cGUuY2luZm8gPSBmdW5jdGlvbiAobG9nRW50cnkpIHtcclxuICAgICAgICAgICAgaWYgKEpMLl9jb25zb2xlLmluZm8pIHtcclxuICAgICAgICAgICAgICAgIEpMLl9jb25zb2xlLmluZm8obG9nRW50cnkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jbG9nKGxvZ0VudHJ5KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgLy8gSUUxMSBoYXMgYSBjb25zb2xlLmRlYnVnIGZ1bmN0aW9uLiBCdXQgaXRzIGNvbnNvbGUgZG9lc24ndCBoYXZlIFxyXG4gICAgICAgIC8vIHRoZSBvcHRpb24gdG8gc2hvdy9oaWRlIGRlYnVnIG1lc3NhZ2VzICh0aGUgc2FtZSB3YXkgQ2hyb21lIGFuZCBGRiBkbyksXHJcbiAgICAgICAgLy8gZXZlbiB0aG91Z2ggaXQgZG9lcyBoYXZlIHN1Y2ggYnV0dG9ucyBmb3IgRXJyb3IsIFdhcm4sIEluZm8uXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBGb3Igbm93LCB0aGlzIG1lYW5zIHRoYXQgZGVidWcgbWVzc2FnZXMgY2FuIG5vdCBiZSBoaWRkZW4gb24gSUUuXHJcbiAgICAgICAgLy8gTGl2ZSB3aXRoIHRoaXMsIHNlZWluZyB0aGF0IGl0IHdvcmtzIGZpbmUgb24gRkYgYW5kIENocm9tZSwgd2hpY2hcclxuICAgICAgICAvLyB3aWxsIGJlIG11Y2ggbW9yZSBwb3B1bGFyIHdpdGggZGV2ZWxvcGVycy5cclxuICAgICAgICBDb25zb2xlQXBwZW5kZXIucHJvdG90eXBlLmNkZWJ1ZyA9IGZ1bmN0aW9uIChsb2dFbnRyeSkge1xyXG4gICAgICAgICAgICBpZiAoSkwuX2NvbnNvbGUuZGVidWcpIHtcclxuICAgICAgICAgICAgICAgIEpMLl9jb25zb2xlLmRlYnVnKGxvZ0VudHJ5KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2luZm8obG9nRW50cnkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBDb25zb2xlQXBwZW5kZXIucHJvdG90eXBlLnNlbmRMb2dJdGVtc0NvbnNvbGUgPSBmdW5jdGlvbiAobG9nSXRlbXMsIHN1Y2Nlc3NDYWxsYmFjaykge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgLy8gRG8gbm90IHNlbmQgbG9ncywgaWYgSkwuZW5hYmxlZCBpcyBzZXQgdG8gZmFsc2VcclxuICAgICAgICAgICAgICAgIC8vXHJcbiAgICAgICAgICAgICAgICAvLyBEbyBub3QgY2FsbCBzdWNjZXNzQ2FsbGJhY2sgaGVyZS4gQWZ0ZXIgZWFjaCB0aW1lb3V0LCBqc25sb2cgd2lsbCByZXRyeSBzZW5kaW5nIHRoZSBtZXNzYWdlLlxyXG4gICAgICAgICAgICAgICAgLy8gSWYganNubG9nIGdldHMgcmUtZW5hYmxlZCwgaXQgd2lsbCB0aGVuIGxvZyB0aGUgbnVtYmVyIG9mIG1lc3NhZ2VzIGxvZ2dlZC5cclxuICAgICAgICAgICAgICAgIC8vIElmIGl0IGRvZXNuJ3QgZ2V0IHJlLWVuYWJsZWQsIGFtb3VudCBvZiBjcHUgY3ljbGVzIHdhc3RlZCBpcyBtaW5pbWFsLlxyXG4gICAgICAgICAgICAgICAgaWYgKCFhbGxvdyh0aGlzKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmICghSkwuX2NvbnNvbGUpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB2YXIgaTtcclxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsb2dJdGVtcy5sZW5ndGg7ICsraSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBsaSA9IGxvZ0l0ZW1zW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtc2cgPSBsaS5uICsgXCI6IFwiICsgbGkubTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGxvZyB0aGUgdGltZXN0YW1wIGlmIHdlJ3JlIG9uIHRoZSBzZXJ2ZXJcclxuICAgICAgICAgICAgICAgICAgICAvLyAod2luZG93IGlzIHVuZGVmaW5lZCkuIE9uIHRoZSBicm93c2VyLCB0aGUgdXNlclxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHNlZXMgdGhlIGxvZyBlbnRyeSBwcm9iYWJseSBpbW1lZGlhdGVseSwgc28gaW4gdGhhdCBjYXNlXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIHRpbWVzdGFtcCBpcyBjbHV0dGVyLlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtc2cgPSBuZXcgRGF0ZShsaS50KSArIFwiIHwgXCIgKyBtc2c7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChsaS5sIDw9IEpMLmdldERlYnVnTGV2ZWwoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNkZWJ1Zyhtc2cpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChsaS5sIDw9IEpMLmdldEluZm9MZXZlbCgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2luZm8obXNnKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobGkubCA8PSBKTC5nZXRXYXJuTGV2ZWwoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN3YXJuKG1zZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNlcnJvcihtc2cpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjaygpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgcmV0dXJuIENvbnNvbGVBcHBlbmRlcjtcclxuICAgIH0oQXBwZW5kZXIpKTtcclxuICAgIEpMLkNvbnNvbGVBcHBlbmRlciA9IENvbnNvbGVBcHBlbmRlcjtcclxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICB2YXIgTG9nZ2VyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIExvZ2dlcihsb2dnZXJOYW1lKSB7XHJcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyTmFtZSA9IGxvZ2dlck5hbWU7XHJcbiAgICAgICAgICAgIC8vIENyZWF0ZSBzZWVuUmV4ZXMsIG90aGVyd2lzZSB0aGlzIGxvZ2dlciB3aWxsIHVzZSB0aGUgc2VlblJleGVzXHJcbiAgICAgICAgICAgIC8vIG9mIGl0cyBwYXJlbnQgdmlhIHRoZSBwcm90b3R5cGUgY2hhaW4uXHJcbiAgICAgICAgICAgIHRoaXMuc2VlblJlZ2V4ZXMgPSBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgTG9nZ2VyLnByb3RvdHlwZS5zZXRPcHRpb25zID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwibGV2ZWxcIiwgb3B0aW9ucywgdGhpcyk7XHJcbiAgICAgICAgICAgIGNvcHlQcm9wZXJ0eShcInVzZXJBZ2VudFJlZ2V4XCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJkaXNhbGxvd1wiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwiaXBSZWdleFwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgY29weVByb3BlcnR5KFwiYXBwZW5kZXJzXCIsIG9wdGlvbnMsIHRoaXMpO1xyXG4gICAgICAgICAgICBjb3B5UHJvcGVydHkoXCJvbmNlT25seVwiLCBvcHRpb25zLCB0aGlzKTtcclxuICAgICAgICAgICAgLy8gUmVzZXQgc2VlblJlZ2V4ZXMsIGluIGNhc2Ugb25jZU9ubHkgaGFzIGJlZW4gY2hhbmdlZC5cclxuICAgICAgICAgICAgdGhpcy5zZWVuUmVnZXhlcyA9IFtdO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIFR1cm5zIGFuIGV4Y2VwdGlvbiBpbnRvIGFuIG9iamVjdCB0aGF0IGNhbiBiZSBzZW50IHRvIHRoZSBzZXJ2ZXIuXHJcbiAgICAgICAgTG9nZ2VyLnByb3RvdHlwZS5idWlsZEV4Y2VwdGlvbk9iamVjdCA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIHZhciBleGNPYmplY3QgPSB7fTtcclxuICAgICAgICAgICAgaWYgKGUuc3RhY2spIHtcclxuICAgICAgICAgICAgICAgIGV4Y09iamVjdC5zdGFjayA9IGUuc3RhY2s7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBleGNPYmplY3QuZSA9IGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGUubWVzc2FnZSkge1xyXG4gICAgICAgICAgICAgICAgZXhjT2JqZWN0Lm1lc3NhZ2UgPSBlLm1lc3NhZ2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGUubmFtZSkge1xyXG4gICAgICAgICAgICAgICAgZXhjT2JqZWN0Lm5hbWUgPSBlLm5hbWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGUuZGF0YSkge1xyXG4gICAgICAgICAgICAgICAgZXhjT2JqZWN0LmRhdGEgPSBlLmRhdGE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGUuaW5uZXIpIHtcclxuICAgICAgICAgICAgICAgIGV4Y09iamVjdC5pbm5lciA9IHRoaXMuYnVpbGRFeGNlcHRpb25PYmplY3QoZS5pbm5lcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGV4Y09iamVjdDtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIExvZ3MgYSBsb2cgaXRlbS5cclxuICAgICAgICAvLyBQYXJhbWV0ZXIgZSBjb250YWlucyBhbiBleGNlcHRpb24gKG9yIG51bGwgb3IgdW5kZWZpbmVkKS5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIFJlYXNvbiB0aGF0IHByb2Nlc3NpbmcgZXhjZXB0aW9ucyBpcyBkb25lIGF0IHRoaXMgbG93IGxldmVsIGlzIHRoYXRcclxuICAgICAgICAvLyAxKSBubyBuZWVkIHRvIHNwZW5kIHRoZSBjcHUgY3ljbGVzIGlmIHRoZSBsb2dnZXIgaXMgc3dpdGNoZWQgb2ZmXHJcbiAgICAgICAgLy8gMikgZmF0YWxFeGNlcHRpb24gdGFrZXMgYm90aCBhIGxvZ09iamVjdCBhbmQgYW4gZXhjZXB0aW9uLCBhbmQgdGhlIGxvZ09iamVjdFxyXG4gICAgICAgIC8vICAgIG1heSBiZSBhIGZ1bmN0aW9uIHRoYXQgc2hvdWxkIG9ubHkgYmUgZXhlY3V0ZWQgaWYgdGhlIGxvZ2dlciBpcyBzd2l0Y2hlZCBvbi5cclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIElmIGFuIGV4Y2VwdGlvbiBpcyBwYXNzZWQgaW4sIHRoZSBjb250ZW50cyBvZiBsb2dPYmplY3QgaXMgYXR0YWNoZWQgdG8gdGhlIGV4Y2VwdGlvblxyXG4gICAgICAgIC8vIG9iamVjdCBpbiBhIG5ldyBwcm9wZXJ0eSBsb2dEYXRhLlxyXG4gICAgICAgIC8vIFRoZSByZXN1bHRpbmcgZXhjZXB0aW9uIG9iamVjdCBpcyB0aGFuIHdvcmtlZCBpbnRvIGEgbWVzc2FnZSB0byB0aGUgc2VydmVyLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gZXhjZXB0aW9uLCBsb2dPYmplY3QgaXRzZWxmIGlzIHdvcmtlZCBpbnRvIHRoZSBtZXNzYWdlIHRvIHRoZSBzZXJ2ZXIuXHJcbiAgICAgICAgTG9nZ2VyLnByb3RvdHlwZS5sb2cgPSBmdW5jdGlvbiAobGV2ZWwsIGxvZ09iamVjdCwgZSkge1xyXG4gICAgICAgICAgICB2YXIgaSA9IDA7XHJcbiAgICAgICAgICAgIHZhciBjb21wb3NpdGVNZXNzYWdlO1xyXG4gICAgICAgICAgICB2YXIgZXhjT2JqZWN0O1xyXG4gICAgICAgICAgICAvLyBJZiB3ZSBjYW4ndCBmaW5kIGFueSBhcHBlbmRlcnMsIGRvIG5vdGhpbmdcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmFwcGVuZGVycykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCgobGV2ZWwgPj0gdGhpcy5sZXZlbCkpICYmIGFsbG93KHRoaXMpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGV4Y09iamVjdCA9IHRoaXMuYnVpbGRFeGNlcHRpb25PYmplY3QoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgZXhjT2JqZWN0LmxvZ0RhdGEgPSBzdHJpbmdpZnlMb2dPYmplY3RGdW5jdGlvbihsb2dPYmplY3QpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXhjT2JqZWN0ID0gbG9nT2JqZWN0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgY29tcG9zaXRlTWVzc2FnZSA9IHN0cmluZ2lmeUxvZ09iamVjdChleGNPYmplY3QpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGFsbG93TWVzc2FnZSh0aGlzLCBjb21wb3NpdGVNZXNzYWdlLmZpbmFsU3RyaW5nKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFNlZSB3aGV0aGVyIG1lc3NhZ2UgaXMgYSBkdXBsaWNhdGVcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5vbmNlT25seSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpID0gdGhpcy5vbmNlT25seS5sZW5ndGggLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaSA+PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV3IFJlZ0V4cCh0aGlzLm9uY2VPbmx5W2ldKS50ZXN0KGNvbXBvc2l0ZU1lc3NhZ2UuZmluYWxTdHJpbmcpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2VlblJlZ2V4ZXNbaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VlblJlZ2V4ZXNbaV0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaS0tO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIFBhc3MgbWVzc2FnZSB0byBhbGwgYXBwZW5kZXJzXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gTm90ZSB0aGF0IHRoZXNlIGFwcGVuZGVycyBjb3VsZCBiZSBXaW5zdG9uIHRyYW5zcG9ydHNcclxuICAgICAgICAgICAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZmxhdGlyb24vd2luc3RvblxyXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvc2l0ZU1lc3NhZ2UubWV0YSA9IGNvbXBvc2l0ZU1lc3NhZ2UubWV0YSB8fCB7fTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBOb3RlIHRoYXQgaWYgdGhlIHVzZXIgaXMgbG9nZ2luZyBhbiBvYmplY3QsIGNvbXBvc2l0ZU1lc3NhZ2UubWV0YSB3aWxsIGhvbGQgYSByZWZlcmVuY2UgdG8gdGhhdCBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90IGFkZCBmaWVsZHMgdG8gY29tcG9zaXRlTWVzc2FnZS5tZXRhLCBvdGhlcndpc2UgdGhlIHVzZXIncyBvYmplY3Qgd2lsbCBnZXQgdGhhdCBmaWVsZCBvdXQgb2YgdGhlIGJsdWUuXHJcbiAgICAgICAgICAgICAgICAgICAgaSA9IHRoaXMuYXBwZW5kZXJzLmxlbmd0aCAtIDE7XHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGkgPj0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFwcGVuZGVyc1tpXS5sb2cobGV2ZWxUb1N0cmluZyhsZXZlbCksIGNvbXBvc2l0ZU1lc3NhZ2UubXNnLCBjb21wb3NpdGVNZXNzYWdlLm1ldGEsIGZ1bmN0aW9uICgpIHsgfSwgbGV2ZWwsIGNvbXBvc2l0ZU1lc3NhZ2UuZmluYWxTdHJpbmcsIHRoaXMubG9nZ2VyTmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGktLTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBMb2dnZXIucHJvdG90eXBlLnRyYWNlID0gZnVuY3Rpb24gKGxvZ09iamVjdCkgeyByZXR1cm4gdGhpcy5sb2coZ2V0VHJhY2VMZXZlbCgpLCBsb2dPYmplY3QpOyB9O1xyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUuZGVidWcgPSBmdW5jdGlvbiAobG9nT2JqZWN0KSB7IHJldHVybiB0aGlzLmxvZyhnZXREZWJ1Z0xldmVsKCksIGxvZ09iamVjdCk7IH07XHJcbiAgICAgICAgTG9nZ2VyLnByb3RvdHlwZS5pbmZvID0gZnVuY3Rpb24gKGxvZ09iamVjdCkgeyByZXR1cm4gdGhpcy5sb2coZ2V0SW5mb0xldmVsKCksIGxvZ09iamVjdCk7IH07XHJcbiAgICAgICAgTG9nZ2VyLnByb3RvdHlwZS53YXJuID0gZnVuY3Rpb24gKGxvZ09iamVjdCkgeyByZXR1cm4gdGhpcy5sb2coZ2V0V2FybkxldmVsKCksIGxvZ09iamVjdCk7IH07XHJcbiAgICAgICAgTG9nZ2VyLnByb3RvdHlwZS5lcnJvciA9IGZ1bmN0aW9uIChsb2dPYmplY3QpIHsgcmV0dXJuIHRoaXMubG9nKGdldEVycm9yTGV2ZWwoKSwgbG9nT2JqZWN0KTsgfTtcclxuICAgICAgICBMb2dnZXIucHJvdG90eXBlLmZhdGFsID0gZnVuY3Rpb24gKGxvZ09iamVjdCkgeyByZXR1cm4gdGhpcy5sb2coZ2V0RmF0YWxMZXZlbCgpLCBsb2dPYmplY3QpOyB9O1xyXG4gICAgICAgIExvZ2dlci5wcm90b3R5cGUuZmF0YWxFeGNlcHRpb24gPSBmdW5jdGlvbiAobG9nT2JqZWN0LCBlKSB7IHJldHVybiB0aGlzLmxvZyhnZXRGYXRhbExldmVsKCksIGxvZ09iamVjdCwgZSk7IH07XHJcbiAgICAgICAgcmV0dXJuIExvZ2dlcjtcclxuICAgIH0oKSk7XHJcbiAgICBKTC5Mb2dnZXIgPSBMb2dnZXI7XHJcbiAgICBmdW5jdGlvbiBjcmVhdGVBamF4QXBwZW5kZXIoYXBwZW5kZXJOYW1lKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBamF4QXBwZW5kZXIoYXBwZW5kZXJOYW1lKTtcclxuICAgIH1cclxuICAgIEpMLmNyZWF0ZUFqYXhBcHBlbmRlciA9IGNyZWF0ZUFqYXhBcHBlbmRlcjtcclxuICAgIGZ1bmN0aW9uIGNyZWF0ZUNvbnNvbGVBcHBlbmRlcihhcHBlbmRlck5hbWUpIHtcclxuICAgICAgICByZXR1cm4gbmV3IENvbnNvbGVBcHBlbmRlcihhcHBlbmRlck5hbWUpO1xyXG4gICAgfVxyXG4gICAgSkwuY3JlYXRlQ29uc29sZUFwcGVuZGVyID0gY3JlYXRlQ29uc29sZUFwcGVuZGVyO1xyXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAgIC8vIEluIHRoZSBicm93c2VyLCB0aGUgZGVmYXVsdCBhcHBlbmRlciBpcyB0aGUgQWpheEFwcGVuZGVyLlxyXG4gICAgLy8gVW5kZXIgbm9kZWpzICh3aGVyZSB0aGVyZSBpcyBubyBcIndpbmRvd1wiKSwgdXNlIHRoZSBDb25zb2xlQXBwZW5kZXIgaW5zdGVhZC5cclxuICAgIC8vIFxyXG4gICAgLy8gRG8gTk9UIGNyZWF0ZSBhbiBBamF4QXBwZW5kZXIgb2JqZWN0IGlmIHlvdSBhcmUgbm90IG9uIGEgYnJvd3NlciAodGhhdCBpcywgd2luZG93IGlzIG5vdCBkZWZpbmVkKS5cclxuICAgIC8vIFRoYXQgd291bGQgdHJ5IHRvIGNyZWF0ZSBhbiBYbWxIdHRwUmVxdWVzdCBvYmplY3QsIHdoaWNoIHdpbGwgY3Jhc2ggb3V0c2lkZSBhIGJyb3dzZXIuXHJcbiAgICB2YXIgZGVmYXVsdEFwcGVuZGVyO1xyXG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgZGVmYXVsdEFwcGVuZGVyID0gbmV3IEFqYXhBcHBlbmRlcihcIlwiKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIGRlZmF1bHRBcHBlbmRlciA9IG5ldyBDb25zb2xlQXBwZW5kZXIoXCJcIik7XHJcbiAgICB9XHJcbiAgICAvLyBDcmVhdGUgcm9vdCBsb2dnZXJcclxuICAgIC8vXHJcbiAgICAvLyBOb3RlIHRoYXQgdGhpcyBpcyB0aGUgcGFyZW50IG9mIGFsbCBvdGhlciBsb2dnZXJzLlxyXG4gICAgLy8gTG9nZ2VyIFwieFwiIHdpbGwgYmUgc3RvcmVkIGF0XHJcbiAgICAvLyBKTC5fXy54XHJcbiAgICAvLyBMb2dnZXIgXCJ4LnlcIiBhdFxyXG4gICAgLy8gSkwuX18ueC55XHJcbiAgICBKTC5fXyA9IG5ldyBKTC5Mb2dnZXIoXCJcIik7XHJcbiAgICBKTC5fXy5zZXRPcHRpb25zKHtcclxuICAgICAgICBsZXZlbDogSkwuZ2V0RGVidWdMZXZlbCgpLFxyXG4gICAgICAgIGFwcGVuZGVyczogW2RlZmF1bHRBcHBlbmRlcl1cclxuICAgIH0pO1xyXG59KShKTCB8fCAoSkwgPSB7fSkpO1xyXG5pZiAodHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAvLyBBbGxvd3MgU3lzdGVtSnMgdG8gaW1wb3J0IGpzbmxvZy5qcy4gU2VlXHJcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbXBlcmRlY2svanNubG9nLmpzL2lzc3Vlcy81NlxyXG4gICAgZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcclxuICAgIGV4cG9ydHMuSkwgPSBKTDtcclxufVxyXG4vLyBTdXBwb3J0IEFNRCBtb2R1bGUgZm9ybWF0XHJcbnZhciBkZWZpbmU7XHJcbmlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xyXG4gICAgZGVmaW5lKCdqc25sb2cnLCBbXSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBKTDtcclxuICAgIH0pO1xyXG59XHJcbi8vIElmIHRoZSBfX2pzbmxvZ19jb25maWd1cmUgZ2xvYmFsIGZ1bmN0aW9uIGhhcyBiZWVuXHJcbi8vIGNyZWF0ZWQsIGNhbGwgaXQgbm93LiBUaGlzIGFsbG93cyB5b3UgdG8gY3JlYXRlIGEgZ2xvYmFsIGZ1bmN0aW9uXHJcbi8vIHNldHRpbmcgbG9nZ2VyIG9wdGlvbnMgZXRjLiBpbmxpbmUgaW4gdGhlIHBhZ2UgYmVmb3JlIGpzbmxvZy5qc1xyXG4vLyBoYXMgYmVlbiBsb2FkZWQuXHJcbmlmICh0eXBlb2YgX19qc25sb2dfY29uZmlndXJlID09ICdmdW5jdGlvbicpIHtcclxuICAgIF9fanNubG9nX2NvbmZpZ3VyZShKTCk7XHJcbn1cclxuLy8gQ3JlYXRlIG9uZXJyb3IgaGFuZGxlciB0byBsb2cgdW5jYXVnaHQgZXhjZXB0aW9ucyB0byB0aGUgc2VydmVyIHNpZGUgbG9nLCBidXQgb25seSBpZiB0aGVyZSBcclxuLy8gaXMgbm8gc3VjaCBoYW5kbGVyIGFscmVhZHkuXHJcbi8vIE11c3QgdXNlIFwidHlwZW9mIHdpbmRvd1wiIGhlcmUsIGJlY2F1c2UgaW4gTm9kZUpzLCB3aW5kb3cgaXMgbm90IGRlZmluZWQgYXQgYWxsLCBzbyBjYW5ub3QgcmVmZXIgdG8gd2luZG93IGluIGFueSB3YXkuXHJcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiAhd2luZG93Lm9uZXJyb3IpIHtcclxuICAgIHdpbmRvdy5vbmVycm9yID0gZnVuY3Rpb24gKGVycm9yTXNnLCB1cmwsIGxpbmVOdW1iZXIsIGNvbHVtbiwgZXJyb3JPYmopIHtcclxuICAgICAgICAvLyBTZW5kIG9iamVjdCB3aXRoIGFsbCBkYXRhIHRvIHNlcnZlciBzaWRlIGxvZywgdXNpbmcgc2V2ZXJpdHkgZmF0YWwsIFxyXG4gICAgICAgIC8vIGZyb20gbG9nZ2VyIFwib25lcnJvckxvZ2dlclwiXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBVc2UgZXJyb3JNc2cubWVzc2FnZSBpZiBhdmFpbGFibGUsIHNvIEFuZ3VsYXIgNCB0ZW1wbGF0ZSBlcnJvcnMgd2lsbCBiZSBsb2dnZWQuXHJcbiAgICAgICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9tcGVyZGVjay9qc25sb2cuanMvcHVsbC82OFxyXG4gICAgICAgIEpMKFwib25lcnJvckxvZ2dlclwiKS5mYXRhbEV4Y2VwdGlvbih7XHJcbiAgICAgICAgICAgIFwibXNnXCI6IFwiVW5jYXVnaHQgRXhjZXB0aW9uXCIsXHJcbiAgICAgICAgICAgIFwiZXJyb3JNc2dcIjogZXJyb3JNc2cgPyAoZXJyb3JNc2cubWVzc2FnZSB8fCBlcnJvck1zZykgOiAnJyxcclxuICAgICAgICAgICAgXCJ1cmxcIjogdXJsLFxyXG4gICAgICAgICAgICBcImxpbmUgbnVtYmVyXCI6IGxpbmVOdW1iZXIsIFwiY29sdW1uXCI6IGNvbHVtblxyXG4gICAgICAgIH0sIGVycm9yT2JqKTtcclxuICAgICAgICAvLyBUZWxsIGJyb3dzZXIgdG8gcnVuIGl0cyBvd24gZXJyb3IgaGFuZGxlciBhcyB3ZWxsICAgXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfTtcclxufVxyXG4vLyBEZWFsIHdpdGggdW5oYW5kbGVkIGV4Y2VwdGlvbnMgdGhyb3duIGluIHByb21pc2VzXHJcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiAhd2luZG93Lm9udW5oYW5kbGVkcmVqZWN0aW9uKSB7XHJcbiAgICB3aW5kb3cub251bmhhbmRsZWRyZWplY3Rpb24gPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAvLyBTZW5kIG9iamVjdCB3aXRoIGFsbCBkYXRhIHRvIHNlcnZlciBzaWRlIGxvZywgdXNpbmcgc2V2ZXJpdHkgZmF0YWwsIFxyXG4gICAgICAgIC8vIGZyb20gbG9nZ2VyIFwib25lcnJvckxvZ2dlclwiLlxyXG4gICAgICAgIC8vIE5lZWQgdG8gY2hlY2sgYm90aCBldmVudC5yZWFzb24ubWVzc2FnZSBhbmQgZXZlbnQubWVzc2FnZSxcclxuICAgICAgICAvLyBiZWNhdXNlIFN5c3RlbUpzIHdyYXBzIGV4Y2VwdGlvbnMgYW5kIHRocm93cyBhIG5ldyBvYmplY3Qgd2hpY2ggZG9lc24ndCBoYXZlIGEgcmVhc29uIHByb3BlcnR5LlxyXG4gICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vc3lzdGVtanMvc3lzdGVtanMvaXNzdWVzLzEzMDlcclxuICAgICAgICBKTChcIm9uZXJyb3JMb2dnZXJcIikuZmF0YWxFeGNlcHRpb24oe1xyXG4gICAgICAgICAgICBcIm1zZ1wiOiBcInVuaGFuZGxlZHJlamVjdGlvblwiLFxyXG4gICAgICAgICAgICBcImVycm9yTXNnXCI6IGV2ZW50LnJlYXNvbiA/IGV2ZW50LnJlYXNvbi5tZXNzYWdlIDogZXZlbnQubWVzc2FnZSB8fCBudWxsXHJcbiAgICAgICAgfSwgZXZlbnQucmVhc29uKTtcclxuICAgIH07XHJcbn1cclxuIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIEBwYXJhbSB0eXBlTWFwIFtPYmplY3RdIE1hcCBvZiBNSU1FIHR5cGUgLT4gQXJyYXlbZXh0ZW5zaW9uc11cbiAqIEBwYXJhbSAuLi5cbiAqL1xuZnVuY3Rpb24gTWltZSgpIHtcbiAgdGhpcy5fdHlwZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICB0aGlzLl9leHRlbnNpb25zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHRoaXMuZGVmaW5lKGFyZ3VtZW50c1tpXSk7XG4gIH1cblxuICB0aGlzLmRlZmluZSA9IHRoaXMuZGVmaW5lLmJpbmQodGhpcyk7XG4gIHRoaXMuZ2V0VHlwZSA9IHRoaXMuZ2V0VHlwZS5iaW5kKHRoaXMpO1xuICB0aGlzLmdldEV4dGVuc2lvbiA9IHRoaXMuZ2V0RXh0ZW5zaW9uLmJpbmQodGhpcyk7XG59XG5cbi8qKlxuICogRGVmaW5lIG1pbWV0eXBlIC0+IGV4dGVuc2lvbiBtYXBwaW5ncy4gIEVhY2gga2V5IGlzIGEgbWltZS10eXBlIHRoYXQgbWFwc1xuICogdG8gYW4gYXJyYXkgb2YgZXh0ZW5zaW9ucyBhc3NvY2lhdGVkIHdpdGggdGhlIHR5cGUuICBUaGUgZmlyc3QgZXh0ZW5zaW9uIGlzXG4gKiB1c2VkIGFzIHRoZSBkZWZhdWx0IGV4dGVuc2lvbiBmb3IgdGhlIHR5cGUuXG4gKlxuICogZS5nLiBtaW1lLmRlZmluZSh7J2F1ZGlvL29nZycsIFsnb2dhJywgJ29nZycsICdzcHgnXX0pO1xuICpcbiAqIElmIGEgdHlwZSBkZWNsYXJlcyBhbiBleHRlbnNpb24gdGhhdCBoYXMgYWxyZWFkeSBiZWVuIGRlZmluZWQsIGFuIGVycm9yIHdpbGxcbiAqIGJlIHRocm93bi4gIFRvIHN1cHByZXNzIHRoaXMgZXJyb3IgYW5kIGZvcmNlIHRoZSBleHRlbnNpb24gdG8gYmUgYXNzb2NpYXRlZFxuICogd2l0aCB0aGUgbmV3IHR5cGUsIHBhc3MgYGZvcmNlYD10cnVlLiAgQWx0ZXJuYXRpdmVseSwgeW91IG1heSBwcmVmaXggdGhlXG4gKiBleHRlbnNpb24gd2l0aCBcIipcIiB0byBtYXAgdGhlIHR5cGUgdG8gZXh0ZW5zaW9uLCB3aXRob3V0IG1hcHBpbmcgdGhlXG4gKiBleHRlbnNpb24gdG8gdGhlIHR5cGUuXG4gKlxuICogZS5nLiBtaW1lLmRlZmluZSh7J2F1ZGlvL3dhdicsIFsnd2F2J119LCB7J2F1ZGlvL3gtd2F2JywgWycqd2F2J119KTtcbiAqXG4gKlxuICogQHBhcmFtIG1hcCAoT2JqZWN0KSB0eXBlIGRlZmluaXRpb25zXG4gKiBAcGFyYW0gZm9yY2UgKEJvb2xlYW4pIGlmIHRydWUsIGZvcmNlIG92ZXJyaWRpbmcgb2YgZXhpc3RpbmcgZGVmaW5pdGlvbnNcbiAqL1xuTWltZS5wcm90b3R5cGUuZGVmaW5lID0gZnVuY3Rpb24odHlwZU1hcCwgZm9yY2UpIHtcbiAgZm9yIChsZXQgdHlwZSBpbiB0eXBlTWFwKSB7XG4gICAgbGV0IGV4dGVuc2lvbnMgPSB0eXBlTWFwW3R5cGVdLm1hcChmdW5jdGlvbih0KSB7XG4gICAgICByZXR1cm4gdC50b0xvd2VyQ2FzZSgpO1xuICAgIH0pO1xuICAgIHR5cGUgPSB0eXBlLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4dGVuc2lvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGV4dCA9IGV4dGVuc2lvbnNbaV07XG5cbiAgICAgIC8vICcqJyBwcmVmaXggPSBub3QgdGhlIHByZWZlcnJlZCB0eXBlIGZvciB0aGlzIGV4dGVuc2lvbi4gIFNvIGZpeHVwIHRoZVxuICAgICAgLy8gZXh0ZW5zaW9uLCBhbmQgc2tpcCBpdC5cbiAgICAgIGlmIChleHRbMF0gPT09ICcqJykge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFmb3JjZSAmJiAoZXh0IGluIHRoaXMuX3R5cGVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ0F0dGVtcHQgdG8gY2hhbmdlIG1hcHBpbmcgZm9yIFwiJyArIGV4dCArXG4gICAgICAgICAgJ1wiIGV4dGVuc2lvbiBmcm9tIFwiJyArIHRoaXMuX3R5cGVzW2V4dF0gKyAnXCIgdG8gXCInICsgdHlwZSArXG4gICAgICAgICAgJ1wiLiBQYXNzIGBmb3JjZT10cnVlYCB0byBhbGxvdyB0aGlzLCBvdGhlcndpc2UgcmVtb3ZlIFwiJyArIGV4dCArXG4gICAgICAgICAgJ1wiIGZyb20gdGhlIGxpc3Qgb2YgZXh0ZW5zaW9ucyBmb3IgXCInICsgdHlwZSArICdcIi4nXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3R5cGVzW2V4dF0gPSB0eXBlO1xuICAgIH1cblxuICAgIC8vIFVzZSBmaXJzdCBleHRlbnNpb24gYXMgZGVmYXVsdFxuICAgIGlmIChmb3JjZSB8fCAhdGhpcy5fZXh0ZW5zaW9uc1t0eXBlXSkge1xuICAgICAgY29uc3QgZXh0ID0gZXh0ZW5zaW9uc1swXTtcbiAgICAgIHRoaXMuX2V4dGVuc2lvbnNbdHlwZV0gPSAoZXh0WzBdICE9PSAnKicpID8gZXh0IDogZXh0LnN1YnN0cigxKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogTG9va3VwIGEgbWltZSB0eXBlIGJhc2VkIG9uIGV4dGVuc2lvblxuICovXG5NaW1lLnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24ocGF0aCkge1xuICBwYXRoID0gU3RyaW5nKHBhdGgpO1xuICBsZXQgbGFzdCA9IHBhdGgucmVwbGFjZSgvXi4qWy9cXFxcXS8sICcnKS50b0xvd2VyQ2FzZSgpO1xuICBsZXQgZXh0ID0gbGFzdC5yZXBsYWNlKC9eLipcXC4vLCAnJykudG9Mb3dlckNhc2UoKTtcblxuICBsZXQgaGFzUGF0aCA9IGxhc3QubGVuZ3RoIDwgcGF0aC5sZW5ndGg7XG4gIGxldCBoYXNEb3QgPSBleHQubGVuZ3RoIDwgbGFzdC5sZW5ndGggLSAxO1xuXG4gIHJldHVybiAoaGFzRG90IHx8ICFoYXNQYXRoKSAmJiB0aGlzLl90eXBlc1tleHRdIHx8IG51bGw7XG59O1xuXG4vKipcbiAqIFJldHVybiBmaWxlIGV4dGVuc2lvbiBhc3NvY2lhdGVkIHdpdGggYSBtaW1lIHR5cGVcbiAqL1xuTWltZS5wcm90b3R5cGUuZ2V0RXh0ZW5zaW9uID0gZnVuY3Rpb24odHlwZSkge1xuICB0eXBlID0gL15cXHMqKFteO1xcc10qKS8udGVzdCh0eXBlKSAmJiBSZWdFeHAuJDE7XG4gIHJldHVybiB0eXBlICYmIHRoaXMuX2V4dGVuc2lvbnNbdHlwZS50b0xvd2VyQ2FzZSgpXSB8fCBudWxsO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBNaW1lO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5sZXQgTWltZSA9IHJlcXVpcmUoJy4vTWltZScpO1xubW9kdWxlLmV4cG9ydHMgPSBuZXcgTWltZShyZXF1aXJlKCcuL3R5cGVzL3N0YW5kYXJkJykpO1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XCJhcHBsaWNhdGlvbi9hbmRyZXctaW5zZXRcIjpbXCJlelwiXSxcImFwcGxpY2F0aW9uL2FwcGxpeHdhcmVcIjpbXCJhd1wiXSxcImFwcGxpY2F0aW9uL2F0b20reG1sXCI6W1wiYXRvbVwiXSxcImFwcGxpY2F0aW9uL2F0b21jYXQreG1sXCI6W1wiYXRvbWNhdFwiXSxcImFwcGxpY2F0aW9uL2F0b21kZWxldGVkK3htbFwiOltcImF0b21kZWxldGVkXCJdLFwiYXBwbGljYXRpb24vYXRvbXN2Yyt4bWxcIjpbXCJhdG9tc3ZjXCJdLFwiYXBwbGljYXRpb24vYXRzYy1kd2QreG1sXCI6W1wiZHdkXCJdLFwiYXBwbGljYXRpb24vYXRzYy1oZWxkK3htbFwiOltcImhlbGRcIl0sXCJhcHBsaWNhdGlvbi9hdHNjLXJzYXQreG1sXCI6W1wicnNhdFwiXSxcImFwcGxpY2F0aW9uL2Jkb2NcIjpbXCJiZG9jXCJdLFwiYXBwbGljYXRpb24vY2FsZW5kYXIreG1sXCI6W1wieGNzXCJdLFwiYXBwbGljYXRpb24vY2N4bWwreG1sXCI6W1wiY2N4bWxcIl0sXCJhcHBsaWNhdGlvbi9jZGZ4K3htbFwiOltcImNkZnhcIl0sXCJhcHBsaWNhdGlvbi9jZG1pLWNhcGFiaWxpdHlcIjpbXCJjZG1pYVwiXSxcImFwcGxpY2F0aW9uL2NkbWktY29udGFpbmVyXCI6W1wiY2RtaWNcIl0sXCJhcHBsaWNhdGlvbi9jZG1pLWRvbWFpblwiOltcImNkbWlkXCJdLFwiYXBwbGljYXRpb24vY2RtaS1vYmplY3RcIjpbXCJjZG1pb1wiXSxcImFwcGxpY2F0aW9uL2NkbWktcXVldWVcIjpbXCJjZG1pcVwiXSxcImFwcGxpY2F0aW9uL2N1LXNlZW1lXCI6W1wiY3VcIl0sXCJhcHBsaWNhdGlvbi9kYXNoK3htbFwiOltcIm1wZFwiXSxcImFwcGxpY2F0aW9uL2Rhdm1vdW50K3htbFwiOltcImRhdm1vdW50XCJdLFwiYXBwbGljYXRpb24vZG9jYm9vayt4bWxcIjpbXCJkYmtcIl0sXCJhcHBsaWNhdGlvbi9kc3NjK2RlclwiOltcImRzc2NcIl0sXCJhcHBsaWNhdGlvbi9kc3NjK3htbFwiOltcInhkc3NjXCJdLFwiYXBwbGljYXRpb24vZWNtYXNjcmlwdFwiOltcImVzXCIsXCJlY21hXCJdLFwiYXBwbGljYXRpb24vZW1tYSt4bWxcIjpbXCJlbW1hXCJdLFwiYXBwbGljYXRpb24vZW1vdGlvbm1sK3htbFwiOltcImVtb3Rpb25tbFwiXSxcImFwcGxpY2F0aW9uL2VwdWIremlwXCI6W1wiZXB1YlwiXSxcImFwcGxpY2F0aW9uL2V4aVwiOltcImV4aVwiXSxcImFwcGxpY2F0aW9uL2V4cHJlc3NcIjpbXCJleHBcIl0sXCJhcHBsaWNhdGlvbi9mZHQreG1sXCI6W1wiZmR0XCJdLFwiYXBwbGljYXRpb24vZm9udC10ZHBmclwiOltcInBmclwiXSxcImFwcGxpY2F0aW9uL2dlbytqc29uXCI6W1wiZ2VvanNvblwiXSxcImFwcGxpY2F0aW9uL2dtbCt4bWxcIjpbXCJnbWxcIl0sXCJhcHBsaWNhdGlvbi9ncHgreG1sXCI6W1wiZ3B4XCJdLFwiYXBwbGljYXRpb24vZ3hmXCI6W1wiZ3hmXCJdLFwiYXBwbGljYXRpb24vZ3ppcFwiOltcImd6XCJdLFwiYXBwbGljYXRpb24vaGpzb25cIjpbXCJoanNvblwiXSxcImFwcGxpY2F0aW9uL2h5cGVyc3R1ZGlvXCI6W1wic3RrXCJdLFwiYXBwbGljYXRpb24vaW5rbWwreG1sXCI6W1wiaW5rXCIsXCJpbmttbFwiXSxcImFwcGxpY2F0aW9uL2lwZml4XCI6W1wiaXBmaXhcIl0sXCJhcHBsaWNhdGlvbi9pdHMreG1sXCI6W1wiaXRzXCJdLFwiYXBwbGljYXRpb24vamF2YS1hcmNoaXZlXCI6W1wiamFyXCIsXCJ3YXJcIixcImVhclwiXSxcImFwcGxpY2F0aW9uL2phdmEtc2VyaWFsaXplZC1vYmplY3RcIjpbXCJzZXJcIl0sXCJhcHBsaWNhdGlvbi9qYXZhLXZtXCI6W1wiY2xhc3NcIl0sXCJhcHBsaWNhdGlvbi9qYXZhc2NyaXB0XCI6W1wianNcIixcIm1qc1wiXSxcImFwcGxpY2F0aW9uL2pzb25cIjpbXCJqc29uXCIsXCJtYXBcIl0sXCJhcHBsaWNhdGlvbi9qc29uNVwiOltcImpzb241XCJdLFwiYXBwbGljYXRpb24vanNvbm1sK2pzb25cIjpbXCJqc29ubWxcIl0sXCJhcHBsaWNhdGlvbi9sZCtqc29uXCI6W1wianNvbmxkXCJdLFwiYXBwbGljYXRpb24vbGdyK3htbFwiOltcImxnclwiXSxcImFwcGxpY2F0aW9uL2xvc3QreG1sXCI6W1wibG9zdHhtbFwiXSxcImFwcGxpY2F0aW9uL21hYy1iaW5oZXg0MFwiOltcImhxeFwiXSxcImFwcGxpY2F0aW9uL21hYy1jb21wYWN0cHJvXCI6W1wiY3B0XCJdLFwiYXBwbGljYXRpb24vbWFkcyt4bWxcIjpbXCJtYWRzXCJdLFwiYXBwbGljYXRpb24vbWFuaWZlc3QranNvblwiOltcIndlYm1hbmlmZXN0XCJdLFwiYXBwbGljYXRpb24vbWFyY1wiOltcIm1yY1wiXSxcImFwcGxpY2F0aW9uL21hcmN4bWwreG1sXCI6W1wibXJjeFwiXSxcImFwcGxpY2F0aW9uL21hdGhlbWF0aWNhXCI6W1wibWFcIixcIm5iXCIsXCJtYlwiXSxcImFwcGxpY2F0aW9uL21hdGhtbCt4bWxcIjpbXCJtYXRobWxcIl0sXCJhcHBsaWNhdGlvbi9tYm94XCI6W1wibWJveFwiXSxcImFwcGxpY2F0aW9uL21lZGlhc2VydmVyY29udHJvbCt4bWxcIjpbXCJtc2NtbFwiXSxcImFwcGxpY2F0aW9uL21ldGFsaW5rK3htbFwiOltcIm1ldGFsaW5rXCJdLFwiYXBwbGljYXRpb24vbWV0YWxpbms0K3htbFwiOltcIm1ldGE0XCJdLFwiYXBwbGljYXRpb24vbWV0cyt4bWxcIjpbXCJtZXRzXCJdLFwiYXBwbGljYXRpb24vbW10LWFlaSt4bWxcIjpbXCJtYWVpXCJdLFwiYXBwbGljYXRpb24vbW10LXVzZCt4bWxcIjpbXCJtdXNkXCJdLFwiYXBwbGljYXRpb24vbW9kcyt4bWxcIjpbXCJtb2RzXCJdLFwiYXBwbGljYXRpb24vbXAyMVwiOltcIm0yMVwiLFwibXAyMVwiXSxcImFwcGxpY2F0aW9uL21wNFwiOltcIm1wNHNcIixcIm00cFwiXSxcImFwcGxpY2F0aW9uL21zd29yZFwiOltcImRvY1wiLFwiZG90XCJdLFwiYXBwbGljYXRpb24vbXhmXCI6W1wibXhmXCJdLFwiYXBwbGljYXRpb24vbi1xdWFkc1wiOltcIm5xXCJdLFwiYXBwbGljYXRpb24vbi10cmlwbGVzXCI6W1wibnRcIl0sXCJhcHBsaWNhdGlvbi9ub2RlXCI6W1wiY2pzXCJdLFwiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXCI6W1wiYmluXCIsXCJkbXNcIixcImxyZlwiLFwibWFyXCIsXCJzb1wiLFwiZGlzdFwiLFwiZGlzdHpcIixcInBrZ1wiLFwiYnBrXCIsXCJkdW1wXCIsXCJlbGNcIixcImRlcGxveVwiLFwiZXhlXCIsXCJkbGxcIixcImRlYlwiLFwiZG1nXCIsXCJpc29cIixcImltZ1wiLFwibXNpXCIsXCJtc3BcIixcIm1zbVwiLFwiYnVmZmVyXCJdLFwiYXBwbGljYXRpb24vb2RhXCI6W1wib2RhXCJdLFwiYXBwbGljYXRpb24vb2VicHMtcGFja2FnZSt4bWxcIjpbXCJvcGZcIl0sXCJhcHBsaWNhdGlvbi9vZ2dcIjpbXCJvZ3hcIl0sXCJhcHBsaWNhdGlvbi9vbWRvYyt4bWxcIjpbXCJvbWRvY1wiXSxcImFwcGxpY2F0aW9uL29uZW5vdGVcIjpbXCJvbmV0b2NcIixcIm9uZXRvYzJcIixcIm9uZXRtcFwiLFwib25lcGtnXCJdLFwiYXBwbGljYXRpb24vb3hwc1wiOltcIm94cHNcIl0sXCJhcHBsaWNhdGlvbi9wMnAtb3ZlcmxheSt4bWxcIjpbXCJyZWxvXCJdLFwiYXBwbGljYXRpb24vcGF0Y2gtb3BzLWVycm9yK3htbFwiOltcInhlclwiXSxcImFwcGxpY2F0aW9uL3BkZlwiOltcInBkZlwiXSxcImFwcGxpY2F0aW9uL3BncC1lbmNyeXB0ZWRcIjpbXCJwZ3BcIl0sXCJhcHBsaWNhdGlvbi9wZ3Atc2lnbmF0dXJlXCI6W1wiYXNjXCIsXCJzaWdcIl0sXCJhcHBsaWNhdGlvbi9waWNzLXJ1bGVzXCI6W1wicHJmXCJdLFwiYXBwbGljYXRpb24vcGtjczEwXCI6W1wicDEwXCJdLFwiYXBwbGljYXRpb24vcGtjczctbWltZVwiOltcInA3bVwiLFwicDdjXCJdLFwiYXBwbGljYXRpb24vcGtjczctc2lnbmF0dXJlXCI6W1wicDdzXCJdLFwiYXBwbGljYXRpb24vcGtjczhcIjpbXCJwOFwiXSxcImFwcGxpY2F0aW9uL3BraXgtYXR0ci1jZXJ0XCI6W1wiYWNcIl0sXCJhcHBsaWNhdGlvbi9wa2l4LWNlcnRcIjpbXCJjZXJcIl0sXCJhcHBsaWNhdGlvbi9wa2l4LWNybFwiOltcImNybFwiXSxcImFwcGxpY2F0aW9uL3BraXgtcGtpcGF0aFwiOltcInBraXBhdGhcIl0sXCJhcHBsaWNhdGlvbi9wa2l4Y21wXCI6W1wicGtpXCJdLFwiYXBwbGljYXRpb24vcGxzK3htbFwiOltcInBsc1wiXSxcImFwcGxpY2F0aW9uL3Bvc3RzY3JpcHRcIjpbXCJhaVwiLFwiZXBzXCIsXCJwc1wiXSxcImFwcGxpY2F0aW9uL3Byb3ZlbmFuY2UreG1sXCI6W1wicHJvdnhcIl0sXCJhcHBsaWNhdGlvbi9wc2tjK3htbFwiOltcInBza2N4bWxcIl0sXCJhcHBsaWNhdGlvbi9yYW1sK3lhbWxcIjpbXCJyYW1sXCJdLFwiYXBwbGljYXRpb24vcmRmK3htbFwiOltcInJkZlwiLFwib3dsXCJdLFwiYXBwbGljYXRpb24vcmVnaW5mbyt4bWxcIjpbXCJyaWZcIl0sXCJhcHBsaWNhdGlvbi9yZWxheC1uZy1jb21wYWN0LXN5bnRheFwiOltcInJuY1wiXSxcImFwcGxpY2F0aW9uL3Jlc291cmNlLWxpc3RzK3htbFwiOltcInJsXCJdLFwiYXBwbGljYXRpb24vcmVzb3VyY2UtbGlzdHMtZGlmZit4bWxcIjpbXCJybGRcIl0sXCJhcHBsaWNhdGlvbi9ybHMtc2VydmljZXMreG1sXCI6W1wicnNcIl0sXCJhcHBsaWNhdGlvbi9yb3V0ZS1hcGQreG1sXCI6W1wicmFwZFwiXSxcImFwcGxpY2F0aW9uL3JvdXRlLXMtdHNpZCt4bWxcIjpbXCJzbHNcIl0sXCJhcHBsaWNhdGlvbi9yb3V0ZS11c2QreG1sXCI6W1wicnVzZFwiXSxcImFwcGxpY2F0aW9uL3Jwa2ktZ2hvc3RidXN0ZXJzXCI6W1wiZ2JyXCJdLFwiYXBwbGljYXRpb24vcnBraS1tYW5pZmVzdFwiOltcIm1mdFwiXSxcImFwcGxpY2F0aW9uL3Jwa2ktcm9hXCI6W1wicm9hXCJdLFwiYXBwbGljYXRpb24vcnNkK3htbFwiOltcInJzZFwiXSxcImFwcGxpY2F0aW9uL3Jzcyt4bWxcIjpbXCJyc3NcIl0sXCJhcHBsaWNhdGlvbi9ydGZcIjpbXCJydGZcIl0sXCJhcHBsaWNhdGlvbi9zYm1sK3htbFwiOltcInNibWxcIl0sXCJhcHBsaWNhdGlvbi9zY3ZwLWN2LXJlcXVlc3RcIjpbXCJzY3FcIl0sXCJhcHBsaWNhdGlvbi9zY3ZwLWN2LXJlc3BvbnNlXCI6W1wic2NzXCJdLFwiYXBwbGljYXRpb24vc2N2cC12cC1yZXF1ZXN0XCI6W1wic3BxXCJdLFwiYXBwbGljYXRpb24vc2N2cC12cC1yZXNwb25zZVwiOltcInNwcFwiXSxcImFwcGxpY2F0aW9uL3NkcFwiOltcInNkcFwiXSxcImFwcGxpY2F0aW9uL3Nlbm1sK3htbFwiOltcInNlbm1seFwiXSxcImFwcGxpY2F0aW9uL3NlbnNtbCt4bWxcIjpbXCJzZW5zbWx4XCJdLFwiYXBwbGljYXRpb24vc2V0LXBheW1lbnQtaW5pdGlhdGlvblwiOltcInNldHBheVwiXSxcImFwcGxpY2F0aW9uL3NldC1yZWdpc3RyYXRpb24taW5pdGlhdGlvblwiOltcInNldHJlZ1wiXSxcImFwcGxpY2F0aW9uL3NoZit4bWxcIjpbXCJzaGZcIl0sXCJhcHBsaWNhdGlvbi9zaWV2ZVwiOltcInNpdlwiLFwic2lldmVcIl0sXCJhcHBsaWNhdGlvbi9zbWlsK3htbFwiOltcInNtaVwiLFwic21pbFwiXSxcImFwcGxpY2F0aW9uL3NwYXJxbC1xdWVyeVwiOltcInJxXCJdLFwiYXBwbGljYXRpb24vc3BhcnFsLXJlc3VsdHMreG1sXCI6W1wic3J4XCJdLFwiYXBwbGljYXRpb24vc3Jnc1wiOltcImdyYW1cIl0sXCJhcHBsaWNhdGlvbi9zcmdzK3htbFwiOltcImdyeG1sXCJdLFwiYXBwbGljYXRpb24vc3J1K3htbFwiOltcInNydVwiXSxcImFwcGxpY2F0aW9uL3NzZGwreG1sXCI6W1wic3NkbFwiXSxcImFwcGxpY2F0aW9uL3NzbWwreG1sXCI6W1wic3NtbFwiXSxcImFwcGxpY2F0aW9uL3N3aWQreG1sXCI6W1wic3dpZHRhZ1wiXSxcImFwcGxpY2F0aW9uL3RlaSt4bWxcIjpbXCJ0ZWlcIixcInRlaWNvcnB1c1wiXSxcImFwcGxpY2F0aW9uL3RocmF1ZCt4bWxcIjpbXCJ0ZmlcIl0sXCJhcHBsaWNhdGlvbi90aW1lc3RhbXBlZC1kYXRhXCI6W1widHNkXCJdLFwiYXBwbGljYXRpb24vdG9tbFwiOltcInRvbWxcIl0sXCJhcHBsaWNhdGlvbi90cmlnXCI6W1widHJpZ1wiXSxcImFwcGxpY2F0aW9uL3R0bWwreG1sXCI6W1widHRtbFwiXSxcImFwcGxpY2F0aW9uL3VianNvblwiOltcInVialwiXSxcImFwcGxpY2F0aW9uL3VyYy1yZXNzaGVldCt4bWxcIjpbXCJyc2hlZXRcIl0sXCJhcHBsaWNhdGlvbi91cmMtdGFyZ2V0ZGVzYyt4bWxcIjpbXCJ0ZFwiXSxcImFwcGxpY2F0aW9uL3ZvaWNleG1sK3htbFwiOltcInZ4bWxcIl0sXCJhcHBsaWNhdGlvbi93YXNtXCI6W1wid2FzbVwiXSxcImFwcGxpY2F0aW9uL3dpZGdldFwiOltcIndndFwiXSxcImFwcGxpY2F0aW9uL3dpbmhscFwiOltcImhscFwiXSxcImFwcGxpY2F0aW9uL3dzZGwreG1sXCI6W1wid3NkbFwiXSxcImFwcGxpY2F0aW9uL3dzcG9saWN5K3htbFwiOltcIndzcG9saWN5XCJdLFwiYXBwbGljYXRpb24veGFtbCt4bWxcIjpbXCJ4YW1sXCJdLFwiYXBwbGljYXRpb24veGNhcC1hdHQreG1sXCI6W1wieGF2XCJdLFwiYXBwbGljYXRpb24veGNhcC1jYXBzK3htbFwiOltcInhjYVwiXSxcImFwcGxpY2F0aW9uL3hjYXAtZGlmZit4bWxcIjpbXCJ4ZGZcIl0sXCJhcHBsaWNhdGlvbi94Y2FwLWVsK3htbFwiOltcInhlbFwiXSxcImFwcGxpY2F0aW9uL3hjYXAtbnMreG1sXCI6W1wieG5zXCJdLFwiYXBwbGljYXRpb24veGVuYyt4bWxcIjpbXCJ4ZW5jXCJdLFwiYXBwbGljYXRpb24veGh0bWwreG1sXCI6W1wieGh0bWxcIixcInhodFwiXSxcImFwcGxpY2F0aW9uL3hsaWZmK3htbFwiOltcInhsZlwiXSxcImFwcGxpY2F0aW9uL3htbFwiOltcInhtbFwiLFwieHNsXCIsXCJ4c2RcIixcInJuZ1wiXSxcImFwcGxpY2F0aW9uL3htbC1kdGRcIjpbXCJkdGRcIl0sXCJhcHBsaWNhdGlvbi94b3AreG1sXCI6W1wieG9wXCJdLFwiYXBwbGljYXRpb24veHByb2MreG1sXCI6W1wieHBsXCJdLFwiYXBwbGljYXRpb24veHNsdCt4bWxcIjpbXCIqeHNsXCIsXCJ4c2x0XCJdLFwiYXBwbGljYXRpb24veHNwZit4bWxcIjpbXCJ4c3BmXCJdLFwiYXBwbGljYXRpb24veHYreG1sXCI6W1wibXhtbFwiLFwieGh2bWxcIixcInh2bWxcIixcInh2bVwiXSxcImFwcGxpY2F0aW9uL3lhbmdcIjpbXCJ5YW5nXCJdLFwiYXBwbGljYXRpb24veWluK3htbFwiOltcInlpblwiXSxcImFwcGxpY2F0aW9uL3ppcFwiOltcInppcFwiXSxcImF1ZGlvLzNncHBcIjpbXCIqM2dwcFwiXSxcImF1ZGlvL2FkcGNtXCI6W1wiYWRwXCJdLFwiYXVkaW8vYW1yXCI6W1wiYW1yXCJdLFwiYXVkaW8vYmFzaWNcIjpbXCJhdVwiLFwic25kXCJdLFwiYXVkaW8vbWlkaVwiOltcIm1pZFwiLFwibWlkaVwiLFwia2FyXCIsXCJybWlcIl0sXCJhdWRpby9tb2JpbGUteG1mXCI6W1wibXhtZlwiXSxcImF1ZGlvL21wM1wiOltcIiptcDNcIl0sXCJhdWRpby9tcDRcIjpbXCJtNGFcIixcIm1wNGFcIl0sXCJhdWRpby9tcGVnXCI6W1wibXBnYVwiLFwibXAyXCIsXCJtcDJhXCIsXCJtcDNcIixcIm0yYVwiLFwibTNhXCJdLFwiYXVkaW8vb2dnXCI6W1wib2dhXCIsXCJvZ2dcIixcInNweFwiLFwib3B1c1wiXSxcImF1ZGlvL3MzbVwiOltcInMzbVwiXSxcImF1ZGlvL3NpbGtcIjpbXCJzaWxcIl0sXCJhdWRpby93YXZcIjpbXCJ3YXZcIl0sXCJhdWRpby93YXZlXCI6W1wiKndhdlwiXSxcImF1ZGlvL3dlYm1cIjpbXCJ3ZWJhXCJdLFwiYXVkaW8veG1cIjpbXCJ4bVwiXSxcImZvbnQvY29sbGVjdGlvblwiOltcInR0Y1wiXSxcImZvbnQvb3RmXCI6W1wib3RmXCJdLFwiZm9udC90dGZcIjpbXCJ0dGZcIl0sXCJmb250L3dvZmZcIjpbXCJ3b2ZmXCJdLFwiZm9udC93b2ZmMlwiOltcIndvZmYyXCJdLFwiaW1hZ2UvYWNlc1wiOltcImV4clwiXSxcImltYWdlL2FwbmdcIjpbXCJhcG5nXCJdLFwiaW1hZ2UvYXZpZlwiOltcImF2aWZcIl0sXCJpbWFnZS9ibXBcIjpbXCJibXBcIl0sXCJpbWFnZS9jZ21cIjpbXCJjZ21cIl0sXCJpbWFnZS9kaWNvbS1ybGVcIjpbXCJkcmxlXCJdLFwiaW1hZ2UvZW1mXCI6W1wiZW1mXCJdLFwiaW1hZ2UvZml0c1wiOltcImZpdHNcIl0sXCJpbWFnZS9nM2ZheFwiOltcImczXCJdLFwiaW1hZ2UvZ2lmXCI6W1wiZ2lmXCJdLFwiaW1hZ2UvaGVpY1wiOltcImhlaWNcIl0sXCJpbWFnZS9oZWljLXNlcXVlbmNlXCI6W1wiaGVpY3NcIl0sXCJpbWFnZS9oZWlmXCI6W1wiaGVpZlwiXSxcImltYWdlL2hlaWYtc2VxdWVuY2VcIjpbXCJoZWlmc1wiXSxcImltYWdlL2hlajJrXCI6W1wiaGVqMlwiXSxcImltYWdlL2hzajJcIjpbXCJoc2oyXCJdLFwiaW1hZ2UvaWVmXCI6W1wiaWVmXCJdLFwiaW1hZ2UvamxzXCI6W1wiamxzXCJdLFwiaW1hZ2UvanAyXCI6W1wianAyXCIsXCJqcGcyXCJdLFwiaW1hZ2UvanBlZ1wiOltcImpwZWdcIixcImpwZ1wiLFwianBlXCJdLFwiaW1hZ2UvanBoXCI6W1wianBoXCJdLFwiaW1hZ2UvanBoY1wiOltcImpoY1wiXSxcImltYWdlL2pwbVwiOltcImpwbVwiXSxcImltYWdlL2pweFwiOltcImpweFwiLFwianBmXCJdLFwiaW1hZ2UvanhyXCI6W1wianhyXCJdLFwiaW1hZ2UvanhyYVwiOltcImp4cmFcIl0sXCJpbWFnZS9qeHJzXCI6W1wianhyc1wiXSxcImltYWdlL2p4c1wiOltcImp4c1wiXSxcImltYWdlL2p4c2NcIjpbXCJqeHNjXCJdLFwiaW1hZ2UvanhzaVwiOltcImp4c2lcIl0sXCJpbWFnZS9qeHNzXCI6W1wianhzc1wiXSxcImltYWdlL2t0eFwiOltcImt0eFwiXSxcImltYWdlL2t0eDJcIjpbXCJrdHgyXCJdLFwiaW1hZ2UvcG5nXCI6W1wicG5nXCJdLFwiaW1hZ2Uvc2dpXCI6W1wic2dpXCJdLFwiaW1hZ2Uvc3ZnK3htbFwiOltcInN2Z1wiLFwic3ZnelwiXSxcImltYWdlL3QzOFwiOltcInQzOFwiXSxcImltYWdlL3RpZmZcIjpbXCJ0aWZcIixcInRpZmZcIl0sXCJpbWFnZS90aWZmLWZ4XCI6W1widGZ4XCJdLFwiaW1hZ2Uvd2VicFwiOltcIndlYnBcIl0sXCJpbWFnZS93bWZcIjpbXCJ3bWZcIl0sXCJtZXNzYWdlL2Rpc3Bvc2l0aW9uLW5vdGlmaWNhdGlvblwiOltcImRpc3Bvc2l0aW9uLW5vdGlmaWNhdGlvblwiXSxcIm1lc3NhZ2UvZ2xvYmFsXCI6W1widThtc2dcIl0sXCJtZXNzYWdlL2dsb2JhbC1kZWxpdmVyeS1zdGF0dXNcIjpbXCJ1OGRzblwiXSxcIm1lc3NhZ2UvZ2xvYmFsLWRpc3Bvc2l0aW9uLW5vdGlmaWNhdGlvblwiOltcInU4bWRuXCJdLFwibWVzc2FnZS9nbG9iYWwtaGVhZGVyc1wiOltcInU4aGRyXCJdLFwibWVzc2FnZS9yZmM4MjJcIjpbXCJlbWxcIixcIm1pbWVcIl0sXCJtb2RlbC8zbWZcIjpbXCIzbWZcIl0sXCJtb2RlbC9nbHRmK2pzb25cIjpbXCJnbHRmXCJdLFwibW9kZWwvZ2x0Zi1iaW5hcnlcIjpbXCJnbGJcIl0sXCJtb2RlbC9pZ2VzXCI6W1wiaWdzXCIsXCJpZ2VzXCJdLFwibW9kZWwvbWVzaFwiOltcIm1zaFwiLFwibWVzaFwiLFwic2lsb1wiXSxcIm1vZGVsL210bFwiOltcIm10bFwiXSxcIm1vZGVsL29ialwiOltcIm9ialwiXSxcIm1vZGVsL3N0ZXAreG1sXCI6W1wic3RweFwiXSxcIm1vZGVsL3N0ZXAremlwXCI6W1wic3RwelwiXSxcIm1vZGVsL3N0ZXAteG1sK3ppcFwiOltcInN0cHh6XCJdLFwibW9kZWwvc3RsXCI6W1wic3RsXCJdLFwibW9kZWwvdnJtbFwiOltcIndybFwiLFwidnJtbFwiXSxcIm1vZGVsL3gzZCtiaW5hcnlcIjpbXCIqeDNkYlwiLFwieDNkYnpcIl0sXCJtb2RlbC94M2QrZmFzdGluZm9zZXRcIjpbXCJ4M2RiXCJdLFwibW9kZWwveDNkK3ZybWxcIjpbXCIqeDNkdlwiLFwieDNkdnpcIl0sXCJtb2RlbC94M2QreG1sXCI6W1wieDNkXCIsXCJ4M2R6XCJdLFwibW9kZWwveDNkLXZybWxcIjpbXCJ4M2R2XCJdLFwidGV4dC9jYWNoZS1tYW5pZmVzdFwiOltcImFwcGNhY2hlXCIsXCJtYW5pZmVzdFwiXSxcInRleHQvY2FsZW5kYXJcIjpbXCJpY3NcIixcImlmYlwiXSxcInRleHQvY29mZmVlc2NyaXB0XCI6W1wiY29mZmVlXCIsXCJsaXRjb2ZmZWVcIl0sXCJ0ZXh0L2Nzc1wiOltcImNzc1wiXSxcInRleHQvY3N2XCI6W1wiY3N2XCJdLFwidGV4dC9odG1sXCI6W1wiaHRtbFwiLFwiaHRtXCIsXCJzaHRtbFwiXSxcInRleHQvamFkZVwiOltcImphZGVcIl0sXCJ0ZXh0L2pzeFwiOltcImpzeFwiXSxcInRleHQvbGVzc1wiOltcImxlc3NcIl0sXCJ0ZXh0L21hcmtkb3duXCI6W1wibWFya2Rvd25cIixcIm1kXCJdLFwidGV4dC9tYXRobWxcIjpbXCJtbWxcIl0sXCJ0ZXh0L21keFwiOltcIm1keFwiXSxcInRleHQvbjNcIjpbXCJuM1wiXSxcInRleHQvcGxhaW5cIjpbXCJ0eHRcIixcInRleHRcIixcImNvbmZcIixcImRlZlwiLFwibGlzdFwiLFwibG9nXCIsXCJpblwiLFwiaW5pXCJdLFwidGV4dC9yaWNodGV4dFwiOltcInJ0eFwiXSxcInRleHQvcnRmXCI6W1wiKnJ0ZlwiXSxcInRleHQvc2dtbFwiOltcInNnbWxcIixcInNnbVwiXSxcInRleHQvc2hleFwiOltcInNoZXhcIl0sXCJ0ZXh0L3NsaW1cIjpbXCJzbGltXCIsXCJzbG1cIl0sXCJ0ZXh0L3NwZHhcIjpbXCJzcGR4XCJdLFwidGV4dC9zdHlsdXNcIjpbXCJzdHlsdXNcIixcInN0eWxcIl0sXCJ0ZXh0L3RhYi1zZXBhcmF0ZWQtdmFsdWVzXCI6W1widHN2XCJdLFwidGV4dC90cm9mZlwiOltcInRcIixcInRyXCIsXCJyb2ZmXCIsXCJtYW5cIixcIm1lXCIsXCJtc1wiXSxcInRleHQvdHVydGxlXCI6W1widHRsXCJdLFwidGV4dC91cmktbGlzdFwiOltcInVyaVwiLFwidXJpc1wiLFwidXJsc1wiXSxcInRleHQvdmNhcmRcIjpbXCJ2Y2FyZFwiXSxcInRleHQvdnR0XCI6W1widnR0XCJdLFwidGV4dC94bWxcIjpbXCIqeG1sXCJdLFwidGV4dC95YW1sXCI6W1wieWFtbFwiLFwieW1sXCJdLFwidmlkZW8vM2dwcFwiOltcIjNncFwiLFwiM2dwcFwiXSxcInZpZGVvLzNncHAyXCI6W1wiM2cyXCJdLFwidmlkZW8vaDI2MVwiOltcImgyNjFcIl0sXCJ2aWRlby9oMjYzXCI6W1wiaDI2M1wiXSxcInZpZGVvL2gyNjRcIjpbXCJoMjY0XCJdLFwidmlkZW8vaXNvLnNlZ21lbnRcIjpbXCJtNHNcIl0sXCJ2aWRlby9qcGVnXCI6W1wianBndlwiXSxcInZpZGVvL2pwbVwiOltcIipqcG1cIixcImpwZ21cIl0sXCJ2aWRlby9tajJcIjpbXCJtajJcIixcIm1qcDJcIl0sXCJ2aWRlby9tcDJ0XCI6W1widHNcIl0sXCJ2aWRlby9tcDRcIjpbXCJtcDRcIixcIm1wNHZcIixcIm1wZzRcIl0sXCJ2aWRlby9tcGVnXCI6W1wibXBlZ1wiLFwibXBnXCIsXCJtcGVcIixcIm0xdlwiLFwibTJ2XCJdLFwidmlkZW8vb2dnXCI6W1wib2d2XCJdLFwidmlkZW8vcXVpY2t0aW1lXCI6W1wicXRcIixcIm1vdlwiXSxcInZpZGVvL3dlYm1cIjpbXCJ3ZWJtXCJdfTsiLCIvKipcbiAgIyBub3JtYWxpY2VcblxuICBOb3JtYWxpemUgYW4gaWNlIHNlcnZlciBjb25maWd1cmF0aW9uIG9iamVjdCAob3IgcGxhaW4gb2xkIHN0cmluZykgaW50byBhIGZvcm1hdFxuICB0aGF0IGlzIHVzYWJsZSBpbiBhbGwgYnJvd3NlcnMgc3VwcG9ydGluZyBXZWJSVEMuICBQcmltYXJpbHkgdGhpcyBtb2R1bGUgaXMgZGVzaWduZWRcbiAgdG8gaGVscCB3aXRoIHRoZSB0cmFuc2l0aW9uIG9mIHRoZSBgdXJsYCBhdHRyaWJ1dGUgb2YgdGhlIGNvbmZpZ3VyYXRpb24gb2JqZWN0IHRvXG4gIHRoZSBgdXJsc2AgYXR0cmlidXRlLlxuXG4gICMjIEV4YW1wbGUgVXNhZ2VcblxuICA8PDwgZXhhbXBsZXMvc2ltcGxlLmpzXG5cbioqL1xuXG52YXIgcHJvdG9jb2xzID0gW1xuICAnc3R1bjonLFxuICAndHVybjonXG5dO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGlucHV0KSB7XG4gIHZhciB1cmwgPSAoaW5wdXQgfHwge30pLnVybCB8fCBpbnB1dDtcbiAgdmFyIHByb3RvY29sO1xuICB2YXIgcGFydHM7XG4gIHZhciBvdXRwdXQgPSB7fTtcblxuICAvLyBpZiB3ZSBkb24ndCBoYXZlIGEgc3RyaW5nIHVybCwgdGhlbiBhbGxvdyB0aGUgaW5wdXQgdG8gcGFzc3Rocm91Z2hcbiAgaWYgKHR5cGVvZiB1cmwgIT0gJ3N0cmluZycgJiYgKCEgKHVybCBpbnN0YW5jZW9mIFN0cmluZykpKSB7XG4gICAgcmV0dXJuIGlucHV0O1xuICB9XG5cbiAgLy8gdHJpbSB0aGUgdXJsIHN0cmluZywgYW5kIGNvbnZlcnQgdG8gYW4gYXJyYXlcbiAgdXJsID0gdXJsLnRyaW0oKTtcblxuICAvLyBpZiB0aGUgcHJvdG9jb2wgaXMgbm90IGtub3duLCB0aGVuIHBhc3N0aHJvdWdoXG4gIHByb3RvY29sID0gcHJvdG9jb2xzW3Byb3RvY29scy5pbmRleE9mKHVybC5zbGljZSgwLCA1KSldO1xuICBpZiAoISBwcm90b2NvbCkge1xuICAgIHJldHVybiBpbnB1dDtcbiAgfVxuXG4gIC8vIG5vdyBsZXQncyBhdHRhY2sgdGhlIHJlbWFpbmluZyB1cmwgcGFydHNcbiAgdXJsID0gdXJsLnNsaWNlKDUpO1xuICBwYXJ0cyA9IHVybC5zcGxpdCgnQCcpO1xuXG4gIG91dHB1dC51c2VybmFtZSA9IGlucHV0LnVzZXJuYW1lO1xuICBvdXRwdXQuY3JlZGVudGlhbCA9IGlucHV0LmNyZWRlbnRpYWw7XG4gIC8vIGlmIHdlIGhhdmUgYW4gYXV0aGVudGljYXRpb24gcGFydCwgdGhlbiBzZXQgdGhlIGNyZWRlbnRpYWxzXG4gIGlmIChwYXJ0cy5sZW5ndGggPiAxKSB7XG4gICAgdXJsID0gcGFydHNbMV07XG4gICAgcGFydHMgPSBwYXJ0c1swXS5zcGxpdCgnOicpO1xuXG4gICAgLy8gYWRkIHRoZSBvdXRwdXQgY3JlZGVudGlhbCBhbmQgdXNlcm5hbWVcbiAgICBvdXRwdXQudXNlcm5hbWUgPSBwYXJ0c1swXTtcbiAgICBvdXRwdXQuY3JlZGVudGlhbCA9IChpbnB1dCB8fCB7fSkuY3JlZGVudGlhbCB8fCBwYXJ0c1sxXSB8fCAnJztcbiAgfVxuXG4gIG91dHB1dC51cmwgPSBwcm90b2NvbCArIHVybDtcbiAgb3V0cHV0LnVybHMgPSBbIG91dHB1dC51cmwgXTtcblxuICByZXR1cm4gb3V0cHV0O1xufTtcbiIsIi8qIVxuICogUGxhdGZvcm0uanMgdjEuMy42XG4gKiBDb3B5cmlnaHQgMjAxNC0yMDIwIEJlbmphbWluIFRhblxuICogQ29weXJpZ2h0IDIwMTEtMjAxMyBKb2huLURhdmlkIERhbHRvblxuICogQXZhaWxhYmxlIHVuZGVyIE1JVCBsaWNlbnNlXG4gKi9cbjsoZnVuY3Rpb24oKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvKiogVXNlZCB0byBkZXRlcm1pbmUgaWYgdmFsdWVzIGFyZSBvZiB0aGUgbGFuZ3VhZ2UgdHlwZSBgT2JqZWN0YC4gKi9cbiAgdmFyIG9iamVjdFR5cGVzID0ge1xuICAgICdmdW5jdGlvbic6IHRydWUsXG4gICAgJ29iamVjdCc6IHRydWVcbiAgfTtcblxuICAvKiogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzO1xuXG4gIC8qKiBCYWNrdXAgcG9zc2libGUgZ2xvYmFsIG9iamVjdC4gKi9cbiAgdmFyIG9sZFJvb3QgPSByb290O1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG4gIHZhciBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzO1xuXG4gIC8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbiAgdmFyIGZyZWVNb2R1bGUgPSBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbiAgLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSBhbmQgdXNlIGl0IGFzIGByb290YC4gKi9cbiAgdmFyIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBmcmVlTW9kdWxlICYmIHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsO1xuICBpZiAoZnJlZUdsb2JhbCAmJiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC5zZWxmID09PSBmcmVlR2xvYmFsKSkge1xuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZWQgYXMgdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFuIGFycmF5LWxpa2Ugb2JqZWN0LlxuICAgKiBTZWUgdGhlIFtFUzYgc3BlY10oaHR0cDovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtdG9sZW5ndGgpXG4gICAqIGZvciBtb3JlIGRldGFpbHMuXG4gICAqL1xuICB2YXIgbWF4U2FmZUludGVnZXIgPSBNYXRoLnBvdygyLCA1MykgLSAxO1xuXG4gIC8qKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gZGV0ZWN0IE9wZXJhLiAqL1xuICB2YXIgcmVPcGVyYSA9IC9cXGJPcGVyYS87XG5cbiAgLyoqIFBvc3NpYmxlIGdsb2JhbCBvYmplY3QuICovXG4gIHZhciB0aGlzQmluZGluZyA9IHRoaXM7XG5cbiAgLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbiAgdmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuICAvKiogVXNlZCB0byBjaGVjayBmb3Igb3duIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0LiAqL1xuICB2YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuICAvKiogVXNlZCB0byByZXNvbHZlIHRoZSBpbnRlcm5hbCBgW1tDbGFzc11dYCBvZiB2YWx1ZXMuICovXG4gIHZhciB0b1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8qKlxuICAgKiBDYXBpdGFsaXplcyBhIHN0cmluZyB2YWx1ZS5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNhcGl0YWxpemUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjYXBpdGFsaXplZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBjYXBpdGFsaXplKHN0cmluZykge1xuICAgIHN0cmluZyA9IFN0cmluZyhzdHJpbmcpO1xuICAgIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG4gIH1cblxuICAvKipcbiAgICogQSB1dGlsaXR5IGZ1bmN0aW9uIHRvIGNsZWFuIHVwIHRoZSBPUyBuYW1lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3MgVGhlIE9TIG5hbWUgdG8gY2xlYW4gdXAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcGF0dGVybl0gQSBgUmVnRXhwYCBwYXR0ZXJuIG1hdGNoaW5nIHRoZSBPUyBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2xhYmVsXSBBIGxhYmVsIGZvciB0aGUgT1MuXG4gICAqL1xuICBmdW5jdGlvbiBjbGVhbnVwT1Mob3MsIHBhdHRlcm4sIGxhYmVsKSB7XG4gICAgLy8gUGxhdGZvcm0gdG9rZW5zIGFyZSBkZWZpbmVkIGF0OlxuICAgIC8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIC8vIGh0dHA6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMDgxMTIyMDUzOTUwL2h0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNzUwMyhWUy44NSkuYXNweFxuICAgIHZhciBkYXRhID0ge1xuICAgICAgJzEwLjAnOiAnMTAnLFxuICAgICAgJzYuNCc6ICAnMTAgVGVjaG5pY2FsIFByZXZpZXcnLFxuICAgICAgJzYuMyc6ICAnOC4xJyxcbiAgICAgICc2LjInOiAgJzgnLFxuICAgICAgJzYuMSc6ICAnU2VydmVyIDIwMDggUjIgLyA3JyxcbiAgICAgICc2LjAnOiAgJ1NlcnZlciAyMDA4IC8gVmlzdGEnLFxuICAgICAgJzUuMic6ICAnU2VydmVyIDIwMDMgLyBYUCA2NC1iaXQnLFxuICAgICAgJzUuMSc6ICAnWFAnLFxuICAgICAgJzUuMDEnOiAnMjAwMCBTUDEnLFxuICAgICAgJzUuMCc6ICAnMjAwMCcsXG4gICAgICAnNC4wJzogICdOVCcsXG4gICAgICAnNC45MCc6ICdNRSdcbiAgICB9O1xuICAgIC8vIERldGVjdCBXaW5kb3dzIHZlcnNpb24gZnJvbSBwbGF0Zm9ybSB0b2tlbnMuXG4gICAgaWYgKHBhdHRlcm4gJiYgbGFiZWwgJiYgL15XaW4vaS50ZXN0KG9zKSAmJiAhL15XaW5kb3dzIFBob25lIC9pLnRlc3Qob3MpICYmXG4gICAgICAgIChkYXRhID0gZGF0YVsvW1xcZC5dKyQvLmV4ZWMob3MpXSkpIHtcbiAgICAgIG9zID0gJ1dpbmRvd3MgJyArIGRhdGE7XG4gICAgfVxuICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgIG9zID0gU3RyaW5nKG9zKTtcblxuICAgIGlmIChwYXR0ZXJuICYmIGxhYmVsKSB7XG4gICAgICBvcyA9IG9zLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGxhYmVsKTtcbiAgICB9XG5cbiAgICBvcyA9IGZvcm1hdChcbiAgICAgIG9zLnJlcGxhY2UoLyBjZSQvaSwgJyBDRScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJocHcvaSwgJ3dlYicpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWNpbnRvc2hcXGIvLCAnTWFjIE9TJylcbiAgICAgICAgLnJlcGxhY2UoL19Qb3dlclBDXFxiL2ksICcgT1MnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKE9TIFgpIFteIFxcZF0rL2ksICckMScpXG4gICAgICAgIC5yZXBsYWNlKC9cXGJNYWMgKE9TIFgpXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcLyhcXGQpLywgJyAkMScpXG4gICAgICAgIC5yZXBsYWNlKC9fL2csICcuJylcbiAgICAgICAgLnJlcGxhY2UoLyg/OiBCZVBDfFsgLl0qZmNbIFxcZC5dKykkL2ksICcnKVxuICAgICAgICAucmVwbGFjZSgvXFxieDg2XFwuNjRcXGIvZ2ksICd4ODZfNjQnKVxuICAgICAgICAucmVwbGFjZSgvXFxiKFdpbmRvd3MgUGhvbmUpIE9TXFxiLywgJyQxJylcbiAgICAgICAgLnJlcGxhY2UoL1xcYihDaHJvbWUgT1MgXFx3KykgW1xcZC5dK1xcYi8sICckMScpXG4gICAgICAgIC5zcGxpdCgnIG9uICcpWzBdXG4gICAgKTtcblxuICAgIHJldHVybiBvcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbiBpdGVyYXRpb24gdXRpbGl0eSBmb3IgYXJyYXlzIGFuZCBvYmplY3RzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gY2FsbGVkIHBlciBpdGVyYXRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBlYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gb2JqZWN0ID8gb2JqZWN0Lmxlbmd0aCA6IDA7XG5cbiAgICBpZiAodHlwZW9mIGxlbmd0aCA9PSAnbnVtYmVyJyAmJiBsZW5ndGggPiAtMSAmJiBsZW5ndGggPD0gbWF4U2FmZUludGVnZXIpIHtcbiAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtpbmRleF0sIGluZGV4LCBvYmplY3QpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3JPd24ob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyaW0gYW5kIGNvbmRpdGlvbmFsbHkgY2FwaXRhbGl6ZSBzdHJpbmcgdmFsdWVzLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZm9ybWF0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHN0cmluZy5cbiAgICovXG4gIGZ1bmN0aW9uIGZvcm1hdChzdHJpbmcpIHtcbiAgICBzdHJpbmcgPSB0cmltKHN0cmluZyk7XG4gICAgcmV0dXJuIC9eKD86d2ViT1N8aSg/Ok9TfFApKS8udGVzdChzdHJpbmcpXG4gICAgICA/IHN0cmluZ1xuICAgICAgOiBjYXBpdGFsaXplKHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICogSXRlcmF0ZXMgb3ZlciBhbiBvYmplY3QncyBvd24gcHJvcGVydGllcywgZXhlY3V0aW5nIHRoZSBgY2FsbGJhY2tgIGZvciBlYWNoLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gZXhlY3V0ZWQgcGVyIG93biBwcm9wZXJ0eS5cbiAgICovXG4gIGZ1bmN0aW9uIGZvck93bihvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpKSB7XG4gICAgICAgIGNhbGxiYWNrKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGludGVybmFsIGBbW0NsYXNzXV1gIG9mIGEgdmFsdWUuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgYFtbQ2xhc3NdXWAuXG4gICAqL1xuICBmdW5jdGlvbiBnZXRDbGFzc09mKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09IG51bGxcbiAgICAgID8gY2FwaXRhbGl6ZSh2YWx1ZSlcbiAgICAgIDogdG9TdHJpbmcuY2FsbCh2YWx1ZSkuc2xpY2UoOCwgLTEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvc3Qgb2JqZWN0cyBjYW4gcmV0dXJuIHR5cGUgdmFsdWVzIHRoYXQgYXJlIGRpZmZlcmVudCBmcm9tIHRoZWlyIGFjdHVhbFxuICAgKiBkYXRhIHR5cGUuIFRoZSBvYmplY3RzIHdlIGFyZSBjb25jZXJuZWQgd2l0aCB1c3VhbGx5IHJldHVybiBub24tcHJpbWl0aXZlXG4gICAqIHR5cGVzIG9mIFwib2JqZWN0XCIsIFwiZnVuY3Rpb25cIiwgb3IgXCJ1bmtub3duXCIuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBwYXJhbSB7Kn0gb2JqZWN0IFRoZSBvd25lciBvZiB0aGUgcHJvcGVydHkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvcGVydHkgdmFsdWUgaXMgYSBub24tcHJpbWl0aXZlLCBlbHNlIGBmYWxzZWAuXG4gICAqL1xuICBmdW5jdGlvbiBpc0hvc3RUeXBlKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICB2YXIgdHlwZSA9IG9iamVjdCAhPSBudWxsID8gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV0gOiAnbnVtYmVyJztcbiAgICByZXR1cm4gIS9eKD86Ym9vbGVhbnxudW1iZXJ8c3RyaW5nfHVuZGVmaW5lZCkkLy50ZXN0KHR5cGUpICYmXG4gICAgICAodHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6IHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmVzIGEgc3RyaW5nIGZvciB1c2UgaW4gYSBgUmVnRXhwYCBieSBtYWtpbmcgaHlwaGVucyBhbmQgc3BhY2VzIG9wdGlvbmFsLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gcXVhbGlmeS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHF1YWxpZmllZCBzdHJpbmcuXG4gICAqL1xuICBmdW5jdGlvbiBxdWFsaWZ5KHN0cmluZykge1xuICAgIHJldHVybiBTdHJpbmcoc3RyaW5nKS5yZXBsYWNlKC8oWyAtXSkoPyEkKS9nLCAnJDE/Jyk7XG4gIH1cblxuICAvKipcbiAgICogQSBiYXJlLWJvbmVzIGBBcnJheSNyZWR1Y2VgIGxpa2UgdXRpbGl0eSBmdW5jdGlvbi5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgVGhlIGZ1bmN0aW9uIGNhbGxlZCBwZXIgaXRlcmF0aW9uLlxuICAgKiBAcmV0dXJucyB7Kn0gVGhlIGFjY3VtdWxhdGVkIHJlc3VsdC5cbiAgICovXG4gIGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2spIHtcbiAgICB2YXIgYWNjdW11bGF0b3IgPSBudWxsO1xuICAgIGVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgYWNjdW11bGF0b3IgPSBjYWxsYmFjayhhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBhcnJheSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgbGVhZGluZyBhbmQgdHJhaWxpbmcgd2hpdGVzcGFjZSBmcm9tIGEgc3RyaW5nLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gdHJpbS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyaW1tZWQgc3RyaW5nLlxuICAgKi9cbiAgZnVuY3Rpb24gdHJpbShzdHJpbmcpIHtcbiAgICByZXR1cm4gU3RyaW5nKHN0cmluZykucmVwbGFjZSgvXiArfCArJC9nLCAnJyk7XG4gIH1cblxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBwbGF0Zm9ybSBvYmplY3QuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgKiBAcGFyYW0ge09iamVjdHxzdHJpbmd9IFt1YT1uYXZpZ2F0b3IudXNlckFnZW50XSBUaGUgdXNlciBhZ2VudCBzdHJpbmcgb3JcbiAgICogIGNvbnRleHQgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBBIHBsYXRmb3JtIG9iamVjdC5cbiAgICovXG4gIGZ1bmN0aW9uIHBhcnNlKHVhKSB7XG5cbiAgICAvKiogVGhlIGVudmlyb25tZW50IGNvbnRleHQgb2JqZWN0LiAqL1xuICAgIHZhciBjb250ZXh0ID0gcm9vdDtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBhIGN1c3RvbSBjb250ZXh0IGlzIHByb3ZpZGVkLiAqL1xuICAgIHZhciBpc0N1c3RvbUNvbnRleHQgPSB1YSAmJiB0eXBlb2YgdWEgPT0gJ29iamVjdCcgJiYgZ2V0Q2xhc3NPZih1YSkgIT0gJ1N0cmluZyc7XG5cbiAgICAvLyBKdWdnbGUgYXJndW1lbnRzLlxuICAgIGlmIChpc0N1c3RvbUNvbnRleHQpIHtcbiAgICAgIGNvbnRleHQgPSB1YTtcbiAgICAgIHVhID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogQnJvd3NlciBuYXZpZ2F0b3Igb2JqZWN0LiAqL1xuICAgIHZhciBuYXYgPSBjb250ZXh0Lm5hdmlnYXRvciB8fCB7fTtcblxuICAgIC8qKiBCcm93c2VyIHVzZXIgYWdlbnQgc3RyaW5nLiAqL1xuICAgIHZhciB1c2VyQWdlbnQgPSBuYXYudXNlckFnZW50IHx8ICcnO1xuXG4gICAgdWEgfHwgKHVhID0gdXNlckFnZW50KTtcblxuICAgIC8qKiBVc2VkIHRvIGZsYWcgd2hlbiBgdGhpc0JpbmRpbmdgIGlzIHRoZSBbTW9kdWxlU2NvcGVdLiAqL1xuICAgIHZhciBpc01vZHVsZVNjb3BlID0gaXNDdXN0b21Db250ZXh0IHx8IHRoaXNCaW5kaW5nID09IG9sZFJvb3Q7XG5cbiAgICAvKiogVXNlZCB0byBkZXRlY3QgaWYgYnJvd3NlciBpcyBsaWtlIENocm9tZS4gKi9cbiAgICB2YXIgbGlrZUNocm9tZSA9IGlzQ3VzdG9tQ29udGV4dFxuICAgICAgPyAhIW5hdi5saWtlQ2hyb21lXG4gICAgICA6IC9cXGJDaHJvbWVcXGIvLnRlc3QodWEpICYmICEvaW50ZXJuYWx8XFxuL2kudGVzdCh0b1N0cmluZy50b1N0cmluZygpKTtcblxuICAgIC8qKiBJbnRlcm5hbCBgW1tDbGFzc11dYCB2YWx1ZSBzaG9ydGN1dHMuICovXG4gICAgdmFyIG9iamVjdENsYXNzID0gJ09iamVjdCcsXG4gICAgICAgIGFpclJ1bnRpbWVDbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ1NjcmlwdEJyaWRnaW5nUHJveHlPYmplY3QnLFxuICAgICAgICBlbnZpcm9DbGFzcyA9IGlzQ3VzdG9tQ29udGV4dCA/IG9iamVjdENsYXNzIDogJ0Vudmlyb25tZW50JyxcbiAgICAgICAgamF2YUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBjb250ZXh0LmphdmEpID8gJ0phdmFQYWNrYWdlJyA6IGdldENsYXNzT2YoY29udGV4dC5qYXZhKSxcbiAgICAgICAgcGhhbnRvbUNsYXNzID0gaXNDdXN0b21Db250ZXh0ID8gb2JqZWN0Q2xhc3MgOiAnUnVudGltZU9iamVjdCc7XG5cbiAgICAvKiogRGV0ZWN0IEphdmEgZW52aXJvbm1lbnRzLiAqL1xuICAgIHZhciBqYXZhID0gL1xcYkphdmEvLnRlc3QoamF2YUNsYXNzKSAmJiBjb250ZXh0LmphdmE7XG5cbiAgICAvKiogRGV0ZWN0IFJoaW5vLiAqL1xuICAgIHZhciByaGlubyA9IGphdmEgJiYgZ2V0Q2xhc3NPZihjb250ZXh0LmVudmlyb25tZW50KSA9PSBlbnZpcm9DbGFzcztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYWxwaGEuICovXG4gICAgdmFyIGFscGhhID0gamF2YSA/ICdhJyA6ICdcXHUwM2IxJztcblxuICAgIC8qKiBBIGNoYXJhY3RlciB0byByZXByZXNlbnQgYmV0YS4gKi9cbiAgICB2YXIgYmV0YSA9IGphdmEgPyAnYicgOiAnXFx1MDNiMic7XG5cbiAgICAvKiogQnJvd3NlciBkb2N1bWVudCBvYmplY3QuICovXG4gICAgdmFyIGRvYyA9IGNvbnRleHQuZG9jdW1lbnQgfHwge307XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgT3BlcmEgYnJvd3NlciAoUHJlc3RvLWJhc2VkKS5cbiAgICAgKiBodHRwOi8vd3d3Lmhvd3RvY3JlYXRlLmNvLnVrL29wZXJhU3R1ZmYvb3BlcmFPYmplY3QuaHRtbFxuICAgICAqIGh0dHA6Ly9kZXYub3BlcmEuY29tL2FydGljbGVzL3ZpZXcvb3BlcmEtbWluaS13ZWItY29udGVudC1hdXRob3JpbmctZ3VpZGVsaW5lcy8jb3BlcmFtaW5pXG4gICAgICovXG4gICAgdmFyIG9wZXJhID0gY29udGV4dC5vcGVyYW1pbmkgfHwgY29udGV4dC5vcGVyYTtcblxuICAgIC8qKiBPcGVyYSBgW1tDbGFzc11dYC4gKi9cbiAgICB2YXIgb3BlcmFDbGFzcyA9IHJlT3BlcmEudGVzdChvcGVyYUNsYXNzID0gKGlzQ3VzdG9tQ29udGV4dCAmJiBvcGVyYSkgPyBvcGVyYVsnW1tDbGFzc11dJ10gOiBnZXRDbGFzc09mKG9wZXJhKSlcbiAgICAgID8gb3BlcmFDbGFzc1xuICAgICAgOiAob3BlcmEgPSBudWxsKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKiBUZW1wb3JhcnkgdmFyaWFibGUgdXNlZCBvdmVyIHRoZSBzY3JpcHQncyBsaWZldGltZS4gKi9cbiAgICB2YXIgZGF0YTtcblxuICAgIC8qKiBUaGUgQ1BVIGFyY2hpdGVjdHVyZS4gKi9cbiAgICB2YXIgYXJjaCA9IHVhO1xuXG4gICAgLyoqIFBsYXRmb3JtIGRlc2NyaXB0aW9uIGFycmF5LiAqL1xuICAgIHZhciBkZXNjcmlwdGlvbiA9IFtdO1xuXG4gICAgLyoqIFBsYXRmb3JtIGFscGhhL2JldGEgaW5kaWNhdG9yLiAqL1xuICAgIHZhciBwcmVyZWxlYXNlID0gbnVsbDtcblxuICAgIC8qKiBBIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCBlbnZpcm9ubWVudCBmZWF0dXJlcyBzaG91bGQgYmUgdXNlZCB0byByZXNvbHZlIHRoZSBwbGF0Zm9ybS4gKi9cbiAgICB2YXIgdXNlRmVhdHVyZXMgPSB1YSA9PSB1c2VyQWdlbnQ7XG5cbiAgICAvKiogVGhlIGJyb3dzZXIvZW52aXJvbm1lbnQgdmVyc2lvbi4gKi9cbiAgICB2YXIgdmVyc2lvbiA9IHVzZUZlYXR1cmVzICYmIG9wZXJhICYmIHR5cGVvZiBvcGVyYS52ZXJzaW9uID09ICdmdW5jdGlvbicgJiYgb3BlcmEudmVyc2lvbigpO1xuXG4gICAgLyoqIEEgZmxhZyB0byBpbmRpY2F0ZSBpZiB0aGUgT1MgZW5kcyB3aXRoIFwiLyBWZXJzaW9uXCIgKi9cbiAgICB2YXIgaXNTcGVjaWFsQ2FzZWRPUztcblxuICAgIC8qIERldGVjdGFibGUgbGF5b3V0IGVuZ2luZXMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIGxheW91dCA9IGdldExheW91dChbXG4gICAgICB7ICdsYWJlbCc6ICdFZGdlSFRNTCcsICdwYXR0ZXJuJzogJ0VkZ2UnIH0sXG4gICAgICAnVHJpZGVudCcsXG4gICAgICB7ICdsYWJlbCc6ICdXZWJLaXQnLCAncGF0dGVybic6ICdBcHBsZVdlYktpdCcgfSxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdQcmVzdG8nLFxuICAgICAgJ05ldEZyb250JyxcbiAgICAgICdUYXNtYW4nLFxuICAgICAgJ0tIVE1MJyxcbiAgICAgICdHZWNrbydcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgYnJvd3NlciBuYW1lcyAob3JkZXIgaXMgaW1wb3J0YW50KS4gKi9cbiAgICB2YXIgbmFtZSA9IGdldE5hbWUoW1xuICAgICAgJ0Fkb2JlIEFJUicsXG4gICAgICAnQXJvcmEnLFxuICAgICAgJ0F2YW50IEJyb3dzZXInLFxuICAgICAgJ0JyZWFjaCcsXG4gICAgICAnQ2FtaW5vJyxcbiAgICAgICdFbGVjdHJvbicsXG4gICAgICAnRXBpcGhhbnknLFxuICAgICAgJ0Zlbm5lYycsXG4gICAgICAnRmxvY2snLFxuICAgICAgJ0dhbGVvbicsXG4gICAgICAnR3JlZW5Ccm93c2VyJyxcbiAgICAgICdpQ2FiJyxcbiAgICAgICdJY2V3ZWFzZWwnLFxuICAgICAgJ0stTWVsZW9uJyxcbiAgICAgICdLb25xdWVyb3InLFxuICAgICAgJ0x1bmFzY2FwZScsXG4gICAgICAnTWF4dGhvbicsXG4gICAgICB7ICdsYWJlbCc6ICdNaWNyb3NvZnQgRWRnZScsICdwYXR0ZXJuJzogJyg/OkVkZ2V8RWRnfEVkZ0F8RWRnaU9TKScgfSxcbiAgICAgICdNaWRvcmknLFxuICAgICAgJ05vb2sgQnJvd3NlcicsXG4gICAgICAnUGFsZU1vb24nLFxuICAgICAgJ1BoYW50b21KUycsXG4gICAgICAnUmF2ZW4nLFxuICAgICAgJ1Jla29ucScsXG4gICAgICAnUm9ja01lbHQnLFxuICAgICAgeyAnbGFiZWwnOiAnU2Ftc3VuZyBJbnRlcm5ldCcsICdwYXR0ZXJuJzogJ1NhbXN1bmdCcm93c2VyJyB9LFxuICAgICAgJ1NlYU1vbmtleScsXG4gICAgICB7ICdsYWJlbCc6ICdTaWxrJywgJ3BhdHRlcm4nOiAnKD86Q2xvdWQ5fFNpbGstQWNjZWxlcmF0ZWQpJyB9LFxuICAgICAgJ1NsZWlwbmlyJyxcbiAgICAgICdTbGltQnJvd3NlcicsXG4gICAgICB7ICdsYWJlbCc6ICdTUldhcmUgSXJvbicsICdwYXR0ZXJuJzogJ0lyb24nIH0sXG4gICAgICAnU3VucmlzZScsXG4gICAgICAnU3dpZnRmb3gnLFxuICAgICAgJ1ZpdmFsZGknLFxuICAgICAgJ1dhdGVyZm94JyxcbiAgICAgICdXZWJQb3NpdGl2ZScsXG4gICAgICB7ICdsYWJlbCc6ICdZYW5kZXggQnJvd3NlcicsICdwYXR0ZXJuJzogJ1lhQnJvd3NlcicgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ1VDIEJyb3dzZXInLCAncGF0dGVybic6ICdVQ0Jyb3dzZXInIH0sXG4gICAgICAnT3BlcmEgTWluaScsXG4gICAgICB7ICdsYWJlbCc6ICdPcGVyYSBNaW5pJywgJ3BhdHRlcm4nOiAnT1BpT1MnIH0sXG4gICAgICAnT3BlcmEnLFxuICAgICAgeyAnbGFiZWwnOiAnT3BlcmEnLCAncGF0dGVybic6ICdPUFInIH0sXG4gICAgICAnQ2hyb21pdW0nLFxuICAgICAgJ0Nocm9tZScsXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUnLCAncGF0dGVybic6ICcoPzpIZWFkbGVzc0Nocm9tZSknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdDaHJvbWUgTW9iaWxlJywgJ3BhdHRlcm4nOiAnKD86Q3JpT1N8Q3JNbyknIH0sXG4gICAgICB7ICdsYWJlbCc6ICdGaXJlZm94JywgJ3BhdHRlcm4nOiAnKD86RmlyZWZveHxNaW5lZmllbGQpJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnRmlyZWZveCBmb3IgaU9TJywgJ3BhdHRlcm4nOiAnRnhpT1MnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdJRScsICdwYXR0ZXJuJzogJ0lFTW9iaWxlJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnSUUnLCAncGF0dGVybic6ICdNU0lFJyB9LFxuICAgICAgJ1NhZmFyaSdcbiAgICBdKTtcblxuICAgIC8qIERldGVjdGFibGUgcHJvZHVjdHMgKG9yZGVyIGlzIGltcG9ydGFudCkuICovXG4gICAgdmFyIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFtcbiAgICAgIHsgJ2xhYmVsJzogJ0JsYWNrQmVycnknLCAncGF0dGVybic6ICdCQjEwJyB9LFxuICAgICAgJ0JsYWNrQmVycnknLFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMnLCAncGF0dGVybic6ICdHVC1JOTAwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTMicsICdwYXR0ZXJuJzogJ0dULUk5MTAwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFMzJywgJ3BhdHRlcm4nOiAnR1QtSTkzMDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzQnLCAncGF0dGVybic6ICdHVC1JOTUwMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNScsICdwYXR0ZXJuJzogJ1NNLUc5MDAnIH0sXG4gICAgICB7ICdsYWJlbCc6ICdHYWxheHkgUzYnLCAncGF0dGVybic6ICdTTS1HOTIwJyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM2IEVkZ2UnLCAncGF0dGVybic6ICdTTS1HOTI1JyB9LFxuICAgICAgeyAnbGFiZWwnOiAnR2FsYXh5IFM3JywgJ3BhdHRlcm4nOiAnU00tRzkzMCcgfSxcbiAgICAgIHsgJ2xhYmVsJzogJ0dhbGF4eSBTNyBFZGdlJywgJ3BhdHRlcm4nOiAnU00tRzkzNScgfSxcbiAgICAgICdHb29nbGUgVFYnLFxuICAgICAgJ0x1bWlhJyxcbiAgICAgICdpUGFkJyxcbiAgICAgICdpUG9kJyxcbiAgICAgICdpUGhvbmUnLFxuICAgICAgJ0tpbmRsZScsXG4gICAgICB7ICdsYWJlbCc6ICdLaW5kbGUgRmlyZScsICdwYXR0ZXJuJzogJyg/OkNsb3VkOXxTaWxrLUFjY2VsZXJhdGVkKScgfSxcbiAgICAgICdOZXh1cycsXG4gICAgICAnTm9vaycsXG4gICAgICAnUGxheUJvb2snLFxuICAgICAgJ1BsYXlTdGF0aW9uIFZpdGEnLFxuICAgICAgJ1BsYXlTdGF0aW9uJyxcbiAgICAgICdUb3VjaFBhZCcsXG4gICAgICAnVHJhbnNmb3JtZXInLFxuICAgICAgeyAnbGFiZWwnOiAnV2lpIFUnLCAncGF0dGVybic6ICdXaWlVJyB9LFxuICAgICAgJ1dpaScsXG4gICAgICAnWGJveCBPbmUnLFxuICAgICAgeyAnbGFiZWwnOiAnWGJveCAzNjAnLCAncGF0dGVybic6ICdYYm94JyB9LFxuICAgICAgJ1hvb20nXG4gICAgXSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG1hbnVmYWN0dXJlcnMuICovXG4gICAgdmFyIG1hbnVmYWN0dXJlciA9IGdldE1hbnVmYWN0dXJlcih7XG4gICAgICAnQXBwbGUnOiB7ICdpUGFkJzogMSwgJ2lQaG9uZSc6IDEsICdpUG9kJzogMSB9LFxuICAgICAgJ0FsY2F0ZWwnOiB7fSxcbiAgICAgICdBcmNob3MnOiB7fSxcbiAgICAgICdBbWF6b24nOiB7ICdLaW5kbGUnOiAxLCAnS2luZGxlIEZpcmUnOiAxIH0sXG4gICAgICAnQXN1cyc6IHsgJ1RyYW5zZm9ybWVyJzogMSB9LFxuICAgICAgJ0Jhcm5lcyAmIE5vYmxlJzogeyAnTm9vayc6IDEgfSxcbiAgICAgICdCbGFja0JlcnJ5JzogeyAnUGxheUJvb2snOiAxIH0sXG4gICAgICAnR29vZ2xlJzogeyAnR29vZ2xlIFRWJzogMSwgJ05leHVzJzogMSB9LFxuICAgICAgJ0hQJzogeyAnVG91Y2hQYWQnOiAxIH0sXG4gICAgICAnSFRDJzoge30sXG4gICAgICAnSHVhd2VpJzoge30sXG4gICAgICAnTGVub3ZvJzoge30sXG4gICAgICAnTEcnOiB7fSxcbiAgICAgICdNaWNyb3NvZnQnOiB7ICdYYm94JzogMSwgJ1hib3ggT25lJzogMSB9LFxuICAgICAgJ01vdG9yb2xhJzogeyAnWG9vbSc6IDEgfSxcbiAgICAgICdOaW50ZW5kbyc6IHsgJ1dpaSBVJzogMSwgICdXaWknOiAxIH0sXG4gICAgICAnTm9raWEnOiB7ICdMdW1pYSc6IDEgfSxcbiAgICAgICdPcHBvJzoge30sXG4gICAgICAnU2Ftc3VuZyc6IHsgJ0dhbGF4eSBTJzogMSwgJ0dhbGF4eSBTMic6IDEsICdHYWxheHkgUzMnOiAxLCAnR2FsYXh5IFM0JzogMSB9LFxuICAgICAgJ1NvbnknOiB7ICdQbGF5U3RhdGlvbic6IDEsICdQbGF5U3RhdGlvbiBWaXRhJzogMSB9LFxuICAgICAgJ1hpYW9taSc6IHsgJ01pJzogMSwgJ1JlZG1pJzogMSB9XG4gICAgfSk7XG5cbiAgICAvKiBEZXRlY3RhYmxlIG9wZXJhdGluZyBzeXN0ZW1zIChvcmRlciBpcyBpbXBvcnRhbnQpLiAqL1xuICAgIHZhciBvcyA9IGdldE9TKFtcbiAgICAgICdXaW5kb3dzIFBob25lJyxcbiAgICAgICdLYWlPUycsXG4gICAgICAnQW5kcm9pZCcsXG4gICAgICAnQ2VudE9TJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0Nocm9tZSBPUycsICdwYXR0ZXJuJzogJ0NyT1MnIH0sXG4gICAgICAnRGViaWFuJyxcbiAgICAgIHsgJ2xhYmVsJzogJ0RyYWdvbkZseSBCU0QnLCAncGF0dGVybic6ICdEcmFnb25GbHknIH0sXG4gICAgICAnRmVkb3JhJyxcbiAgICAgICdGcmVlQlNEJyxcbiAgICAgICdHZW50b28nLFxuICAgICAgJ0hhaWt1JyxcbiAgICAgICdLdWJ1bnR1JyxcbiAgICAgICdMaW51eCBNaW50JyxcbiAgICAgICdPcGVuQlNEJyxcbiAgICAgICdSZWQgSGF0JyxcbiAgICAgICdTdVNFJyxcbiAgICAgICdVYnVudHUnLFxuICAgICAgJ1h1YnVudHUnLFxuICAgICAgJ0N5Z3dpbicsXG4gICAgICAnU3ltYmlhbiBPUycsXG4gICAgICAnaHB3T1MnLFxuICAgICAgJ3dlYk9TICcsXG4gICAgICAnd2ViT1MnLFxuICAgICAgJ1RhYmxldCBPUycsXG4gICAgICAnVGl6ZW4nLFxuICAgICAgJ0xpbnV4JyxcbiAgICAgICdNYWMgT1MgWCcsXG4gICAgICAnTWFjaW50b3NoJyxcbiAgICAgICdNYWMnLFxuICAgICAgJ1dpbmRvd3MgOTg7JyxcbiAgICAgICdXaW5kb3dzICdcbiAgICBdKTtcblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBsYXlvdXQgZW5naW5lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIGxheW91dCBlbmdpbmUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0TGF5b3V0KGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IFJlZ0V4cCgnXFxcXGInICsgKFxuICAgICAgICAgIGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcylcbiAgICAgICAgKSArICdcXFxcYicsICdpJykuZXhlYyh1YSkgJiYgKGd1ZXNzLmxhYmVsIHx8IGd1ZXNzKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBtYW51ZmFjdHVyZXIgZnJvbSBhbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBndWVzc2VzIEFuIG9iamVjdCBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIG1hbnVmYWN0dXJlci5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRNYW51ZmFjdHVyZXIoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgICAgICAgLy8gTG9va3VwIHRoZSBtYW51ZmFjdHVyZXIgYnkgcHJvZHVjdCBvciBzY2FuIHRoZSBVQSBmb3IgdGhlIG1hbnVmYWN0dXJlci5cbiAgICAgICAgcmV0dXJuIHJlc3VsdCB8fCAoXG4gICAgICAgICAgdmFsdWVbcHJvZHVjdF0gfHxcbiAgICAgICAgICB2YWx1ZVsvXlthLXpdKyg/OiArW2Etel0rXFxiKSovaS5leGVjKHByb2R1Y3QpXSB8fFxuICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcXVhbGlmeShrZXkpICsgJyg/OlxcXFxifFxcXFx3KlxcXFxkKScsICdpJykuZXhlYyh1YSlcbiAgICAgICAgKSAmJiBrZXk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQaWNrcyB0aGUgYnJvd3NlciBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIGJyb3dzZXIgbmFtZS5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXROYW1lKGd1ZXNzZXMpIHtcbiAgICAgIHJldHVybiByZWR1Y2UoZ3Vlc3NlcywgZnVuY3Rpb24ocmVzdWx0LCBndWVzcykge1xuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IFJlZ0V4cCgnXFxcXGInICsgKFxuICAgICAgICAgIGd1ZXNzLnBhdHRlcm4gfHwgcXVhbGlmeShndWVzcylcbiAgICAgICAgKSArICdcXFxcYicsICdpJykuZXhlYyh1YSkgJiYgKGd1ZXNzLmxhYmVsIHx8IGd1ZXNzKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBpY2tzIHRoZSBPUyBuYW1lIGZyb20gYW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gZ3Vlc3NlcyBBbiBhcnJheSBvZiBndWVzc2VzLlxuICAgICAqIEByZXR1cm5zIHtudWxsfHN0cmluZ30gVGhlIGRldGVjdGVkIE9TIG5hbWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0T1MoZ3Vlc3Nlcykge1xuICAgICAgcmV0dXJuIHJlZHVjZShndWVzc2VzLCBmdW5jdGlvbihyZXN1bHQsIGd1ZXNzKSB7XG4gICAgICAgIHZhciBwYXR0ZXJuID0gZ3Vlc3MucGF0dGVybiB8fCBxdWFsaWZ5KGd1ZXNzKTtcbiAgICAgICAgaWYgKCFyZXN1bHQgJiYgKHJlc3VsdCA9XG4gICAgICAgICAgICAgIFJlZ0V4cCgnXFxcXGInICsgcGF0dGVybiArICcoPzovW1xcXFxkLl0rfFsgXFxcXHcuXSopJywgJ2knKS5leGVjKHVhKVxuICAgICAgICAgICAgKSkge1xuICAgICAgICAgIHJlc3VsdCA9IGNsZWFudXBPUyhyZXN1bHQsIHBhdHRlcm4sIGd1ZXNzLmxhYmVsIHx8IGd1ZXNzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUGlja3MgdGhlIHByb2R1Y3QgbmFtZSBmcm9tIGFuIGFycmF5IG9mIGd1ZXNzZXMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGd1ZXNzZXMgQW4gYXJyYXkgb2YgZ3Vlc3Nlcy5cbiAgICAgKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9IFRoZSBkZXRlY3RlZCBwcm9kdWN0IG5hbWUuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0UHJvZHVjdChndWVzc2VzKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKGd1ZXNzZXMsIGZ1bmN0aW9uKHJlc3VsdCwgZ3Vlc3MpIHtcbiAgICAgICAgdmFyIHBhdHRlcm4gPSBndWVzcy5wYXR0ZXJuIHx8IHF1YWxpZnkoZ3Vlc3MpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiAocmVzdWx0ID1cbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyAqXFxcXGQrWy5cXFxcd19dKicsICdpJykuZXhlYyh1YSkgfHxcbiAgICAgICAgICAgICAgUmVnRXhwKCdcXFxcYicgKyBwYXR0ZXJuICsgJyAqXFxcXHcrLVtcXFxcd10qJywgJ2knKS5leGVjKHVhKSB8fFxuICAgICAgICAgICAgICBSZWdFeHAoJ1xcXFxiJyArIHBhdHRlcm4gKyAnKD86OyAqKD86W2Etel0rW18tXSk/W2Etel0rXFxcXGQrfFteICgpOy1dKiknLCAnaScpLmV4ZWModWEpXG4gICAgICAgICAgICApKSB7XG4gICAgICAgICAgLy8gU3BsaXQgYnkgZm9yd2FyZCBzbGFzaCBhbmQgYXBwZW5kIHByb2R1Y3QgdmVyc2lvbiBpZiBuZWVkZWQuXG4gICAgICAgICAgaWYgKChyZXN1bHQgPSBTdHJpbmcoKGd1ZXNzLmxhYmVsICYmICFSZWdFeHAocGF0dGVybiwgJ2knKS50ZXN0KGd1ZXNzLmxhYmVsKSkgPyBndWVzcy5sYWJlbCA6IHJlc3VsdCkuc3BsaXQoJy8nKSlbMV0gJiYgIS9bXFxkLl0rLy50ZXN0KHJlc3VsdFswXSkpIHtcbiAgICAgICAgICAgIHJlc3VsdFswXSArPSAnICcgKyByZXN1bHRbMV07XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIENvcnJlY3QgY2hhcmFjdGVyIGNhc2UgYW5kIGNsZWFudXAgc3RyaW5nLlxuICAgICAgICAgIGd1ZXNzID0gZ3Vlc3MubGFiZWwgfHwgZ3Vlc3M7XG4gICAgICAgICAgcmVzdWx0ID0gZm9ybWF0KHJlc3VsdFswXVxuICAgICAgICAgICAgLnJlcGxhY2UoUmVnRXhwKHBhdHRlcm4sICdpJyksIGd1ZXNzKVxuICAgICAgICAgICAgLnJlcGxhY2UoUmVnRXhwKCc7ICooPzonICsgZ3Vlc3MgKyAnW18tXSk/JywgJ2knKSwgJyAnKVxuICAgICAgICAgICAgLnJlcGxhY2UoUmVnRXhwKCcoJyArIGd1ZXNzICsgJylbLV8uXT8oXFxcXHcpJywgJ2knKSwgJyQxICQyJykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXNvbHZlcyB0aGUgdmVyc2lvbiB1c2luZyBhbiBhcnJheSBvZiBVQSBwYXR0ZXJucy5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtBcnJheX0gcGF0dGVybnMgQW4gYXJyYXkgb2YgVUEgcGF0dGVybnMuXG4gICAgICogQHJldHVybnMge251bGx8c3RyaW5nfSBUaGUgZGV0ZWN0ZWQgdmVyc2lvbi5cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRWZXJzaW9uKHBhdHRlcm5zKSB7XG4gICAgICByZXR1cm4gcmVkdWNlKHBhdHRlcm5zLCBmdW5jdGlvbihyZXN1bHQsIHBhdHRlcm4pIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdCB8fCAoUmVnRXhwKHBhdHRlcm4gK1xuICAgICAgICAgICcoPzotW1xcXFxkLl0rL3woPzogZm9yIFtcXFxcdy1dKyk/WyAvLV0pKFtcXFxcZC5dK1teICgpOy9fLV0qKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHwgbnVsbDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYHBsYXRmb3JtLmRlc2NyaXB0aW9uYCB3aGVuIHRoZSBwbGF0Zm9ybSBvYmplY3QgaXMgY29lcmNlZCB0byBhIHN0cmluZy5cbiAgICAgKlxuICAgICAqIEBuYW1lIHRvU3RyaW5nXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyBgcGxhdGZvcm0uZGVzY3JpcHRpb25gIGlmIGF2YWlsYWJsZSwgZWxzZSBhbiBlbXB0eSBzdHJpbmcuXG4gICAgICovXG4gICAgZnVuY3Rpb24gdG9TdHJpbmdQbGF0Zm9ybSgpIHtcbiAgICAgIHJldHVybiB0aGlzLmRlc2NyaXB0aW9uIHx8ICcnO1xuICAgIH1cblxuICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgIC8vIENvbnZlcnQgbGF5b3V0IHRvIGFuIGFycmF5IHNvIHdlIGNhbiBhZGQgZXh0cmEgZGV0YWlscy5cbiAgICBsYXlvdXQgJiYgKGxheW91dCA9IFtsYXlvdXRdKTtcblxuICAgIC8vIERldGVjdCBBbmRyb2lkIHByb2R1Y3RzLlxuICAgIC8vIEJyb3dzZXJzIG9uIEFuZHJvaWQgZGV2aWNlcyB0eXBpY2FsbHkgcHJvdmlkZSB0aGVpciBwcm9kdWN0IElEUyBhZnRlciBcIkFuZHJvaWQ7XCJcbiAgICAvLyB1cCB0byBcIkJ1aWxkXCIgb3IgXCIpIEFwcGxlV2ViS2l0XCIuXG4gICAgLy8gRXhhbXBsZTpcbiAgICAvLyBcIk1vemlsbGEvNS4wIChMaW51eDsgQW5kcm9pZCA4LjEuMDsgTW90byBHICg1KSBQbHVzKSBBcHBsZVdlYktpdC81MzcuMzZcbiAgICAvLyAoS0hUTUwsIGxpa2UgR2Vja28pIENocm9tZS83MC4wLjM1MzguODAgTW9iaWxlIFNhZmFyaS81MzcuMzZcIlxuICAgIGlmICgvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgJiYgIXByb2R1Y3QgJiZcbiAgICAgICAgKGRhdGEgPSAvXFxiQW5kcm9pZFteO10qOyguKj8pKD86QnVpbGR8XFwpIEFwcGxlV2ViS2l0KVxcYi9pLmV4ZWModWEpKSkge1xuICAgICAgcHJvZHVjdCA9IHRyaW0oZGF0YVsxXSlcbiAgICAgICAgLy8gUmVwbGFjZSBhbnkgbGFuZ3VhZ2UgY29kZXMgKGVnLiBcImVuLVVTXCIpLlxuICAgICAgICAucmVwbGFjZSgvXlthLXpdezJ9LVthLXpdezJ9O1xccyovaSwgJycpXG4gICAgICAgIHx8IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBwcm9kdWN0IG5hbWVzIHRoYXQgY29udGFpbiB0aGVpciBtYW51ZmFjdHVyZXIncyBuYW1lLlxuICAgIGlmIChtYW51ZmFjdHVyZXIgJiYgIXByb2R1Y3QpIHtcbiAgICAgIHByb2R1Y3QgPSBnZXRQcm9kdWN0KFttYW51ZmFjdHVyZXJdKTtcbiAgICB9IGVsc2UgaWYgKG1hbnVmYWN0dXJlciAmJiBwcm9kdWN0KSB7XG4gICAgICBwcm9kdWN0ID0gcHJvZHVjdFxuICAgICAgICAucmVwbGFjZShSZWdFeHAoJ14oJyArIHF1YWxpZnkobWFudWZhY3R1cmVyKSArICcpWy1fLlxcXFxzXScsICdpJyksIG1hbnVmYWN0dXJlciArICcgJylcbiAgICAgICAgLnJlcGxhY2UoUmVnRXhwKCdeKCcgKyBxdWFsaWZ5KG1hbnVmYWN0dXJlcikgKyAnKVstXy5dPyhcXFxcdyknLCAnaScpLCBtYW51ZmFjdHVyZXIgKyAnICQyJyk7XG4gICAgfVxuICAgIC8vIENsZWFuIHVwIEdvb2dsZSBUVi5cbiAgICBpZiAoKGRhdGEgPSAvXFxiR29vZ2xlIFRWXFxiLy5leGVjKHByb2R1Y3QpKSkge1xuICAgICAgcHJvZHVjdCA9IGRhdGFbMF07XG4gICAgfVxuICAgIC8vIERldGVjdCBzaW11bGF0b3JzLlxuICAgIGlmICgvXFxiU2ltdWxhdG9yXFxiL2kudGVzdCh1YSkpIHtcbiAgICAgIHByb2R1Y3QgPSAocHJvZHVjdCA/IHByb2R1Y3QgKyAnICcgOiAnJykgKyAnU2ltdWxhdG9yJztcbiAgICB9XG4gICAgLy8gRGV0ZWN0IE9wZXJhIE1pbmkgOCsgcnVubmluZyBpbiBUdXJiby9VbmNvbXByZXNzZWQgbW9kZSBvbiBpT1MuXG4gICAgaWYgKG5hbWUgPT0gJ09wZXJhIE1pbmknICYmIC9cXGJPUGlPU1xcYi8udGVzdCh1YSkpIHtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ3J1bm5pbmcgaW4gVHVyYm8vVW5jb21wcmVzc2VkIG1vZGUnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIE1vYmlsZSAxMS5cbiAgICBpZiAobmFtZSA9PSAnSUUnICYmIC9cXGJsaWtlIGlQaG9uZSBPU1xcYi8udGVzdCh1YSkpIHtcbiAgICAgIGRhdGEgPSBwYXJzZSh1YS5yZXBsYWNlKC9saWtlIGlQaG9uZSBPUy8sICcnKSk7XG4gICAgICBtYW51ZmFjdHVyZXIgPSBkYXRhLm1hbnVmYWN0dXJlcjtcbiAgICAgIHByb2R1Y3QgPSBkYXRhLnByb2R1Y3Q7XG4gICAgfVxuICAgIC8vIERldGVjdCBpT1MuXG4gICAgZWxzZSBpZiAoL15pUC8udGVzdChwcm9kdWN0KSkge1xuICAgICAgbmFtZSB8fCAobmFtZSA9ICdTYWZhcmknKTtcbiAgICAgIG9zID0gJ2lPUycgKyAoKGRhdGEgPSAvIE9TIChbXFxkX10rKS9pLmV4ZWModWEpKVxuICAgICAgICA/ICcgJyArIGRhdGFbMV0ucmVwbGFjZSgvXy9nLCAnLicpXG4gICAgICAgIDogJycpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgS3VidW50dS5cbiAgICBlbHNlIGlmIChuYW1lID09ICdLb25xdWVyb3InICYmIC9eTGludXhcXGIvaS50ZXN0KG9zKSkge1xuICAgICAgb3MgPSAnS3VidW50dSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBBbmRyb2lkIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKChtYW51ZmFjdHVyZXIgJiYgbWFudWZhY3R1cmVyICE9ICdHb29nbGUnICYmXG4gICAgICAgICgoL0Nocm9tZS8udGVzdChuYW1lKSAmJiAhL1xcYk1vYmlsZSBTYWZhcmlcXGIvaS50ZXN0KHVhKSkgfHwgL1xcYlZpdGFcXGIvLnRlc3QocHJvZHVjdCkpKSB8fFxuICAgICAgICAoL1xcYkFuZHJvaWRcXGIvLnRlc3Qob3MpICYmIC9eQ2hyb21lLy50ZXN0KG5hbWUpICYmIC9cXGJWZXJzaW9uXFwvL2kudGVzdCh1YSkpKSB7XG4gICAgICBuYW1lID0gJ0FuZHJvaWQgQnJvd3Nlcic7XG4gICAgICBvcyA9IC9cXGJBbmRyb2lkXFxiLy50ZXN0KG9zKSA/IG9zIDogJ0FuZHJvaWQnO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgU2lsayBkZXNrdG9wL2FjY2VsZXJhdGVkIG1vZGVzLlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ1NpbGsnKSB7XG4gICAgICBpZiAoIS9cXGJNb2JpL2kudGVzdCh1YSkpIHtcbiAgICAgICAgb3MgPSAnQW5kcm9pZCc7XG4gICAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgICAgfVxuICAgICAgaWYgKC9BY2NlbGVyYXRlZCAqPSAqdHJ1ZS9pLnRlc3QodWEpKSB7XG4gICAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2FjY2VsZXJhdGVkJyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBVQyBCcm93c2VyIHNwZWVkIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnVUMgQnJvd3NlcicgJiYgL1xcYlVDV0VCXFxiLy50ZXN0KHVhKSkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgnc3BlZWQgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgUGFsZU1vb24gaWRlbnRpZnlpbmcgYXMgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdQYWxlTW9vbicgJiYgKGRhdGEgPSAvXFxiRmlyZWZveFxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkpKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyBGaXJlZm94ICcgKyBkYXRhWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggT1MgYW5kIHByb2R1Y3RzIHJ1bm5pbmcgRmlyZWZveC5cbiAgICBlbHNlIGlmIChuYW1lID09ICdGaXJlZm94JyAmJiAoZGF0YSA9IC9cXGIoTW9iaWxlfFRhYmxldHxUVilcXGIvaS5leGVjKHVhKSkpIHtcbiAgICAgIG9zIHx8IChvcyA9ICdGaXJlZm94IE9TJyk7XG4gICAgICBwcm9kdWN0IHx8IChwcm9kdWN0ID0gZGF0YVsxXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBmYWxzZSBwb3NpdGl2ZXMgZm9yIEZpcmVmb3gvU2FmYXJpLlxuICAgIGVsc2UgaWYgKCFuYW1lIHx8IChkYXRhID0gIS9cXGJNaW5lZmllbGRcXGIvaS50ZXN0KHVhKSAmJiAvXFxiKD86RmlyZWZveHxTYWZhcmkpXFxiLy5leGVjKG5hbWUpKSkge1xuICAgICAgLy8gRXNjYXBlIHRoZSBgL2AgZm9yIEZpcmVmb3ggMS5cbiAgICAgIGlmIChuYW1lICYmICFwcm9kdWN0ICYmIC9bXFwvLF18XlteKF0rP1xcKS8udGVzdCh1YS5zbGljZSh1YS5pbmRleE9mKGRhdGEgKyAnLycpICsgOCkpKSB7XG4gICAgICAgIC8vIENsZWFyIG5hbWUgb2YgZmFsc2UgcG9zaXRpdmVzLlxuICAgICAgICBuYW1lID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFJlYXNzaWduIGEgZ2VuZXJpYyBuYW1lLlxuICAgICAgaWYgKChkYXRhID0gcHJvZHVjdCB8fCBtYW51ZmFjdHVyZXIgfHwgb3MpICYmXG4gICAgICAgICAgKHByb2R1Y3QgfHwgbWFudWZhY3R1cmVyIHx8IC9cXGIoPzpBbmRyb2lkfFN5bWJpYW4gT1N8VGFibGV0IE9TfHdlYk9TKVxcYi8udGVzdChvcykpKSB7XG4gICAgICAgIG5hbWUgPSAvW2Etel0rKD86IEhhdCk/L2kuZXhlYygvXFxiQW5kcm9pZFxcYi8udGVzdChvcykgPyBvcyA6IGRhdGEpICsgJyBCcm93c2VyJztcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQWRkIENocm9tZSB2ZXJzaW9uIHRvIGRlc2NyaXB0aW9uIGZvciBFbGVjdHJvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdFbGVjdHJvbicgJiYgKGRhdGEgPSAoL1xcYkNocm9tZVxcLyhbXFxkLl0rKVxcYi8uZXhlYyh1YSkgfHwgMClbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCdDaHJvbWl1bSAnICsgZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBub24tT3BlcmEgKFByZXN0by1iYXNlZCkgdmVyc2lvbnMgKG9yZGVyIGlzIGltcG9ydGFudCkuXG4gICAgaWYgKCF2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gZ2V0VmVyc2lvbihbXG4gICAgICAgICcoPzpDbG91ZDl8Q3JpT1N8Q3JNb3xFZGdlfEVkZ3xFZGdBfEVkZ2lPU3xGeGlPU3xIZWFkbGVzc0Nocm9tZXxJRU1vYmlsZXxJcm9ufE9wZXJhID9NaW5pfE9QaU9TfE9QUnxSYXZlbnxTYW1zdW5nQnJvd3NlcnxTaWxrKD8hL1tcXFxcZC5dKyQpfFVDQnJvd3NlcnxZYUJyb3dzZXIpJyxcbiAgICAgICAgJ1ZlcnNpb24nLFxuICAgICAgICBxdWFsaWZ5KG5hbWUpLFxuICAgICAgICAnKD86RmlyZWZveHxNaW5lZmllbGR8TmV0RnJvbnQpJ1xuICAgICAgXSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBzdHViYm9ybiBsYXlvdXQgZW5naW5lcy5cbiAgICBpZiAoKGRhdGEgPVxuICAgICAgICAgIGxheW91dCA9PSAnaUNhYicgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+IDMgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAvXFxiT3BlcmFcXGIvLnRlc3QobmFtZSkgJiYgKC9cXGJPUFJcXGIvLnRlc3QodWEpID8gJ0JsaW5rJyA6ICdQcmVzdG8nKSB8fFxuICAgICAgICAgIC9cXGIoPzpNaWRvcml8Tm9va3xTYWZhcmkpXFxiL2kudGVzdCh1YSkgJiYgIS9eKD86VHJpZGVudHxFZGdlSFRNTCkkLy50ZXN0KGxheW91dCkgJiYgJ1dlYktpdCcgfHxcbiAgICAgICAgICAhbGF5b3V0ICYmIC9cXGJNU0lFXFxiL2kudGVzdCh1YSkgJiYgKG9zID09ICdNYWMgT1MnID8gJ1Rhc21hbicgOiAnVHJpZGVudCcpIHx8XG4gICAgICAgICAgbGF5b3V0ID09ICdXZWJLaXQnICYmIC9cXGJQbGF5U3RhdGlvblxcYig/ISBWaXRhXFxiKS9pLnRlc3QobmFtZSkgJiYgJ05ldEZyb250J1xuICAgICAgICApKSB7XG4gICAgICBsYXlvdXQgPSBbZGF0YV07XG4gICAgfVxuICAgIC8vIERldGVjdCBXaW5kb3dzIFBob25lIDcgZGVza3RvcCBtb2RlLlxuICAgIGlmIChuYW1lID09ICdJRScgJiYgKGRhdGEgPSAoLzsgKig/OlhCTFdQfFp1bmVXUCkoXFxkKykvaS5leGVjKHVhKSB8fCAwKVsxXSkpIHtcbiAgICAgIG5hbWUgKz0gJyBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSAnICsgKC9cXCskLy50ZXN0KGRhdGEpID8gZGF0YSA6IGRhdGEgKyAnLngnKTtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2Rlc2t0b3AgbW9kZScpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgV2luZG93cyBQaG9uZSA4LnggZGVza3RvcCBtb2RlLlxuICAgIGVsc2UgaWYgKC9cXGJXUERlc2t0b3BcXGIvaS50ZXN0KHVhKSkge1xuICAgICAgbmFtZSA9ICdJRSBNb2JpbGUnO1xuICAgICAgb3MgPSAnV2luZG93cyBQaG9uZSA4LngnO1xuICAgICAgZGVzY3JpcHRpb24udW5zaGlmdCgnZGVza3RvcCBtb2RlJyk7XG4gICAgICB2ZXJzaW9uIHx8ICh2ZXJzaW9uID0gKC9cXGJydjooW1xcZC5dKykvLmV4ZWModWEpIHx8IDApWzFdKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IElFIDExIGlkZW50aWZ5aW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgIGVsc2UgaWYgKG5hbWUgIT0gJ0lFJyAmJiBsYXlvdXQgPT0gJ1RyaWRlbnQnICYmIChkYXRhID0gL1xcYnJ2OihbXFxkLl0rKS8uZXhlYyh1YSkpKSB7XG4gICAgICBpZiAobmFtZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdpZGVudGlmeWluZyBhcyAnICsgbmFtZSArICh2ZXJzaW9uID8gJyAnICsgdmVyc2lvbiA6ICcnKSk7XG4gICAgICB9XG4gICAgICBuYW1lID0gJ0lFJztcbiAgICAgIHZlcnNpb24gPSBkYXRhWzFdO1xuICAgIH1cbiAgICAvLyBMZXZlcmFnZSBlbnZpcm9ubWVudCBmZWF0dXJlcy5cbiAgICBpZiAodXNlRmVhdHVyZXMpIHtcbiAgICAgIC8vIERldGVjdCBzZXJ2ZXItc2lkZSBlbnZpcm9ubWVudHMuXG4gICAgICAvLyBSaGlubyBoYXMgYSBnbG9iYWwgZnVuY3Rpb24gd2hpbGUgb3RoZXJzIGhhdmUgYSBnbG9iYWwgb2JqZWN0LlxuICAgICAgaWYgKGlzSG9zdFR5cGUoY29udGV4dCwgJ2dsb2JhbCcpKSB7XG4gICAgICAgIGlmIChqYXZhKSB7XG4gICAgICAgICAgZGF0YSA9IGphdmEubGFuZy5TeXN0ZW07XG4gICAgICAgICAgYXJjaCA9IGRhdGEuZ2V0UHJvcGVydHkoJ29zLmFyY2gnKTtcbiAgICAgICAgICBvcyA9IG9zIHx8IGRhdGEuZ2V0UHJvcGVydHkoJ29zLm5hbWUnKSArICcgJyArIGRhdGEuZ2V0UHJvcGVydHkoJ29zLnZlcnNpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmhpbm8pIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmVyc2lvbiA9IGNvbnRleHQucmVxdWlyZSgncmluZ28vZW5naW5lJykudmVyc2lvbi5qb2luKCcuJyk7XG4gICAgICAgICAgICBuYW1lID0gJ1JpbmdvSlMnO1xuICAgICAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICAgICAgaWYgKChkYXRhID0gY29udGV4dC5zeXN0ZW0pICYmIGRhdGEuZ2xvYmFsLnN5c3RlbSA9PSBjb250ZXh0LnN5c3RlbSkge1xuICAgICAgICAgICAgICBuYW1lID0gJ05hcndoYWwnO1xuICAgICAgICAgICAgICBvcyB8fCAob3MgPSBkYXRhWzBdLm9zIHx8IG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnUmhpbm8nO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChcbiAgICAgICAgICB0eXBlb2YgY29udGV4dC5wcm9jZXNzID09ICdvYmplY3QnICYmICFjb250ZXh0LnByb2Nlc3MuYnJvd3NlciAmJlxuICAgICAgICAgIChkYXRhID0gY29udGV4dC5wcm9jZXNzKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAodHlwZW9mIGRhdGEudmVyc2lvbnMgPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZGF0YS52ZXJzaW9ucy5lbGVjdHJvbiA9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5wdXNoKCdOb2RlICcgKyBkYXRhLnZlcnNpb25zLm5vZGUpO1xuICAgICAgICAgICAgICBuYW1lID0gJ0VsZWN0cm9uJztcbiAgICAgICAgICAgICAgdmVyc2lvbiA9IGRhdGEudmVyc2lvbnMuZWxlY3Ryb247XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLnZlcnNpb25zLm53ID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0Nocm9taXVtICcgKyB2ZXJzaW9uLCAnTm9kZSAnICsgZGF0YS52ZXJzaW9ucy5ub2RlKTtcbiAgICAgICAgICAgICAgbmFtZSA9ICdOVy5qcyc7XG4gICAgICAgICAgICAgIHZlcnNpb24gPSBkYXRhLnZlcnNpb25zLm53O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgICAgIG5hbWUgPSAnTm9kZS5qcyc7XG4gICAgICAgICAgICBhcmNoID0gZGF0YS5hcmNoO1xuICAgICAgICAgICAgb3MgPSBkYXRhLnBsYXRmb3JtO1xuICAgICAgICAgICAgdmVyc2lvbiA9IC9bXFxkLl0rLy5leGVjKGRhdGEudmVyc2lvbik7XG4gICAgICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbiA/IHZlcnNpb25bMF0gOiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IEFkb2JlIEFJUi5cbiAgICAgIGVsc2UgaWYgKGdldENsYXNzT2YoKGRhdGEgPSBjb250ZXh0LnJ1bnRpbWUpKSA9PSBhaXJSdW50aW1lQ2xhc3MpIHtcbiAgICAgICAgbmFtZSA9ICdBZG9iZSBBSVInO1xuICAgICAgICBvcyA9IGRhdGEuZmxhc2guc3lzdGVtLkNhcGFiaWxpdGllcy5vcztcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBQaGFudG9tSlMuXG4gICAgICBlbHNlIGlmIChnZXRDbGFzc09mKChkYXRhID0gY29udGV4dC5waGFudG9tKSkgPT0gcGhhbnRvbUNsYXNzKSB7XG4gICAgICAgIG5hbWUgPSAnUGhhbnRvbUpTJztcbiAgICAgICAgdmVyc2lvbiA9IChkYXRhID0gZGF0YS52ZXJzaW9uIHx8IG51bGwpICYmIChkYXRhLm1ham9yICsgJy4nICsgZGF0YS5taW5vciArICcuJyArIGRhdGEucGF0Y2gpO1xuICAgICAgfVxuICAgICAgLy8gRGV0ZWN0IElFIGNvbXBhdGliaWxpdHkgbW9kZXMuXG4gICAgICBlbHNlIGlmICh0eXBlb2YgZG9jLmRvY3VtZW50TW9kZSA9PSAnbnVtYmVyJyAmJiAoZGF0YSA9IC9cXGJUcmlkZW50XFwvKFxcZCspL2kuZXhlYyh1YSkpKSB7XG4gICAgICAgIC8vIFdlJ3JlIGluIGNvbXBhdGliaWxpdHkgbW9kZSB3aGVuIHRoZSBUcmlkZW50IHZlcnNpb24gKyA0IGRvZXNuJ3RcbiAgICAgICAgLy8gZXF1YWwgdGhlIGRvY3VtZW50IG1vZGUuXG4gICAgICAgIHZlcnNpb24gPSBbdmVyc2lvbiwgZG9jLmRvY3VtZW50TW9kZV07XG4gICAgICAgIGlmICgoZGF0YSA9ICtkYXRhWzFdICsgNCkgIT0gdmVyc2lvblsxXSkge1xuICAgICAgICAgIGRlc2NyaXB0aW9uLnB1c2goJ0lFICcgKyB2ZXJzaW9uWzFdICsgJyBtb2RlJyk7XG4gICAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnJyk7XG4gICAgICAgICAgdmVyc2lvblsxXSA9IGRhdGE7XG4gICAgICAgIH1cbiAgICAgICAgdmVyc2lvbiA9IG5hbWUgPT0gJ0lFJyA/IFN0cmluZyh2ZXJzaW9uWzFdLnRvRml4ZWQoMSkpIDogdmVyc2lvblswXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBJRSAxMSBtYXNraW5nIGFzIG90aGVyIGJyb3dzZXJzLlxuICAgICAgZWxzZSBpZiAodHlwZW9mIGRvYy5kb2N1bWVudE1vZGUgPT0gJ251bWJlcicgJiYgL14oPzpDaHJvbWV8RmlyZWZveClcXGIvLnRlc3QobmFtZSkpIHtcbiAgICAgICAgZGVzY3JpcHRpb24ucHVzaCgnbWFza2luZyBhcyAnICsgbmFtZSArICcgJyArIHZlcnNpb24pO1xuICAgICAgICBuYW1lID0gJ0lFJztcbiAgICAgICAgdmVyc2lvbiA9ICcxMS4wJztcbiAgICAgICAgbGF5b3V0ID0gWydUcmlkZW50J107XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcyAmJiBmb3JtYXQob3MpO1xuICAgIH1cbiAgICAvLyBEZXRlY3QgcHJlcmVsZWFzZSBwaGFzZXMuXG4gICAgaWYgKHZlcnNpb24gJiYgKGRhdGEgPVxuICAgICAgICAgIC8oPzpbYWJdfGRwfHByZXxbYWJdXFxkK3ByZSkoPzpcXGQrXFwrPyk/JC9pLmV4ZWModmVyc2lvbikgfHxcbiAgICAgICAgICAvKD86YWxwaGF8YmV0YSkoPzogP1xcZCk/L2kuZXhlYyh1YSArICc7JyArICh1c2VGZWF0dXJlcyAmJiBuYXYuYXBwTWlub3JWZXJzaW9uKSkgfHxcbiAgICAgICAgICAvXFxiTWluZWZpZWxkXFxiL2kudGVzdCh1YSkgJiYgJ2EnXG4gICAgICAgICkpIHtcbiAgICAgIHByZXJlbGVhc2UgPSAvYi9pLnRlc3QoZGF0YSkgPyAnYmV0YScgOiAnYWxwaGEnO1xuICAgICAgdmVyc2lvbiA9IHZlcnNpb24ucmVwbGFjZShSZWdFeHAoZGF0YSArICdcXFxcKz8kJyksICcnKSArXG4gICAgICAgIChwcmVyZWxlYXNlID09ICdiZXRhJyA/IGJldGEgOiBhbHBoYSkgKyAoL1xcZCtcXCs/Ly5leGVjKGRhdGEpIHx8ICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IEZpcmVmb3ggTW9iaWxlLlxuICAgIGlmIChuYW1lID09ICdGZW5uZWMnIHx8IG5hbWUgPT0gJ0ZpcmVmb3gnICYmIC9cXGIoPzpBbmRyb2lkfEZpcmVmb3ggT1N8S2FpT1MpXFxiLy50ZXN0KG9zKSkge1xuICAgICAgbmFtZSA9ICdGaXJlZm94IE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIE9ic2N1cmUgTWF4dGhvbidzIHVucmVsaWFibGUgdmVyc2lvbi5cbiAgICBlbHNlIGlmIChuYW1lID09ICdNYXh0aG9uJyAmJiB2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvbi5yZXBsYWNlKC9cXC5bXFxkLl0rLywgJy54Jyk7XG4gICAgfVxuICAgIC8vIERldGVjdCBYYm94IDM2MCBhbmQgWGJveCBPbmUuXG4gICAgZWxzZSBpZiAoL1xcYlhib3hcXGIvaS50ZXN0KHByb2R1Y3QpKSB7XG4gICAgICBpZiAocHJvZHVjdCA9PSAnWGJveCAzNjAnKSB7XG4gICAgICAgIG9zID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwcm9kdWN0ID09ICdYYm94IDM2MCcgJiYgL1xcYklFTW9iaWxlXFxiLy50ZXN0KHVhKSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdtb2JpbGUgbW9kZScpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbW9iaWxlIHBvc3RmaXguXG4gICAgZWxzZSBpZiAoKC9eKD86Q2hyb21lfElFfE9wZXJhKSQvLnRlc3QobmFtZSkgfHwgbmFtZSAmJiAhcHJvZHVjdCAmJiAhL0Jyb3dzZXJ8TW9iaS8udGVzdChuYW1lKSkgJiZcbiAgICAgICAgKG9zID09ICdXaW5kb3dzIENFJyB8fCAvTW9iaS9pLnRlc3QodWEpKSkge1xuICAgICAgbmFtZSArPSAnIE1vYmlsZSc7XG4gICAgfVxuICAgIC8vIERldGVjdCBJRSBwbGF0Zm9ybSBwcmV2aWV3LlxuICAgIGVsc2UgaWYgKG5hbWUgPT0gJ0lFJyAmJiB1c2VGZWF0dXJlcykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGNvbnRleHQuZXh0ZXJuYWwgPT09IG51bGwpIHtcbiAgICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdwbGF0Zm9ybSBwcmV2aWV3Jyk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdlbWJlZGRlZCcpO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBEZXRlY3QgQmxhY2tCZXJyeSBPUyB2ZXJzaW9uLlxuICAgIC8vIGh0dHA6Ly9kb2NzLmJsYWNrYmVycnkuY29tL2VuL2RldmVsb3BlcnMvZGVsaXZlcmFibGVzLzE4MTY5L0hUVFBfaGVhZGVyc19zZW50X2J5X0JCX0Jyb3dzZXJfMTIzNDkxMV8xMS5qc3BcbiAgICBlbHNlIGlmICgoL1xcYkJsYWNrQmVycnlcXGIvLnRlc3QocHJvZHVjdCkgfHwgL1xcYkJCMTBcXGIvLnRlc3QodWEpKSAmJiAoZGF0YSA9XG4gICAgICAgICAgKFJlZ0V4cChwcm9kdWN0LnJlcGxhY2UoLyArL2csICcgKicpICsgJy8oWy5cXFxcZF0rKScsICdpJykuZXhlYyh1YSkgfHwgMClbMV0gfHxcbiAgICAgICAgICB2ZXJzaW9uXG4gICAgICAgICkpIHtcbiAgICAgIGRhdGEgPSBbZGF0YSwgL0JCMTAvLnRlc3QodWEpXTtcbiAgICAgIG9zID0gKGRhdGFbMV0gPyAocHJvZHVjdCA9IG51bGwsIG1hbnVmYWN0dXJlciA9ICdCbGFja0JlcnJ5JykgOiAnRGV2aWNlIFNvZnR3YXJlJykgKyAnICcgKyBkYXRhWzBdO1xuICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBpZGVudGlmeWluZy9tYXNraW5nIGl0c2VsZiBhcyBhbm90aGVyIGJyb3dzZXIuXG4gICAgLy8gaHR0cDovL3d3dy5vcGVyYS5jb20vc3VwcG9ydC9rYi92aWV3Lzg0My9cbiAgICBlbHNlIGlmICh0aGlzICE9IGZvck93biAmJiBwcm9kdWN0ICE9ICdXaWknICYmIChcbiAgICAgICAgICAodXNlRmVhdHVyZXMgJiYgb3BlcmEpIHx8XG4gICAgICAgICAgKC9PcGVyYS8udGVzdChuYW1lKSAmJiAvXFxiKD86TVNJRXxGaXJlZm94KVxcYi9pLnRlc3QodWEpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdGaXJlZm94JyAmJiAvXFxiT1MgWCAoPzpcXGQrXFwuKXsyLH0vLnRlc3Qob3MpKSB8fFxuICAgICAgICAgIChuYW1lID09ICdJRScgJiYgKFxuICAgICAgICAgICAgKG9zICYmICEvXldpbi8udGVzdChvcykgJiYgdmVyc2lvbiA+IDUuNSkgfHxcbiAgICAgICAgICAgIC9cXGJXaW5kb3dzIFhQXFxiLy50ZXN0KG9zKSAmJiB2ZXJzaW9uID4gOCB8fFxuICAgICAgICAgICAgdmVyc2lvbiA9PSA4ICYmICEvXFxiVHJpZGVudFxcYi8udGVzdCh1YSlcbiAgICAgICAgICApKVxuICAgICAgICApICYmICFyZU9wZXJhLnRlc3QoKGRhdGEgPSBwYXJzZS5jYWxsKGZvck93biwgdWEucmVwbGFjZShyZU9wZXJhLCAnJykgKyAnOycpKSkgJiYgZGF0YS5uYW1lKSB7XG4gICAgICAvLyBXaGVuIFwiaWRlbnRpZnlpbmdcIiwgdGhlIFVBIGNvbnRhaW5zIGJvdGggT3BlcmEgYW5kIHRoZSBvdGhlciBicm93c2VyJ3MgbmFtZS5cbiAgICAgIGRhdGEgPSAnaW5nIGFzICcgKyBkYXRhLm5hbWUgKyAoKGRhdGEgPSBkYXRhLnZlcnNpb24pID8gJyAnICsgZGF0YSA6ICcnKTtcbiAgICAgIGlmIChyZU9wZXJhLnRlc3QobmFtZSkpIHtcbiAgICAgICAgaWYgKC9cXGJJRVxcYi8udGVzdChkYXRhKSAmJiBvcyA9PSAnTWFjIE9TJykge1xuICAgICAgICAgIG9zID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gJ2lkZW50aWZ5JyArIGRhdGE7XG4gICAgICB9XG4gICAgICAvLyBXaGVuIFwibWFza2luZ1wiLCB0aGUgVUEgY29udGFpbnMgb25seSB0aGUgb3RoZXIgYnJvd3NlcidzIG5hbWUuXG4gICAgICBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdtYXNrJyArIGRhdGE7XG4gICAgICAgIGlmIChvcGVyYUNsYXNzKSB7XG4gICAgICAgICAgbmFtZSA9IGZvcm1hdChvcGVyYUNsYXNzLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0gJ09wZXJhJztcbiAgICAgICAgfVxuICAgICAgICBpZiAoL1xcYklFXFxiLy50ZXN0KGRhdGEpKSB7XG4gICAgICAgICAgb3MgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdXNlRmVhdHVyZXMpIHtcbiAgICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGF5b3V0ID0gWydQcmVzdG8nXTtcbiAgICAgIGRlc2NyaXB0aW9uLnB1c2goZGF0YSk7XG4gICAgfVxuICAgIC8vIERldGVjdCBXZWJLaXQgTmlnaHRseSBhbmQgYXBwcm94aW1hdGUgQ2hyb21lL1NhZmFyaSB2ZXJzaW9ucy5cbiAgICBpZiAoKGRhdGEgPSAoL1xcYkFwcGxlV2ViS2l0XFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgLy8gQ29ycmVjdCBidWlsZCBudW1iZXIgZm9yIG51bWVyaWMgY29tcGFyaXNvbi5cbiAgICAgIC8vIChlLmcuIFwiNTMyLjVcIiBiZWNvbWVzIFwiNTMyLjA1XCIpXG4gICAgICBkYXRhID0gW3BhcnNlRmxvYXQoZGF0YS5yZXBsYWNlKC9cXC4oXFxkKSQvLCAnLjAkMScpKSwgZGF0YV07XG4gICAgICAvLyBOaWdodGx5IGJ1aWxkcyBhcmUgcG9zdGZpeGVkIHdpdGggYSBcIitcIi5cbiAgICAgIGlmIChuYW1lID09ICdTYWZhcmknICYmIGRhdGFbMV0uc2xpY2UoLTEpID09ICcrJykge1xuICAgICAgICBuYW1lID0gJ1dlYktpdCBOaWdodGx5JztcbiAgICAgICAgcHJlcmVsZWFzZSA9ICdhbHBoYSc7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhWzFdLnNsaWNlKDAsIC0xKTtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIGluY29ycmVjdCBicm93c2VyIHZlcnNpb25zLlxuICAgICAgZWxzZSBpZiAodmVyc2lvbiA9PSBkYXRhWzFdIHx8XG4gICAgICAgICAgdmVyc2lvbiA9PSAoZGF0YVsyXSA9ICgvXFxiU2FmYXJpXFwvKFtcXGQuXStcXCs/KS9pLmV4ZWModWEpIHx8IDApWzFdKSkge1xuICAgICAgICB2ZXJzaW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgZnVsbCBDaHJvbWUgdmVyc2lvbiB3aGVuIGF2YWlsYWJsZS5cbiAgICAgIGRhdGFbMV0gPSAoL1xcYig/OkhlYWRsZXNzKT9DaHJvbWVcXC8oW1xcZC5dKykvaS5leGVjKHVhKSB8fCAwKVsxXTtcbiAgICAgIC8vIERldGVjdCBCbGluayBsYXlvdXQgZW5naW5lLlxuICAgICAgaWYgKGRhdGFbMF0gPT0gNTM3LjM2ICYmIGRhdGFbMl0gPT0gNTM3LjM2ICYmIHBhcnNlRmxvYXQoZGF0YVsxXSkgPj0gMjggJiYgbGF5b3V0ID09ICdXZWJLaXQnKSB7XG4gICAgICAgIGxheW91dCA9IFsnQmxpbmsnXTtcbiAgICAgIH1cbiAgICAgIC8vIERldGVjdCBKYXZhU2NyaXB0Q29yZS5cbiAgICAgIC8vIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNjc2ODQ3NC9ob3ctY2FuLWktZGV0ZWN0LXdoaWNoLWphdmFzY3JpcHQtZW5naW5lLXY4LW9yLWpzYy1pcy11c2VkLWF0LXJ1bnRpbWUtaW4tYW5kcm9pXG4gICAgICBpZiAoIXVzZUZlYXR1cmVzIHx8ICghbGlrZUNocm9tZSAmJiAhZGF0YVsxXSkpIHtcbiAgICAgICAgbGF5b3V0ICYmIChsYXlvdXRbMV0gPSAnbGlrZSBTYWZhcmknKTtcbiAgICAgICAgZGF0YSA9IChkYXRhID0gZGF0YVswXSwgZGF0YSA8IDQwMCA/IDEgOiBkYXRhIDwgNTAwID8gMiA6IGRhdGEgPCA1MjYgPyAzIDogZGF0YSA8IDUzMyA/IDQgOiBkYXRhIDwgNTM0ID8gJzQrJyA6IGRhdGEgPCA1MzUgPyA1IDogZGF0YSA8IDUzNyA/IDYgOiBkYXRhIDwgNTM4ID8gNyA6IGRhdGEgPCA2MDEgPyA4IDogZGF0YSA8IDYwMiA/IDkgOiBkYXRhIDwgNjA0ID8gMTAgOiBkYXRhIDwgNjA2ID8gMTEgOiBkYXRhIDwgNjA4ID8gMTIgOiAnMTInKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxheW91dCAmJiAobGF5b3V0WzFdID0gJ2xpa2UgQ2hyb21lJyk7XG4gICAgICAgIGRhdGEgPSBkYXRhWzFdIHx8IChkYXRhID0gZGF0YVswXSwgZGF0YSA8IDUzMCA/IDEgOiBkYXRhIDwgNTMyID8gMiA6IGRhdGEgPCA1MzIuMDUgPyAzIDogZGF0YSA8IDUzMyA/IDQgOiBkYXRhIDwgNTM0LjAzID8gNSA6IGRhdGEgPCA1MzQuMDcgPyA2IDogZGF0YSA8IDUzNC4xMCA/IDcgOiBkYXRhIDwgNTM0LjEzID8gOCA6IGRhdGEgPCA1MzQuMTYgPyA5IDogZGF0YSA8IDUzNC4yNCA/IDEwIDogZGF0YSA8IDUzNC4zMCA/IDExIDogZGF0YSA8IDUzNS4wMSA/IDEyIDogZGF0YSA8IDUzNS4wMiA/ICcxMysnIDogZGF0YSA8IDUzNS4wNyA/IDE1IDogZGF0YSA8IDUzNS4xMSA/IDE2IDogZGF0YSA8IDUzNS4xOSA/IDE3IDogZGF0YSA8IDUzNi4wNSA/IDE4IDogZGF0YSA8IDUzNi4xMCA/IDE5IDogZGF0YSA8IDUzNy4wMSA/IDIwIDogZGF0YSA8IDUzNy4xMSA/ICcyMSsnIDogZGF0YSA8IDUzNy4xMyA/IDIzIDogZGF0YSA8IDUzNy4xOCA/IDI0IDogZGF0YSA8IDUzNy4yNCA/IDI1IDogZGF0YSA8IDUzNy4zNiA/IDI2IDogbGF5b3V0ICE9ICdCbGluaycgPyAnMjcnIDogJzI4Jyk7XG4gICAgICB9XG4gICAgICAvLyBBZGQgdGhlIHBvc3RmaXggb2YgXCIueFwiIG9yIFwiK1wiIGZvciBhcHByb3hpbWF0ZSB2ZXJzaW9ucy5cbiAgICAgIGxheW91dCAmJiAobGF5b3V0WzFdICs9ICcgJyArIChkYXRhICs9IHR5cGVvZiBkYXRhID09ICdudW1iZXInID8gJy54JyA6IC9bLitdLy50ZXN0KGRhdGEpID8gJycgOiAnKycpKTtcbiAgICAgIC8vIE9ic2N1cmUgdmVyc2lvbiBmb3Igc29tZSBTYWZhcmkgMS0yIHJlbGVhc2VzLlxuICAgICAgaWYgKG5hbWUgPT0gJ1NhZmFyaScgJiYgKCF2ZXJzaW9uIHx8IHBhcnNlSW50KHZlcnNpb24pID4gNDUpKSB7XG4gICAgICAgIHZlcnNpb24gPSBkYXRhO1xuICAgICAgfSBlbHNlIGlmIChuYW1lID09ICdDaHJvbWUnICYmIC9cXGJIZWFkbGVzc0Nocm9tZS9pLnRlc3QodWEpKSB7XG4gICAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQoJ2hlYWRsZXNzJyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIERldGVjdCBPcGVyYSBkZXNrdG9wIG1vZGVzLlxuICAgIGlmIChuYW1lID09ICdPcGVyYScgJiYgIChkYXRhID0gL1xcYnpib3Z8enZhdiQvLmV4ZWMob3MpKSkge1xuICAgICAgbmFtZSArPSAnICc7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIGlmIChkYXRhID09ICd6dmF2Jykge1xuICAgICAgICBuYW1lICs9ICdNaW5pJztcbiAgICAgICAgdmVyc2lvbiA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuYW1lICs9ICdNb2JpbGUnO1xuICAgICAgfVxuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgZGF0YSArICckJyksICcnKTtcbiAgICB9XG4gICAgLy8gRGV0ZWN0IENocm9tZSBkZXNrdG9wIG1vZGUuXG4gICAgZWxzZSBpZiAobmFtZSA9PSAnU2FmYXJpJyAmJiAvXFxiQ2hyb21lXFxiLy5leGVjKGxheW91dCAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCdkZXNrdG9wIG1vZGUnKTtcbiAgICAgIG5hbWUgPSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgICB2ZXJzaW9uID0gbnVsbDtcblxuICAgICAgaWYgKC9cXGJPUyBYXFxiLy50ZXN0KG9zKSkge1xuICAgICAgICBtYW51ZmFjdHVyZXIgPSAnQXBwbGUnO1xuICAgICAgICBvcyA9ICdpT1MgNC4zKyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIE5ld2VyIHZlcnNpb25zIG9mIFNSV2FyZSBJcm9uIHVzZXMgdGhlIENocm9tZSB0YWcgdG8gaW5kaWNhdGUgaXRzIHZlcnNpb24gbnVtYmVyLlxuICAgIGVsc2UgaWYgKC9cXGJTUldhcmUgSXJvblxcYi8udGVzdChuYW1lKSAmJiAhdmVyc2lvbikge1xuICAgICAgdmVyc2lvbiA9IGdldFZlcnNpb24oJ0Nocm9tZScpO1xuICAgIH1cbiAgICAvLyBTdHJpcCBpbmNvcnJlY3QgT1MgdmVyc2lvbnMuXG4gICAgaWYgKHZlcnNpb24gJiYgdmVyc2lvbi5pbmRleE9mKChkYXRhID0gL1tcXGQuXSskLy5leGVjKG9zKSkpID09IDAgJiZcbiAgICAgICAgdWEuaW5kZXhPZignLycgKyBkYXRhICsgJy0nKSA+IC0xKSB7XG4gICAgICBvcyA9IHRyaW0ob3MucmVwbGFjZShkYXRhLCAnJykpO1xuICAgIH1cbiAgICAvLyBFbnN1cmUgT1MgZG9lcyBub3QgaW5jbHVkZSB0aGUgYnJvd3NlciBuYW1lLlxuICAgIGlmIChvcyAmJiBvcy5pbmRleE9mKG5hbWUpICE9IC0xICYmICFSZWdFeHAobmFtZSArICcgT1MnKS50ZXN0KG9zKSkge1xuICAgICAgb3MgPSBvcy5yZXBsYWNlKFJlZ0V4cCgnIConICsgcXVhbGlmeShuYW1lKSArICcgKicpLCAnJyk7XG4gICAgfVxuICAgIC8vIEFkZCBsYXlvdXQgZW5naW5lLlxuICAgIGlmIChsYXlvdXQgJiYgIS9cXGIoPzpBdmFudHxOb29rKVxcYi8udGVzdChuYW1lKSAmJiAoXG4gICAgICAgIC9Ccm93c2VyfEx1bmFzY2FwZXxNYXh0aG9uLy50ZXN0KG5hbWUpIHx8XG4gICAgICAgIG5hbWUgIT0gJ1NhZmFyaScgJiYgL15pT1MvLnRlc3Qob3MpICYmIC9cXGJTYWZhcmlcXGIvLnRlc3QobGF5b3V0WzFdKSB8fFxuICAgICAgICAvXig/OkFkb2JlfEFyb3JhfEJyZWFjaHxNaWRvcml8T3BlcmF8UGhhbnRvbXxSZWtvbnF8Um9ja3xTYW1zdW5nIEludGVybmV0fFNsZWlwbmlyfFNSV2FyZSBJcm9ufFZpdmFsZGl8V2ViKS8udGVzdChuYW1lKSAmJiBsYXlvdXRbMV0pKSB7XG4gICAgICAvLyBEb24ndCBhZGQgbGF5b3V0IGRldGFpbHMgdG8gZGVzY3JpcHRpb24gaWYgdGhleSBhcmUgZmFsc2V5LlxuICAgICAgKGRhdGEgPSBsYXlvdXRbbGF5b3V0Lmxlbmd0aCAtIDFdKSAmJiBkZXNjcmlwdGlvbi5wdXNoKGRhdGEpO1xuICAgIH1cbiAgICAvLyBDb21iaW5lIGNvbnRleHR1YWwgaW5mb3JtYXRpb24uXG4gICAgaWYgKGRlc2NyaXB0aW9uLmxlbmd0aCkge1xuICAgICAgZGVzY3JpcHRpb24gPSBbJygnICsgZGVzY3JpcHRpb24uam9pbignOyAnKSArICcpJ107XG4gICAgfVxuICAgIC8vIEFwcGVuZCBtYW51ZmFjdHVyZXIgdG8gZGVzY3JpcHRpb24uXG4gICAgaWYgKG1hbnVmYWN0dXJlciAmJiBwcm9kdWN0ICYmIHByb2R1Y3QuaW5kZXhPZihtYW51ZmFjdHVyZXIpIDwgMCkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaCgnb24gJyArIG1hbnVmYWN0dXJlcik7XG4gICAgfVxuICAgIC8vIEFwcGVuZCBwcm9kdWN0IHRvIGRlc2NyaXB0aW9uLlxuICAgIGlmIChwcm9kdWN0KSB7XG4gICAgICBkZXNjcmlwdGlvbi5wdXNoKCgvXm9uIC8udGVzdChkZXNjcmlwdGlvbltkZXNjcmlwdGlvbi5sZW5ndGggLSAxXSkgPyAnJyA6ICdvbiAnKSArIHByb2R1Y3QpO1xuICAgIH1cbiAgICAvLyBQYXJzZSB0aGUgT1MgaW50byBhbiBvYmplY3QuXG4gICAgaWYgKG9zKSB7XG4gICAgICBkYXRhID0gLyAoW1xcZC4rXSspJC8uZXhlYyhvcyk7XG4gICAgICBpc1NwZWNpYWxDYXNlZE9TID0gZGF0YSAmJiBvcy5jaGFyQXQob3MubGVuZ3RoIC0gZGF0YVswXS5sZW5ndGggLSAxKSA9PSAnLyc7XG4gICAgICBvcyA9IHtcbiAgICAgICAgJ2FyY2hpdGVjdHVyZSc6IDMyLFxuICAgICAgICAnZmFtaWx5JzogKGRhdGEgJiYgIWlzU3BlY2lhbENhc2VkT1MpID8gb3MucmVwbGFjZShkYXRhWzBdLCAnJykgOiBvcyxcbiAgICAgICAgJ3ZlcnNpb24nOiBkYXRhID8gZGF0YVsxXSA6IG51bGwsXG4gICAgICAgICd0b1N0cmluZyc6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciB2ZXJzaW9uID0gdGhpcy52ZXJzaW9uO1xuICAgICAgICAgIHJldHVybiB0aGlzLmZhbWlseSArICgodmVyc2lvbiAmJiAhaXNTcGVjaWFsQ2FzZWRPUykgPyAnICcgKyB2ZXJzaW9uIDogJycpICsgKHRoaXMuYXJjaGl0ZWN0dXJlID09IDY0ID8gJyA2NC1iaXQnIDogJycpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cbiAgICAvLyBBZGQgYnJvd3Nlci9PUyBhcmNoaXRlY3R1cmUuXG4gICAgaWYgKChkYXRhID0gL1xcYig/OkFNRHxJQXxXaW58V09XfHg4Nl98eCk2NFxcYi9pLmV4ZWMoYXJjaCkpICYmICEvXFxiaTY4NlxcYi9pLnRlc3QoYXJjaCkpIHtcbiAgICAgIGlmIChvcykge1xuICAgICAgICBvcy5hcmNoaXRlY3R1cmUgPSA2NDtcbiAgICAgICAgb3MuZmFtaWx5ID0gb3MuZmFtaWx5LnJlcGxhY2UoUmVnRXhwKCcgKicgKyBkYXRhKSwgJycpO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICAgIG5hbWUgJiYgKC9cXGJXT1c2NFxcYi9pLnRlc3QodWEpIHx8XG4gICAgICAgICAgKHVzZUZlYXR1cmVzICYmIC9cXHcoPzo4NnwzMikkLy50ZXN0KG5hdi5jcHVDbGFzcyB8fCBuYXYucGxhdGZvcm0pICYmICEvXFxiV2luNjQ7IHg2NFxcYi9pLnRlc3QodWEpKSlcbiAgICAgICkge1xuICAgICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KCczMi1iaXQnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gQ2hyb21lIDM5IGFuZCBhYm92ZSBvbiBPUyBYIGlzIGFsd2F5cyA2NC1iaXQuXG4gICAgZWxzZSBpZiAoXG4gICAgICAgIG9zICYmIC9eT1MgWC8udGVzdChvcy5mYW1pbHkpICYmXG4gICAgICAgIG5hbWUgPT0gJ0Nocm9tZScgJiYgcGFyc2VGbG9hdCh2ZXJzaW9uKSA+PSAzOVxuICAgICkge1xuICAgICAgb3MuYXJjaGl0ZWN0dXJlID0gNjQ7XG4gICAgfVxuXG4gICAgdWEgfHwgKHVhID0gbnVsbCk7XG5cbiAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAvKipcbiAgICAgKiBUaGUgcGxhdGZvcm0gb2JqZWN0LlxuICAgICAqXG4gICAgICogQG5hbWUgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBPYmplY3RcbiAgICAgKi9cbiAgICB2YXIgcGxhdGZvcm0gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF0Zm9ybSBkZXNjcmlwdGlvbi5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0uZGVzY3JpcHRpb24gPSB1YTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBicm93c2VyJ3MgbGF5b3V0IGVuZ2luZS5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBsYXlvdXQgZW5naW5lcyBpbmNsdWRlOlxuICAgICAqIFwiQmxpbmtcIiwgXCJFZGdlSFRNTFwiLCBcIkdlY2tvXCIsIFwiVHJpZGVudFwiIGFuZCBcIldlYktpdFwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLmxheW91dCA9IGxheW91dCAmJiBsYXlvdXRbMF07XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcHJvZHVjdCdzIG1hbnVmYWN0dXJlci5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIG1hbnVmYWN0dXJlcnMgaW5jbHVkZTpcbiAgICAgKiBcIkFwcGxlXCIsIFwiQXJjaG9zXCIsIFwiQW1hem9uXCIsIFwiQXN1c1wiLCBcIkJhcm5lcyAmIE5vYmxlXCIsIFwiQmxhY2tCZXJyeVwiLFxuICAgICAqIFwiR29vZ2xlXCIsIFwiSFBcIiwgXCJIVENcIiwgXCJMR1wiLCBcIk1pY3Jvc29mdFwiLCBcIk1vdG9yb2xhXCIsIFwiTmludGVuZG9cIixcbiAgICAgKiBcIk5va2lhXCIsIFwiU2Ftc3VuZ1wiIGFuZCBcIlNvbnlcIlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIHBsYXRmb3JtXG4gICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgKi9cbiAgICBwbGF0Zm9ybS5tYW51ZmFjdHVyZXIgPSBtYW51ZmFjdHVyZXI7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgYnJvd3Nlci9lbnZpcm9ubWVudC5cbiAgICAgKlxuICAgICAqIFRoZSBsaXN0IG9mIGNvbW1vbiBicm93c2VyIG5hbWVzIGluY2x1ZGU6XG4gICAgICogXCJDaHJvbWVcIiwgXCJFbGVjdHJvblwiLCBcIkZpcmVmb3hcIiwgXCJGaXJlZm94IGZvciBpT1NcIiwgXCJJRVwiLFxuICAgICAqIFwiTWljcm9zb2Z0IEVkZ2VcIiwgXCJQaGFudG9tSlNcIiwgXCJTYWZhcmlcIiwgXCJTZWFNb25rZXlcIiwgXCJTaWxrXCIsXG4gICAgICogXCJPcGVyYSBNaW5pXCIgYW5kIFwiT3BlcmFcIlxuICAgICAqXG4gICAgICogTW9iaWxlIHZlcnNpb25zIG9mIHNvbWUgYnJvd3NlcnMgaGF2ZSBcIk1vYmlsZVwiIGFwcGVuZGVkIHRvIHRoZWlyIG5hbWU6XG4gICAgICogZWcuIFwiQ2hyb21lIE1vYmlsZVwiLCBcIkZpcmVmb3ggTW9iaWxlXCIsIFwiSUUgTW9iaWxlXCIgYW5kIFwiT3BlcmEgTW9iaWxlXCJcbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ubmFtZSA9IG5hbWU7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgYWxwaGEvYmV0YSByZWxlYXNlIGluZGljYXRvci5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0ucHJlcmVsZWFzZSA9IHByZXJlbGVhc2U7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgcHJvZHVjdCBob3N0aW5nIHRoZSBicm93c2VyLlxuICAgICAqXG4gICAgICogVGhlIGxpc3Qgb2YgY29tbW9uIHByb2R1Y3RzIGluY2x1ZGU6XG4gICAgICpcbiAgICAgKiBcIkJsYWNrQmVycnlcIiwgXCJHYWxheHkgUzRcIiwgXCJMdW1pYVwiLCBcImlQYWRcIiwgXCJpUG9kXCIsIFwiaVBob25lXCIsIFwiS2luZGxlXCIsXG4gICAgICogXCJLaW5kbGUgRmlyZVwiLCBcIk5leHVzXCIsIFwiTm9va1wiLCBcIlBsYXlCb29rXCIsIFwiVG91Y2hQYWRcIiBhbmQgXCJUcmFuc2Zvcm1lclwiXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnByb2R1Y3QgPSBwcm9kdWN0O1xuXG4gICAgLyoqXG4gICAgICogVGhlIGJyb3dzZXIncyB1c2VyIGFnZW50IHN0cmluZy5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIHN0cmluZ3xudWxsXG4gICAgICovXG4gICAgcGxhdGZvcm0udWEgPSB1YTtcblxuICAgIC8qKlxuICAgICAqIFRoZSBicm93c2VyL2Vudmlyb25tZW50IHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm1cbiAgICAgKiBAdHlwZSBzdHJpbmd8bnVsbFxuICAgICAqL1xuICAgIHBsYXRmb3JtLnZlcnNpb24gPSBuYW1lICYmIHZlcnNpb247XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbmFtZSBvZiB0aGUgb3BlcmF0aW5nIHN5c3RlbS5cbiAgICAgKlxuICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybVxuICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAqL1xuICAgIHBsYXRmb3JtLm9zID0gb3MgfHwge1xuXG4gICAgICAvKipcbiAgICAgICAqIFRoZSBDUFUgYXJjaGl0ZWN0dXJlIHRoZSBPUyBpcyBidWlsdCBmb3IuXG4gICAgICAgKlxuICAgICAgICogQG1lbWJlck9mIHBsYXRmb3JtLm9zXG4gICAgICAgKiBAdHlwZSBudW1iZXJ8bnVsbFxuICAgICAgICovXG4gICAgICAnYXJjaGl0ZWN0dXJlJzogbnVsbCxcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgZmFtaWx5IG9mIHRoZSBPUy5cbiAgICAgICAqXG4gICAgICAgKiBDb21tb24gdmFsdWVzIGluY2x1ZGU6XG4gICAgICAgKiBcIldpbmRvd3NcIiwgXCJXaW5kb3dzIFNlcnZlciAyMDA4IFIyIC8gN1wiLCBcIldpbmRvd3MgU2VydmVyIDIwMDggLyBWaXN0YVwiLFxuICAgICAgICogXCJXaW5kb3dzIFhQXCIsIFwiT1MgWFwiLCBcIkxpbnV4XCIsIFwiVWJ1bnR1XCIsIFwiRGViaWFuXCIsIFwiRmVkb3JhXCIsIFwiUmVkIEhhdFwiLFxuICAgICAgICogXCJTdVNFXCIsIFwiQW5kcm9pZFwiLCBcImlPU1wiIGFuZCBcIldpbmRvd3MgUGhvbmVcIlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgICAqL1xuICAgICAgJ2ZhbWlseSc6IG51bGwsXG5cbiAgICAgIC8qKlxuICAgICAgICogVGhlIHZlcnNpb24gb2YgdGhlIE9TLlxuICAgICAgICpcbiAgICAgICAqIEBtZW1iZXJPZiBwbGF0Zm9ybS5vc1xuICAgICAgICogQHR5cGUgc3RyaW5nfG51bGxcbiAgICAgICAqL1xuICAgICAgJ3ZlcnNpb24nOiBudWxsLFxuXG4gICAgICAvKipcbiAgICAgICAqIFJldHVybnMgdGhlIE9TIHN0cmluZy5cbiAgICAgICAqXG4gICAgICAgKiBAbWVtYmVyT2YgcGxhdGZvcm0ub3NcbiAgICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBPUyBzdHJpbmcuXG4gICAgICAgKi9cbiAgICAgICd0b1N0cmluZyc6IGZ1bmN0aW9uKCkgeyByZXR1cm4gJ251bGwnOyB9XG4gICAgfTtcblxuICAgIHBsYXRmb3JtLnBhcnNlID0gcGFyc2U7XG4gICAgcGxhdGZvcm0udG9TdHJpbmcgPSB0b1N0cmluZ1BsYXRmb3JtO1xuXG4gICAgaWYgKHBsYXRmb3JtLnZlcnNpb24pIHtcbiAgICAgIGRlc2NyaXB0aW9uLnVuc2hpZnQodmVyc2lvbik7XG4gICAgfVxuICAgIGlmIChwbGF0Zm9ybS5uYW1lKSB7XG4gICAgICBkZXNjcmlwdGlvbi51bnNoaWZ0KG5hbWUpO1xuICAgIH1cbiAgICBpZiAob3MgJiYgbmFtZSAmJiAhKG9zID09IFN0cmluZyhvcykuc3BsaXQoJyAnKVswXSAmJiAob3MgPT0gbmFtZS5zcGxpdCgnICcpWzBdIHx8IHByb2R1Y3QpKSkge1xuICAgICAgZGVzY3JpcHRpb24ucHVzaChwcm9kdWN0ID8gJygnICsgb3MgKyAnKScgOiAnb24gJyArIG9zKTtcbiAgICB9XG4gICAgaWYgKGRlc2NyaXB0aW9uLmxlbmd0aCkge1xuICAgICAgcGxhdGZvcm0uZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbi5qb2luKCcgJyk7XG4gICAgfVxuICAgIHJldHVybiBwbGF0Zm9ybTtcbiAgfVxuXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gIC8vIEV4cG9ydCBwbGF0Zm9ybS5cbiAgdmFyIHBsYXRmb3JtID0gcGFyc2UoKTtcblxuICAvLyBTb21lIEFNRCBidWlsZCBvcHRpbWl6ZXJzLCBsaWtlIHIuanMsIGNoZWNrIGZvciBjb25kaXRpb24gcGF0dGVybnMgbGlrZSB0aGUgZm9sbG93aW5nOlxuICBpZiAodHlwZW9mIGRlZmluZSA9PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBkZWZpbmUuYW1kID09ICdvYmplY3QnICYmIGRlZmluZS5hbWQpIHtcbiAgICAvLyBFeHBvc2UgcGxhdGZvcm0gb24gdGhlIGdsb2JhbCBvYmplY3QgdG8gcHJldmVudCBlcnJvcnMgd2hlbiBwbGF0Zm9ybSBpc1xuICAgIC8vIGxvYWRlZCBieSBhIHNjcmlwdCB0YWcgaW4gdGhlIHByZXNlbmNlIG9mIGFuIEFNRCBsb2FkZXIuXG4gICAgLy8gU2VlIGh0dHA6Ly9yZXF1aXJlanMub3JnL2RvY3MvZXJyb3JzLmh0bWwjbWlzbWF0Y2ggZm9yIG1vcmUgZGV0YWlscy5cbiAgICByb290LnBsYXRmb3JtID0gcGxhdGZvcm07XG5cbiAgICAvLyBEZWZpbmUgYXMgYW4gYW5vbnltb3VzIG1vZHVsZSBzbyBwbGF0Zm9ybSBjYW4gYmUgYWxpYXNlZCB0aHJvdWdoIHBhdGggbWFwcGluZy5cbiAgICBkZWZpbmUoZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gcGxhdGZvcm07XG4gICAgfSk7XG4gIH1cbiAgLy8gQ2hlY2sgZm9yIGBleHBvcnRzYCBhZnRlciBgZGVmaW5lYCBpbiBjYXNlIGEgYnVpbGQgb3B0aW1pemVyIGFkZHMgYW4gYGV4cG9ydHNgIG9iamVjdC5cbiAgZWxzZSBpZiAoZnJlZUV4cG9ydHMgJiYgZnJlZU1vZHVsZSkge1xuICAgIC8vIEV4cG9ydCBmb3IgQ29tbW9uSlMgc3VwcG9ydC5cbiAgICBmb3JPd24ocGxhdGZvcm0sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgIGZyZWVFeHBvcnRzW2tleV0gPSB2YWx1ZTtcbiAgICB9KTtcbiAgfVxuICBlbHNlIHtcbiAgICAvLyBFeHBvcnQgdG8gdGhlIGdsb2JhbCBvYmplY3QuXG4gICAgcm9vdC5wbGF0Zm9ybSA9IHBsYXRmb3JtO1xuICB9XG59LmNhbGwodGhpcykpO1xuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbi8vIGNhY2hlZCBmcm9tIHdoYXRldmVyIGdsb2JhbCBpcyBwcmVzZW50IHNvIHRoYXQgdGVzdCBydW5uZXJzIHRoYXQgc3R1YiBpdFxuLy8gZG9uJ3QgYnJlYWsgdGhpbmdzLiAgQnV0IHdlIG5lZWQgdG8gd3JhcCBpdCBpbiBhIHRyeSBjYXRjaCBpbiBjYXNlIGl0IGlzXG4vLyB3cmFwcGVkIGluIHN0cmljdCBtb2RlIGNvZGUgd2hpY2ggZG9lc24ndCBkZWZpbmUgYW55IGdsb2JhbHMuICBJdCdzIGluc2lkZSBhXG4vLyBmdW5jdGlvbiBiZWNhdXNlIHRyeS9jYXRjaGVzIGRlb3B0aW1pemUgaW4gY2VydGFpbiBlbmdpbmVzLlxuXG52YXIgY2FjaGVkU2V0VGltZW91dDtcbnZhciBjYWNoZWRDbGVhclRpbWVvdXQ7XG5cbmZ1bmN0aW9uIGRlZmF1bHRTZXRUaW1vdXQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkJyk7XG59XG5mdW5jdGlvbiBkZWZhdWx0Q2xlYXJUaW1lb3V0ICgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsZWFyVGltZW91dCBoYXMgbm90IGJlZW4gZGVmaW5lZCcpO1xufVxuKGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIHNldFRpbWVvdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGRlZmF1bHRTZXRUaW1vdXQ7XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBkZWZhdWx0U2V0VGltb3V0O1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBpZiAodHlwZW9mIGNsZWFyVGltZW91dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkQ2xlYXJUaW1lb3V0ID0gZGVmYXVsdENsZWFyVGltZW91dDtcbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICAvL25vcm1hbCBlbnZpcm9tZW50cyBpbiBzYW5lIHNpdHVhdGlvbnNcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9XG4gICAgLy8gaWYgc2V0VGltZW91dCB3YXNuJ3QgYXZhaWxhYmxlIGJ1dCB3YXMgbGF0dGVyIGRlZmluZWRcbiAgICBpZiAoKGNhY2hlZFNldFRpbWVvdXQgPT09IGRlZmF1bHRTZXRUaW1vdXQgfHwgIWNhY2hlZFNldFRpbWVvdXQpICYmIHNldFRpbWVvdXQpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1biwgMCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIC8vIHdoZW4gd2hlbiBzb21lYm9keSBoYXMgc2NyZXdlZCB3aXRoIHNldFRpbWVvdXQgYnV0IG5vIEkuRS4gbWFkZG5lc3NcbiAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQoZnVuLCAwKTtcbiAgICB9IGNhdGNoKGUpe1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gV2hlbiB3ZSBhcmUgaW4gSS5FLiBidXQgdGhlIHNjcmlwdCBoYXMgYmVlbiBldmFsZWQgc28gSS5FLiBkb2Vzbid0IHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkU2V0VGltZW91dC5jYWxsKG51bGwsIGZ1biwgMCk7XG4gICAgICAgIH0gY2F0Y2goZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvclxuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFNldFRpbWVvdXQuY2FsbCh0aGlzLCBmdW4sIDApO1xuICAgICAgICB9XG4gICAgfVxuXG5cbn1cbmZ1bmN0aW9uIHJ1bkNsZWFyVGltZW91dChtYXJrZXIpIHtcbiAgICBpZiAoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBjbGVhclRpbWVvdXQpIHtcbiAgICAgICAgLy9ub3JtYWwgZW52aXJvbWVudHMgaW4gc2FuZSBzaXR1YXRpb25zXG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgLy8gaWYgY2xlYXJUaW1lb3V0IHdhc24ndCBhdmFpbGFibGUgYnV0IHdhcyBsYXR0ZXIgZGVmaW5lZFxuICAgIGlmICgoY2FjaGVkQ2xlYXJUaW1lb3V0ID09PSBkZWZhdWx0Q2xlYXJUaW1lb3V0IHx8ICFjYWNoZWRDbGVhclRpbWVvdXQpICYmIGNsZWFyVGltZW91dCkge1xuICAgICAgICBjYWNoZWRDbGVhclRpbWVvdXQgPSBjbGVhclRpbWVvdXQ7XG4gICAgICAgIHJldHVybiBjbGVhclRpbWVvdXQobWFya2VyKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gd2hlbiB3aGVuIHNvbWVib2R5IGhhcyBzY3Jld2VkIHdpdGggc2V0VGltZW91dCBidXQgbm8gSS5FLiBtYWRkbmVzc1xuICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0KG1hcmtlcik7XG4gICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBXaGVuIHdlIGFyZSBpbiBJLkUuIGJ1dCB0aGUgc2NyaXB0IGhhcyBiZWVuIGV2YWxlZCBzbyBJLkUuIGRvZXNuJ3QgIHRydXN0IHRoZSBnbG9iYWwgb2JqZWN0IHdoZW4gY2FsbGVkIG5vcm1hbGx5XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkQ2xlYXJUaW1lb3V0LmNhbGwobnVsbCwgbWFya2VyKTtcbiAgICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aGVuIGl0J3MgYSB2ZXJzaW9uIG9mIEkuRS4gdGhhdCBtdXN0IGhhdmUgdGhlIGdsb2JhbCBvYmplY3QgZm9yICd0aGlzJywgaG9wZnVsbHkgb3VyIGNvbnRleHQgY29ycmVjdCBvdGhlcndpc2UgaXQgd2lsbCB0aHJvdyBhIGdsb2JhbCBlcnJvci5cbiAgICAgICAgICAgIC8vIFNvbWUgdmVyc2lvbnMgb2YgSS5FLiBoYXZlIGRpZmZlcmVudCBydWxlcyBmb3IgY2xlYXJUaW1lb3V0IHZzIHNldFRpbWVvdXRcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRDbGVhclRpbWVvdXQuY2FsbCh0aGlzLCBtYXJrZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG5cblxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5wcmVwZW5kT25jZUxpc3RlbmVyID0gbm9vcDtcblxucHJvY2Vzcy5saXN0ZW5lcnMgPSBmdW5jdGlvbiAobmFtZSkgeyByZXR1cm4gW10gfVxuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsImNvbnN0IGRlYnVnID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvZGVidWcnKVxuY29uc3QgeyBNQVhfTEVOR1RILCBNQVhfU0FGRV9JTlRFR0VSIH0gPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9jb25zdGFudHMnKVxuY29uc3QgeyByZSwgdCB9ID0gcmVxdWlyZSgnLi4vaW50ZXJuYWwvcmUnKVxuXG5jb25zdCBwYXJzZU9wdGlvbnMgPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9wYXJzZS1vcHRpb25zJylcbmNvbnN0IHsgY29tcGFyZUlkZW50aWZpZXJzIH0gPSByZXF1aXJlKCcuLi9pbnRlcm5hbC9pZGVudGlmaWVycycpXG5jbGFzcyBTZW1WZXIge1xuICBjb25zdHJ1Y3RvciAodmVyc2lvbiwgb3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBwYXJzZU9wdGlvbnMob3B0aW9ucylcblxuICAgIGlmICh2ZXJzaW9uIGluc3RhbmNlb2YgU2VtVmVyKSB7XG4gICAgICBpZiAodmVyc2lvbi5sb29zZSA9PT0gISFvcHRpb25zLmxvb3NlICYmXG4gICAgICAgICAgdmVyc2lvbi5pbmNsdWRlUHJlcmVsZWFzZSA9PT0gISFvcHRpb25zLmluY2x1ZGVQcmVyZWxlYXNlKSB7XG4gICAgICAgIHJldHVybiB2ZXJzaW9uXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2ZXJzaW9uID0gdmVyc2lvbi52ZXJzaW9uXG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdmVyc2lvbiAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgVmVyc2lvbjogJHt2ZXJzaW9ufWApXG4gICAgfVxuXG4gICAgaWYgKHZlcnNpb24ubGVuZ3RoID4gTUFYX0xFTkdUSCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgYHZlcnNpb24gaXMgbG9uZ2VyIHRoYW4gJHtNQVhfTEVOR1RIfSBjaGFyYWN0ZXJzYFxuICAgICAgKVxuICAgIH1cblxuICAgIGRlYnVnKCdTZW1WZXInLCB2ZXJzaW9uLCBvcHRpb25zKVxuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnNcbiAgICB0aGlzLmxvb3NlID0gISFvcHRpb25zLmxvb3NlXG4gICAgLy8gdGhpcyBpc24ndCBhY3R1YWxseSByZWxldmFudCBmb3IgdmVyc2lvbnMsIGJ1dCBrZWVwIGl0IHNvIHRoYXQgd2VcbiAgICAvLyBkb24ndCBydW4gaW50byB0cm91YmxlIHBhc3NpbmcgdGhpcy5vcHRpb25zIGFyb3VuZC5cbiAgICB0aGlzLmluY2x1ZGVQcmVyZWxlYXNlID0gISFvcHRpb25zLmluY2x1ZGVQcmVyZWxlYXNlXG5cbiAgICBjb25zdCBtID0gdmVyc2lvbi50cmltKCkubWF0Y2gob3B0aW9ucy5sb29zZSA/IHJlW3QuTE9PU0VdIDogcmVbdC5GVUxMXSlcblxuICAgIGlmICghbSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgSW52YWxpZCBWZXJzaW9uOiAke3ZlcnNpb259YClcbiAgICB9XG5cbiAgICB0aGlzLnJhdyA9IHZlcnNpb25cblxuICAgIC8vIHRoZXNlIGFyZSBhY3R1YWxseSBudW1iZXJzXG4gICAgdGhpcy5tYWpvciA9ICttWzFdXG4gICAgdGhpcy5taW5vciA9ICttWzJdXG4gICAgdGhpcy5wYXRjaCA9ICttWzNdXG5cbiAgICBpZiAodGhpcy5tYWpvciA+IE1BWF9TQUZFX0lOVEVHRVIgfHwgdGhpcy5tYWpvciA8IDApIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbWFqb3IgdmVyc2lvbicpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWlub3IgPiBNQVhfU0FGRV9JTlRFR0VSIHx8IHRoaXMubWlub3IgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1pbm9yIHZlcnNpb24nKVxuICAgIH1cblxuICAgIGlmICh0aGlzLnBhdGNoID4gTUFYX1NBRkVfSU5URUdFUiB8fCB0aGlzLnBhdGNoIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBwYXRjaCB2ZXJzaW9uJylcbiAgICB9XG5cbiAgICAvLyBudW1iZXJpZnkgYW55IHByZXJlbGVhc2UgbnVtZXJpYyBpZHNcbiAgICBpZiAoIW1bNF0pIHtcbiAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtdXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHJlcmVsZWFzZSA9IG1bNF0uc3BsaXQoJy4nKS5tYXAoKGlkKSA9PiB7XG4gICAgICAgIGlmICgvXlswLTldKyQvLnRlc3QoaWQpKSB7XG4gICAgICAgICAgY29uc3QgbnVtID0gK2lkXG4gICAgICAgICAgaWYgKG51bSA+PSAwICYmIG51bSA8IE1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgICAgICAgICAgIHJldHVybiBudW1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlkXG4gICAgICB9KVxuICAgIH1cblxuICAgIHRoaXMuYnVpbGQgPSBtWzVdID8gbVs1XS5zcGxpdCgnLicpIDogW11cbiAgICB0aGlzLmZvcm1hdCgpXG4gIH1cblxuICBmb3JtYXQgKCkge1xuICAgIHRoaXMudmVyc2lvbiA9IGAke3RoaXMubWFqb3J9LiR7dGhpcy5taW5vcn0uJHt0aGlzLnBhdGNofWBcbiAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCkge1xuICAgICAgdGhpcy52ZXJzaW9uICs9IGAtJHt0aGlzLnByZXJlbGVhc2Uuam9pbignLicpfWBcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudmVyc2lvblxuICB9XG5cbiAgdG9TdHJpbmcgKCkge1xuICAgIHJldHVybiB0aGlzLnZlcnNpb25cbiAgfVxuXG4gIGNvbXBhcmUgKG90aGVyKSB7XG4gICAgZGVidWcoJ1NlbVZlci5jb21wYXJlJywgdGhpcy52ZXJzaW9uLCB0aGlzLm9wdGlvbnMsIG90aGVyKVxuICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgU2VtVmVyKSkge1xuICAgICAgaWYgKHR5cGVvZiBvdGhlciA9PT0gJ3N0cmluZycgJiYgb3RoZXIgPT09IHRoaXMudmVyc2lvbikge1xuICAgICAgICByZXR1cm4gMFxuICAgICAgfVxuICAgICAgb3RoZXIgPSBuZXcgU2VtVmVyKG90aGVyLCB0aGlzLm9wdGlvbnMpXG4gICAgfVxuXG4gICAgaWYgKG90aGVyLnZlcnNpb24gPT09IHRoaXMudmVyc2lvbikge1xuICAgICAgcmV0dXJuIDBcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jb21wYXJlTWFpbihvdGhlcikgfHwgdGhpcy5jb21wYXJlUHJlKG90aGVyKVxuICB9XG5cbiAgY29tcGFyZU1haW4gKG90aGVyKSB7XG4gICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKSB7XG4gICAgICBvdGhlciA9IG5ldyBTZW1WZXIob3RoZXIsIHRoaXMub3B0aW9ucylcbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgY29tcGFyZUlkZW50aWZpZXJzKHRoaXMubWFqb3IsIG90aGVyLm1ham9yKSB8fFxuICAgICAgY29tcGFyZUlkZW50aWZpZXJzKHRoaXMubWlub3IsIG90aGVyLm1pbm9yKSB8fFxuICAgICAgY29tcGFyZUlkZW50aWZpZXJzKHRoaXMucGF0Y2gsIG90aGVyLnBhdGNoKVxuICAgIClcbiAgfVxuXG4gIGNvbXBhcmVQcmUgKG90aGVyKSB7XG4gICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTZW1WZXIpKSB7XG4gICAgICBvdGhlciA9IG5ldyBTZW1WZXIob3RoZXIsIHRoaXMub3B0aW9ucylcbiAgICB9XG5cbiAgICAvLyBOT1QgaGF2aW5nIGEgcHJlcmVsZWFzZSBpcyA+IGhhdmluZyBvbmVcbiAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCAmJiAhb3RoZXIucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiAtMVxuICAgIH0gZWxzZSBpZiAoIXRoaXMucHJlcmVsZWFzZS5sZW5ndGggJiYgb3RoZXIucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiAxXG4gICAgfSBlbHNlIGlmICghdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCAmJiAhb3RoZXIucHJlcmVsZWFzZS5sZW5ndGgpIHtcbiAgICAgIHJldHVybiAwXG4gICAgfVxuXG4gICAgbGV0IGkgPSAwXG4gICAgZG8ge1xuICAgICAgY29uc3QgYSA9IHRoaXMucHJlcmVsZWFzZVtpXVxuICAgICAgY29uc3QgYiA9IG90aGVyLnByZXJlbGVhc2VbaV1cbiAgICAgIGRlYnVnKCdwcmVyZWxlYXNlIGNvbXBhcmUnLCBpLCBhLCBiKVxuICAgICAgaWYgKGEgPT09IHVuZGVmaW5lZCAmJiBiID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIDBcbiAgICAgIH0gZWxzZSBpZiAoYiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiAxXG4gICAgICB9IGVsc2UgaWYgKGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gLTFcbiAgICAgIH0gZWxzZSBpZiAoYSA9PT0gYikge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGNvbXBhcmVJZGVudGlmaWVycyhhLCBiKVxuICAgICAgfVxuICAgIH0gd2hpbGUgKCsraSlcbiAgfVxuXG4gIGNvbXBhcmVCdWlsZCAob3RoZXIpIHtcbiAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFNlbVZlcikpIHtcbiAgICAgIG90aGVyID0gbmV3IFNlbVZlcihvdGhlciwgdGhpcy5vcHRpb25zKVxuICAgIH1cblxuICAgIGxldCBpID0gMFxuICAgIGRvIHtcbiAgICAgIGNvbnN0IGEgPSB0aGlzLmJ1aWxkW2ldXG4gICAgICBjb25zdCBiID0gb3RoZXIuYnVpbGRbaV1cbiAgICAgIGRlYnVnKCdwcmVyZWxlYXNlIGNvbXBhcmUnLCBpLCBhLCBiKVxuICAgICAgaWYgKGEgPT09IHVuZGVmaW5lZCAmJiBiID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIDBcbiAgICAgIH0gZWxzZSBpZiAoYiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiAxXG4gICAgICB9IGVsc2UgaWYgKGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gLTFcbiAgICAgIH0gZWxzZSBpZiAoYSA9PT0gYikge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGNvbXBhcmVJZGVudGlmaWVycyhhLCBiKVxuICAgICAgfVxuICAgIH0gd2hpbGUgKCsraSlcbiAgfVxuXG4gIC8vIHByZW1pbm9yIHdpbGwgYnVtcCB0aGUgdmVyc2lvbiB1cCB0byB0aGUgbmV4dCBtaW5vciByZWxlYXNlLCBhbmQgaW1tZWRpYXRlbHlcbiAgLy8gZG93biB0byBwcmUtcmVsZWFzZS4gcHJlbWFqb3IgYW5kIHByZXBhdGNoIHdvcmsgdGhlIHNhbWUgd2F5LlxuICBpbmMgKHJlbGVhc2UsIGlkZW50aWZpZXIpIHtcbiAgICBzd2l0Y2ggKHJlbGVhc2UpIHtcbiAgICAgIGNhc2UgJ3ByZW1ham9yJzpcbiAgICAgICAgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9IDBcbiAgICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgICAgdGhpcy5taW5vciA9IDBcbiAgICAgICAgdGhpcy5tYWpvcisrXG4gICAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAncHJlbWlub3InOlxuICAgICAgICB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID0gMFxuICAgICAgICB0aGlzLnBhdGNoID0gMFxuICAgICAgICB0aGlzLm1pbm9yKytcbiAgICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdwcmVwYXRjaCc6XG4gICAgICAgIC8vIElmIHRoaXMgaXMgYWxyZWFkeSBhIHByZXJlbGVhc2UsIGl0IHdpbGwgYnVtcCB0byB0aGUgbmV4dCB2ZXJzaW9uXG4gICAgICAgIC8vIGRyb3AgYW55IHByZXJlbGVhc2VzIHRoYXQgbWlnaHQgYWxyZWFkeSBleGlzdCwgc2luY2UgdGhleSBhcmUgbm90XG4gICAgICAgIC8vIHJlbGV2YW50IGF0IHRoaXMgcG9pbnQuXG4gICAgICAgIHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPSAwXG4gICAgICAgIHRoaXMuaW5jKCdwYXRjaCcsIGlkZW50aWZpZXIpXG4gICAgICAgIHRoaXMuaW5jKCdwcmUnLCBpZGVudGlmaWVyKVxuICAgICAgICBicmVha1xuICAgICAgLy8gSWYgdGhlIGlucHV0IGlzIGEgbm9uLXByZXJlbGVhc2UgdmVyc2lvbiwgdGhpcyBhY3RzIHRoZSBzYW1lIGFzXG4gICAgICAvLyBwcmVwYXRjaC5cbiAgICAgIGNhc2UgJ3ByZXJlbGVhc2UnOlxuICAgICAgICBpZiAodGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRoaXMuaW5jKCdwYXRjaCcsIGlkZW50aWZpZXIpXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbmMoJ3ByZScsIGlkZW50aWZpZXIpXG4gICAgICAgIGJyZWFrXG5cbiAgICAgIGNhc2UgJ21ham9yJzpcbiAgICAgICAgLy8gSWYgdGhpcyBpcyBhIHByZS1tYWpvciB2ZXJzaW9uLCBidW1wIHVwIHRvIHRoZSBzYW1lIG1ham9yIHZlcnNpb24uXG4gICAgICAgIC8vIE90aGVyd2lzZSBpbmNyZW1lbnQgbWFqb3IuXG4gICAgICAgIC8vIDEuMC4wLTUgYnVtcHMgdG8gMS4wLjBcbiAgICAgICAgLy8gMS4xLjAgYnVtcHMgdG8gMi4wLjBcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMubWlub3IgIT09IDAgfHxcbiAgICAgICAgICB0aGlzLnBhdGNoICE9PSAwIHx8XG4gICAgICAgICAgdGhpcy5wcmVyZWxlYXNlLmxlbmd0aCA9PT0gMFxuICAgICAgICApIHtcbiAgICAgICAgICB0aGlzLm1ham9yKytcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm1pbm9yID0gMFxuICAgICAgICB0aGlzLnBhdGNoID0gMFxuICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbXVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnbWlub3InOlxuICAgICAgICAvLyBJZiB0aGlzIGlzIGEgcHJlLW1pbm9yIHZlcnNpb24sIGJ1bXAgdXAgdG8gdGhlIHNhbWUgbWlub3IgdmVyc2lvbi5cbiAgICAgICAgLy8gT3RoZXJ3aXNlIGluY3JlbWVudCBtaW5vci5cbiAgICAgICAgLy8gMS4yLjAtNSBidW1wcyB0byAxLjIuMFxuICAgICAgICAvLyAxLjIuMSBidW1wcyB0byAxLjMuMFxuICAgICAgICBpZiAodGhpcy5wYXRjaCAhPT0gMCB8fCB0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5taW5vcisrXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wYXRjaCA9IDBcbiAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW11cbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ3BhdGNoJzpcbiAgICAgICAgLy8gSWYgdGhpcyBpcyBub3QgYSBwcmUtcmVsZWFzZSB2ZXJzaW9uLCBpdCB3aWxsIGluY3JlbWVudCB0aGUgcGF0Y2guXG4gICAgICAgIC8vIElmIGl0IGlzIGEgcHJlLXJlbGVhc2UgaXQgd2lsbCBidW1wIHVwIHRvIHRoZSBzYW1lIHBhdGNoIHZlcnNpb24uXG4gICAgICAgIC8vIDEuMi4wLTUgcGF0Y2hlcyB0byAxLjIuMFxuICAgICAgICAvLyAxLjIuMCBwYXRjaGVzIHRvIDEuMi4xXG4gICAgICAgIGlmICh0aGlzLnByZXJlbGVhc2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5wYXRjaCsrXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wcmVyZWxlYXNlID0gW11cbiAgICAgICAgYnJlYWtcbiAgICAgIC8vIFRoaXMgcHJvYmFibHkgc2hvdWxkbid0IGJlIHVzZWQgcHVibGljbHkuXG4gICAgICAvLyAxLjAuMCAncHJlJyB3b3VsZCBiZWNvbWUgMS4wLjAtMCB3aGljaCBpcyB0aGUgd3JvbmcgZGlyZWN0aW9uLlxuICAgICAgY2FzZSAncHJlJzpcbiAgICAgICAgaWYgKHRoaXMucHJlcmVsZWFzZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbMF1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsZXQgaSA9IHRoaXMucHJlcmVsZWFzZS5sZW5ndGhcbiAgICAgICAgICB3aGlsZSAoLS1pID49IDApIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5wcmVyZWxlYXNlW2ldID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICB0aGlzLnByZXJlbGVhc2VbaV0rK1xuICAgICAgICAgICAgICBpID0gLTJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGkgPT09IC0xKSB7XG4gICAgICAgICAgICAvLyBkaWRuJ3QgaW5jcmVtZW50IGFueXRoaW5nXG4gICAgICAgICAgICB0aGlzLnByZXJlbGVhc2UucHVzaCgwKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaWRlbnRpZmllcikge1xuICAgICAgICAgIC8vIDEuMi4wLWJldGEuMSBidW1wcyB0byAxLjIuMC1iZXRhLjIsXG4gICAgICAgICAgLy8gMS4yLjAtYmV0YS5mb29ibHogb3IgMS4yLjAtYmV0YSBidW1wcyB0byAxLjIuMC1iZXRhLjBcbiAgICAgICAgICBpZiAoY29tcGFyZUlkZW50aWZpZXJzKHRoaXMucHJlcmVsZWFzZVswXSwgaWRlbnRpZmllcikgPT09IDApIHtcbiAgICAgICAgICAgIGlmIChpc05hTih0aGlzLnByZXJlbGVhc2VbMV0pKSB7XG4gICAgICAgICAgICAgIHRoaXMucHJlcmVsZWFzZSA9IFtpZGVudGlmaWVyLCAwXVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnByZXJlbGVhc2UgPSBbaWRlbnRpZmllciwgMF1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWtcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIGluY3JlbWVudCBhcmd1bWVudDogJHtyZWxlYXNlfWApXG4gICAgfVxuICAgIHRoaXMuZm9ybWF0KClcbiAgICB0aGlzLnJhdyA9IHRoaXMudmVyc2lvblxuICAgIHJldHVybiB0aGlzXG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBTZW1WZXJcbiIsImNvbnN0IFNlbVZlciA9IHJlcXVpcmUoJy4uL2NsYXNzZXMvc2VtdmVyJylcbmNvbnN0IG1ham9yID0gKGEsIGxvb3NlKSA9PiBuZXcgU2VtVmVyKGEsIGxvb3NlKS5tYWpvclxubW9kdWxlLmV4cG9ydHMgPSBtYWpvclxuIiwiY29uc3QgU2VtVmVyID0gcmVxdWlyZSgnLi4vY2xhc3Nlcy9zZW12ZXInKVxuY29uc3QgbWlub3IgPSAoYSwgbG9vc2UpID0+IG5ldyBTZW1WZXIoYSwgbG9vc2UpLm1pbm9yXG5tb2R1bGUuZXhwb3J0cyA9IG1pbm9yXG4iLCIvLyBOb3RlOiB0aGlzIGlzIHRoZSBzZW12ZXIub3JnIHZlcnNpb24gb2YgdGhlIHNwZWMgdGhhdCBpdCBpbXBsZW1lbnRzXG4vLyBOb3QgbmVjZXNzYXJpbHkgdGhlIHBhY2thZ2UgdmVyc2lvbiBvZiB0aGlzIGNvZGUuXG5jb25zdCBTRU1WRVJfU1BFQ19WRVJTSU9OID0gJzIuMC4wJ1xuXG5jb25zdCBNQVhfTEVOR1RIID0gMjU2XG5jb25zdCBNQVhfU0FGRV9JTlRFR0VSID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIgfHxcbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovIDkwMDcxOTkyNTQ3NDA5OTFcblxuLy8gTWF4IHNhZmUgc2VnbWVudCBsZW5ndGggZm9yIGNvZXJjaW9uLlxuY29uc3QgTUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSCA9IDE2XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBTRU1WRVJfU1BFQ19WRVJTSU9OLFxuICBNQVhfTEVOR1RILFxuICBNQVhfU0FGRV9JTlRFR0VSLFxuICBNQVhfU0FGRV9DT01QT05FTlRfTEVOR1RILFxufVxuIiwiY29uc3QgZGVidWcgPSAoXG4gIHR5cGVvZiBwcm9jZXNzID09PSAnb2JqZWN0JyAmJlxuICBwcm9jZXNzLmVudiAmJlxuICBwcm9jZXNzLmVudi5OT0RFX0RFQlVHICYmXG4gIC9cXGJzZW12ZXJcXGIvaS50ZXN0KHByb2Nlc3MuZW52Lk5PREVfREVCVUcpXG4pID8gKC4uLmFyZ3MpID0+IGNvbnNvbGUuZXJyb3IoJ1NFTVZFUicsIC4uLmFyZ3MpXG4gIDogKCkgPT4ge31cblxubW9kdWxlLmV4cG9ydHMgPSBkZWJ1Z1xuIiwiY29uc3QgbnVtZXJpYyA9IC9eWzAtOV0rJC9cbmNvbnN0IGNvbXBhcmVJZGVudGlmaWVycyA9IChhLCBiKSA9PiB7XG4gIGNvbnN0IGFudW0gPSBudW1lcmljLnRlc3QoYSlcbiAgY29uc3QgYm51bSA9IG51bWVyaWMudGVzdChiKVxuXG4gIGlmIChhbnVtICYmIGJudW0pIHtcbiAgICBhID0gK2FcbiAgICBiID0gK2JcbiAgfVxuXG4gIHJldHVybiBhID09PSBiID8gMFxuICAgIDogKGFudW0gJiYgIWJudW0pID8gLTFcbiAgICA6IChibnVtICYmICFhbnVtKSA/IDFcbiAgICA6IGEgPCBiID8gLTFcbiAgICA6IDFcbn1cblxuY29uc3QgcmNvbXBhcmVJZGVudGlmaWVycyA9IChhLCBiKSA9PiBjb21wYXJlSWRlbnRpZmllcnMoYiwgYSlcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGNvbXBhcmVJZGVudGlmaWVycyxcbiAgcmNvbXBhcmVJZGVudGlmaWVycyxcbn1cbiIsIi8vIHBhcnNlIG91dCBqdXN0IHRoZSBvcHRpb25zIHdlIGNhcmUgYWJvdXQgc28gd2UgYWx3YXlzIGdldCBhIGNvbnNpc3RlbnRcbi8vIG9iaiB3aXRoIGtleXMgaW4gYSBjb25zaXN0ZW50IG9yZGVyLlxuY29uc3Qgb3B0cyA9IFsnaW5jbHVkZVByZXJlbGVhc2UnLCAnbG9vc2UnLCAncnRsJ11cbmNvbnN0IHBhcnNlT3B0aW9ucyA9IG9wdGlvbnMgPT5cbiAgIW9wdGlvbnMgPyB7fVxuICA6IHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0JyA/IHsgbG9vc2U6IHRydWUgfVxuICA6IG9wdHMuZmlsdGVyKGsgPT4gb3B0aW9uc1trXSkucmVkdWNlKChvLCBrKSA9PiB7XG4gICAgb1trXSA9IHRydWVcbiAgICByZXR1cm4gb1xuICB9LCB7fSlcbm1vZHVsZS5leHBvcnRzID0gcGFyc2VPcHRpb25zXG4iLCJjb25zdCB7IE1BWF9TQUZFX0NPTVBPTkVOVF9MRU5HVEggfSA9IHJlcXVpcmUoJy4vY29uc3RhbnRzJylcbmNvbnN0IGRlYnVnID0gcmVxdWlyZSgnLi9kZWJ1ZycpXG5leHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSB7fVxuXG4vLyBUaGUgYWN0dWFsIHJlZ2V4cHMgZ28gb24gZXhwb3J0cy5yZVxuY29uc3QgcmUgPSBleHBvcnRzLnJlID0gW11cbmNvbnN0IHNyYyA9IGV4cG9ydHMuc3JjID0gW11cbmNvbnN0IHQgPSBleHBvcnRzLnQgPSB7fVxubGV0IFIgPSAwXG5cbmNvbnN0IGNyZWF0ZVRva2VuID0gKG5hbWUsIHZhbHVlLCBpc0dsb2JhbCkgPT4ge1xuICBjb25zdCBpbmRleCA9IFIrK1xuICBkZWJ1ZyhuYW1lLCBpbmRleCwgdmFsdWUpXG4gIHRbbmFtZV0gPSBpbmRleFxuICBzcmNbaW5kZXhdID0gdmFsdWVcbiAgcmVbaW5kZXhdID0gbmV3IFJlZ0V4cCh2YWx1ZSwgaXNHbG9iYWwgPyAnZycgOiB1bmRlZmluZWQpXG59XG5cbi8vIFRoZSBmb2xsb3dpbmcgUmVndWxhciBFeHByZXNzaW9ucyBjYW4gYmUgdXNlZCBmb3IgdG9rZW5pemluZyxcbi8vIHZhbGlkYXRpbmcsIGFuZCBwYXJzaW5nIFNlbVZlciB2ZXJzaW9uIHN0cmluZ3MuXG5cbi8vICMjIE51bWVyaWMgSWRlbnRpZmllclxuLy8gQSBzaW5nbGUgYDBgLCBvciBhIG5vbi16ZXJvIGRpZ2l0IGZvbGxvd2VkIGJ5IHplcm8gb3IgbW9yZSBkaWdpdHMuXG5cbmNyZWF0ZVRva2VuKCdOVU1FUklDSURFTlRJRklFUicsICcwfFsxLTldXFxcXGQqJylcbmNyZWF0ZVRva2VuKCdOVU1FUklDSURFTlRJRklFUkxPT1NFJywgJ1swLTldKycpXG5cbi8vICMjIE5vbi1udW1lcmljIElkZW50aWZpZXJcbi8vIFplcm8gb3IgbW9yZSBkaWdpdHMsIGZvbGxvd2VkIGJ5IGEgbGV0dGVyIG9yIGh5cGhlbiwgYW5kIHRoZW4gemVybyBvclxuLy8gbW9yZSBsZXR0ZXJzLCBkaWdpdHMsIG9yIGh5cGhlbnMuXG5cbmNyZWF0ZVRva2VuKCdOT05OVU1FUklDSURFTlRJRklFUicsICdcXFxcZCpbYS16QS1aLV1bYS16QS1aMC05LV0qJylcblxuLy8gIyMgTWFpbiBWZXJzaW9uXG4vLyBUaHJlZSBkb3Qtc2VwYXJhdGVkIG51bWVyaWMgaWRlbnRpZmllcnMuXG5cbmNyZWF0ZVRva2VuKCdNQUlOVkVSU0lPTicsIGAoJHtzcmNbdC5OVU1FUklDSURFTlRJRklFUl19KVxcXFwuYCArXG4gICAgICAgICAgICAgICAgICAgYCgke3NyY1t0Lk5VTUVSSUNJREVOVElGSUVSXX0pXFxcXC5gICtcbiAgICAgICAgICAgICAgICAgICBgKCR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJdfSlgKVxuXG5jcmVhdGVUb2tlbignTUFJTlZFUlNJT05MT09TRScsIGAoJHtzcmNbdC5OVU1FUklDSURFTlRJRklFUkxPT1NFXX0pXFxcXC5gICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGAoJHtzcmNbdC5OVU1FUklDSURFTlRJRklFUkxPT1NFXX0pXFxcXC5gICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGAoJHtzcmNbdC5OVU1FUklDSURFTlRJRklFUkxPT1NFXX0pYClcblxuLy8gIyMgUHJlLXJlbGVhc2UgVmVyc2lvbiBJZGVudGlmaWVyXG4vLyBBIG51bWVyaWMgaWRlbnRpZmllciwgb3IgYSBub24tbnVtZXJpYyBpZGVudGlmaWVyLlxuXG5jcmVhdGVUb2tlbignUFJFUkVMRUFTRUlERU5USUZJRVInLCBgKD86JHtzcmNbdC5OVU1FUklDSURFTlRJRklFUl1cbn18JHtzcmNbdC5OT05OVU1FUklDSURFTlRJRklFUl19KWApXG5cbmNyZWF0ZVRva2VuKCdQUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFJywgYCg/OiR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJMT09TRV1cbn18JHtzcmNbdC5OT05OVU1FUklDSURFTlRJRklFUl19KWApXG5cbi8vICMjIFByZS1yZWxlYXNlIFZlcnNpb25cbi8vIEh5cGhlbiwgZm9sbG93ZWQgYnkgb25lIG9yIG1vcmUgZG90LXNlcGFyYXRlZCBwcmUtcmVsZWFzZSB2ZXJzaW9uXG4vLyBpZGVudGlmaWVycy5cblxuY3JlYXRlVG9rZW4oJ1BSRVJFTEVBU0UnLCBgKD86LSgke3NyY1t0LlBSRVJFTEVBU0VJREVOVElGSUVSXVxufSg/OlxcXFwuJHtzcmNbdC5QUkVSRUxFQVNFSURFTlRJRklFUl19KSopKWApXG5cbmNyZWF0ZVRva2VuKCdQUkVSRUxFQVNFTE9PU0UnLCBgKD86LT8oJHtzcmNbdC5QUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFXVxufSg/OlxcXFwuJHtzcmNbdC5QUkVSRUxFQVNFSURFTlRJRklFUkxPT1NFXX0pKikpYClcblxuLy8gIyMgQnVpbGQgTWV0YWRhdGEgSWRlbnRpZmllclxuLy8gQW55IGNvbWJpbmF0aW9uIG9mIGRpZ2l0cywgbGV0dGVycywgb3IgaHlwaGVucy5cblxuY3JlYXRlVG9rZW4oJ0JVSUxESURFTlRJRklFUicsICdbMC05QS1aYS16LV0rJylcblxuLy8gIyMgQnVpbGQgTWV0YWRhdGFcbi8vIFBsdXMgc2lnbiwgZm9sbG93ZWQgYnkgb25lIG9yIG1vcmUgcGVyaW9kLXNlcGFyYXRlZCBidWlsZCBtZXRhZGF0YVxuLy8gaWRlbnRpZmllcnMuXG5cbmNyZWF0ZVRva2VuKCdCVUlMRCcsIGAoPzpcXFxcKygke3NyY1t0LkJVSUxESURFTlRJRklFUl1cbn0oPzpcXFxcLiR7c3JjW3QuQlVJTERJREVOVElGSUVSXX0pKikpYClcblxuLy8gIyMgRnVsbCBWZXJzaW9uIFN0cmluZ1xuLy8gQSBtYWluIHZlcnNpb24sIGZvbGxvd2VkIG9wdGlvbmFsbHkgYnkgYSBwcmUtcmVsZWFzZSB2ZXJzaW9uIGFuZFxuLy8gYnVpbGQgbWV0YWRhdGEuXG5cbi8vIE5vdGUgdGhhdCB0aGUgb25seSBtYWpvciwgbWlub3IsIHBhdGNoLCBhbmQgcHJlLXJlbGVhc2Ugc2VjdGlvbnMgb2Zcbi8vIHRoZSB2ZXJzaW9uIHN0cmluZyBhcmUgY2FwdHVyaW5nIGdyb3Vwcy4gIFRoZSBidWlsZCBtZXRhZGF0YSBpcyBub3QgYVxuLy8gY2FwdHVyaW5nIGdyb3VwLCBiZWNhdXNlIGl0IHNob3VsZCBub3QgZXZlciBiZSB1c2VkIGluIHZlcnNpb25cbi8vIGNvbXBhcmlzb24uXG5cbmNyZWF0ZVRva2VuKCdGVUxMUExBSU4nLCBgdj8ke3NyY1t0Lk1BSU5WRVJTSU9OXVxufSR7c3JjW3QuUFJFUkVMRUFTRV19PyR7XG4gIHNyY1t0LkJVSUxEXX0/YClcblxuY3JlYXRlVG9rZW4oJ0ZVTEwnLCBgXiR7c3JjW3QuRlVMTFBMQUlOXX0kYClcblxuLy8gbGlrZSBmdWxsLCBidXQgYWxsb3dzIHYxLjIuMyBhbmQgPTEuMi4zLCB3aGljaCBwZW9wbGUgZG8gc29tZXRpbWVzLlxuLy8gYWxzbywgMS4wLjBhbHBoYTEgKHByZXJlbGVhc2Ugd2l0aG91dCB0aGUgaHlwaGVuKSB3aGljaCBpcyBwcmV0dHlcbi8vIGNvbW1vbiBpbiB0aGUgbnBtIHJlZ2lzdHJ5LlxuY3JlYXRlVG9rZW4oJ0xPT1NFUExBSU4nLCBgW3Y9XFxcXHNdKiR7c3JjW3QuTUFJTlZFUlNJT05MT09TRV1cbn0ke3NyY1t0LlBSRVJFTEVBU0VMT09TRV19PyR7XG4gIHNyY1t0LkJVSUxEXX0/YClcblxuY3JlYXRlVG9rZW4oJ0xPT1NFJywgYF4ke3NyY1t0LkxPT1NFUExBSU5dfSRgKVxuXG5jcmVhdGVUb2tlbignR1RMVCcsICcoKD86PHw+KT89PyknKVxuXG4vLyBTb21ldGhpbmcgbGlrZSBcIjIuKlwiIG9yIFwiMS4yLnhcIi5cbi8vIE5vdGUgdGhhdCBcIngueFwiIGlzIGEgdmFsaWQgeFJhbmdlIGlkZW50aWZlciwgbWVhbmluZyBcImFueSB2ZXJzaW9uXCJcbi8vIE9ubHkgdGhlIGZpcnN0IGl0ZW0gaXMgc3RyaWN0bHkgcmVxdWlyZWQuXG5jcmVhdGVUb2tlbignWFJBTkdFSURFTlRJRklFUkxPT1NFJywgYCR7c3JjW3QuTlVNRVJJQ0lERU5USUZJRVJMT09TRV19fHh8WHxcXFxcKmApXG5jcmVhdGVUb2tlbignWFJBTkdFSURFTlRJRklFUicsIGAke3NyY1t0Lk5VTUVSSUNJREVOVElGSUVSXX18eHxYfFxcXFwqYClcblxuY3JlYXRlVG9rZW4oJ1hSQU5HRVBMQUlOJywgYFt2PVxcXFxzXSooJHtzcmNbdC5YUkFOR0VJREVOVElGSUVSXX0pYCArXG4gICAgICAgICAgICAgICAgICAgYCg/OlxcXFwuKCR7c3JjW3QuWFJBTkdFSURFTlRJRklFUl19KWAgK1xuICAgICAgICAgICAgICAgICAgIGAoPzpcXFxcLigke3NyY1t0LlhSQU5HRUlERU5USUZJRVJdfSlgICtcbiAgICAgICAgICAgICAgICAgICBgKD86JHtzcmNbdC5QUkVSRUxFQVNFXX0pPyR7XG4gICAgICAgICAgICAgICAgICAgICBzcmNbdC5CVUlMRF19P2AgK1xuICAgICAgICAgICAgICAgICAgIGApPyk/YClcblxuY3JlYXRlVG9rZW4oJ1hSQU5HRVBMQUlOTE9PU0UnLCBgW3Y9XFxcXHNdKigke3NyY1t0LlhSQU5HRUlERU5USUZJRVJMT09TRV19KWAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYCg/OlxcXFwuKCR7c3JjW3QuWFJBTkdFSURFTlRJRklFUkxPT1NFXX0pYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgKD86XFxcXC4oJHtzcmNbdC5YUkFOR0VJREVOVElGSUVSTE9PU0VdfSlgICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGAoPzoke3NyY1t0LlBSRVJFTEVBU0VMT09TRV19KT8ke1xuICAgICAgICAgICAgICAgICAgICAgICAgICBzcmNbdC5CVUlMRF19P2AgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYCk/KT9gKVxuXG5jcmVhdGVUb2tlbignWFJBTkdFJywgYF4ke3NyY1t0LkdUTFRdfVxcXFxzKiR7c3JjW3QuWFJBTkdFUExBSU5dfSRgKVxuY3JlYXRlVG9rZW4oJ1hSQU5HRUxPT1NFJywgYF4ke3NyY1t0LkdUTFRdfVxcXFxzKiR7c3JjW3QuWFJBTkdFUExBSU5MT09TRV19JGApXG5cbi8vIENvZXJjaW9uLlxuLy8gRXh0cmFjdCBhbnl0aGluZyB0aGF0IGNvdWxkIGNvbmNlaXZhYmx5IGJlIGEgcGFydCBvZiBhIHZhbGlkIHNlbXZlclxuY3JlYXRlVG9rZW4oJ0NPRVJDRScsIGAkeycoXnxbXlxcXFxkXSknICtcbiAgICAgICAgICAgICAgJyhcXFxcZHsxLCd9JHtNQVhfU0FGRV9DT01QT05FTlRfTEVOR1RIfX0pYCArXG4gICAgICAgICAgICAgIGAoPzpcXFxcLihcXFxcZHsxLCR7TUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSH19KSk/YCArXG4gICAgICAgICAgICAgIGAoPzpcXFxcLihcXFxcZHsxLCR7TUFYX1NBRkVfQ09NUE9ORU5UX0xFTkdUSH19KSk/YCArXG4gICAgICAgICAgICAgIGAoPzokfFteXFxcXGRdKWApXG5jcmVhdGVUb2tlbignQ09FUkNFUlRMJywgc3JjW3QuQ09FUkNFXSwgdHJ1ZSlcblxuLy8gVGlsZGUgcmFuZ2VzLlxuLy8gTWVhbmluZyBpcyBcInJlYXNvbmFibHkgYXQgb3IgZ3JlYXRlciB0aGFuXCJcbmNyZWF0ZVRva2VuKCdMT05FVElMREUnLCAnKD86fj4/KScpXG5cbmNyZWF0ZVRva2VuKCdUSUxERVRSSU0nLCBgKFxcXFxzKikke3NyY1t0LkxPTkVUSUxERV19XFxcXHMrYCwgdHJ1ZSlcbmV4cG9ydHMudGlsZGVUcmltUmVwbGFjZSA9ICckMX4nXG5cbmNyZWF0ZVRva2VuKCdUSUxERScsIGBeJHtzcmNbdC5MT05FVElMREVdfSR7c3JjW3QuWFJBTkdFUExBSU5dfSRgKVxuY3JlYXRlVG9rZW4oJ1RJTERFTE9PU0UnLCBgXiR7c3JjW3QuTE9ORVRJTERFXX0ke3NyY1t0LlhSQU5HRVBMQUlOTE9PU0VdfSRgKVxuXG4vLyBDYXJldCByYW5nZXMuXG4vLyBNZWFuaW5nIGlzIFwiYXQgbGVhc3QgYW5kIGJhY2t3YXJkcyBjb21wYXRpYmxlIHdpdGhcIlxuY3JlYXRlVG9rZW4oJ0xPTkVDQVJFVCcsICcoPzpcXFxcXiknKVxuXG5jcmVhdGVUb2tlbignQ0FSRVRUUklNJywgYChcXFxccyopJHtzcmNbdC5MT05FQ0FSRVRdfVxcXFxzK2AsIHRydWUpXG5leHBvcnRzLmNhcmV0VHJpbVJlcGxhY2UgPSAnJDFeJ1xuXG5jcmVhdGVUb2tlbignQ0FSRVQnLCBgXiR7c3JjW3QuTE9ORUNBUkVUXX0ke3NyY1t0LlhSQU5HRVBMQUlOXX0kYClcbmNyZWF0ZVRva2VuKCdDQVJFVExPT1NFJywgYF4ke3NyY1t0LkxPTkVDQVJFVF19JHtzcmNbdC5YUkFOR0VQTEFJTkxPT1NFXX0kYClcblxuLy8gQSBzaW1wbGUgZ3QvbHQvZXEgdGhpbmcsIG9yIGp1c3QgXCJcIiB0byBpbmRpY2F0ZSBcImFueSB2ZXJzaW9uXCJcbmNyZWF0ZVRva2VuKCdDT01QQVJBVE9STE9PU0UnLCBgXiR7c3JjW3QuR1RMVF19XFxcXHMqKCR7c3JjW3QuTE9PU0VQTEFJTl19KSR8XiRgKVxuY3JlYXRlVG9rZW4oJ0NPTVBBUkFUT1InLCBgXiR7c3JjW3QuR1RMVF19XFxcXHMqKCR7c3JjW3QuRlVMTFBMQUlOXX0pJHxeJGApXG5cbi8vIEFuIGV4cHJlc3Npb24gdG8gc3RyaXAgYW55IHdoaXRlc3BhY2UgYmV0d2VlbiB0aGUgZ3RsdCBhbmQgdGhlIHRoaW5nXG4vLyBpdCBtb2RpZmllcywgc28gdGhhdCBgPiAxLjIuM2AgPT0+IGA+MS4yLjNgXG5jcmVhdGVUb2tlbignQ09NUEFSQVRPUlRSSU0nLCBgKFxcXFxzKikke3NyY1t0LkdUTFRdXG59XFxcXHMqKCR7c3JjW3QuTE9PU0VQTEFJTl19fCR7c3JjW3QuWFJBTkdFUExBSU5dfSlgLCB0cnVlKVxuZXhwb3J0cy5jb21wYXJhdG9yVHJpbVJlcGxhY2UgPSAnJDEkMiQzJ1xuXG4vLyBTb21ldGhpbmcgbGlrZSBgMS4yLjMgLSAxLjIuNGBcbi8vIE5vdGUgdGhhdCB0aGVzZSBhbGwgdXNlIHRoZSBsb29zZSBmb3JtLCBiZWNhdXNlIHRoZXknbGwgYmVcbi8vIGNoZWNrZWQgYWdhaW5zdCBlaXRoZXIgdGhlIHN0cmljdCBvciBsb29zZSBjb21wYXJhdG9yIGZvcm1cbi8vIGxhdGVyLlxuY3JlYXRlVG9rZW4oJ0hZUEhFTlJBTkdFJywgYF5cXFxccyooJHtzcmNbdC5YUkFOR0VQTEFJTl19KWAgK1xuICAgICAgICAgICAgICAgICAgIGBcXFxccystXFxcXHMrYCArXG4gICAgICAgICAgICAgICAgICAgYCgke3NyY1t0LlhSQU5HRVBMQUlOXX0pYCArXG4gICAgICAgICAgICAgICAgICAgYFxcXFxzKiRgKVxuXG5jcmVhdGVUb2tlbignSFlQSEVOUkFOR0VMT09TRScsIGBeXFxcXHMqKCR7c3JjW3QuWFJBTkdFUExBSU5MT09TRV19KWAgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYFxcXFxzKy1cXFxccytgICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGAoJHtzcmNbdC5YUkFOR0VQTEFJTkxPT1NFXX0pYCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgXFxcXHMqJGApXG5cbi8vIFN0YXIgcmFuZ2VzIGJhc2ljYWxseSBqdXN0IGFsbG93IGFueXRoaW5nIGF0IGFsbC5cbmNyZWF0ZVRva2VuKCdTVEFSJywgJyg8fD4pPz0/XFxcXHMqXFxcXConKVxuLy8gPj0wLjAuMCBpcyBsaWtlIGEgc3RhclxuY3JlYXRlVG9rZW4oJ0dURTAnLCAnXlxcXFxzKj49XFxcXHMqMFxcXFwuMFxcXFwuMFxcXFxzKiQnKVxuY3JlYXRlVG9rZW4oJ0dURTBQUkUnLCAnXlxcXFxzKj49XFxcXHMqMFxcXFwuMFxcXFwuMC0wXFxcXHMqJCcpXG4iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcInYxXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF92LmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjNcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3YyLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjRcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3YzLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidjVcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3Y0LmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiTklMXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9uaWwuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJ2ZXJzaW9uXCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF92ZXJzaW9uLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwidmFsaWRhdGVcIiwge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gX3ZhbGlkYXRlLmRlZmF1bHQ7XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwic3RyaW5naWZ5XCIsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF9zdHJpbmdpZnkuZGVmYXVsdDtcbiAgfVxufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJwYXJzZVwiLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfcGFyc2UuZGVmYXVsdDtcbiAgfVxufSk7XG5cbnZhciBfdiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdjEuanNcIikpO1xuXG52YXIgX3YyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92My5qc1wiKSk7XG5cbnZhciBfdjMgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3Y0LmpzXCIpKTtcblxudmFyIF92NCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdjUuanNcIikpO1xuXG52YXIgX25pbCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vbmlsLmpzXCIpKTtcblxudmFyIF92ZXJzaW9uID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92ZXJzaW9uLmpzXCIpKTtcblxudmFyIF92YWxpZGF0ZSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vdmFsaWRhdGUuanNcIikpO1xuXG52YXIgX3N0cmluZ2lmeSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vc3RyaW5naWZ5LmpzXCIpKTtcblxudmFyIF9wYXJzZSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vcGFyc2UuanNcIikpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfSIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG4vKlxuICogQnJvd3Nlci1jb21wYXRpYmxlIEphdmFTY3JpcHQgTUQ1XG4gKlxuICogTW9kaWZpY2F0aW9uIG9mIEphdmFTY3JpcHQgTUQ1XG4gKiBodHRwczovL2dpdGh1Yi5jb20vYmx1ZWltcC9KYXZhU2NyaXB0LU1ENVxuICpcbiAqIENvcHlyaWdodCAyMDExLCBTZWJhc3RpYW4gVHNjaGFuXG4gKiBodHRwczovL2JsdWVpbXAubmV0XG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlOlxuICogaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVRcbiAqXG4gKiBCYXNlZCBvblxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBSU0EgRGF0YSBTZWN1cml0eSwgSW5jLiBNRDUgTWVzc2FnZVxuICogRGlnZXN0IEFsZ29yaXRobSwgYXMgZGVmaW5lZCBpbiBSRkMgMTMyMS5cbiAqIFZlcnNpb24gMi4yIENvcHlyaWdodCAoQykgUGF1bCBKb2huc3RvbiAxOTk5IC0gMjAwOVxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlXG4gKiBTZWUgaHR0cDovL3BhamhvbWUub3JnLnVrL2NyeXB0L21kNSBmb3IgbW9yZSBpbmZvLlxuICovXG5mdW5jdGlvbiBtZDUoYnl0ZXMpIHtcbiAgaWYgKHR5cGVvZiBieXRlcyA9PT0gJ3N0cmluZycpIHtcbiAgICBjb25zdCBtc2cgPSB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoYnl0ZXMpKTsgLy8gVVRGOCBlc2NhcGVcblxuICAgIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobXNnLmxlbmd0aCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1zZy5sZW5ndGg7ICsraSkge1xuICAgICAgYnl0ZXNbaV0gPSBtc2cuY2hhckNvZGVBdChpKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbWQ1VG9IZXhFbmNvZGVkQXJyYXkod29yZHNUb01kNShieXRlc1RvV29yZHMoYnl0ZXMpLCBieXRlcy5sZW5ndGggKiA4KSk7XG59XG4vKlxuICogQ29udmVydCBhbiBhcnJheSBvZiBsaXR0bGUtZW5kaWFuIHdvcmRzIHRvIGFuIGFycmF5IG9mIGJ5dGVzXG4gKi9cblxuXG5mdW5jdGlvbiBtZDVUb0hleEVuY29kZWRBcnJheShpbnB1dCkge1xuICBjb25zdCBvdXRwdXQgPSBbXTtcbiAgY29uc3QgbGVuZ3RoMzIgPSBpbnB1dC5sZW5ndGggKiAzMjtcbiAgY29uc3QgaGV4VGFiID0gJzAxMjM0NTY3ODlhYmNkZWYnO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoMzI7IGkgKz0gOCkge1xuICAgIGNvbnN0IHggPSBpbnB1dFtpID4+IDVdID4+PiBpICUgMzIgJiAweGZmO1xuICAgIGNvbnN0IGhleCA9IHBhcnNlSW50KGhleFRhYi5jaGFyQXQoeCA+Pj4gNCAmIDB4MGYpICsgaGV4VGFiLmNoYXJBdCh4ICYgMHgwZiksIDE2KTtcbiAgICBvdXRwdXQucHVzaChoZXgpO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cbi8qKlxuICogQ2FsY3VsYXRlIG91dHB1dCBsZW5ndGggd2l0aCBwYWRkaW5nIGFuZCBiaXQgbGVuZ3RoXG4gKi9cblxuXG5mdW5jdGlvbiBnZXRPdXRwdXRMZW5ndGgoaW5wdXRMZW5ndGg4KSB7XG4gIHJldHVybiAoaW5wdXRMZW5ndGg4ICsgNjQgPj4+IDkgPDwgNCkgKyAxNCArIDE7XG59XG4vKlxuICogQ2FsY3VsYXRlIHRoZSBNRDUgb2YgYW4gYXJyYXkgb2YgbGl0dGxlLWVuZGlhbiB3b3JkcywgYW5kIGEgYml0IGxlbmd0aC5cbiAqL1xuXG5cbmZ1bmN0aW9uIHdvcmRzVG9NZDUoeCwgbGVuKSB7XG4gIC8qIGFwcGVuZCBwYWRkaW5nICovXG4gIHhbbGVuID4+IDVdIHw9IDB4ODAgPDwgbGVuICUgMzI7XG4gIHhbZ2V0T3V0cHV0TGVuZ3RoKGxlbikgLSAxXSA9IGxlbjtcbiAgbGV0IGEgPSAxNzMyNTg0MTkzO1xuICBsZXQgYiA9IC0yNzE3MzM4Nzk7XG4gIGxldCBjID0gLTE3MzI1ODQxOTQ7XG4gIGxldCBkID0gMjcxNzMzODc4O1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkgKz0gMTYpIHtcbiAgICBjb25zdCBvbGRhID0gYTtcbiAgICBjb25zdCBvbGRiID0gYjtcbiAgICBjb25zdCBvbGRjID0gYztcbiAgICBjb25zdCBvbGRkID0gZDtcbiAgICBhID0gbWQ1ZmYoYSwgYiwgYywgZCwgeFtpXSwgNywgLTY4MDg3NjkzNik7XG4gICAgZCA9IG1kNWZmKGQsIGEsIGIsIGMsIHhbaSArIDFdLCAxMiwgLTM4OTU2NDU4Nik7XG4gICAgYyA9IG1kNWZmKGMsIGQsIGEsIGIsIHhbaSArIDJdLCAxNywgNjA2MTA1ODE5KTtcbiAgICBiID0gbWQ1ZmYoYiwgYywgZCwgYSwgeFtpICsgM10sIDIyLCAtMTA0NDUyNTMzMCk7XG4gICAgYSA9IG1kNWZmKGEsIGIsIGMsIGQsIHhbaSArIDRdLCA3LCAtMTc2NDE4ODk3KTtcbiAgICBkID0gbWQ1ZmYoZCwgYSwgYiwgYywgeFtpICsgNV0sIDEyLCAxMjAwMDgwNDI2KTtcbiAgICBjID0gbWQ1ZmYoYywgZCwgYSwgYiwgeFtpICsgNl0sIDE3LCAtMTQ3MzIzMTM0MSk7XG4gICAgYiA9IG1kNWZmKGIsIGMsIGQsIGEsIHhbaSArIDddLCAyMiwgLTQ1NzA1OTgzKTtcbiAgICBhID0gbWQ1ZmYoYSwgYiwgYywgZCwgeFtpICsgOF0sIDcsIDE3NzAwMzU0MTYpO1xuICAgIGQgPSBtZDVmZihkLCBhLCBiLCBjLCB4W2kgKyA5XSwgMTIsIC0xOTU4NDE0NDE3KTtcbiAgICBjID0gbWQ1ZmYoYywgZCwgYSwgYiwgeFtpICsgMTBdLCAxNywgLTQyMDYzKTtcbiAgICBiID0gbWQ1ZmYoYiwgYywgZCwgYSwgeFtpICsgMTFdLCAyMiwgLTE5OTA0MDQxNjIpO1xuICAgIGEgPSBtZDVmZihhLCBiLCBjLCBkLCB4W2kgKyAxMl0sIDcsIDE4MDQ2MDM2ODIpO1xuICAgIGQgPSBtZDVmZihkLCBhLCBiLCBjLCB4W2kgKyAxM10sIDEyLCAtNDAzNDExMDEpO1xuICAgIGMgPSBtZDVmZihjLCBkLCBhLCBiLCB4W2kgKyAxNF0sIDE3LCAtMTUwMjAwMjI5MCk7XG4gICAgYiA9IG1kNWZmKGIsIGMsIGQsIGEsIHhbaSArIDE1XSwgMjIsIDEyMzY1MzUzMjkpO1xuICAgIGEgPSBtZDVnZyhhLCBiLCBjLCBkLCB4W2kgKyAxXSwgNSwgLTE2NTc5NjUxMCk7XG4gICAgZCA9IG1kNWdnKGQsIGEsIGIsIGMsIHhbaSArIDZdLCA5LCAtMTA2OTUwMTYzMik7XG4gICAgYyA9IG1kNWdnKGMsIGQsIGEsIGIsIHhbaSArIDExXSwgMTQsIDY0MzcxNzcxMyk7XG4gICAgYiA9IG1kNWdnKGIsIGMsIGQsIGEsIHhbaV0sIDIwLCAtMzczODk3MzAyKTtcbiAgICBhID0gbWQ1Z2coYSwgYiwgYywgZCwgeFtpICsgNV0sIDUsIC03MDE1NTg2OTEpO1xuICAgIGQgPSBtZDVnZyhkLCBhLCBiLCBjLCB4W2kgKyAxMF0sIDksIDM4MDE2MDgzKTtcbiAgICBjID0gbWQ1Z2coYywgZCwgYSwgYiwgeFtpICsgMTVdLCAxNCwgLTY2MDQ3ODMzNSk7XG4gICAgYiA9IG1kNWdnKGIsIGMsIGQsIGEsIHhbaSArIDRdLCAyMCwgLTQwNTUzNzg0OCk7XG4gICAgYSA9IG1kNWdnKGEsIGIsIGMsIGQsIHhbaSArIDldLCA1LCA1Njg0NDY0MzgpO1xuICAgIGQgPSBtZDVnZyhkLCBhLCBiLCBjLCB4W2kgKyAxNF0sIDksIC0xMDE5ODAzNjkwKTtcbiAgICBjID0gbWQ1Z2coYywgZCwgYSwgYiwgeFtpICsgM10sIDE0LCAtMTg3MzYzOTYxKTtcbiAgICBiID0gbWQ1Z2coYiwgYywgZCwgYSwgeFtpICsgOF0sIDIwLCAxMTYzNTMxNTAxKTtcbiAgICBhID0gbWQ1Z2coYSwgYiwgYywgZCwgeFtpICsgMTNdLCA1LCAtMTQ0NDY4MTQ2Nyk7XG4gICAgZCA9IG1kNWdnKGQsIGEsIGIsIGMsIHhbaSArIDJdLCA5LCAtNTE0MDM3ODQpO1xuICAgIGMgPSBtZDVnZyhjLCBkLCBhLCBiLCB4W2kgKyA3XSwgMTQsIDE3MzUzMjg0NzMpO1xuICAgIGIgPSBtZDVnZyhiLCBjLCBkLCBhLCB4W2kgKyAxMl0sIDIwLCAtMTkyNjYwNzczNCk7XG4gICAgYSA9IG1kNWhoKGEsIGIsIGMsIGQsIHhbaSArIDVdLCA0LCAtMzc4NTU4KTtcbiAgICBkID0gbWQ1aGgoZCwgYSwgYiwgYywgeFtpICsgOF0sIDExLCAtMjAyMjU3NDQ2Myk7XG4gICAgYyA9IG1kNWhoKGMsIGQsIGEsIGIsIHhbaSArIDExXSwgMTYsIDE4MzkwMzA1NjIpO1xuICAgIGIgPSBtZDVoaChiLCBjLCBkLCBhLCB4W2kgKyAxNF0sIDIzLCAtMzUzMDk1NTYpO1xuICAgIGEgPSBtZDVoaChhLCBiLCBjLCBkLCB4W2kgKyAxXSwgNCwgLTE1MzA5OTIwNjApO1xuICAgIGQgPSBtZDVoaChkLCBhLCBiLCBjLCB4W2kgKyA0XSwgMTEsIDEyNzI4OTMzNTMpO1xuICAgIGMgPSBtZDVoaChjLCBkLCBhLCBiLCB4W2kgKyA3XSwgMTYsIC0xNTU0OTc2MzIpO1xuICAgIGIgPSBtZDVoaChiLCBjLCBkLCBhLCB4W2kgKyAxMF0sIDIzLCAtMTA5NDczMDY0MCk7XG4gICAgYSA9IG1kNWhoKGEsIGIsIGMsIGQsIHhbaSArIDEzXSwgNCwgNjgxMjc5MTc0KTtcbiAgICBkID0gbWQ1aGgoZCwgYSwgYiwgYywgeFtpXSwgMTEsIC0zNTg1MzcyMjIpO1xuICAgIGMgPSBtZDVoaChjLCBkLCBhLCBiLCB4W2kgKyAzXSwgMTYsIC03MjI1MjE5NzkpO1xuICAgIGIgPSBtZDVoaChiLCBjLCBkLCBhLCB4W2kgKyA2XSwgMjMsIDc2MDI5MTg5KTtcbiAgICBhID0gbWQ1aGgoYSwgYiwgYywgZCwgeFtpICsgOV0sIDQsIC02NDAzNjQ0ODcpO1xuICAgIGQgPSBtZDVoaChkLCBhLCBiLCBjLCB4W2kgKyAxMl0sIDExLCAtNDIxODE1ODM1KTtcbiAgICBjID0gbWQ1aGgoYywgZCwgYSwgYiwgeFtpICsgMTVdLCAxNiwgNTMwNzQyNTIwKTtcbiAgICBiID0gbWQ1aGgoYiwgYywgZCwgYSwgeFtpICsgMl0sIDIzLCAtOTk1MzM4NjUxKTtcbiAgICBhID0gbWQ1aWkoYSwgYiwgYywgZCwgeFtpXSwgNiwgLTE5ODYzMDg0NCk7XG4gICAgZCA9IG1kNWlpKGQsIGEsIGIsIGMsIHhbaSArIDddLCAxMCwgMTEyNjg5MTQxNSk7XG4gICAgYyA9IG1kNWlpKGMsIGQsIGEsIGIsIHhbaSArIDE0XSwgMTUsIC0xNDE2MzU0OTA1KTtcbiAgICBiID0gbWQ1aWkoYiwgYywgZCwgYSwgeFtpICsgNV0sIDIxLCAtNTc0MzQwNTUpO1xuICAgIGEgPSBtZDVpaShhLCBiLCBjLCBkLCB4W2kgKyAxMl0sIDYsIDE3MDA0ODU1NzEpO1xuICAgIGQgPSBtZDVpaShkLCBhLCBiLCBjLCB4W2kgKyAzXSwgMTAsIC0xODk0OTg2NjA2KTtcbiAgICBjID0gbWQ1aWkoYywgZCwgYSwgYiwgeFtpICsgMTBdLCAxNSwgLTEwNTE1MjMpO1xuICAgIGIgPSBtZDVpaShiLCBjLCBkLCBhLCB4W2kgKyAxXSwgMjEsIC0yMDU0OTIyNzk5KTtcbiAgICBhID0gbWQ1aWkoYSwgYiwgYywgZCwgeFtpICsgOF0sIDYsIDE4NzMzMTMzNTkpO1xuICAgIGQgPSBtZDVpaShkLCBhLCBiLCBjLCB4W2kgKyAxNV0sIDEwLCAtMzA2MTE3NDQpO1xuICAgIGMgPSBtZDVpaShjLCBkLCBhLCBiLCB4W2kgKyA2XSwgMTUsIC0xNTYwMTk4MzgwKTtcbiAgICBiID0gbWQ1aWkoYiwgYywgZCwgYSwgeFtpICsgMTNdLCAyMSwgMTMwOTE1MTY0OSk7XG4gICAgYSA9IG1kNWlpKGEsIGIsIGMsIGQsIHhbaSArIDRdLCA2LCAtMTQ1NTIzMDcwKTtcbiAgICBkID0gbWQ1aWkoZCwgYSwgYiwgYywgeFtpICsgMTFdLCAxMCwgLTExMjAyMTAzNzkpO1xuICAgIGMgPSBtZDVpaShjLCBkLCBhLCBiLCB4W2kgKyAyXSwgMTUsIDcxODc4NzI1OSk7XG4gICAgYiA9IG1kNWlpKGIsIGMsIGQsIGEsIHhbaSArIDldLCAyMSwgLTM0MzQ4NTU1MSk7XG4gICAgYSA9IHNhZmVBZGQoYSwgb2xkYSk7XG4gICAgYiA9IHNhZmVBZGQoYiwgb2xkYik7XG4gICAgYyA9IHNhZmVBZGQoYywgb2xkYyk7XG4gICAgZCA9IHNhZmVBZGQoZCwgb2xkZCk7XG4gIH1cblxuICByZXR1cm4gW2EsIGIsIGMsIGRdO1xufVxuLypcbiAqIENvbnZlcnQgYW4gYXJyYXkgYnl0ZXMgdG8gYW4gYXJyYXkgb2YgbGl0dGxlLWVuZGlhbiB3b3Jkc1xuICogQ2hhcmFjdGVycyA+MjU1IGhhdmUgdGhlaXIgaGlnaC1ieXRlIHNpbGVudGx5IGlnbm9yZWQuXG4gKi9cblxuXG5mdW5jdGlvbiBieXRlc1RvV29yZHMoaW5wdXQpIHtcbiAgaWYgKGlucHV0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IGxlbmd0aDggPSBpbnB1dC5sZW5ndGggKiA4O1xuICBjb25zdCBvdXRwdXQgPSBuZXcgVWludDMyQXJyYXkoZ2V0T3V0cHV0TGVuZ3RoKGxlbmd0aDgpKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDg7IGkgKz0gOCkge1xuICAgIG91dHB1dFtpID4+IDVdIHw9IChpbnB1dFtpIC8gOF0gJiAweGZmKSA8PCBpICUgMzI7XG4gIH1cblxuICByZXR1cm4gb3V0cHV0O1xufVxuLypcbiAqIEFkZCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zIGludGVybmFsbHlcbiAqIHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG4gKi9cblxuXG5mdW5jdGlvbiBzYWZlQWRkKHgsIHkpIHtcbiAgY29uc3QgbHN3ID0gKHggJiAweGZmZmYpICsgKHkgJiAweGZmZmYpO1xuICBjb25zdCBtc3cgPSAoeCA+PiAxNikgKyAoeSA+PiAxNikgKyAobHN3ID4+IDE2KTtcbiAgcmV0dXJuIG1zdyA8PCAxNiB8IGxzdyAmIDB4ZmZmZjtcbn1cbi8qXG4gKiBCaXR3aXNlIHJvdGF0ZSBhIDMyLWJpdCBudW1iZXIgdG8gdGhlIGxlZnQuXG4gKi9cblxuXG5mdW5jdGlvbiBiaXRSb3RhdGVMZWZ0KG51bSwgY250KSB7XG4gIHJldHVybiBudW0gPDwgY250IHwgbnVtID4+PiAzMiAtIGNudDtcbn1cbi8qXG4gKiBUaGVzZSBmdW5jdGlvbnMgaW1wbGVtZW50IHRoZSBmb3VyIGJhc2ljIG9wZXJhdGlvbnMgdGhlIGFsZ29yaXRobSB1c2VzLlxuICovXG5cblxuZnVuY3Rpb24gbWQ1Y21uKHEsIGEsIGIsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIHNhZmVBZGQoYml0Um90YXRlTGVmdChzYWZlQWRkKHNhZmVBZGQoYSwgcSksIHNhZmVBZGQoeCwgdCkpLCBzKSwgYik7XG59XG5cbmZ1bmN0aW9uIG1kNWZmKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIG1kNWNtbihiICYgYyB8IH5iICYgZCwgYSwgYiwgeCwgcywgdCk7XG59XG5cbmZ1bmN0aW9uIG1kNWdnKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIG1kNWNtbihiICYgZCB8IGMgJiB+ZCwgYSwgYiwgeCwgcywgdCk7XG59XG5cbmZ1bmN0aW9uIG1kNWhoKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHtcbiAgcmV0dXJuIG1kNWNtbihiIF4gYyBeIGQsIGEsIGIsIHgsIHMsIHQpO1xufVxuXG5mdW5jdGlvbiBtZDVpaShhLCBiLCBjLCBkLCB4LCBzLCB0KSB7XG4gIHJldHVybiBtZDVjbW4oYyBeIChiIHwgfmQpLCBhLCBiLCB4LCBzLCB0KTtcbn1cblxudmFyIF9kZWZhdWx0ID0gbWQ1O1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG52YXIgX2RlZmF1bHQgPSAnMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwJztcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3ZhbGlkYXRlID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92YWxpZGF0ZS5qc1wiKSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIHBhcnNlKHV1aWQpIHtcbiAgaWYgKCEoMCwgX3ZhbGlkYXRlLmRlZmF1bHQpKHV1aWQpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKCdJbnZhbGlkIFVVSUQnKTtcbiAgfVxuXG4gIGxldCB2O1xuICBjb25zdCBhcnIgPSBuZXcgVWludDhBcnJheSgxNik7IC8vIFBhcnNlICMjIyMjIyMjLS4uLi4tLi4uLi0uLi4uLS4uLi4uLi4uLi4uLlxuXG4gIGFyclswXSA9ICh2ID0gcGFyc2VJbnQodXVpZC5zbGljZSgwLCA4KSwgMTYpKSA+Pj4gMjQ7XG4gIGFyclsxXSA9IHYgPj4+IDE2ICYgMHhmZjtcbiAgYXJyWzJdID0gdiA+Pj4gOCAmIDB4ZmY7XG4gIGFyclszXSA9IHYgJiAweGZmOyAvLyBQYXJzZSAuLi4uLi4uLi0jIyMjLS4uLi4tLi4uLi0uLi4uLi4uLi4uLi5cblxuICBhcnJbNF0gPSAodiA9IHBhcnNlSW50KHV1aWQuc2xpY2UoOSwgMTMpLCAxNikpID4+PiA4O1xuICBhcnJbNV0gPSB2ICYgMHhmZjsgLy8gUGFyc2UgLi4uLi4uLi4tLi4uLi0jIyMjLS4uLi4tLi4uLi4uLi4uLi4uXG5cbiAgYXJyWzZdID0gKHYgPSBwYXJzZUludCh1dWlkLnNsaWNlKDE0LCAxOCksIDE2KSkgPj4+IDg7XG4gIGFycls3XSA9IHYgJiAweGZmOyAvLyBQYXJzZSAuLi4uLi4uLi0uLi4uLS4uLi4tIyMjIy0uLi4uLi4uLi4uLi5cblxuICBhcnJbOF0gPSAodiA9IHBhcnNlSW50KHV1aWQuc2xpY2UoMTksIDIzKSwgMTYpKSA+Pj4gODtcbiAgYXJyWzldID0gdiAmIDB4ZmY7IC8vIFBhcnNlIC4uLi4uLi4uLS4uLi4tLi4uLi0uLi4uLSMjIyMjIyMjIyMjI1xuICAvLyAoVXNlIFwiL1wiIHRvIGF2b2lkIDMyLWJpdCB0cnVuY2F0aW9uIHdoZW4gYml0LXNoaWZ0aW5nIGhpZ2gtb3JkZXIgYnl0ZXMpXG5cbiAgYXJyWzEwXSA9ICh2ID0gcGFyc2VJbnQodXVpZC5zbGljZSgyNCwgMzYpLCAxNikpIC8gMHgxMDAwMDAwMDAwMCAmIDB4ZmY7XG4gIGFyclsxMV0gPSB2IC8gMHgxMDAwMDAwMDAgJiAweGZmO1xuICBhcnJbMTJdID0gdiA+Pj4gMjQgJiAweGZmO1xuICBhcnJbMTNdID0gdiA+Pj4gMTYgJiAweGZmO1xuICBhcnJbMTRdID0gdiA+Pj4gOCAmIDB4ZmY7XG4gIGFyclsxNV0gPSB2ICYgMHhmZjtcbiAgcmV0dXJuIGFycjtcbn1cblxudmFyIF9kZWZhdWx0ID0gcGFyc2U7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcbnZhciBfZGVmYXVsdCA9IC9eKD86WzAtOWEtZl17OH0tWzAtOWEtZl17NH0tWzEtNV1bMC05YS1mXXszfS1bODlhYl1bMC05YS1mXXszfS1bMC05YS1mXXsxMn18MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwKSQvaTtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gcm5nO1xuLy8gVW5pcXVlIElEIGNyZWF0aW9uIHJlcXVpcmVzIGEgaGlnaCBxdWFsaXR5IHJhbmRvbSAjIGdlbmVyYXRvci4gSW4gdGhlIGJyb3dzZXIgd2UgdGhlcmVmb3JlXG4vLyByZXF1aXJlIHRoZSBjcnlwdG8gQVBJIGFuZCBkbyBub3Qgc3VwcG9ydCBidWlsdC1pbiBmYWxsYmFjayB0byBsb3dlciBxdWFsaXR5IHJhbmRvbSBudW1iZXJcbi8vIGdlbmVyYXRvcnMgKGxpa2UgTWF0aC5yYW5kb20oKSkuXG5sZXQgZ2V0UmFuZG9tVmFsdWVzO1xuY29uc3Qgcm5kczggPSBuZXcgVWludDhBcnJheSgxNik7XG5cbmZ1bmN0aW9uIHJuZygpIHtcbiAgLy8gbGF6eSBsb2FkIHNvIHRoYXQgZW52aXJvbm1lbnRzIHRoYXQgbmVlZCB0byBwb2x5ZmlsbCBoYXZlIGEgY2hhbmNlIHRvIGRvIHNvXG4gIGlmICghZ2V0UmFuZG9tVmFsdWVzKSB7XG4gICAgLy8gZ2V0UmFuZG9tVmFsdWVzIG5lZWRzIHRvIGJlIGludm9rZWQgaW4gYSBjb250ZXh0IHdoZXJlIFwidGhpc1wiIGlzIGEgQ3J5cHRvIGltcGxlbWVudGF0aW9uLiBBbHNvLFxuICAgIC8vIGZpbmQgdGhlIGNvbXBsZXRlIGltcGxlbWVudGF0aW9uIG9mIGNyeXB0byAobXNDcnlwdG8pIG9uIElFMTEuXG4gICAgZ2V0UmFuZG9tVmFsdWVzID0gdHlwZW9mIGNyeXB0byAhPT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQoY3J5cHRvKSB8fCB0eXBlb2YgbXNDcnlwdG8gIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBtc0NyeXB0by5nZXRSYW5kb21WYWx1ZXMgPT09ICdmdW5jdGlvbicgJiYgbXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQobXNDcnlwdG8pO1xuXG4gICAgaWYgKCFnZXRSYW5kb21WYWx1ZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY3J5cHRvLmdldFJhbmRvbVZhbHVlcygpIG5vdCBzdXBwb3J0ZWQuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vdXVpZGpzL3V1aWQjZ2V0cmFuZG9tdmFsdWVzLW5vdC1zdXBwb3J0ZWQnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZ2V0UmFuZG9tVmFsdWVzKHJuZHM4KTtcbn0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxuLy8gQWRhcHRlZCBmcm9tIENocmlzIFZlbmVzcycgU0hBMSBjb2RlIGF0XG4vLyBodHRwOi8vd3d3Lm1vdmFibGUtdHlwZS5jby51ay9zY3JpcHRzL3NoYTEuaHRtbFxuZnVuY3Rpb24gZihzLCB4LCB5LCB6KSB7XG4gIHN3aXRjaCAocykge1xuICAgIGNhc2UgMDpcbiAgICAgIHJldHVybiB4ICYgeSBeIH54ICYgejtcblxuICAgIGNhc2UgMTpcbiAgICAgIHJldHVybiB4IF4geSBeIHo7XG5cbiAgICBjYXNlIDI6XG4gICAgICByZXR1cm4geCAmIHkgXiB4ICYgeiBeIHkgJiB6O1xuXG4gICAgY2FzZSAzOlxuICAgICAgcmV0dXJuIHggXiB5IF4gejtcbiAgfVxufVxuXG5mdW5jdGlvbiBST1RMKHgsIG4pIHtcbiAgcmV0dXJuIHggPDwgbiB8IHggPj4+IDMyIC0gbjtcbn1cblxuZnVuY3Rpb24gc2hhMShieXRlcykge1xuICBjb25zdCBLID0gWzB4NWE4Mjc5OTksIDB4NmVkOWViYTEsIDB4OGYxYmJjZGMsIDB4Y2E2MmMxZDZdO1xuICBjb25zdCBIID0gWzB4Njc0NTIzMDEsIDB4ZWZjZGFiODksIDB4OThiYWRjZmUsIDB4MTAzMjU0NzYsIDB4YzNkMmUxZjBdO1xuXG4gIGlmICh0eXBlb2YgYnl0ZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uc3QgbXNnID0gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KGJ5dGVzKSk7IC8vIFVURjggZXNjYXBlXG5cbiAgICBieXRlcyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtc2cubGVuZ3RoOyArK2kpIHtcbiAgICAgIGJ5dGVzLnB1c2gobXNnLmNoYXJDb2RlQXQoaSkpO1xuICAgIH1cbiAgfSBlbHNlIGlmICghQXJyYXkuaXNBcnJheShieXRlcykpIHtcbiAgICAvLyBDb252ZXJ0IEFycmF5LWxpa2UgdG8gQXJyYXlcbiAgICBieXRlcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGJ5dGVzKTtcbiAgfVxuXG4gIGJ5dGVzLnB1c2goMHg4MCk7XG4gIGNvbnN0IGwgPSBieXRlcy5sZW5ndGggLyA0ICsgMjtcbiAgY29uc3QgTiA9IE1hdGguY2VpbChsIC8gMTYpO1xuICBjb25zdCBNID0gbmV3IEFycmF5KE4pO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgTjsgKytpKSB7XG4gICAgY29uc3QgYXJyID0gbmV3IFVpbnQzMkFycmF5KDE2KTtcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgMTY7ICsraikge1xuICAgICAgYXJyW2pdID0gYnl0ZXNbaSAqIDY0ICsgaiAqIDRdIDw8IDI0IHwgYnl0ZXNbaSAqIDY0ICsgaiAqIDQgKyAxXSA8PCAxNiB8IGJ5dGVzW2kgKiA2NCArIGogKiA0ICsgMl0gPDwgOCB8IGJ5dGVzW2kgKiA2NCArIGogKiA0ICsgM107XG4gICAgfVxuXG4gICAgTVtpXSA9IGFycjtcbiAgfVxuXG4gIE1bTiAtIDFdWzE0XSA9IChieXRlcy5sZW5ndGggLSAxKSAqIDggLyBNYXRoLnBvdygyLCAzMik7XG4gIE1bTiAtIDFdWzE0XSA9IE1hdGguZmxvb3IoTVtOIC0gMV1bMTRdKTtcbiAgTVtOIC0gMV1bMTVdID0gKGJ5dGVzLmxlbmd0aCAtIDEpICogOCAmIDB4ZmZmZmZmZmY7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBOOyArK2kpIHtcbiAgICBjb25zdCBXID0gbmV3IFVpbnQzMkFycmF5KDgwKTtcblxuICAgIGZvciAobGV0IHQgPSAwOyB0IDwgMTY7ICsrdCkge1xuICAgICAgV1t0XSA9IE1baV1bdF07XG4gICAgfVxuXG4gICAgZm9yIChsZXQgdCA9IDE2OyB0IDwgODA7ICsrdCkge1xuICAgICAgV1t0XSA9IFJPVEwoV1t0IC0gM10gXiBXW3QgLSA4XSBeIFdbdCAtIDE0XSBeIFdbdCAtIDE2XSwgMSk7XG4gICAgfVxuXG4gICAgbGV0IGEgPSBIWzBdO1xuICAgIGxldCBiID0gSFsxXTtcbiAgICBsZXQgYyA9IEhbMl07XG4gICAgbGV0IGQgPSBIWzNdO1xuICAgIGxldCBlID0gSFs0XTtcblxuICAgIGZvciAobGV0IHQgPSAwOyB0IDwgODA7ICsrdCkge1xuICAgICAgY29uc3QgcyA9IE1hdGguZmxvb3IodCAvIDIwKTtcbiAgICAgIGNvbnN0IFQgPSBST1RMKGEsIDUpICsgZihzLCBiLCBjLCBkKSArIGUgKyBLW3NdICsgV1t0XSA+Pj4gMDtcbiAgICAgIGUgPSBkO1xuICAgICAgZCA9IGM7XG4gICAgICBjID0gUk9UTChiLCAzMCkgPj4+IDA7XG4gICAgICBiID0gYTtcbiAgICAgIGEgPSBUO1xuICAgIH1cblxuICAgIEhbMF0gPSBIWzBdICsgYSA+Pj4gMDtcbiAgICBIWzFdID0gSFsxXSArIGIgPj4+IDA7XG4gICAgSFsyXSA9IEhbMl0gKyBjID4+PiAwO1xuICAgIEhbM10gPSBIWzNdICsgZCA+Pj4gMDtcbiAgICBIWzRdID0gSFs0XSArIGUgPj4+IDA7XG4gIH1cblxuICByZXR1cm4gW0hbMF0gPj4gMjQgJiAweGZmLCBIWzBdID4+IDE2ICYgMHhmZiwgSFswXSA+PiA4ICYgMHhmZiwgSFswXSAmIDB4ZmYsIEhbMV0gPj4gMjQgJiAweGZmLCBIWzFdID4+IDE2ICYgMHhmZiwgSFsxXSA+PiA4ICYgMHhmZiwgSFsxXSAmIDB4ZmYsIEhbMl0gPj4gMjQgJiAweGZmLCBIWzJdID4+IDE2ICYgMHhmZiwgSFsyXSA+PiA4ICYgMHhmZiwgSFsyXSAmIDB4ZmYsIEhbM10gPj4gMjQgJiAweGZmLCBIWzNdID4+IDE2ICYgMHhmZiwgSFszXSA+PiA4ICYgMHhmZiwgSFszXSAmIDB4ZmYsIEhbNF0gPj4gMjQgJiAweGZmLCBIWzRdID4+IDE2ICYgMHhmZiwgSFs0XSA+PiA4ICYgMHhmZiwgSFs0XSAmIDB4ZmZdO1xufVxuXG52YXIgX2RlZmF1bHQgPSBzaGExO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfdmFsaWRhdGUgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZhbGlkYXRlLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuLyoqXG4gKiBDb252ZXJ0IGFycmF5IG9mIDE2IGJ5dGUgdmFsdWVzIHRvIFVVSUQgc3RyaW5nIGZvcm1hdCBvZiB0aGUgZm9ybTpcbiAqIFhYWFhYWFhYLVhYWFgtWFhYWC1YWFhYLVhYWFhYWFhYWFhYWFxuICovXG5jb25zdCBieXRlVG9IZXggPSBbXTtcblxuZm9yIChsZXQgaSA9IDA7IGkgPCAyNTY7ICsraSkge1xuICBieXRlVG9IZXgucHVzaCgoaSArIDB4MTAwKS50b1N0cmluZygxNikuc3Vic3RyKDEpKTtcbn1cblxuZnVuY3Rpb24gc3RyaW5naWZ5KGFyciwgb2Zmc2V0ID0gMCkge1xuICAvLyBOb3RlOiBCZSBjYXJlZnVsIGVkaXRpbmcgdGhpcyBjb2RlISAgSXQncyBiZWVuIHR1bmVkIGZvciBwZXJmb3JtYW5jZVxuICAvLyBhbmQgd29ya3MgaW4gd2F5cyB5b3UgbWF5IG5vdCBleHBlY3QuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vdXVpZGpzL3V1aWQvcHVsbC80MzRcbiAgY29uc3QgdXVpZCA9IChieXRlVG9IZXhbYXJyW29mZnNldCArIDBdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgMV1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyAyXV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDNdXSArICctJyArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgNF1dICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyA1XV0gKyAnLScgKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDZdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgN11dICsgJy0nICsgYnl0ZVRvSGV4W2FycltvZmZzZXQgKyA4XV0gKyBieXRlVG9IZXhbYXJyW29mZnNldCArIDldXSArICctJyArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgMTBdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgMTFdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgMTJdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgMTNdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgMTRdXSArIGJ5dGVUb0hleFthcnJbb2Zmc2V0ICsgMTVdXSkudG9Mb3dlckNhc2UoKTsgLy8gQ29uc2lzdGVuY3kgY2hlY2sgZm9yIHZhbGlkIFVVSUQuICBJZiB0aGlzIHRocm93cywgaXQncyBsaWtlbHkgZHVlIHRvIG9uZVxuICAvLyBvZiB0aGUgZm9sbG93aW5nOlxuICAvLyAtIE9uZSBvciBtb3JlIGlucHV0IGFycmF5IHZhbHVlcyBkb24ndCBtYXAgdG8gYSBoZXggb2N0ZXQgKGxlYWRpbmcgdG9cbiAgLy8gXCJ1bmRlZmluZWRcIiBpbiB0aGUgdXVpZClcbiAgLy8gLSBJbnZhbGlkIGlucHV0IHZhbHVlcyBmb3IgdGhlIFJGQyBgdmVyc2lvbmAgb3IgYHZhcmlhbnRgIGZpZWxkc1xuXG4gIGlmICghKDAsIF92YWxpZGF0ZS5kZWZhdWx0KSh1dWlkKSkge1xuICAgIHRocm93IFR5cGVFcnJvcignU3RyaW5naWZpZWQgVVVJRCBpcyBpbnZhbGlkJyk7XG4gIH1cblxuICByZXR1cm4gdXVpZDtcbn1cblxudmFyIF9kZWZhdWx0ID0gc3RyaW5naWZ5O1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfcm5nID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9ybmcuanNcIikpO1xuXG52YXIgX3N0cmluZ2lmeSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vc3RyaW5naWZ5LmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuLy8gKipgdjEoKWAgLSBHZW5lcmF0ZSB0aW1lLWJhc2VkIFVVSUQqKlxuLy9cbi8vIEluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9MaW9zSy9VVUlELmpzXG4vLyBhbmQgaHR0cDovL2RvY3MucHl0aG9uLm9yZy9saWJyYXJ5L3V1aWQuaHRtbFxubGV0IF9ub2RlSWQ7XG5cbmxldCBfY2xvY2tzZXE7IC8vIFByZXZpb3VzIHV1aWQgY3JlYXRpb24gdGltZVxuXG5cbmxldCBfbGFzdE1TZWNzID0gMDtcbmxldCBfbGFzdE5TZWNzID0gMDsgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS91dWlkanMvdXVpZCBmb3IgQVBJIGRldGFpbHNcblxuZnVuY3Rpb24gdjEob3B0aW9ucywgYnVmLCBvZmZzZXQpIHtcbiAgbGV0IGkgPSBidWYgJiYgb2Zmc2V0IHx8IDA7XG4gIGNvbnN0IGIgPSBidWYgfHwgbmV3IEFycmF5KDE2KTtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGxldCBub2RlID0gb3B0aW9ucy5ub2RlIHx8IF9ub2RlSWQ7XG4gIGxldCBjbG9ja3NlcSA9IG9wdGlvbnMuY2xvY2tzZXEgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuY2xvY2tzZXEgOiBfY2xvY2tzZXE7IC8vIG5vZGUgYW5kIGNsb2Nrc2VxIG5lZWQgdG8gYmUgaW5pdGlhbGl6ZWQgdG8gcmFuZG9tIHZhbHVlcyBpZiB0aGV5J3JlIG5vdFxuICAvLyBzcGVjaWZpZWQuICBXZSBkbyB0aGlzIGxhemlseSB0byBtaW5pbWl6ZSBpc3N1ZXMgcmVsYXRlZCB0byBpbnN1ZmZpY2llbnRcbiAgLy8gc3lzdGVtIGVudHJvcHkuICBTZWUgIzE4OVxuXG4gIGlmIChub2RlID09IG51bGwgfHwgY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgIGNvbnN0IHNlZWRCeXRlcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBfcm5nLmRlZmF1bHQpKCk7XG5cbiAgICBpZiAobm9kZSA9PSBudWxsKSB7XG4gICAgICAvLyBQZXIgNC41LCBjcmVhdGUgYW5kIDQ4LWJpdCBub2RlIGlkLCAoNDcgcmFuZG9tIGJpdHMgKyBtdWx0aWNhc3QgYml0ID0gMSlcbiAgICAgIG5vZGUgPSBfbm9kZUlkID0gW3NlZWRCeXRlc1swXSB8IDB4MDEsIHNlZWRCeXRlc1sxXSwgc2VlZEJ5dGVzWzJdLCBzZWVkQnl0ZXNbM10sIHNlZWRCeXRlc1s0XSwgc2VlZEJ5dGVzWzVdXTtcbiAgICB9XG5cbiAgICBpZiAoY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgICAgLy8gUGVyIDQuMi4yLCByYW5kb21pemUgKDE0IGJpdCkgY2xvY2tzZXFcbiAgICAgIGNsb2Nrc2VxID0gX2Nsb2Nrc2VxID0gKHNlZWRCeXRlc1s2XSA8PCA4IHwgc2VlZEJ5dGVzWzddKSAmIDB4M2ZmZjtcbiAgICB9XG4gIH0gLy8gVVVJRCB0aW1lc3RhbXBzIGFyZSAxMDAgbmFuby1zZWNvbmQgdW5pdHMgc2luY2UgdGhlIEdyZWdvcmlhbiBlcG9jaCxcbiAgLy8gKDE1ODItMTAtMTUgMDA6MDApLiAgSlNOdW1iZXJzIGFyZW4ndCBwcmVjaXNlIGVub3VnaCBmb3IgdGhpcywgc29cbiAgLy8gdGltZSBpcyBoYW5kbGVkIGludGVybmFsbHkgYXMgJ21zZWNzJyAoaW50ZWdlciBtaWxsaXNlY29uZHMpIGFuZCAnbnNlY3MnXG4gIC8vICgxMDAtbmFub3NlY29uZHMgb2Zmc2V0IGZyb20gbXNlY3MpIHNpbmNlIHVuaXggZXBvY2gsIDE5NzAtMDEtMDEgMDA6MDAuXG5cblxuICBsZXQgbXNlY3MgPSBvcHRpb25zLm1zZWNzICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLm1zZWNzIDogRGF0ZS5ub3coKTsgLy8gUGVyIDQuMi4xLjIsIHVzZSBjb3VudCBvZiB1dWlkJ3MgZ2VuZXJhdGVkIGR1cmluZyB0aGUgY3VycmVudCBjbG9ja1xuICAvLyBjeWNsZSB0byBzaW11bGF0ZSBoaWdoZXIgcmVzb2x1dGlvbiBjbG9ja1xuXG4gIGxldCBuc2VjcyA9IG9wdGlvbnMubnNlY3MgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMubnNlY3MgOiBfbGFzdE5TZWNzICsgMTsgLy8gVGltZSBzaW5jZSBsYXN0IHV1aWQgY3JlYXRpb24gKGluIG1zZWNzKVxuXG4gIGNvbnN0IGR0ID0gbXNlY3MgLSBfbGFzdE1TZWNzICsgKG5zZWNzIC0gX2xhc3ROU2VjcykgLyAxMDAwMDsgLy8gUGVyIDQuMi4xLjIsIEJ1bXAgY2xvY2tzZXEgb24gY2xvY2sgcmVncmVzc2lvblxuXG4gIGlmIChkdCA8IDAgJiYgb3B0aW9ucy5jbG9ja3NlcSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY2xvY2tzZXEgPSBjbG9ja3NlcSArIDEgJiAweDNmZmY7XG4gIH0gLy8gUmVzZXQgbnNlY3MgaWYgY2xvY2sgcmVncmVzc2VzIChuZXcgY2xvY2tzZXEpIG9yIHdlJ3ZlIG1vdmVkIG9udG8gYSBuZXdcbiAgLy8gdGltZSBpbnRlcnZhbFxuXG5cbiAgaWYgKChkdCA8IDAgfHwgbXNlY3MgPiBfbGFzdE1TZWNzKSAmJiBvcHRpb25zLm5zZWNzID09PSB1bmRlZmluZWQpIHtcbiAgICBuc2VjcyA9IDA7XG4gIH0gLy8gUGVyIDQuMi4xLjIgVGhyb3cgZXJyb3IgaWYgdG9vIG1hbnkgdXVpZHMgYXJlIHJlcXVlc3RlZFxuXG5cbiAgaWYgKG5zZWNzID49IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwidXVpZC52MSgpOiBDYW4ndCBjcmVhdGUgbW9yZSB0aGFuIDEwTSB1dWlkcy9zZWNcIik7XG4gIH1cblxuICBfbGFzdE1TZWNzID0gbXNlY3M7XG4gIF9sYXN0TlNlY3MgPSBuc2VjcztcbiAgX2Nsb2Nrc2VxID0gY2xvY2tzZXE7IC8vIFBlciA0LjEuNCAtIENvbnZlcnQgZnJvbSB1bml4IGVwb2NoIHRvIEdyZWdvcmlhbiBlcG9jaFxuXG4gIG1zZWNzICs9IDEyMjE5MjkyODAwMDAwOyAvLyBgdGltZV9sb3dgXG5cbiAgY29uc3QgdGwgPSAoKG1zZWNzICYgMHhmZmZmZmZmKSAqIDEwMDAwICsgbnNlY3MpICUgMHgxMDAwMDAwMDA7XG4gIGJbaSsrXSA9IHRsID4+PiAyNCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsID4+PiAxNiAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdGwgJiAweGZmOyAvLyBgdGltZV9taWRgXG5cbiAgY29uc3QgdG1oID0gbXNlY3MgLyAweDEwMDAwMDAwMCAqIDEwMDAwICYgMHhmZmZmZmZmO1xuICBiW2krK10gPSB0bWggPj4+IDggJiAweGZmO1xuICBiW2krK10gPSB0bWggJiAweGZmOyAvLyBgdGltZV9oaWdoX2FuZF92ZXJzaW9uYFxuXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMjQgJiAweGYgfCAweDEwOyAvLyBpbmNsdWRlIHZlcnNpb25cblxuICBiW2krK10gPSB0bWggPj4+IDE2ICYgMHhmZjsgLy8gYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgIChQZXIgNC4yLjIgLSBpbmNsdWRlIHZhcmlhbnQpXG5cbiAgYltpKytdID0gY2xvY2tzZXEgPj4+IDggfCAweDgwOyAvLyBgY2xvY2tfc2VxX2xvd2BcblxuICBiW2krK10gPSBjbG9ja3NlcSAmIDB4ZmY7IC8vIGBub2RlYFxuXG4gIGZvciAobGV0IG4gPSAwOyBuIDwgNjsgKytuKSB7XG4gICAgYltpICsgbl0gPSBub2RlW25dO1xuICB9XG5cbiAgcmV0dXJuIGJ1ZiB8fCAoMCwgX3N0cmluZ2lmeS5kZWZhdWx0KShiKTtcbn1cblxudmFyIF9kZWZhdWx0ID0gdjE7XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF92ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi92MzUuanNcIikpO1xuXG52YXIgX21kID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9tZDUuanNcIikpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5jb25zdCB2MyA9ICgwLCBfdi5kZWZhdWx0KSgndjMnLCAweDMwLCBfbWQuZGVmYXVsdCk7XG52YXIgX2RlZmF1bHQgPSB2MztcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7XG5leHBvcnRzLlVSTCA9IGV4cG9ydHMuRE5TID0gdm9pZCAwO1xuXG52YXIgX3N0cmluZ2lmeSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vc3RyaW5naWZ5LmpzXCIpKTtcblxudmFyIF9wYXJzZSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vcGFyc2UuanNcIikpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBzdHJpbmdUb0J5dGVzKHN0cikge1xuICBzdHIgPSB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoc3RyKSk7IC8vIFVURjggZXNjYXBlXG5cbiAgY29uc3QgYnl0ZXMgPSBbXTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7ICsraSkge1xuICAgIGJ5dGVzLnB1c2goc3RyLmNoYXJDb2RlQXQoaSkpO1xuICB9XG5cbiAgcmV0dXJuIGJ5dGVzO1xufVxuXG5jb25zdCBETlMgPSAnNmJhN2I4MTAtOWRhZC0xMWQxLTgwYjQtMDBjMDRmZDQzMGM4JztcbmV4cG9ydHMuRE5TID0gRE5TO1xuY29uc3QgVVJMID0gJzZiYTdiODExLTlkYWQtMTFkMS04MGI0LTAwYzA0ZmQ0MzBjOCc7XG5leHBvcnRzLlVSTCA9IFVSTDtcblxuZnVuY3Rpb24gX2RlZmF1bHQobmFtZSwgdmVyc2lvbiwgaGFzaGZ1bmMpIHtcbiAgZnVuY3Rpb24gZ2VuZXJhdGVVVUlEKHZhbHVlLCBuYW1lc3BhY2UsIGJ1Ziwgb2Zmc2V0KSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHZhbHVlID0gc3RyaW5nVG9CeXRlcyh2YWx1ZSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBuYW1lc3BhY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBuYW1lc3BhY2UgPSAoMCwgX3BhcnNlLmRlZmF1bHQpKG5hbWVzcGFjZSk7XG4gICAgfVxuXG4gICAgaWYgKG5hbWVzcGFjZS5sZW5ndGggIT09IDE2KSB7XG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ05hbWVzcGFjZSBtdXN0IGJlIGFycmF5LWxpa2UgKDE2IGl0ZXJhYmxlIGludGVnZXIgdmFsdWVzLCAwLTI1NSknKTtcbiAgICB9IC8vIENvbXB1dGUgaGFzaCBvZiBuYW1lc3BhY2UgYW5kIHZhbHVlLCBQZXIgNC4zXG4gICAgLy8gRnV0dXJlOiBVc2Ugc3ByZWFkIHN5bnRheCB3aGVuIHN1cHBvcnRlZCBvbiBhbGwgcGxhdGZvcm1zLCBlLmcuIGBieXRlcyA9XG4gICAgLy8gaGFzaGZ1bmMoWy4uLm5hbWVzcGFjZSwgLi4uIHZhbHVlXSlgXG5cblxuICAgIGxldCBieXRlcyA9IG5ldyBVaW50OEFycmF5KDE2ICsgdmFsdWUubGVuZ3RoKTtcbiAgICBieXRlcy5zZXQobmFtZXNwYWNlKTtcbiAgICBieXRlcy5zZXQodmFsdWUsIG5hbWVzcGFjZS5sZW5ndGgpO1xuICAgIGJ5dGVzID0gaGFzaGZ1bmMoYnl0ZXMpO1xuICAgIGJ5dGVzWzZdID0gYnl0ZXNbNl0gJiAweDBmIHwgdmVyc2lvbjtcbiAgICBieXRlc1s4XSA9IGJ5dGVzWzhdICYgMHgzZiB8IDB4ODA7XG5cbiAgICBpZiAoYnVmKSB7XG4gICAgICBvZmZzZXQgPSBvZmZzZXQgfHwgMDtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAxNjsgKytpKSB7XG4gICAgICAgIGJ1ZltvZmZzZXQgKyBpXSA9IGJ5dGVzW2ldO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYnVmO1xuICAgIH1cblxuICAgIHJldHVybiAoMCwgX3N0cmluZ2lmeS5kZWZhdWx0KShieXRlcyk7XG4gIH0gLy8gRnVuY3Rpb24jbmFtZSBpcyBub3Qgc2V0dGFibGUgb24gc29tZSBwbGF0Zm9ybXMgKCMyNzApXG5cblxuICB0cnkge1xuICAgIGdlbmVyYXRlVVVJRC5uYW1lID0gbmFtZTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVtcHR5XG4gIH0gY2F0Y2ggKGVycikge30gLy8gRm9yIENvbW1vbkpTIGRlZmF1bHQgZXhwb3J0IHN1cHBvcnRcblxuXG4gIGdlbmVyYXRlVVVJRC5ETlMgPSBETlM7XG4gIGdlbmVyYXRlVVVJRC5VUkwgPSBVUkw7XG4gIHJldHVybiBnZW5lcmF0ZVVVSUQ7XG59IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfcm5nID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9ybmcuanNcIikpO1xuXG52YXIgX3N0cmluZ2lmeSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vc3RyaW5naWZ5LmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gdjQob3B0aW9ucywgYnVmLCBvZmZzZXQpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgY29uc3Qgcm5kcyA9IG9wdGlvbnMucmFuZG9tIHx8IChvcHRpb25zLnJuZyB8fCBfcm5nLmRlZmF1bHQpKCk7IC8vIFBlciA0LjQsIHNldCBiaXRzIGZvciB2ZXJzaW9uIGFuZCBgY2xvY2tfc2VxX2hpX2FuZF9yZXNlcnZlZGBcblxuXG4gIHJuZHNbNl0gPSBybmRzWzZdICYgMHgwZiB8IDB4NDA7XG4gIHJuZHNbOF0gPSBybmRzWzhdICYgMHgzZiB8IDB4ODA7IC8vIENvcHkgYnl0ZXMgdG8gYnVmZmVyLCBpZiBwcm92aWRlZFxuXG4gIGlmIChidWYpIHtcbiAgICBvZmZzZXQgPSBvZmZzZXQgfHwgMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMTY7ICsraSkge1xuICAgICAgYnVmW29mZnNldCArIGldID0gcm5kc1tpXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYnVmO1xuICB9XG5cbiAgcmV0dXJuICgwLCBfc3RyaW5naWZ5LmRlZmF1bHQpKHJuZHMpO1xufVxuXG52YXIgX2RlZmF1bHQgPSB2NDtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0OyIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3YgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3YzNS5qc1wiKSk7XG5cbnZhciBfc2hhID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9zaGExLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuY29uc3QgdjUgPSAoMCwgX3YuZGVmYXVsdCkoJ3Y1JywgMHg1MCwgX3NoYS5kZWZhdWx0KTtcbnZhciBfZGVmYXVsdCA9IHY1O1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfcmVnZXggPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3JlZ2V4LmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gdmFsaWRhdGUodXVpZCkge1xuICByZXR1cm4gdHlwZW9mIHV1aWQgPT09ICdzdHJpbmcnICYmIF9yZWdleC5kZWZhdWx0LnRlc3QodXVpZCk7XG59XG5cbnZhciBfZGVmYXVsdCA9IHZhbGlkYXRlO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfdmFsaWRhdGUgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCIuL3ZhbGlkYXRlLmpzXCIpKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gdmVyc2lvbih1dWlkKSB7XG4gIGlmICghKDAsIF92YWxpZGF0ZS5kZWZhdWx0KSh1dWlkKSkge1xuICAgIHRocm93IFR5cGVFcnJvcignSW52YWxpZCBVVUlEJyk7XG4gIH1cblxuICByZXR1cm4gcGFyc2VJbnQodXVpZC5zdWJzdHIoMTQsIDEpLCAxNik7XG59XG5cbnZhciBfZGVmYXVsdCA9IHZlcnNpb247XG5leHBvcnRzLmRlZmF1bHQgPSBfZGVmYXVsdDsiLCIvKlxuV2lsZEVtaXR0ZXIuanMgaXMgYSBzbGltIGxpdHRsZSBldmVudCBlbWl0dGVyIGJ5IEBoZW5yaWtqb3JldGVnIGxhcmdlbHkgYmFzZWRcbm9uIEB2aXNpb25tZWRpYSdzIEVtaXR0ZXIgZnJvbSBVSSBLaXQuXG5cbldoeT8gSSB3YW50ZWQgaXQgc3RhbmRhbG9uZS5cblxuSSBhbHNvIHdhbnRlZCBzdXBwb3J0IGZvciB3aWxkY2FyZCBlbWl0dGVycyBsaWtlIHRoaXM6XG5cbmVtaXR0ZXIub24oJyonLCBmdW5jdGlvbiAoZXZlbnROYW1lLCBvdGhlciwgZXZlbnQsIHBheWxvYWRzKSB7XG5cbn0pO1xuXG5lbWl0dGVyLm9uKCdzb21lbmFtZXNwYWNlKicsIGZ1bmN0aW9uIChldmVudE5hbWUsIHBheWxvYWRzKSB7XG5cbn0pO1xuXG5QbGVhc2Ugbm90ZSB0aGF0IGNhbGxiYWNrcyB0cmlnZ2VyZWQgYnkgd2lsZGNhcmQgcmVnaXN0ZXJlZCBldmVudHMgYWxzbyBnZXRcbnRoZSBldmVudCBuYW1lIGFzIHRoZSBmaXJzdCBhcmd1bWVudC5cbiovXG5cbm1vZHVsZS5leHBvcnRzID0gV2lsZEVtaXR0ZXI7XG5cbmZ1bmN0aW9uIFdpbGRFbWl0dGVyKCkgeyB9XG5cbldpbGRFbWl0dGVyLm1peGluID0gZnVuY3Rpb24gKGNvbnN0cnVjdG9yKSB7XG4gICAgdmFyIHByb3RvdHlwZSA9IGNvbnN0cnVjdG9yLnByb3RvdHlwZSB8fCBjb25zdHJ1Y3RvcjtcblxuICAgIHByb3RvdHlwZS5pc1dpbGRFbWl0dGVyPSB0cnVlO1xuXG4gICAgLy8gTGlzdGVuIG9uIHRoZSBnaXZlbiBgZXZlbnRgIHdpdGggYGZuYC4gU3RvcmUgYSBncm91cCBuYW1lIGlmIHByZXNlbnQuXG4gICAgcHJvdG90eXBlLm9uID0gZnVuY3Rpb24gKGV2ZW50LCBncm91cE5hbWUsIGZuKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XG4gICAgICAgIHZhciBoYXNHcm91cCA9IChhcmd1bWVudHMubGVuZ3RoID09PSAzKSxcbiAgICAgICAgICAgIGdyb3VwID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XG4gICAgICAgIGZ1bmMuX2dyb3VwTmFtZSA9IGdyb3VwO1xuICAgICAgICAodGhpcy5jYWxsYmFja3NbZXZlbnRdID0gdGhpcy5jYWxsYmFja3NbZXZlbnRdIHx8IFtdKS5wdXNoKGZ1bmMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLy8gQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXG4gICAgLy8gdGltZSB0aGVuIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZC5cbiAgICBwcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIChldmVudCwgZ3JvdXBOYW1lLCBmbikge1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICAgICAgICBoYXNHcm91cCA9IChhcmd1bWVudHMubGVuZ3RoID09PSAzKSxcbiAgICAgICAgICAgIGdyb3VwID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBmdW5jID0gaGFzR3JvdXAgPyBhcmd1bWVudHNbMl0gOiBhcmd1bWVudHNbMV07XG4gICAgICAgIGZ1bmN0aW9uIG9uKCkge1xuICAgICAgICAgICAgc2VsZi5vZmYoZXZlbnQsIG9uKTtcbiAgICAgICAgICAgIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9uKGV2ZW50LCBncm91cCwgb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLy8gVW5iaW5kcyBhbiBlbnRpcmUgZ3JvdXBcbiAgICBwcm90b3R5cGUucmVsZWFzZUdyb3VwID0gZnVuY3Rpb24gKGdyb3VwTmFtZSkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgaXRlbSwgaSwgbGVuLCBoYW5kbGVycztcbiAgICAgICAgZm9yIChpdGVtIGluIHRoaXMuY2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBoYW5kbGVycyA9IHRoaXMuY2FsbGJhY2tzW2l0ZW1dO1xuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaGFuZGxlcnNbaV0uX2dyb3VwTmFtZSA9PT0gZ3JvdXBOYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coJ3JlbW92aW5nJyk7XG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBpdCBhbmQgc2hvcnRlbiB0aGUgYXJyYXkgd2UncmUgbG9vcGluZyB0aHJvdWdoXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgaS0tO1xuICAgICAgICAgICAgICAgICAgICBsZW4tLTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8vIFJlbW92ZSB0aGUgZ2l2ZW4gY2FsbGJhY2sgZm9yIGBldmVudGAgb3IgYWxsXG4gICAgLy8gcmVnaXN0ZXJlZCBjYWxsYmFja3MuXG4gICAgcHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgdmFyIGNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XSxcbiAgICAgICAgICAgIGk7XG5cbiAgICAgICAgaWYgKCFjYWxsYmFja3MpIHJldHVybiB0aGlzO1xuXG4gICAgICAgIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnNcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrc1tldmVudF07XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJlbW92ZSBzcGVjaWZpYyBoYW5kbGVyXG4gICAgICAgIGkgPSBjYWxsYmFja3MuaW5kZXhPZihmbik7XG4gICAgICAgIGlmIChpICE9PSAtMSkge1xuICAgICAgICAgICAgY2FsbGJhY2tzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgIGlmIChjYWxsYmFja3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2V2ZW50XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLy8vIEVtaXQgYGV2ZW50YCB3aXRoIHRoZSBnaXZlbiBhcmdzLlxuICAgIC8vIGFsc28gY2FsbHMgYW55IGAqYCBoYW5kbGVyc1xuICAgIHByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3MgfHwge307XG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxuICAgICAgICAgICAgY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3NbZXZlbnRdLFxuICAgICAgICAgICAgc3BlY2lhbENhbGxiYWNrcyA9IHRoaXMuZ2V0V2lsZGNhcmRDYWxsYmFja3MoZXZlbnQpLFxuICAgICAgICAgICAgaSxcbiAgICAgICAgICAgIGxlbixcbiAgICAgICAgICAgIGl0ZW0sXG4gICAgICAgICAgICBsaXN0ZW5lcnM7XG5cbiAgICAgICAgaWYgKGNhbGxiYWNrcykge1xuICAgICAgICAgICAgbGlzdGVuZXJzID0gY2FsbGJhY2tzLnNsaWNlKCk7XG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWxpc3RlbmVyc1tpXSkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNwZWNpYWxDYWxsYmFja3MpIHtcbiAgICAgICAgICAgIGxlbiA9IHNwZWNpYWxDYWxsYmFja3MubGVuZ3RoO1xuICAgICAgICAgICAgbGlzdGVuZXJzID0gc3BlY2lhbENhbGxiYWNrcy5zbGljZSgpO1xuICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsaXN0ZW5lcnNbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBbZXZlbnRdLmNvbmNhdChhcmdzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLy8gSGVscGVyIGZvciBmb3IgZmluZGluZyBzcGVjaWFsIHdpbGRjYXJkIGV2ZW50IGhhbmRsZXJzIHRoYXQgbWF0Y2ggdGhlIGV2ZW50XG4gICAgcHJvdG90eXBlLmdldFdpbGRjYXJkQ2FsbGJhY2tzID0gZnVuY3Rpb24gKGV2ZW50TmFtZSkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICB2YXIgaXRlbSxcbiAgICAgICAgICAgIHNwbGl0LFxuICAgICAgICAgICAgcmVzdWx0ID0gW107XG5cbiAgICAgICAgZm9yIChpdGVtIGluIHRoaXMuY2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBzcGxpdCA9IGl0ZW0uc3BsaXQoJyonKTtcbiAgICAgICAgICAgIGlmIChpdGVtID09PSAnKicgfHwgKHNwbGl0Lmxlbmd0aCA9PT0gMiAmJiBldmVudE5hbWUuc2xpY2UoMCwgc3BsaXRbMF0ubGVuZ3RoKSA9PT0gc3BsaXRbMF0pKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0aGlzLmNhbGxiYWNrc1tpdGVtXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG59O1xuXG5XaWxkRW1pdHRlci5taXhpbihXaWxkRW1pdHRlcik7XG4iLCIvKiFcbiAqIEV2ZW50RW1pdHRlciB2NS4yLjkgLSBnaXQuaW8vZWVcbiAqIFVubGljZW5zZSAtIGh0dHA6Ly91bmxpY2Vuc2Uub3JnL1xuICogT2xpdmVyIENhbGR3ZWxsIC0gaHR0cHM6Ly9vbGkubWUudWsvXG4gKiBAcHJlc2VydmVcbiAqL1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgLyoqXG4gICAgICogQ2xhc3MgZm9yIG1hbmFnaW5nIGV2ZW50cy5cbiAgICAgKiBDYW4gYmUgZXh0ZW5kZWQgdG8gcHJvdmlkZSBldmVudCBmdW5jdGlvbmFsaXR5IGluIG90aGVyIGNsYXNzZXMuXG4gICAgICpcbiAgICAgKiBAY2xhc3MgRXZlbnRFbWl0dGVyIE1hbmFnZXMgZXZlbnQgcmVnaXN0ZXJpbmcgYW5kIGVtaXR0aW5nLlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHt9XG5cbiAgICAvLyBTaG9ydGN1dHMgdG8gaW1wcm92ZSBzcGVlZCBhbmQgc2l6ZVxuICAgIHZhciBwcm90byA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGU7XG4gICAgdmFyIG9yaWdpbmFsR2xvYmFsVmFsdWUgPSBleHBvcnRzLkV2ZW50RW1pdHRlcjtcblxuICAgIC8qKlxuICAgICAqIEZpbmRzIHRoZSBpbmRleCBvZiB0aGUgbGlzdGVuZXIgZm9yIHRoZSBldmVudCBpbiBpdHMgc3RvcmFnZSBhcnJheS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gbGlzdGVuZXJzIEFycmF5IG9mIGxpc3RlbmVycyB0byBzZWFyY2ggdGhyb3VnaC5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gbG9vayBmb3IuXG4gICAgICogQHJldHVybiB7TnVtYmVyfSBJbmRleCBvZiB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyLCAtMSBpZiBub3QgZm91bmRcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzLCBsaXN0ZW5lcikge1xuICAgICAgICB2YXIgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWxpYXMgYSBtZXRob2Qgd2hpbGUga2VlcGluZyB0aGUgY29udGV4dCBjb3JyZWN0LCB0byBhbGxvdyBmb3Igb3ZlcndyaXRpbmcgb2YgdGFyZ2V0IG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSB0YXJnZXQgbWV0aG9kLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufSBUaGUgYWxpYXNlZCBtZXRob2RcbiAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhbGlhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBhbGlhc0Nsb3N1cmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1tuYW1lXS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGxpc3RlbmVyIGFycmF5IGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdpbGwgaW5pdGlhbGlzZSB0aGUgZXZlbnQgb2JqZWN0IGFuZCBsaXN0ZW5lciBhcnJheXMgaWYgcmVxdWlyZWQuXG4gICAgICogV2lsbCByZXR1cm4gYW4gb2JqZWN0IGlmIHlvdSB1c2UgYSByZWdleCBzZWFyY2guIFRoZSBvYmplY3QgY29udGFpbnMga2V5cyBmb3IgZWFjaCBtYXRjaGVkIGV2ZW50LiBTbyAvYmFbcnpdLyBtaWdodCByZXR1cm4gYW4gb2JqZWN0IGNvbnRhaW5pbmcgYmFyIGFuZCBiYXouIEJ1dCBvbmx5IGlmIHlvdSBoYXZlIGVpdGhlciBkZWZpbmVkIHRoZW0gd2l0aCBkZWZpbmVFdmVudCBvciBhZGRlZCBzb21lIGxpc3RlbmVycyB0byB0aGVtLlxuICAgICAqIEVhY2ggcHJvcGVydHkgaW4gdGhlIG9iamVjdCByZXNwb25zZSBpcyBhbiBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZXR1cm4gdGhlIGxpc3RlbmVycyBmcm9tLlxuICAgICAqIEByZXR1cm4ge0Z1bmN0aW9uW118T2JqZWN0fSBBbGwgbGlzdGVuZXIgZnVuY3Rpb25zIGZvciB0aGUgZXZlbnQuXG4gICAgICovXG4gICAgcHJvdG8uZ2V0TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TGlzdGVuZXJzKGV2dCkge1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciByZXNwb25zZTtcbiAgICAgICAgdmFyIGtleTtcblxuICAgICAgICAvLyBSZXR1cm4gYSBjb25jYXRlbmF0ZWQgYXJyYXkgb2YgYWxsIG1hdGNoaW5nIGV2ZW50cyBpZlxuICAgICAgICAvLyB0aGUgc2VsZWN0b3IgaXMgYSByZWd1bGFyIGV4cHJlc3Npb24uXG4gICAgICAgIGlmIChldnQgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICAgICAgICBmb3IgKGtleSBpbiBldmVudHMpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnRzLmhhc093blByb3BlcnR5KGtleSkgJiYgZXZ0LnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXNwb25zZVtrZXldID0gZXZlbnRzW2tleV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSBldmVudHNbZXZ0XSB8fCAoZXZlbnRzW2V2dF0gPSBbXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRha2VzIGEgbGlzdCBvZiBsaXN0ZW5lciBvYmplY3RzIGFuZCBmbGF0dGVucyBpdCBpbnRvIGEgbGlzdCBvZiBsaXN0ZW5lciBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdFtdfSBsaXN0ZW5lcnMgUmF3IGxpc3RlbmVyIG9iamVjdHMuXG4gICAgICogQHJldHVybiB7RnVuY3Rpb25bXX0gSnVzdCB0aGUgbGlzdGVuZXIgZnVuY3Rpb25zLlxuICAgICAqL1xuICAgIHByb3RvLmZsYXR0ZW5MaXN0ZW5lcnMgPSBmdW5jdGlvbiBmbGF0dGVuTGlzdGVuZXJzKGxpc3RlbmVycykge1xuICAgICAgICB2YXIgZmxhdExpc3RlbmVycyA9IFtdO1xuICAgICAgICB2YXIgaTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBmbGF0TGlzdGVuZXJzLnB1c2gobGlzdGVuZXJzW2ldLmxpc3RlbmVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbGF0TGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSByZXF1ZXN0ZWQgbGlzdGVuZXJzIHZpYSBnZXRMaXN0ZW5lcnMgYnV0IHdpbGwgYWx3YXlzIHJldHVybiB0aGUgcmVzdWx0cyBpbnNpZGUgYW4gb2JqZWN0LiBUaGlzIGlzIG1haW5seSBmb3IgaW50ZXJuYWwgdXNlIGJ1dCBvdGhlcnMgbWF5IGZpbmQgaXQgdXNlZnVsLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gcmV0dXJuIHRoZSBsaXN0ZW5lcnMgZnJvbS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEFsbCBsaXN0ZW5lciBmdW5jdGlvbnMgZm9yIGFuIGV2ZW50IGluIGFuIG9iamVjdC5cbiAgICAgKi9cbiAgICBwcm90by5nZXRMaXN0ZW5lcnNBc09iamVjdCA9IGZ1bmN0aW9uIGdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCkge1xuICAgICAgICB2YXIgbGlzdGVuZXJzID0gdGhpcy5nZXRMaXN0ZW5lcnMoZXZ0KTtcbiAgICAgICAgdmFyIHJlc3BvbnNlO1xuXG4gICAgICAgIGlmIChsaXN0ZW5lcnMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgcmVzcG9uc2UgPSB7fTtcbiAgICAgICAgICAgIHJlc3BvbnNlW2V2dF0gPSBsaXN0ZW5lcnM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzcG9uc2UgfHwgbGlzdGVuZXJzO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkTGlzdGVuZXIgKGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICdmdW5jdGlvbicgfHwgbGlzdGVuZXIgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0gZWxzZSBpZiAobGlzdGVuZXIgJiYgdHlwZW9mIGxpc3RlbmVyID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIGlzVmFsaWRMaXN0ZW5lcihsaXN0ZW5lci5saXN0ZW5lcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIHRoZSBzcGVjaWZpZWQgZXZlbnQuXG4gICAgICogVGhlIGxpc3RlbmVyIHdpbGwgbm90IGJlIGFkZGVkIGlmIGl0IGlzIGEgZHVwbGljYXRlLlxuICAgICAqIElmIHRoZSBsaXN0ZW5lciByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgY2FsbGVkLlxuICAgICAqIElmIHlvdSBwYXNzIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lIHRoZW4gdGhlIGxpc3RlbmVyIHdpbGwgYmUgYWRkZWQgdG8gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBldnQgTmFtZSBvZiB0aGUgZXZlbnQgdG8gYXR0YWNoIHRoZSBsaXN0ZW5lciB0by5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lciBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWQuIElmIHRoZSBmdW5jdGlvbiByZXR1cm5zIHRydWUgdGhlbiBpdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgY2FsbGluZy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKCFpc1ZhbGlkTGlzdGVuZXIobGlzdGVuZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcklzV3JhcHBlZCA9IHR5cGVvZiBsaXN0ZW5lciA9PT0gJ29iamVjdCc7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgZm9yIChrZXkgaW4gbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzLmhhc093blByb3BlcnR5KGtleSkgJiYgaW5kZXhPZkxpc3RlbmVyKGxpc3RlbmVyc1trZXldLCBsaXN0ZW5lcikgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0ucHVzaChsaXN0ZW5lcklzV3JhcHBlZCA/IGxpc3RlbmVyIDoge1xuICAgICAgICAgICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICAgICAgICAgIG9uY2U6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgYWRkTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vbiA9IGFsaWFzKCdhZGRMaXN0ZW5lcicpO1xuXG4gICAgLyoqXG4gICAgICogU2VtaS1hbGlhcyBvZiBhZGRMaXN0ZW5lci4gSXQgd2lsbCBhZGQgYSBsaXN0ZW5lciB0aGF0IHdpbGwgYmVcbiAgICAgKiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgYWZ0ZXIgaXRzIGZpcnN0IGV4ZWN1dGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGF0dGFjaCB0aGUgbGlzdGVuZXIgdG8uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkLiBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB0cnVlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGNhbGxpbmcuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uYWRkT25jZUxpc3RlbmVyID0gZnVuY3Rpb24gYWRkT25jZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIoZXZ0LCB7XG4gICAgICAgICAgICBsaXN0ZW5lcjogbGlzdGVuZXIsXG4gICAgICAgICAgICBvbmNlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBbGlhcyBvZiBhZGRPbmNlTGlzdGVuZXIuXG4gICAgICovXG4gICAgcHJvdG8ub25jZSA9IGFsaWFzKCdhZGRPbmNlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgYW4gZXZlbnQgbmFtZS4gVGhpcyBpcyByZXF1aXJlZCBpZiB5b3Ugd2FudCB0byB1c2UgYSByZWdleCB0byBhZGQgYSBsaXN0ZW5lciB0byBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gSWYgeW91IGRvbid0IGRvIHRoaXMgdGhlbiBob3cgZG8geW91IGV4cGVjdCBpdCB0byBrbm93IHdoYXQgZXZlbnQgdG8gYWRkIHRvPyBTaG91bGQgaXQganVzdCBhZGQgdG8gZXZlcnkgcG9zc2libGUgbWF0Y2ggZm9yIGEgcmVnZXg/IE5vLiBUaGF0IGlzIHNjYXJ5IGFuZCBiYWQuXG4gICAgICogWW91IG5lZWQgdG8gdGVsbCBpdCB3aGF0IGV2ZW50IG5hbWVzIHNob3VsZCBiZSBtYXRjaGVkIGJ5IGEgcmVnZXguXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZ0IE5hbWUgb2YgdGhlIGV2ZW50IHRvIGNyZWF0ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5kZWZpbmVFdmVudCA9IGZ1bmN0aW9uIGRlZmluZUV2ZW50KGV2dCkge1xuICAgICAgICB0aGlzLmdldExpc3RlbmVycyhldnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogVXNlcyBkZWZpbmVFdmVudCB0byBkZWZpbmUgbXVsdGlwbGUgZXZlbnRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmdbXX0gZXZ0cyBBbiBhcnJheSBvZiBldmVudCBuYW1lcyB0byBkZWZpbmUuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8uZGVmaW5lRXZlbnRzID0gZnVuY3Rpb24gZGVmaW5lRXZlbnRzKGV2dHMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBldnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICB0aGlzLmRlZmluZUV2ZW50KGV2dHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZnVuY3Rpb24gZnJvbSB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIFdoZW4gcGFzc2VkIGEgcmVndWxhciBleHByZXNzaW9uIGFzIHRoZSBldmVudCBuYW1lLCBpdCB3aWxsIHJlbW92ZSB0aGUgbGlzdGVuZXIgZnJvbSBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byByZW1vdmUgdGhlIGxpc3RlbmVyIGZyb20uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgTWV0aG9kIHRvIHJlbW92ZSBmcm9tIHRoZSBldmVudC5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGV2dCwgbGlzdGVuZXIpIHtcbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IHRoaXMuZ2V0TGlzdGVuZXJzQXNPYmplY3QoZXZ0KTtcbiAgICAgICAgdmFyIGluZGV4O1xuICAgICAgICB2YXIga2V5O1xuXG4gICAgICAgIGZvciAoa2V5IGluIGxpc3RlbmVycykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBpbmRleE9mTGlzdGVuZXIobGlzdGVuZXJzW2tleV0sIGxpc3RlbmVyKTtcblxuICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzW2tleV0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlTGlzdGVuZXJcbiAgICAgKi9cbiAgICBwcm90by5vZmYgPSBhbGlhcygncmVtb3ZlTGlzdGVuZXInKTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy4gWW91IGNhbiBhbHNvIHBhc3MgaXQgYW4gZXZlbnQgbmFtZSBhbmQgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGJlIGFkZGVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIGFkZCB0aGUgYXJyYXkgb2YgbGlzdGVuZXJzIHRvIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKiBZZWFoLCB0aGlzIGZ1bmN0aW9uIGRvZXMgcXVpdGUgYSBiaXQuIFRoYXQncyBwcm9iYWJseSBhIGJhZCB0aGluZy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdHxSZWdFeHB9IGV2dCBBbiBldmVudCBuYW1lIGlmIHlvdSB3aWxsIHBhc3MgYW4gYXJyYXkgb2YgbGlzdGVuZXJzIG5leHQuIEFuIG9iamVjdCBpZiB5b3Ugd2lzaCB0byBhZGQgdG8gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbltdfSBbbGlzdGVuZXJzXSBBbiBvcHRpb25hbCBhcnJheSBvZiBsaXN0ZW5lciBmdW5jdGlvbnMgdG8gYWRkLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLmFkZExpc3RlbmVycyA9IGZ1bmN0aW9uIGFkZExpc3RlbmVycyhldnQsIGxpc3RlbmVycykge1xuICAgICAgICAvLyBQYXNzIHRocm91Z2ggdG8gbWFuaXB1bGF0ZUxpc3RlbmVyc1xuICAgICAgICByZXR1cm4gdGhpcy5tYW5pcHVsYXRlTGlzdGVuZXJzKGZhbHNlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgbGlzdGVuZXJzIGluIGJ1bGsgdXNpbmcgdGhlIG1hbmlwdWxhdGVMaXN0ZW5lcnMgbWV0aG9kLlxuICAgICAqIElmIHlvdSBwYXNzIGFuIG9iamVjdCBhcyB0aGUgZmlyc3QgYXJndW1lbnQgeW91IGNhbiByZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS4gVGhlIG9iamVjdCBzaG91bGQgY29udGFpbiBrZXkgdmFsdWUgcGFpcnMgb2YgZXZlbnRzIGFuZCBsaXN0ZW5lcnMgb3IgbGlzdGVuZXIgYXJyYXlzLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGFuIGV2ZW50IG5hbWUgYW5kIGFuIGFycmF5IG9mIGxpc3RlbmVycyB0byBiZSByZW1vdmVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGl0IGEgcmVndWxhciBleHByZXNzaW9uIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXJzIGZyb20gYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIHJlbW92ZSBmcm9tIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlLlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb25bXX0gW2xpc3RlbmVyc10gQW4gb3B0aW9uYWwgYXJyYXkgb2YgbGlzdGVuZXIgZnVuY3Rpb25zIHRvIHJlbW92ZS5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5yZW1vdmVMaXN0ZW5lcnMgPSBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcnMoZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gUGFzcyB0aHJvdWdoIHRvIG1hbmlwdWxhdGVMaXN0ZW5lcnNcbiAgICAgICAgcmV0dXJuIHRoaXMubWFuaXB1bGF0ZUxpc3RlbmVycyh0cnVlLCBldnQsIGxpc3RlbmVycyk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEVkaXRzIGxpc3RlbmVycyBpbiBidWxrLiBUaGUgYWRkTGlzdGVuZXJzIGFuZCByZW1vdmVMaXN0ZW5lcnMgbWV0aG9kcyBib3RoIHVzZSB0aGlzIHRvIGRvIHRoZWlyIGpvYi4gWW91IHNob3VsZCByZWFsbHkgdXNlIHRob3NlIGluc3RlYWQsIHRoaXMgaXMgYSBsaXR0bGUgbG93ZXIgbGV2ZWwuXG4gICAgICogVGhlIGZpcnN0IGFyZ3VtZW50IHdpbGwgZGV0ZXJtaW5lIGlmIHRoZSBsaXN0ZW5lcnMgYXJlIHJlbW92ZWQgKHRydWUpIG9yIGFkZGVkIChmYWxzZSkuXG4gICAgICogSWYgeW91IHBhc3MgYW4gb2JqZWN0IGFzIHRoZSBzZWNvbmQgYXJndW1lbnQgeW91IGNhbiBhZGQvcmVtb3ZlIGZyb20gbXVsdGlwbGUgZXZlbnRzIGF0IG9uY2UuIFRoZSBvYmplY3Qgc2hvdWxkIGNvbnRhaW4ga2V5IHZhbHVlIHBhaXJzIG9mIGV2ZW50cyBhbmQgbGlzdGVuZXJzIG9yIGxpc3RlbmVyIGFycmF5cy5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhbiBldmVudCBuYW1lIGFuZCBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgdG8gYmUgYWRkZWQvcmVtb3ZlZC5cbiAgICAgKiBZb3UgY2FuIGFsc28gcGFzcyBpdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYW5pcHVsYXRlIHRoZSBsaXN0ZW5lcnMgb2YgYWxsIGV2ZW50cyB0aGF0IG1hdGNoIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtCb29sZWFufSByZW1vdmUgVHJ1ZSBpZiB5b3Ugd2FudCB0byByZW1vdmUgbGlzdGVuZXJzLCBmYWxzZSBpZiB5b3Ugd2FudCB0byBhZGQuXG4gICAgICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fFJlZ0V4cH0gZXZ0IEFuIGV2ZW50IG5hbWUgaWYgeW91IHdpbGwgcGFzcyBhbiBhcnJheSBvZiBsaXN0ZW5lcnMgbmV4dC4gQW4gb2JqZWN0IGlmIHlvdSB3aXNoIHRvIGFkZC9yZW1vdmUgZnJvbSBtdWx0aXBsZSBldmVudHMgYXQgb25jZS5cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9uW119IFtsaXN0ZW5lcnNdIEFuIG9wdGlvbmFsIGFycmF5IG9mIGxpc3RlbmVyIGZ1bmN0aW9ucyB0byBhZGQvcmVtb3ZlLlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gQ3VycmVudCBpbnN0YW5jZSBvZiBFdmVudEVtaXR0ZXIgZm9yIGNoYWluaW5nLlxuICAgICAqL1xuICAgIHByb3RvLm1hbmlwdWxhdGVMaXN0ZW5lcnMgPSBmdW5jdGlvbiBtYW5pcHVsYXRlTGlzdGVuZXJzKHJlbW92ZSwgZXZ0LCBsaXN0ZW5lcnMpIHtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciB2YWx1ZTtcbiAgICAgICAgdmFyIHNpbmdsZSA9IHJlbW92ZSA/IHRoaXMucmVtb3ZlTGlzdGVuZXIgOiB0aGlzLmFkZExpc3RlbmVyO1xuICAgICAgICB2YXIgbXVsdGlwbGUgPSByZW1vdmUgPyB0aGlzLnJlbW92ZUxpc3RlbmVycyA6IHRoaXMuYWRkTGlzdGVuZXJzO1xuXG4gICAgICAgIC8vIElmIGV2dCBpcyBhbiBvYmplY3QgdGhlbiBwYXNzIGVhY2ggb2YgaXRzIHByb3BlcnRpZXMgdG8gdGhpcyBtZXRob2RcbiAgICAgICAgaWYgKHR5cGVvZiBldnQgPT09ICdvYmplY3QnICYmICEoZXZ0IGluc3RhbmNlb2YgUmVnRXhwKSkge1xuICAgICAgICAgICAgZm9yIChpIGluIGV2dCkge1xuICAgICAgICAgICAgICAgIGlmIChldnQuaGFzT3duUHJvcGVydHkoaSkgJiYgKHZhbHVlID0gZXZ0W2ldKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBQYXNzIHRoZSBzaW5nbGUgbGlzdGVuZXIgc3RyYWlnaHQgdGhyb3VnaCB0byB0aGUgc2luZ3VsYXIgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNpbmdsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSBwYXNzIGJhY2sgdG8gdGhlIG11bHRpcGxlIGZ1bmN0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZS5jYWxsKHRoaXMsIGksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNvIGV2dCBtdXN0IGJlIGEgc3RyaW5nXG4gICAgICAgICAgICAvLyBBbmQgbGlzdGVuZXJzIG11c3QgYmUgYW4gYXJyYXkgb2YgbGlzdGVuZXJzXG4gICAgICAgICAgICAvLyBMb29wIG92ZXIgaXQgYW5kIHBhc3MgZWFjaCBvbmUgdG8gdGhlIG11bHRpcGxlIG1ldGhvZFxuICAgICAgICAgICAgaSA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgc2luZ2xlLmNhbGwodGhpcywgZXZ0LCBsaXN0ZW5lcnNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBmcm9tIGEgc3BlY2lmaWVkIGV2ZW50LlxuICAgICAqIElmIHlvdSBkbyBub3Qgc3BlY2lmeSBhbiBldmVudCB0aGVuIGFsbCBsaXN0ZW5lcnMgd2lsbCBiZSByZW1vdmVkLlxuICAgICAqIFRoYXQgbWVhbnMgZXZlcnkgZXZlbnQgd2lsbCBiZSBlbXB0aWVkLlxuICAgICAqIFlvdSBjYW4gYWxzbyBwYXNzIGEgcmVnZXggdG8gcmVtb3ZlIGFsbCBldmVudHMgdGhhdCBtYXRjaCBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7U3RyaW5nfFJlZ0V4cH0gW2V2dF0gT3B0aW9uYWwgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yLiBXaWxsIHJlbW92ZSBmcm9tIGV2ZXJ5IGV2ZW50IGlmIG5vdCBwYXNzZWQuXG4gICAgICogQHJldHVybiB7T2JqZWN0fSBDdXJyZW50IGluc3RhbmNlIG9mIEV2ZW50RW1pdHRlciBmb3IgY2hhaW5pbmcuXG4gICAgICovXG4gICAgcHJvdG8ucmVtb3ZlRXZlbnQgPSBmdW5jdGlvbiByZW1vdmVFdmVudChldnQpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlb2YgZXZ0O1xuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5fZ2V0RXZlbnRzKCk7XG4gICAgICAgIHZhciBrZXk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGRpZmZlcmVudCB0aGluZ3MgZGVwZW5kaW5nIG9uIHRoZSBzdGF0ZSBvZiBldnRcbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAvLyBSZW1vdmUgYWxsIGxpc3RlbmVycyBmb3IgdGhlIHNwZWNpZmllZCBldmVudFxuICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1tldnRdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2dCBpbnN0YW5jZW9mIFJlZ0V4cCkge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGFsbCBldmVudHMgbWF0Y2hpbmcgdGhlIHJlZ2V4LlxuICAgICAgICAgICAgZm9yIChrZXkgaW4gZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50cy5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIGV2dC50ZXN0KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGV2ZW50c1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBhbGwgbGlzdGVuZXJzIGluIGFsbCBldmVudHNcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgcmVtb3ZlRXZlbnQuXG4gICAgICpcbiAgICAgKiBBZGRlZCB0byBtaXJyb3IgdGhlIG5vZGUgQVBJLlxuICAgICAqL1xuICAgIHByb3RvLnJlbW92ZUFsbExpc3RlbmVycyA9IGFsaWFzKCdyZW1vdmVFdmVudCcpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgb2YgeW91ciBjaG9pY2UuXG4gICAgICogV2hlbiBlbWl0dGVkLCBldmVyeSBsaXN0ZW5lciBhdHRhY2hlZCB0byB0aGF0IGV2ZW50IHdpbGwgYmUgZXhlY3V0ZWQuXG4gICAgICogSWYgeW91IHBhc3MgdGhlIG9wdGlvbmFsIGFyZ3VtZW50IGFycmF5IHRoZW4gdGhvc2UgYXJndW1lbnRzIHdpbGwgYmUgcGFzc2VkIHRvIGV2ZXJ5IGxpc3RlbmVyIHVwb24gZXhlY3V0aW9uLlxuICAgICAqIEJlY2F1c2UgaXQgdXNlcyBgYXBwbHlgLCB5b3VyIGFycmF5IG9mIGFyZ3VtZW50cyB3aWxsIGJlIHBhc3NlZCBhcyBpZiB5b3Ugd3JvdGUgdGhlbSBvdXQgc2VwYXJhdGVseS5cbiAgICAgKiBTbyB0aGV5IHdpbGwgbm90IGFycml2ZSB3aXRoaW4gdGhlIGFycmF5IG9uIHRoZSBvdGhlciBzaWRlLCB0aGV5IHdpbGwgYmUgc2VwYXJhdGUuXG4gICAgICogWW91IGNhbiBhbHNvIHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHtBcnJheX0gW2FyZ3NdIE9wdGlvbmFsIGFycmF5IG9mIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0RXZlbnQgPSBmdW5jdGlvbiBlbWl0RXZlbnQoZXZ0LCBhcmdzKSB7XG4gICAgICAgIHZhciBsaXN0ZW5lcnNNYXAgPSB0aGlzLmdldExpc3RlbmVyc0FzT2JqZWN0KGV2dCk7XG4gICAgICAgIHZhciBsaXN0ZW5lcnM7XG4gICAgICAgIHZhciBsaXN0ZW5lcjtcbiAgICAgICAgdmFyIGk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIHZhciByZXNwb25zZTtcblxuICAgICAgICBmb3IgKGtleSBpbiBsaXN0ZW5lcnNNYXApIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNNYXAuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVyc01hcFtrZXldLnNsaWNlKDApO1xuXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGlzdGVuZXIgcmV0dXJucyB0cnVlIHRoZW4gaXQgc2hhbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgZnVuY3Rpb24gaXMgZXhlY3V0ZWQgZWl0aGVyIHdpdGggYSBiYXNpYyBjYWxsIG9yIGFuIGFwcGx5IGlmIHRoZXJlIGlzIGFuIGFyZ3MgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaV07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyLm9uY2UgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZSA9IGxpc3RlbmVyLmxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3MgfHwgW10pO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSA9PT0gdGhpcy5fZ2V0T25jZVJldHVyblZhbHVlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZ0LCBsaXN0ZW5lci5saXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWxpYXMgb2YgZW1pdEV2ZW50XG4gICAgICovXG4gICAgcHJvdG8udHJpZ2dlciA9IGFsaWFzKCdlbWl0RXZlbnQnKTtcblxuICAgIC8qKlxuICAgICAqIFN1YnRseSBkaWZmZXJlbnQgZnJvbSBlbWl0RXZlbnQgaW4gdGhhdCBpdCB3aWxsIHBhc3MgaXRzIGFyZ3VtZW50cyBvbiB0byB0aGUgbGlzdGVuZXJzLCBhcyBvcHBvc2VkIHRvIHRha2luZyBhIHNpbmdsZSBhcnJheSBvZiBhcmd1bWVudHMgdG8gcGFzcyBvbi5cbiAgICAgKiBBcyB3aXRoIGVtaXRFdmVudCwgeW91IGNhbiBwYXNzIGEgcmVnZXggaW4gcGxhY2Ugb2YgdGhlIGV2ZW50IG5hbWUgdG8gZW1pdCB0byBhbGwgZXZlbnRzIHRoYXQgbWF0Y2ggaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ3xSZWdFeHB9IGV2dCBOYW1lIG9mIHRoZSBldmVudCB0byBlbWl0IGFuZCBleGVjdXRlIGxpc3RlbmVycyBmb3IuXG4gICAgICogQHBhcmFtIHsuLi4qfSBPcHRpb25hbCBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBiZSBwYXNzZWQgdG8gZWFjaCBsaXN0ZW5lci5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5lbWl0ID0gZnVuY3Rpb24gZW1pdChldnQpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0RXZlbnQoZXZ0LCBhcmdzKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgY3VycmVudCB2YWx1ZSB0byBjaGVjayBhZ2FpbnN0IHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy4gSWYgYVxuICAgICAqIGxpc3RlbmVycyByZXR1cm4gdmFsdWUgbWF0Y2hlcyB0aGUgb25lIHNldCBoZXJlIHRoZW4gaXQgd2lsbCBiZSByZW1vdmVkXG4gICAgICogYWZ0ZXIgZXhlY3V0aW9uLiBUaGlzIHZhbHVlIGRlZmF1bHRzIHRvIHRydWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0geyp9IHZhbHVlIFRoZSBuZXcgdmFsdWUgdG8gY2hlY2sgZm9yIHdoZW4gZXhlY3V0aW5nIGxpc3RlbmVycy5cbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEN1cnJlbnQgaW5zdGFuY2Ugb2YgRXZlbnRFbWl0dGVyIGZvciBjaGFpbmluZy5cbiAgICAgKi9cbiAgICBwcm90by5zZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBzZXRPbmNlUmV0dXJuVmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fb25jZVJldHVyblZhbHVlID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGZXRjaGVzIHRoZSBjdXJyZW50IHZhbHVlIHRvIGNoZWNrIGFnYWluc3Qgd2hlbiBleGVjdXRpbmcgbGlzdGVuZXJzLiBJZlxuICAgICAqIHRoZSBsaXN0ZW5lcnMgcmV0dXJuIHZhbHVlIG1hdGNoZXMgdGhpcyBvbmUgdGhlbiBpdCBzaG91bGQgYmUgcmVtb3ZlZFxuICAgICAqIGF1dG9tYXRpY2FsbHkuIEl0IHdpbGwgcmV0dXJuIHRydWUgYnkgZGVmYXVsdC5cbiAgICAgKlxuICAgICAqIEByZXR1cm4geyp8Qm9vbGVhbn0gVGhlIGN1cnJlbnQgdmFsdWUgdG8gY2hlY2sgZm9yIG9yIHRoZSBkZWZhdWx0LCB0cnVlLlxuICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAqL1xuICAgIHByb3RvLl9nZXRPbmNlUmV0dXJuVmFsdWUgPSBmdW5jdGlvbiBfZ2V0T25jZVJldHVyblZhbHVlKCkge1xuICAgICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eSgnX29uY2VSZXR1cm5WYWx1ZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25jZVJldHVyblZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRmV0Y2hlcyB0aGUgZXZlbnRzIG9iamVjdCBhbmQgY3JlYXRlcyBvbmUgaWYgcmVxdWlyZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBldmVudHMgc3RvcmFnZSBvYmplY3QuXG4gICAgICogQGFwaSBwcml2YXRlXG4gICAgICovXG4gICAgcHJvdG8uX2dldEV2ZW50cyA9IGZ1bmN0aW9uIF9nZXRFdmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHMgfHwgKHRoaXMuX2V2ZW50cyA9IHt9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogUmV2ZXJ0cyB0aGUgZ2xvYmFsIHtAbGluayBFdmVudEVtaXR0ZXJ9IHRvIGl0cyBwcmV2aW91cyB2YWx1ZSBhbmQgcmV0dXJucyBhIHJlZmVyZW5jZSB0byB0aGlzIHZlcnNpb24uXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gTm9uIGNvbmZsaWN0aW5nIEV2ZW50RW1pdHRlciBjbGFzcy5cbiAgICAgKi9cbiAgICBFdmVudEVtaXR0ZXIubm9Db25mbGljdCA9IGZ1bmN0aW9uIG5vQ29uZmxpY3QoKSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gb3JpZ2luYWxHbG9iYWxWYWx1ZTtcbiAgICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICB9O1xuXG4gICAgLy8gRXhwb3NlIHRoZSBjbGFzcyBlaXRoZXIgdmlhIEFNRCwgQ29tbW9uSlMgb3IgdGhlIGdsb2JhbCBvYmplY3RcbiAgICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpe1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuICAgIH1cbn0odHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB0aGlzIHx8IHt9KSk7XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gICAgXCJhdXRob3JcIjogXCJPcGVuVmlkdVwiLCBcbiAgICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgICAgIFwiZnJlZWljZVwiOiBcIjIuMi4yXCIsIFxuICAgICAgICBcImhhcmtcIjogXCIxLjIuM1wiLCBcbiAgICAgICAgXCJqc25sb2dcIjogXCIyLjMwLjBcIiwgXG4gICAgICAgIFwibWltZVwiOiBcIjMuMC4wXCIsIFxuICAgICAgICBcInBsYXRmb3JtXCI6IFwiMS4zLjZcIiwgXG4gICAgICAgIFwic2VtdmVyXCI6IFwiNy4zLjdcIiwgXG4gICAgICAgIFwidXVpZFwiOiBcIjguMy4yXCIsIFxuICAgICAgICBcIndvbGZ5ODctZXZlbnRlbWl0dGVyXCI6IFwiNS4yLjlcIiwgXG4gICAgICAgIFwiZXZlbnRzXCI6IFwiMy4zLjBcIiwgXG4gICAgICAgIFwiaW5oZXJpdHNcIjogXCIyLjAuNFwiXG4gICAgfSwgXG4gICAgXCJkZXNjcmlwdGlvblwiOiBcIk9wZW5WaWR1IEJyb3dzZXJcIiwgXG4gICAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgICAgICBcIkB0eXBlcy9ub2RlXCI6IFwiMTguMC4wXCIsIFxuICAgICAgICBcIkB0eXBlcy9wbGF0Zm9ybVwiOiBcIjEuMy40XCIsIFxuICAgICAgICBcImJyb3dzZXJpZnlcIjogXCIxNy4wLjBcIiwgXG4gICAgICAgIFwiZ3J1bnRcIjogXCIxLjUuM1wiLCBcbiAgICAgICAgXCJncnVudC1jbGlcIjogXCIxLjQuM1wiLCBcbiAgICAgICAgXCJncnVudC1jb250cmliLWNvcHlcIjogXCIxLjAuMFwiLCBcbiAgICAgICAgXCJncnVudC1jb250cmliLXNhc3NcIjogXCIyLjAuMFwiLCBcbiAgICAgICAgXCJncnVudC1jb250cmliLXVnbGlmeVwiOiBcIjUuMi4yXCIsIFxuICAgICAgICBcImdydW50LWNvbnRyaWItd2F0Y2hcIjogXCIxLjEuMFwiLCBcbiAgICAgICAgXCJncnVudC1wb3N0Y3NzXCI6IFwiMC45LjBcIiwgXG4gICAgICAgIFwiZ3J1bnQtc3RyaW5nLXJlcGxhY2VcIjogXCIxLjMuM1wiLCBcbiAgICAgICAgXCJncnVudC10c1wiOiBcIjYuMC4wLWJldGEuMjJcIiwgXG4gICAgICAgIFwidGVyc2VyXCI6IFwiNS4xNC4xXCIsIFxuICAgICAgICBcInRzaWZ5XCI6IFwiNS4wLjRcIiwgXG4gICAgICAgIFwidHNsaW50XCI6IFwiNi4xLjNcIiwgXG4gICAgICAgIFwidHlwZWRvY1wiOiBcIjAuMjIuMTdcIiwgXG4gICAgICAgIFwidHlwZXNjcmlwdFwiOiBcIjQuNS40XCJcbiAgICB9LCBcbiAgICBcImxpY2Vuc2VcIjogXCJBcGFjaGUtMi4wXCIsIFxuICAgIFwibWFpblwiOiBcImxpYi9pbmRleC5qc1wiLCBcbiAgICBcIm5hbWVcIjogXCJvcGVudmlkdS1icm93c2VyXCIsIFxuICAgIFwicmVwb3NpdG9yeVwiOiB7XG4gICAgICAgIFwidHlwZVwiOiBcImdpdFwiLCBcbiAgICAgICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL09wZW5WaWR1L29wZW52aWR1XCJcbiAgICB9LCBcbiAgICBcInNjcmlwdHNcIjoge1xuICAgICAgICBcImJyb3dzZXJpZnlcIjogXCJWRVJTSU9OPSR7VkVSU0lPTjotZGV2fTsgbWtkaXIgLXAgc3RhdGljL2pzLyAmJiBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyBNYWluLnRzIC1wIFsgdHNpZnkgXSAtLWV4Y2x1ZGUga3VyZW50by1icm93c2VyLWV4dGVuc2lvbnMgLS1kZWJ1ZyAtbyAuLi9zdGF0aWMvanMvb3BlbnZpZHUtYnJvd3Nlci0kVkVSU0lPTi5qcyAtdlwiLCBcbiAgICAgICAgXCJicm93c2VyaWZ5LXByb2RcIjogXCJWRVJTSU9OPSR7VkVSU0lPTjotZGV2fTsgbWtkaXIgLXAgc3RhdGljL2pzLyAmJiBjZCBzcmMgJiYgLi4vbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvYmluL2NtZC5qcyAtLWRlYnVnIE1haW4udHMgLXAgWyB0c2lmeSBdIC0tZXhjbHVkZSBrdXJlbnRvLWJyb3dzZXItZXh0ZW5zaW9ucyB8IC4uL25vZGVfbW9kdWxlcy90ZXJzZXIvYmluL3RlcnNlciAtLXNvdXJjZS1tYXAgY29udGVudD1pbmxpbmUgLS1vdXRwdXQgLi4vc3RhdGljL2pzL29wZW52aWR1LWJyb3dzZXItJFZFUlNJT04ubWluLmpzXCIsIFxuICAgICAgICBcImJ1aWxkXCI6IFwiY2Qgc3JjL09wZW5WaWR1ICYmIC4vLi4vLi4vbm9kZV9tb2R1bGVzL3R5cGVzY3JpcHQvYmluL3RzYyAmJiBjZCAuLi8uLiAmJiAuL25vZGVfbW9kdWxlcy90eXBlc2NyaXB0L2Jpbi90c2MgLS1kZWNsYXJhdGlvbiBzcmMvaW5kZXgudHMgLS1vdXREaXIgLi9saWIgLS1zb3VyY2VNYXAgLS10YXJnZXQgZXM1IC0tbGliIGRvbSxlczUsZXMyMDE1LnByb21pc2Usc2NyaXB0aG9zdCAmJiBybSAtcmYgLi90czQuNCAmJiBta2RpciAtcCAuL3RzNC40L2xpYiAmJiBjcCAtciAuL2xpYiAuL3RzNC40ICYmIGZpbmQgLi90czQuNC9saWIgLXR5cGUgZiAhIC1pbmFtZSAnKi5kLnRzJyAtZGVsZXRlICYmIC4vY29uZmlnL3JlcGxhY2VfZm9yX3RzNDQuc2hcIiwgXG4gICAgICAgIFwiZG9jc1wiOiBcIi4vZ2VuZXJhdGUtZG9jcy5zaFwiXG4gICAgfSwgXG4gICAgXCJ0eXBlc1wiOiBcImxpYi9pbmRleC5kLnRzXCIsIFxuICAgIFwidHlwZXNWZXJzaW9uc1wiOiB7XG4gICAgICAgIFwiPDQuNFwiOiB7XG4gICAgICAgICAgICBcIipcIjogW1xuICAgICAgICAgICAgICAgIFwidHM0LjQvKlwiXG4gICAgICAgICAgICBdXG4gICAgICAgIH1cbiAgICB9LCBcbiAgICBcInZlcnNpb25cIjogXCIyLjI0LjBcIlxufSIsImltcG9ydCB7IE9wZW5WaWR1IH0gZnJvbSAnLi9PcGVuVmlkdS9PcGVuVmlkdSc7XG5pbXBvcnQgeyBKTCB9IGZyb20gJ2pzbmxvZyc7XG5cbmlmICh0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBnbG9iYWxUaGlzWydPcGVuVmlkdSddID0gT3BlblZpZHU7XG59XG5cbi8vIERpc2FibGUganNubG9nIHdoZW4gbGlicmFyeSBpcyBsb2FkZWRcbkpMLnNldE9wdGlvbnMoeyBlbmFibGVkOiBmYWxzZSB9KTtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi9TZXNzaW9uJztcbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IExvY2FsQ29ubmVjdGlvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9Mb2NhbENvbm5lY3Rpb25PcHRpb25zJztcbmltcG9ydCB7IFJlbW90ZUNvbm5lY3Rpb25PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvUmVtb3RlQ29ubmVjdGlvbk9wdGlvbnMnO1xuaW1wb3J0IHsgSW5ib3VuZFN0cmVhbU9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9JbmJvdW5kU3RyZWFtT3B0aW9ucyc7XG5pbXBvcnQgeyBTdHJlYW1PcHRpb25zU2VydmVyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvU3RyZWFtT3B0aW9uc1NlcnZlcic7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IEV4Y2VwdGlvbkV2ZW50LCBFeGNlcHRpb25FdmVudE5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FeGNlcHRpb25FdmVudCc7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSB1c2VyJ3MgY29ubmVjdGlvbiB0byB0aGUgc2Vzc2lvbiAodGhlIGxvY2FsIG9uZSBhbmQgb3RoZXIgdXNlcidzIGNvbm5lY3Rpb25zKS5cbiAqIFRoZXJlZm9yZSBlYWNoIFtbU2Vzc2lvbl1dIGFuZCBbW1N0cmVhbV1dIG9iamVjdCBoYXMgYW4gYXR0cmlidXRlIG9mIHR5cGUgQ29ubmVjdGlvblxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvbiB7XG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGNvbm5lY3Rpb25cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgaW4gT3BlblZpZHUgU2VydmVyIChVVEMgbWlsbGlzZWNvbmRzKVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogRGF0YSBhc3NvY2lhdGVkIHRvIHRoaXMgY29ubmVjdGlvbiAoYW5kIHRoZXJlZm9yZSB0byBjZXJ0YWluIHVzZXIpLiBUaGlzIGlzIGFuIGltcG9ydGFudCBmaWVsZDpcbiAgICAgKiBpdCBhbGxvd3MgeW91IHRvIGJyb2FkY2FzdCBhbGwgdGhlIGluZm9ybWF0aW9uIHlvdSB3YW50IGZvciBlYWNoIHVzZXIgKGEgdXNlcm5hbWUsIGZvciBleGFtcGxlKVxuICAgICAqL1xuICAgIGRhdGE6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFJvbGUgb2YgdGhlIGNvbm5lY3Rpb24uXG4gICAgICogLSBgU1VCU0NSSUJFUmA6IGNhbiBzdWJzY3JpYmUgdG8gcHVibGlzaGVkIFN0cmVhbXMgb2Ygb3RoZXIgdXNlcnMgYnkgY2FsbGluZyBbW1Nlc3Npb24uc3Vic2NyaWJlXV1cbiAgICAgKiAtIGBQVUJMSVNIRVJgOiBTVUJTQ1JJQkVSIHBlcm1pc3Npb25zICsgY2FuIHB1Ymxpc2ggdGhlaXIgb3duIFN0cmVhbXMgYnkgY2FsbGluZyBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICogLSBgTU9ERVJBVE9SYDogU1VCU0NSSUJFUiArIFBVQkxJU0hFUiBwZXJtaXNzaW9ucyArIGNhbiBmb3JjZSB0aGUgdW5wdWJsaXNoaW5nIG9yIGRpc2Nvbm5lY3Rpb24gb3ZlciBhIHRoaXJkLXBhcnR5IFN0cmVhbSBvciBDb25uZWN0aW9uIGJ5IGNhbGwgW1tTZXNzaW9uLmZvcmNlVW5wdWJsaXNoXV0gYW5kIFtbU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3RdXVxuICAgICAqXG4gICAgICogKipPbmx5IGRlZmluZWQgZm9yIHRoZSBsb2NhbCBjb25uZWN0aW9uLiBJbiByZW1vdGUgY29ubmVjdGlvbnMgd2lsbCBiZSBgdW5kZWZpbmVkYCoqXG4gICAgICovXG4gICAgcm9sZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtcyBwdWJsaXNoZWQgYnkgdGhpcyBDb25uZWN0aW9uIHdpbGwgYmUgcmVjb3JkZWQgb3Igbm90LiBUaGlzIG9ubHkgYWZmZWN0cyBbSU5ESVZJRFVBTCByZWNvcmRpbmddKC9lbi9zdGFibGUvYWR2YW5jZWQtZmVhdHVyZXMvcmVjb3JkaW5nLyNpbmRpdmlkdWFsLXJlY29yZGluZy1zZWxlY3Rpb24pIDxhIGhyZWY9XCJodHRwczovL2RvY3Mub3BlbnZpZHUuaW8vZW4vc3RhYmxlL29wZW52aWR1LXByby9cIiBzdHlsZT1cImRpc3BsYXk6IGlubGluZS1ibG9jazsgYmFja2dyb3VuZC1jb2xvcjogcmdiKDAsIDEzNiwgMTcwKTsgY29sb3I6IHdoaXRlOyBmb250LXdlaWdodDogYm9sZDsgcGFkZGluZzogMHB4IDVweDsgbWFyZ2luLXJpZ2h0OiA1cHg7IGJvcmRlci1yYWRpdXM6IDNweDsgZm9udC1zaXplOiAxM3B4OyBsaW5lLWhlaWdodDoyMXB4OyBmb250LWZhbWlseTogTW9udHNlcnJhdCwgc2Fucy1zZXJpZlwiPlBSTzwvYT5cbiAgICAgKlxuICAgICAqICoqT25seSBkZWZpbmVkIGZvciB0aGUgbG9jYWwgY29ubmVjdGlvbi4gSW4gcmVtb3RlIGNvbm5lY3Rpb25zIHdpbGwgYmUgYHVuZGVmaW5lZGAqKlxuICAgICAqL1xuICAgIHJlY29yZDogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW0/OiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbG9jYWxPcHRpb25zOiBMb2NhbENvbm5lY3Rpb25PcHRpb25zIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZU9wdGlvbnM6IFJlbW90ZUNvbm5lY3Rpb25PcHRpb25zIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc3Bvc2VkID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcnBjU2Vzc2lvbklkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzZXNzaW9uOiBTZXNzaW9uLCBjb25uZWN0aW9uT3B0aW9uczogTG9jYWxDb25uZWN0aW9uT3B0aW9ucyB8IFJlbW90ZUNvbm5lY3Rpb25PcHRpb25zKSB7XG4gICAgICAgIGxldCBtc2cgPSBcIidDb25uZWN0aW9uJyBjcmVhdGVkIFwiO1xuICAgICAgICBpZiAoISEoPExvY2FsQ29ubmVjdGlvbk9wdGlvbnM+Y29ubmVjdGlvbk9wdGlvbnMpLnJvbGUpIHtcbiAgICAgICAgICAgIC8vIENvbm5lY3Rpb24gaXMgbG9jYWxcbiAgICAgICAgICAgIHRoaXMubG9jYWxPcHRpb25zID0gPExvY2FsQ29ubmVjdGlvbk9wdGlvbnM+Y29ubmVjdGlvbk9wdGlvbnM7XG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9IHRoaXMubG9jYWxPcHRpb25zLmlkO1xuICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSB0aGlzLmxvY2FsT3B0aW9ucy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICB0aGlzLmRhdGEgPSB0aGlzLmxvY2FsT3B0aW9ucy5tZXRhZGF0YTtcbiAgICAgICAgICAgIHRoaXMucnBjU2Vzc2lvbklkID0gdGhpcy5sb2NhbE9wdGlvbnMuc2Vzc2lvbklkO1xuICAgICAgICAgICAgdGhpcy5yb2xlID0gdGhpcy5sb2NhbE9wdGlvbnMucm9sZTtcbiAgICAgICAgICAgIHRoaXMucmVjb3JkID0gdGhpcy5sb2NhbE9wdGlvbnMucmVjb3JkO1xuICAgICAgICAgICAgbXNnICs9ICcobG9jYWwpJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIENvbm5lY3Rpb24gaXMgcmVtb3RlXG4gICAgICAgICAgICB0aGlzLnJlbW90ZU9wdGlvbnMgPSA8UmVtb3RlQ29ubmVjdGlvbk9wdGlvbnM+Y29ubmVjdGlvbk9wdGlvbnM7XG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25JZCA9IHRoaXMucmVtb3RlT3B0aW9ucy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gdGhpcy5yZW1vdGVPcHRpb25zLmNyZWF0ZWRBdDtcbiAgICAgICAgICAgIGlmICh0aGlzLnJlbW90ZU9wdGlvbnMubWV0YWRhdGEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEgPSB0aGlzLnJlbW90ZU9wdGlvbnMubWV0YWRhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5yZW1vdGVPcHRpb25zLnN0cmVhbXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRSZW1vdGVTdHJlYW1zKHRoaXMucmVtb3RlT3B0aW9ucy5zdHJlYW1zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1zZyArPSBcIihyZW1vdGUpIHdpdGggJ2Nvbm5lY3Rpb25JZCcgW1wiICsgdGhpcy5yZW1vdGVPcHRpb25zLmlkICsgJ10nO1xuICAgICAgICB9XG4gICAgICAgIGxvZ2dlci5pbmZvKG1zZyk7XG4gICAgfVxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZW5kSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlKTogdm9pZCB7XG5cbiAgICAgICAgaWYgKCF0aGlzLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoKCEhdGhpcy5zdHJlYW0hLm91dGJvdW5kU3RyZWFtT3B0cyA/ICdMb2NhbCcgOiAnUmVtb3RlJykgKyAnY2FuZGlkYXRlIGZvcicgKyB0aGlzLmNvbm5lY3Rpb25JZCwgY2FuZGlkYXRlKTtcblxuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICdvbkljZUNhbmRpZGF0ZScsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBlbmRwb2ludE5hbWU6IHRoaXMuY29ubmVjdGlvbklkLFxuICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGU6IGNhbmRpZGF0ZS5jYW5kaWRhdGUsXG4gICAgICAgICAgICAgICAgICAgIHNkcE1pZDogY2FuZGlkYXRlLnNkcE1pZCxcbiAgICAgICAgICAgICAgICAgICAgc2RwTUxpbmVJbmRleDogY2FuZGlkYXRlLnNkcE1MaW5lSW5kZXhcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgSUNFIGNhbmRpZGF0ZTogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdleGNlcHRpb24nLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IEV4Y2VwdGlvbkV2ZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV4Y2VwdGlvbkV2ZW50TmFtZS5JQ0VfQ0FORElEQVRFX0VSUk9SLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUaGVyZSB3YXMgYW4gdW5leHBlY3RlZCBlcnJvciBvbiB0aGUgc2VydmVyLXNpZGUgcHJvY2Vzc2luZyBhbiBJQ0UgY2FuZGlkYXRlIGdlbmVyYXRlZCBhbmQgc2VudCBieSB0aGUgY2xpZW50LXNpZGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKGBDb25uZWN0aW9uICR7dGhpcy5jb25uZWN0aW9uSWR9IGRpc3Bvc2VkIHdoZW4gdHJ5aW5nIHRvIHNlbmQgYW4gSUNFIGNhbmRpZGF0ZS4gSUNFIGNhbmRpZGF0ZSBub3Qgc2VudGApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRSZW1vdGVTdHJlYW1zKG9wdGlvbnM6IFN0cmVhbU9wdGlvbnNTZXJ2ZXJbXSk6IHZvaWQge1xuICAgICAgICAvLyBUaGlzIGlzIHJlYWR5IGZvciBzdXBwb3J0aW5nIG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb24gb2JqZWN0LiBSaWdodCBub3cgdGhlIGxvb3Agd2lsbCBhbHdheXMgcnVuIGp1c3Qgb25jZVxuICAgICAgICAvLyB0aGlzLnN0cmVhbSBzaG91bGQgYWxzbyBiZSByZXBsYWNlZCBieSBhIGNvbGxlY3Rpb24gb2Ygc3RyZWFtcyB0byBzdXBwb3J0IG11bHRpcGxlIHN0cmVhbXMgcGVyIENvbm5lY3Rpb25cbiAgICAgICAgb3B0aW9ucy5mb3JFYWNoKChvcHRzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdHJlYW1PcHRpb25zOiBJbmJvdW5kU3RyZWFtT3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBpZDogb3B0cy5pZCxcbiAgICAgICAgICAgICAgICBjcmVhdGVkQXQ6IG9wdHMuY3JlYXRlZEF0LFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb246IHRoaXMsXG4gICAgICAgICAgICAgICAgaGFzQXVkaW86IG9wdHMuaGFzQXVkaW8sXG4gICAgICAgICAgICAgICAgaGFzVmlkZW86IG9wdHMuaGFzVmlkZW8sXG4gICAgICAgICAgICAgICAgYXVkaW9BY3RpdmU6IG9wdHMuYXVkaW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgdmlkZW9BY3RpdmU6IG9wdHMudmlkZW9BY3RpdmUsXG4gICAgICAgICAgICAgICAgdHlwZU9mVmlkZW86IG9wdHMudHlwZU9mVmlkZW8sXG4gICAgICAgICAgICAgICAgZnJhbWVSYXRlOiBvcHRzLmZyYW1lUmF0ZSxcbiAgICAgICAgICAgICAgICB2aWRlb0RpbWVuc2lvbnM6ICEhb3B0cy52aWRlb0RpbWVuc2lvbnMgPyBKU09OLnBhcnNlKG9wdHMudmlkZW9EaW1lbnNpb25zKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBmaWx0ZXI6ICEhb3B0cy5maWx0ZXIgPyBvcHRzLmZpbHRlciA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IG5ldyBTdHJlYW0odGhpcy5zZXNzaW9uLCBzdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgdGhpcy5hZGRTdHJlYW0oc3RyZWFtKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICBcIlJlbW90ZSAnQ29ubmVjdGlvbicgd2l0aCAnY29ubmVjdGlvbklkJyBbXCIgKyB0aGlzLmNvbm5lY3Rpb25JZCArICddIGlzIG5vdyBjb25maWd1cmVkIGZvciByZWNlaXZpbmcgU3RyZWFtcyB3aXRoIG9wdGlvbnM6ICcsXG4gICAgICAgICAgICB0aGlzLnN0cmVhbSEuaW5ib3VuZFN0cmVhbU9wdHNcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkU3RyZWFtKHN0cmVhbTogU3RyZWFtKTogdm9pZCB7XG4gICAgICAgIHN0cmVhbS5jb25uZWN0aW9uID0gdGhpcztcbiAgICAgICAgdGhpcy5zdHJlYW0gPSBzdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVN0cmVhbSgpOiB2b2lkIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuc3RyZWFtO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5yZW1vdmVTdHJlYW0oKTtcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudCc7XG5pbXBvcnQgeyBFdmVudE1hcCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V2ZW50TWFwL0V2ZW50TWFwJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9Mb2dnZXIvT3BlblZpZHVMb2dnZXInO1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgRXZlbnREaXNwYXRjaGVyIHtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXNlckhhbmRsZXJBcnJvd0hhbmRsZXI6IFdlYWtNYXA8KGV2ZW50OiBFdmVudCkgPT4gdm9pZCwgKGV2ZW50OiBFdmVudCkgPT4gdm9pZD4gPSBuZXcgV2Vha01hcCgpO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIC8qKlxuICAgICAqIEFkZHMgZnVuY3Rpb24gYGhhbmRsZXJgIHRvIGhhbmRsZSBldmVudCBgdHlwZWBcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBFdmVudERpc3BhdGNoZXIgb2JqZWN0XG4gICAgICovXG4gICAgYWJzdHJhY3Qgb248SyBleHRlbmRzIGtleW9mIEV2ZW50TWFwPih0eXBlOiBLLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcztcblxuICAgIC8qKlxuICAgICAqIEFkZHMgZnVuY3Rpb24gYGhhbmRsZXJgIHRvIGhhbmRsZSBldmVudCBgdHlwZWAganVzdCBvbmNlLiBUaGUgaGFuZGxlciB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZCBhZnRlciBmaXJzdCBleGVjdXRpb25cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBvYmplY3QgdGhhdCBkaXNwYXRjaGVkIHRoZSBldmVudFxuICAgICAqL1xuICAgIGFic3RyYWN0IG9uY2U8SyBleHRlbmRzIGtleW9mIEV2ZW50TWFwPih0eXBlOiBLLCBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcztcblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYSBgaGFuZGxlcmAgZnJvbSBldmVudCBgdHlwZWAuIElmIG5vIGhhbmRsZXIgaXMgcHJvdmlkZWQsIGFsbCBoYW5kbGVycyB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgZXZlbnRcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFRoZSBvYmplY3QgdGhhdCBkaXNwYXRjaGVkIHRoZSBldmVudFxuICAgICAqL1xuICAgIGFic3RyYWN0IG9mZjxLIGV4dGVuZHMga2V5b2YgRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI/OiAoZXZlbnQ6IEV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbkF1eCh0eXBlOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZywgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIGNvbnN0IGFycm93SGFuZGxlciA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKG1lc3NhZ2UsIGV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKG1lc3NhZ2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaGFuZGxlcihldmVudCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMudXNlckhhbmRsZXJBcnJvd0hhbmRsZXIuc2V0KGhhbmRsZXIsIGFycm93SGFuZGxlcik7XG4gICAgICAgIHRoaXMuZWUub24odHlwZSwgYXJyb3dIYW5kbGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uY2VBdXgodHlwZTogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcsIGhhbmRsZXI6IChldmVudDogRXZlbnQpID0+IHZvaWQpOiBFdmVudERpc3BhdGNoZXIge1xuICAgICAgICBjb25zdCBhcnJvd0hhbmRsZXIgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhtZXNzYWdlLCBldmVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhtZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGhhbmRsZXIgZnJvbSBtYXAgYWZ0ZXIgZmlyc3QgYW5kIG9ubHkgZXhlY3V0aW9uXG4gICAgICAgICAgICB0aGlzLnVzZXJIYW5kbGVyQXJyb3dIYW5kbGVyLmRlbGV0ZShoYW5kbGVyKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy51c2VySGFuZGxlckFycm93SGFuZGxlci5zZXQoaGFuZGxlciwgYXJyb3dIYW5kbGVyKTtcbiAgICAgICAgdGhpcy5lZS5vbmNlKHR5cGUsIGFycm93SGFuZGxlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvZmZBdXgodHlwZTogc3RyaW5nLCBoYW5kbGVyPzogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCk6IEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgICAgIGlmICghaGFuZGxlcikge1xuICAgICAgICAgICAgdGhpcy5lZS5yZW1vdmVBbGxMaXN0ZW5lcnModHlwZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBNdXN0IHJlbW92ZSBpbnRlcm5hbCBhcnJvdyBmdW5jdGlvbiBoYW5kbGVyIHBhaXJlZCB3aXRoIHVzZXIgaGFuZGxlclxuICAgICAgICAgICAgY29uc3QgYXJyb3dIYW5kbGVyID0gdGhpcy51c2VySGFuZGxlckFycm93SGFuZGxlci5nZXQoaGFuZGxlcik7XG4gICAgICAgICAgICBpZiAoISFhcnJvd0hhbmRsZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLm9mZih0eXBlLCBhcnJvd0hhbmRsZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy51c2VySGFuZGxlckFycm93SGFuZGxlci5kZWxldGUoaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBPcGVuVmlkdUVycm9yLCBPcGVuVmlkdUVycm9yTmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvT3BlblZpZHVFcnJvcic7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqICoqV0FSTklORyoqOiBleHBlcmltZW50YWwgb3B0aW9uLiBUaGlzIGludGVyZmFjZSBtYXkgY2hhbmdlIGluIHRoZSBuZWFyIGZ1dHVyZVxuICpcbiAqIFZpZGVvL2F1ZGlvIGZpbHRlciBhcHBsaWVkIHRvIGEgU3RyZWFtLiBTZWUgW1tTdHJlYW0uYXBwbHlGaWx0ZXJdXVxuICovXG5leHBvcnQgY2xhc3MgRmlsdGVyIHtcbiAgICAvKipcbiAgICAgKiBUeXBlIG9mIGZpbHRlciBhcHBsaWVkLiBUaGlzIGlzIHRoZSBuYW1lIG9mIHRoZSByZW1vdGUgY2xhc3MgaWRlbnRpZnlpbmcgdGhlIGZpbHRlciB0byBhcHBseSBpbiBLdXJlbnRvIE1lZGlhIFNlcnZlci5cbiAgICAgKiBGb3IgZXhhbXBsZTogYFwiRmFjZU92ZXJsYXlGaWx0ZXJcImAsIGBcIkdTdHJlYW1lckZpbHRlclwiYC5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4gZ2V0IHRoaXMgcHJvcGVydHkgaW4gYCoua21kLmpzb25gIGZpbGVzIGRlZmluaW5nIHRoZSBLdXJlbnRvIGZpbHRlcnMuIEZvciBleGFtcGxlLCBmb3IgR1N0cmVhbWVyRmlsdGVyIHRoYXQnc1xuICAgICAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vS3VyZW50by9rbXMtZmlsdGVycy9ibG9iLzUzYTQ1MmZhYzcxZDYxNzk1OTUyZTNkMjIwMjE1NmM2YjAwZjZkNjUvc3JjL3NlcnZlci9pbnRlcmZhY2UvZmlsdGVycy5HU3RyZWFtZXJGaWx0ZXIua21kLmpzb24jTDQpXG4gICAgICovXG4gICAgdHlwZTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogUGFyYW1ldGVycyB1c2VkIHRvIGluaXRpYWxpemUgdGhlIGZpbHRlci5cbiAgICAgKiBUaGVzZSBjb3JyZXNwb25kIHRvIHRoZSBjb25zdHJ1Y3RvciBwYXJhbWV0ZXJzIHVzZWQgaW4gdGhlIGZpbHRlciBpbiBLdXJlbnRvIE1lZGlhIFNlcnZlciAoZXhjZXB0IGZvciBgbWVkaWFQaXBlbGluZWAgcGFyYW1ldGVyLCB3aGljaCBpcyBuZXZlciBuZWVkZWQpLlxuICAgICAqXG4gICAgICogRm9yIGV4YW1wbGU6IGZvciBgZmlsdGVyLnR5cGUgPSBcIkdTdHJlYW1lckZpbHRlclwiYCBjb3VsZCBiZSBgZmlsdGVyLm9wdGlvbnMgPSB7XCJjb21tYW5kXCI6IFwidmlkZW9iYWxhbmNlIHNhdHVyYXRpb249MC4wXCJ9YFxuICAgICAqXG4gICAgICogWW91IGNhbiBnZXQgdGhpcyBwcm9wZXJ0eSBpbiBgKi5rbWQuanNvbmAgZmlsZXMgZGVmaW5pbmcgdGhlIEt1cmVudG8gZmlsdGVycy4gRm9yIGV4YW1wbGUsIGZvciBHU3RyZWFtZXJGaWx0ZXIgdGhhdCdzXG4gICAgICogW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9LdXJlbnRvL2ttcy1maWx0ZXJzL2Jsb2IvNTNhNDUyZmFjNzFkNjE3OTU5NTJlM2QyMjAyMTU2YzZiMDBmNmQ2NS9zcmMvc2VydmVyL2ludGVyZmFjZS9maWx0ZXJzLkdTdHJlYW1lckZpbHRlci5rbWQuanNvbiNMMTMtTDMxKVxuICAgICAqL1xuICAgIG9wdGlvbnM6IE9iamVjdDtcblxuICAgIC8qKlxuICAgICAqIFZhbHVlIHBhc3NlZCB0aGUgbGFzdCB0aW1lIFtbRmlsdGVyLmV4ZWNNZXRob2RdXSB3YXMgY2FsbGVkLiBJZiBgdW5kZWZpbmVkYCB0aGlzIG1ldGhvZCBoYXMgbm90IGJlZW4gY2FsbGVkIHlldC5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4gdXNlIHRoaXMgdmFsdWUgdG8ga25vdyB0aGUgY3VycmVudCBzdGF0dXMgb2YgYW55IGFwcGxpZWQgZmlsdGVyXG4gICAgICovXG4gICAgbGFzdEV4ZWNNZXRob2Q/OiB7XG4gICAgICAgIG1ldGhvZDogc3RyaW5nO1xuICAgICAgICBwYXJhbXM6IE9iamVjdDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhbmRsZXJzOiBNYXA8c3RyaW5nLCAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkPiA9IG5ldyBNYXAoKTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcbiAgICBwcml2YXRlIGxvZ2dlcjogT3BlblZpZHVMb2dnZXI7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodHlwZTogc3RyaW5nLCBvcHRpb25zOiBPYmplY3QpIHtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlcyBhIGZpbHRlciBtZXRob2QuIEF2YWlsYWJsZSBtZXRob2RzIGFyZSBzcGVjaWZpYyBmb3IgZWFjaCBmaWx0ZXJcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtZXRob2QgTmFtZSBvZiB0aGUgbWV0aG9kXG4gICAgICogQHBhcmFtIHBhcmFtcyBQYXJhbWV0ZXJzIG9mIHRoZSBtZXRob2RcbiAgICAgKi9cbiAgICBleGVjTWV0aG9kKG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IE9iamVjdCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ0V4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuXG4gICAgICAgICAgICBsZXQgZmluYWxQYXJhbXM7XG5cbiAgICAgICAgICAgIGNvbnN0IHN1Y2Nlc3NFeGVjTWV0aG9kID0gKHRyaWdnZXJFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdGaWx0ZXIgbWV0aG9kIHN1Y2Nlc3NmdWxseSBleGVjdXRlZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9ICg8YW55Pk9iamVjdCkuYXNzaWduKHt9LCB0aGlzLnN0cmVhbS5maWx0ZXIpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmZpbHRlciEubGFzdEV4ZWNNZXRob2QgPSB7IG1ldGhvZCwgcGFyYW1zOiBmaW5hbFBhcmFtcyB9O1xuICAgICAgICAgICAgICAgIGlmICh0cmlnZ2VyRXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmaWx0ZXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmZpbHRlciEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnXG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZpbHRlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZmlsdGVyISxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZXhlY0ZpbHRlck1ldGhvZCdcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodGhpcy50eXBlLnN0YXJ0c1dpdGgoJ1ZCOicpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwYXJhbXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSBKU09OLnBhcnNlKHBhcmFtcyk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUiwgJ1dyb25nIHBhcmFtcyBzeW50YXg6ICcgKyBlcnJvcikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZmluYWxQYXJhbXMgPSBwYXJhbXM7XG5cbiAgICAgICAgICAgICAgICBpZiAobWV0aG9kID09PSAndXBkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLnZpcnR1YWxCYWNrZ3JvdW5kU2lua0VsZW1lbnRzPy5WQikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5WSVJUVUFMX0JBQ0tHUk9VTkRfRVJST1IsICdUaGVyZSBpcyBubyBWaXJ0dWFsIEJhY2tncm91bmQgZmlsdGVyIGFwcGxpZWQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpcnR1YWxCYWNrZ3JvdW5kU2lua0VsZW1lbnRzLlZCLnVwZGF0ZVZhbHVlcyhwYXJhbXMpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gc3VjY2Vzc0V4ZWNNZXRob2QoZmFsc2UpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09IE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgT3BlblZpZHVFcnJvcihlcnJvci5uYW1lLCBlcnJvci5tZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5WSVJUVUFMX0JBQ0tHUk9VTkRfRVJST1IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdFcnJvciB1cGRhdGluZyB2YWx1ZXMgb24gVmlydHVhbCBCYWNrZ3JvdW5kIGZpbHRlcjogJyArIGVycm9yXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUiwgYFVua25vd24gVmlydHVhbCBCYWNrZ3JvdW5kIG1ldGhvZCBcIiR7bWV0aG9kfVwiYClcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCBzdHJpbmdQYXJhbXM7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwYXJhbXMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdQYXJhbXMgPSBKU09OLnN0cmluZ2lmeShwYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcIidwYXJhbXMnIHByb3BlcnR5IG11c3QgYmUgYSBKU09OIGZvcm1hdHRlZCBvYmplY3RcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yTXNnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ1BhcmFtcyA9IDxzdHJpbmc+cGFyYW1zO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGZpbmFsUGFyYW1zID0gc3RyaW5nUGFyYW1zO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgJ2V4ZWNGaWx0ZXJNZXRob2QnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCwgbWV0aG9kLCBwYXJhbXM6IHN0cmluZ1BhcmFtcyB9LFxuICAgICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGV4ZWN1dGluZyBmaWx0ZXIgbWV0aG9kIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBleGVjdXRlIGEgZmlsdGVyIG1ldGhvZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3VjY2Vzc0V4ZWNNZXRob2QodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gY2VydGFpbiBmaWx0ZXIgZXZlbnQuIEF2YWlsYWJsZSBldmVudHMgYXJlIHNwZWNpZmljIGZvciBlYWNoIGZpbHRlclxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB3aGljaCBzdWJzY3JpYmUgdG8uXG4gICAgICogQHBhcmFtIGhhbmRsZXIgRnVuY3Rpb24gdG8gZXhlY3V0ZSB1cG9uIGV2ZW50IGRpc3BhdGNoZWQuIEl0IHJlY2VpdmVzIGFzIHBhcmFtZXRlciBhIFtbRmlsdGVyRXZlbnRdXSBvYmplY3RcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgZXZlbnQgbGlzdGVuZXIgd2FzIHN1Y2Nlc3NmdWxseSBhdHRhY2hlZCB0byB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZTogc3RyaW5nLCBoYW5kbGVyOiAoZXZlbnQ6IEZpbHRlckV2ZW50KSA9PiB2b2lkKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbygnQWRkaW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ2FkZEZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdFcnJvciBhZGRpbmcgZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHRvIGV2ZW50ICcgKyBldmVudFR5cGUgKyAnZm9yIFN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gYWRkIGEgZmlsdGVyIGV2ZW50IGxpc3RlbmVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVycy5zZXQoZXZlbnRUeXBlLCBoYW5kbGVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdGaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICcgc3VjY2Vzc2Z1bGx5IGFwcGxpZWQgb24gU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZFxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGNlcnRhaW4gZmlsdGVyIGV2ZW50IGxpc3RlbmVyIHByZXZpb3VzbHkgc2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtIGV2ZW50VHlwZSBFdmVudCB0byB1bnN1YnNjcmliZSBmcm9tLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSBldmVudCBsaXN0ZW5lciB3YXMgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQgZnJvbSB0aGUgZmlsdGVyIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpbiBvdGhlciBjYXNlXG4gICAgICovXG4gICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudFR5cGU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ1JlbW92aW5nIGZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyB0byBzdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ3JlbW92ZUZpbHRlckV2ZW50TGlzdGVuZXInLFxuICAgICAgICAgICAgICAgIHsgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLCBldmVudFR5cGUgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdFcnJvciByZW1vdmluZyBmaWx0ZXIgZXZlbnQgbGlzdGVuZXIgdG8gZXZlbnQgJyArIGV2ZW50VHlwZSArICdmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhZGQgYSBmaWx0ZXIgZXZlbnQgbGlzdGVuZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZXJzLmRlbGV0ZShldmVudFR5cGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0ZpbHRlciBldmVudCBsaXN0ZW5lciB0byBldmVudCAnICsgZXZlbnRUeXBlICsgJyBzdWNjZXNzZnVsbHkgcmVtb3ZlZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyU3RhdGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL0xvY2FsUmVjb3JkZXJTdGF0ZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IFBsYXRmb3JtVXRpbHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1V0aWxzL1BsYXRmb3JtJztcbmltcG9ydCBNaW1lID0gcmVxdWlyZSgnbWltZS9saXRlJyk7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmxldCBwbGF0Zm9ybTogUGxhdGZvcm1VdGlscztcblxuLyoqXG4gKiBFYXN5IHJlY29yZGluZyBvZiBbW1N0cmVhbV1dIG9iamVjdHMgc3RyYWlnaHRhd2F5IGZyb20gdGhlIGJyb3dzZXIuIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0TG9jYWxSZWNvcmRlcl1dIG1ldGhvZFxuICovXG5leHBvcnQgY2xhc3MgTG9jYWxSZWNvcmRlciB7XG4gICAgc3RhdGU6IExvY2FsUmVjb3JkZXJTdGF0ZTtcblxuICAgIHByaXZhdGUgY29ubmVjdGlvbklkOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSBtZWRpYVJlY29yZGVyOiBNZWRpYVJlY29yZGVyO1xuICAgIHByaXZhdGUgY2h1bmtzOiBhbnlbXSA9IFtdO1xuICAgIHByaXZhdGUgYmxvYj86IEJsb2I7XG4gICAgcHJpdmF0ZSBpZDogc3RyaW5nO1xuICAgIHByaXZhdGUgdmlkZW9QcmV2aWV3U3JjOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSB2aWRlb1ByZXZpZXc6IEhUTUxWaWRlb0VsZW1lbnQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICBwbGF0Zm9ybSA9IFBsYXRmb3JtVXRpbHMuZ2V0SW5zdGFuY2UoKTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uSWQgPSAhIXRoaXMuc3RyZWFtLmNvbm5lY3Rpb24gPyB0aGlzLnN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA6ICdkZWZhdWx0LWNvbm5lY3Rpb24nO1xuICAgICAgICB0aGlzLmlkID0gdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnXycgKyB0aGlzLmNvbm5lY3Rpb25JZCArICdfbG9jYWxyZWNvcmQnO1xuICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBSRUFEWWAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYFJFQ09SRElOR2BcbiAgICAgKlxuICAgICAqIEBwYXJhbSBvcHRpb25zIFRoZSBbTWVkaWFSZWNvcmRlci5vcHRpb25zXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTWVkaWFSZWNvcmRlci9NZWRpYVJlY29yZGVyI3BhcmFtZXRlcnMpIHRvIGJlIHVzZWQgdG8gcmVjb3JkIHRoaXMgU3RyZWFtLlxuICAgICAqIEZvciBleGFtcGxlOlxuICAgICAqXG4gICAgICogYGBgamF2YXNjcmlwdFxuICAgICAqIHZhciBPViA9IG5ldyBPcGVuVmlkdSgpO1xuICAgICAqIHZhciBwdWJsaXNoZXIgPSBhd2FpdCBPVi5pbml0UHVibGlzaGVyQXN5bmMoKTtcbiAgICAgKiB2YXIgbG9jYWxSZWNvcmRlciA9IE9WLmluaXRMb2NhbFJlY29yZGVyKHB1Ymxpc2hlci5zdHJlYW0pO1xuICAgICAqIHZhciBvcHRpb25zID0ge1xuICAgICAqICAgICAgbWltZVR5cGU6ICd2aWRlby93ZWJtO2NvZGVjcz12cDgnLFxuICAgICAqICAgICAgYXVkaW9CaXRzUGVyU2Vjb25kOjEyODAwMCxcbiAgICAgKiAgICAgIHZpZGVvQml0c1BlclNlY29uZDoyNTAwMDAwXG4gICAgICogfTtcbiAgICAgKiBsb2NhbFJlY29yZGVyLnJlY29yZChvcHRpb25zKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIElmIG5vdCBzcGVjaWZpZWQsIHRoZSBkZWZhdWx0IG9wdGlvbnMgcHJlZmVycmVkIGJ5IHRoZSBwbGF0Zm9ybSB3aWxsIGJlIHVzZWQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHJlY29yZGluZyBzdWNjZXNzZnVsbHkgc3RhcnRlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICovXG4gICAgcmVjb3JkKG9wdGlvbnM/OiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJyB8fCBvcHRpb25zIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgICAgICBgV2hlbiBjYWxsaW5nIExvY2FsUmVjb3JkZXIucmVjb3JkKG9wdGlvbnMpIHBhcmFtZXRlciAnb3B0aW9ucycgY2Fubm90IGJlIGEgc3RyaW5nLiBNdXN0IGJlIGFuIG9iamVjdCBsaWtlIHsgbWltZVR5cGU6IFwiJHtvcHRpb25zfVwiIH1gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFSZWNvcmRlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGRldmljZS4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ01lZGlhUmVjb3JkZXIgbm90IHN1cHBvcnRlZCBvbiB5b3VyIGRldmljZS4gU2VlIGNvbXBhdGliaWxpdHkgaW4gaHR0cHM6Ly9jYW5pdXNlLmNvbS8jc2VhcmNoPU1lZGlhUmVjb3JkZXInXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBcIidMb2NhbFJlY29yZC5yZWNvcmQoKScgbmVlZHMgJ0xvY2FsUmVjb3JkLnN0YXRlJyB0byBiZSAnUkVBRFknIChjdXJyZW50IHZhbHVlOiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiJykuIENhbGwgJ0xvY2FsUmVjb3JkZXIuY2xlYW4oKScgb3IgaW5pdCBhIG5ldyBMb2NhbFJlY29yZGVyIGJlZm9yZVwiXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coXCJTdGFydGluZyBsb2NhbCByZWNvcmRpbmcgb2Ygc3RyZWFtICdcIiArIHRoaXMuc3RyZWFtLnN0cmVhbUlkICsgXCInIG9mIGNvbm5lY3Rpb24gJ1wiICsgdGhpcy5jb25uZWN0aW9uSWQgKyBcIidcIik7XG5cbiAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IHsgbWltZVR5cGU6ICd2aWRlby93ZWJtJyB9O1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIW9wdGlvbnMubWltZVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5taW1lVHlwZSA9ICd2aWRlby93ZWJtJztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIgPSBuZXcgTWVkaWFSZWNvcmRlcih0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhcnQoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uZGF0YWF2YWlsYWJsZSA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGUuZGF0YS5zaXplID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uZXJyb3IgPSAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignTWVkaWFSZWNvcmRlciBlcnJvcjogJywgZSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIub25zdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIubG9nKCdNZWRpYVJlY29yZGVyIHN0YXJ0ZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLm9uc3RvcCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLm9uU3RvcERlZmF1bHQoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnBhdXNlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coJ01lZGlhUmVjb3JkZXIgcGF1c2VkIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnJlc3VtZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIubG9nKCdNZWRpYVJlY29yZGVyIHJlc3VtZWQgKHN0YXRlPScgKyB0aGlzLm1lZGlhUmVjb3JkZXIuc3RhdGUgKyAnKScpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbmRzIHRoZSByZWNvcmRpbmcgb2YgdGhlIFN0cmVhbS4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYFJFQ09SRElOR2Agb3IgYFBBVVNFRGAuIEFmdGVyIG1ldGhvZCBzdWNjZWVkcyBpcyBzZXQgdG8gYEZJTklTSEVEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHN1Y2Nlc3NmdWxseSBzdG9wcGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlJFQURZIHx8IHRoaXMuc3RhdGUgPT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiJ0xvY2FsUmVjb3JkLnN0b3AoKScgbmVlZHMgJ0xvY2FsUmVjb3JkLnN0YXRlJyB0byBiZSAnUkVDT1JESU5HJyBvciAnUEFVU0VEJyAoY3VycmVudCB2YWx1ZTogJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIicpLiBDYWxsICdMb2NhbFJlY29yZGVyLnN0YXJ0KCknIGJlZm9yZVwiXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMubWVkaWFSZWNvcmRlci5vbnN0b3AgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25TdG9wRGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVJlY29yZGVyLnN0b3AoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXVzZXMgdGhlIHJlY29yZGluZyBvZiB0aGUgU3RyZWFtLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgUkVDT1JESU5HYC4gQWZ0ZXIgbWV0aG9kIHN1Y2NlZWRzIGlzIHNldCB0byBgUEFVU0VEYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgcmVjb3JkaW5nIHdhcyBzdWNjZXNzZnVsbHkgcGF1c2VkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBwYXVzZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgIEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiJ0xvY2FsUmVjb3JkLnBhdXNlKCknIG5lZWRzICdMb2NhbFJlY29yZC5zdGF0ZScgdG8gYmUgJ1JFQ09SRElORycgKGN1cnJlbnQgdmFsdWU6ICdcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIicpLiBDYWxsICdMb2NhbFJlY29yZGVyLnN0YXJ0KCknIG9yICdMb2NhbFJlY29yZGVyLnJlc3VtZSgpJyBiZWZvcmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRDtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVzdW1lcyB0aGUgcmVjb3JkaW5nIG9mIHRoZSBTdHJlYW0uIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBQQVVTRURgLiBBZnRlciBtZXRob2Qgc3VjY2VlZHMgaXMgc2V0IHRvIGBSRUNPUkRJTkdgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvcmRpbmcgd2FzIHN1Y2Nlc3NmdWxseSByZXN1bWVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICByZXN1bWUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuUEFVU0VEKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgXCInTG9jYWxSZWNvcmQucmVzdW1lKCknIG5lZWRzICdMb2NhbFJlY29yZC5zdGF0ZScgdG8gYmUgJ1BBVVNFRCcgKGN1cnJlbnQgdmFsdWU6ICdcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInKS4gQ2FsbCAnTG9jYWxSZWNvcmRlci5wYXVzZSgpJyBiZWZvcmVcIlxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLm1lZGlhUmVjb3JkZXIucmVzdW1lKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFByZXZpZXdzIHRoZSByZWNvcmRpbmcsIGFwcGVuZGluZyBhIG5ldyBIVE1MVmlkZW9FbGVtZW50IHRvIGVsZW1lbnQgd2l0aCBpZCBgcGFyZW50SWRgLiBbW3N0YXRlXV0gcHJvcGVydHkgbXVzdCBiZSBgRklOSVNIRURgXG4gICAgICovXG4gICAgcHJldmlldyhwYXJlbnRFbGVtZW50KTogSFRNTFZpZGVvRWxlbWVudCB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBMb2NhbFJlY29yZGVyU3RhdGUuRklOSVNIRUQpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiJ0xvY2FsUmVjb3JkLnByZXZpZXcoKScgbmVlZHMgJ0xvY2FsUmVjb3JkLnN0YXRlJyB0byBiZSAnRklOSVNIRUQnIChjdXJyZW50IHZhbHVlOiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlICtcbiAgICAgICAgICAgICAgICAgICAgXCInKS4gQ2FsbCAnTG9jYWxSZWNvcmRlci5zdG9wKCknIGJlZm9yZVwiXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LmlkID0gdGhpcy5pZDtcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcuYXV0b3BsYXkgPSB0cnVlO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5pc1NhZmFyaUJyb3dzZXIoKSkge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcucGxheXNJbmxpbmUgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBwYXJlbnRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uc3QgcGFyZW50RWxlbWVudERvbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHBhcmVudEVsZW1lbnQpO1xuICAgICAgICAgICAgaWYgKHBhcmVudEVsZW1lbnREb20pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUHJldmlldyA9IHBhcmVudEVsZW1lbnREb20uYXBwZW5kQ2hpbGQodGhpcy52aWRlb1ByZXZpZXcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52aWRlb1ByZXZpZXcgPSBwYXJlbnRFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudmlkZW9QcmV2aWV3KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudmlkZW9QcmV2aWV3LnNyYyA9IHRoaXMudmlkZW9QcmV2aWV3U3JjO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnZpZGVvUHJldmlldztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHcmFjZWZ1bGx5IHN0b3BzIGFuZCBjbGVhbnMgdGhlIGN1cnJlbnQgcmVjb3JkaW5nIChXQVJOSU5HOiBpdCBpcyBjb21wbGV0ZWx5IGRpc21pc3NlZCkuIFNldHMgW1tzdGF0ZV1dIHRvIGBSRUFEWWAgc28gdGhlIHJlY29yZGluZyBjYW4gc3RhcnQgYWdhaW5cbiAgICAgKi9cbiAgICBjbGVhbigpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZiA9ICgpID0+IHtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmJsb2I7XG4gICAgICAgICAgICB0aGlzLmNodW5rcyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUFEWTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IExvY2FsUmVjb3JkZXJTdGF0ZS5SRUNPUkRJTkcgfHwgdGhpcy5zdGF0ZSA9PT0gTG9jYWxSZWNvcmRlclN0YXRlLlBBVVNFRCkge1xuICAgICAgICAgICAgdGhpcy5zdG9wKClcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiBmKCkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKCgpID0+IGYoKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEb3dubG9hZHMgdGhlIHJlY29yZGVkIHZpZGVvIHRocm91Z2ggdGhlIGJyb3dzZXIuIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBGSU5JU0hFRGBcbiAgICAgKi9cbiAgICBkb3dubG9hZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IExvY2FsUmVjb3JkZXJTdGF0ZS5GSU5JU0hFRCkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgICAgICAgXCInTG9jYWxSZWNvcmQuZG93bmxvYWQoKScgbmVlZHMgJ0xvY2FsUmVjb3JkLnN0YXRlJyB0byBiZSAnRklOSVNIRUQnIChjdXJyZW50IHZhbHVlOiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0YXRlICtcbiAgICAgICAgICAgICAgICAgICAgXCInKS4gQ2FsbCAnTG9jYWxSZWNvcmRlci5zdG9wKCknIGJlZm9yZVwiXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYTogSFRNTEFuY2hvckVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgICAgICAgICBhLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGEpO1xuXG4gICAgICAgICAgICBjb25zdCB1cmwgPSBnbG9iYWxUaGlzLlVSTC5jcmVhdGVPYmplY3RVUkwoPGFueT50aGlzLmJsb2IpO1xuICAgICAgICAgICAgYS5ocmVmID0gdXJsO1xuICAgICAgICAgICAgYS5kb3dubG9hZCA9IHRoaXMuaWQgKyAnLicgKyBNaW1lLmdldEV4dGVuc2lvbih0aGlzLmJsb2IhLnR5cGUpO1xuICAgICAgICAgICAgYS5jbGljaygpO1xuICAgICAgICAgICAgZ2xvYmFsVGhpcy5VUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG5cbiAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoYSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSByYXcgQmxvYiBmaWxlLiBNZXRob2RzIHByZXZpZXcsIGRvd25sb2FkLCB1cGxvYWRBc0JpbmFyeSBhbmQgdXBsb2FkQXNNdWx0aXBhcnRmaWxlIHVzZSB0aGlzIHNhbWUgZmlsZSB0byBwZXJmb3JtIHRoZWlyIHNwZWNpZmljIGFjdGlvbnMuIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBGSU5JU0hFRGBcbiAgICAgKi9cbiAgICBnZXRCbG9iKCk6IEJsb2Ige1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcIkNhbGwgJ0xvY2FsUmVjb3JkLnN0b3AoKScgYmVmb3JlIGdldHRpbmcgQmxvYiBmaWxlXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYmxvYiE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGxvYWRzIHRoZSByZWNvcmRlZCB2aWRlbyBhcyBhIGJpbmFyeSBmaWxlIHBlcmZvcm1pbmcgYW4gSFRUUC9QT1NUIG9wZXJhdGlvbiB0byBVUkwgYGVuZHBvaW50YC4gW1tzdGF0ZV1dIHByb3BlcnR5IG11c3QgYmUgYEZJTklTSEVEYC4gT3B0aW9uYWwgSFRUUCBoZWFkZXJzIGNhbiBiZSBwYXNzZWQgYXMgc2Vjb25kIHBhcmFtZXRlci4gRm9yIGV4YW1wbGU6XG4gICAgICogYGBgXG4gICAgICogdmFyIGhlYWRlcnMgPSB7XG4gICAgICogIFwiQ29va2llXCI6IFwiJFZlcnNpb249MTsgU2tpbj1uZXc7XCIsXG4gICAgICogIFwiQXV0aG9yaXphdGlvblwiOlwiQmFzaWMgUVd4aFpHcGJqcHVJSE5sY3RaUT09XCJcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGBodHRwLnJlc3BvbnNlVGV4dGAgZnJvbSBzZXJ2ZXIgaWYgdGhlIG9wZXJhdGlvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCB0aGUgZmFpbGVkIGBodHRwLnN0YXR1c2AgaWYgbm90XG4gICAgICovXG4gICAgdXBsb2FkQXNCaW5hcnkoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBcIidMb2NhbFJlY29yZC51cGxvYWRBc0JpbmFyeSgpJyBuZWVkcyAnTG9jYWxSZWNvcmQuc3RhdGUnIHRvIGJlICdGSU5JU0hFRCcgKGN1cnJlbnQgdmFsdWU6ICdcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInKS4gQ2FsbCAnTG9jYWxSZWNvcmRlci5zdG9wKCknIGJlZm9yZVwiXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBodHRwID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICAgICAgaHR0cC5vcGVuKCdQT1NUJywgZW5kcG9pbnQsIHRydWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaHR0cC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgaGVhZGVyc1trZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGh0dHAub25yZWFkeXN0YXRlY2hhbmdlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaHR0cC5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaHR0cC5zdGF0dXMudG9TdHJpbmcoKS5jaGFyQXQoMCkgPT09ICcyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN1Y2Nlc3MgcmVzcG9uc2UgZnJvbSBzZXJ2ZXIgKEhUVFAgc3RhdHVzIHN0YW5kYXJkOiAyWFggaXMgc3VjY2VzcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoaHR0cC5zdGF0dXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBodHRwLnNlbmQodGhpcy5ibG9iKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBsb2FkcyB0aGUgcmVjb3JkZWQgdmlkZW8gYXMgYSBtdWx0aXBhcnQgZmlsZSBwZXJmb3JtaW5nIGFuIEhUVFAvUE9TVCBvcGVyYXRpb24gdG8gVVJMIGBlbmRwb2ludGAuIFtbc3RhdGVdXSBwcm9wZXJ0eSBtdXN0IGJlIGBGSU5JU0hFRGAuIE9wdGlvbmFsIEhUVFAgaGVhZGVycyBjYW4gYmUgcGFzc2VkIGFzIHNlY29uZCBwYXJhbWV0ZXIuIEZvciBleGFtcGxlOlxuICAgICAqIGBgYFxuICAgICAqIHZhciBoZWFkZXJzID0ge1xuICAgICAqICBcIkNvb2tpZVwiOiBcIiRWZXJzaW9uPTE7IFNraW49bmV3O1wiLFxuICAgICAqICBcIkF1dGhvcml6YXRpb25cIjpcIkJhc2ljIFFXeGhaR3BianB1SUhObGN0WlE9PVwiXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCB3aXRoIHRoZSBgaHR0cC5yZXNwb25zZVRleHRgIGZyb20gc2VydmVyIGlmIHRoZSBvcGVyYXRpb24gd2FzIHN1Y2Nlc3NmdWwgYW5kIHJlamVjdGVkIHdpdGggdGhlIGZhaWxlZCBgaHR0cC5zdGF0dXNgIGlmIG5vdDpcbiAgICAgKi9cbiAgICB1cGxvYWRBc011bHRpcGFydGZpbGUoZW5kcG9pbnQ6IHN0cmluZywgaGVhZGVycz86IGFueSk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBcIidMb2NhbFJlY29yZC51cGxvYWRBc011bHRpcGFydGZpbGUoKScgbmVlZHMgJ0xvY2FsUmVjb3JkLnN0YXRlJyB0byBiZSAnRklOSVNIRUQnIChjdXJyZW50IHZhbHVlOiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiJykuIENhbGwgJ0xvY2FsUmVjb3JkZXIuc3RvcCgpJyBiZWZvcmVcIlxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaHR0cCA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIGh0dHAub3BlbignUE9TVCcsIGVuZHBvaW50LCB0cnVlKTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoaGVhZGVycykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGh0dHAuc2V0UmVxdWVzdEhlYWRlcihrZXksIGhlYWRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzZW5kYWJsZSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgICAgICAgICAgICAgIHNlbmRhYmxlLmFwcGVuZCgnZmlsZScsIHRoaXMuYmxvYiEsIHRoaXMuaWQgKyAnLicgKyBNaW1lLmdldEV4dGVuc2lvbih0aGlzLmJsb2IhLnR5cGUpKTtcblxuICAgICAgICAgICAgICAgIGh0dHAub25yZWFkeXN0YXRlY2hhbmdlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaHR0cC5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaHR0cC5zdGF0dXMudG9TdHJpbmcoKS5jaGFyQXQoMCkgPT09ICcyJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN1Y2Nlc3MgcmVzcG9uc2UgZnJvbSBzZXJ2ZXIgKEhUVFAgc3RhdHVzIHN0YW5kYXJkOiAyWFggaXMgc3VjY2VzcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShodHRwLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoaHR0cC5zdGF0dXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGh0dHAuc2VuZChzZW5kYWJsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBvblN0b3BEZWZhdWx0KCk6IHZvaWQge1xuICAgICAgICBsb2dnZXIubG9nKCdNZWRpYVJlY29yZGVyIHN0b3BwZWQgIChzdGF0ZT0nICsgdGhpcy5tZWRpYVJlY29yZGVyLnN0YXRlICsgJyknKTtcblxuICAgICAgICB0aGlzLmJsb2IgPSBuZXcgQmxvYih0aGlzLmNodW5rcywgeyB0eXBlOiB0aGlzLm1lZGlhUmVjb3JkZXIubWltZVR5cGUgfSk7XG4gICAgICAgIHRoaXMuY2h1bmtzID0gW107XG5cbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXdTcmMgPSBnbG9iYWxUaGlzLlVSTC5jcmVhdGVPYmplY3RVUkwodGhpcy5ibG9iKTtcblxuICAgICAgICB0aGlzLnN0YXRlID0gTG9jYWxSZWNvcmRlclN0YXRlLkZJTklTSEVEO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBMb2NhbFJlY29yZGVyIH0gZnJvbSAnLi9Mb2NhbFJlY29yZGVyJztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4vUHVibGlzaGVyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgRGV2aWNlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9EZXZpY2UnO1xuaW1wb3J0IHsgT3BlblZpZHVBZHZhbmNlZENvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFB1Ymxpc2hlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1B1Ymxpc2hlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgQ3VzdG9tTWVkaWFTdHJlYW1Db25zdHJhaW50cyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0N1c3RvbU1lZGlhU3RyZWFtQ29uc3RyYWludHMnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5pbXBvcnQgeyBQbGF0Zm9ybVV0aWxzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9VdGlscy9QbGF0Zm9ybSc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudFJlYXNvbiwgQ2hhbmdlZFByb3BlcnR5VHlwZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1R5cGVzL1R5cGVzJztcblxuaW1wb3J0ICogYXMgc2NyZWVuU2hhcmluZ0F1dG8gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9TY3JlZW5TaGFyaW5nL1NjcmVlbi1DYXB0dXJpbmctQXV0byc7XG5pbXBvcnQgKiBhcyBzY3JlZW5TaGFyaW5nIGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvU2NyZWVuU2hhcmluZy9TY3JlZW4tQ2FwdHVyaW5nJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbic7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuaW1wb3J0IEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ3dvbGZ5ODctZXZlbnRlbWl0dGVyJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuaW1wb3J0IFJwY0J1aWxkZXIgPSByZXF1aXJlKCcuLi9PcGVuVmlkdUludGVybmFsL0t1cmVudG9VdGlscy9rdXJlbnRvLWpzb25ycGMnKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHBhY2thZ2VKc29uID0gcmVxdWlyZSgnLi4vLi4vcGFja2FnZS5qc29uJyk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuZGVjbGFyZSB2YXIgY29yZG92YTogYW55O1xuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqL1xubGV0IHBsYXRmb3JtOiBQbGF0Zm9ybVV0aWxzO1xuXG4vKipcbiAqIEVudHJ5cG9pbnQgb2YgT3BlblZpZHUgQnJvd3NlciBsaWJyYXJ5LlxuICogVXNlIGl0IHRvIGluaXRpYWxpemUgb2JqZWN0cyBvZiB0eXBlIFtbU2Vzc2lvbl1dLCBbW1B1Ymxpc2hlcl1dIGFuZCBbW0xvY2FsUmVjb3JkZXJdXVxuICovXG5leHBvcnQgY2xhc3MgT3BlblZpZHUge1xuICAgIHByaXZhdGUganNvblJwY0NsaWVudDogYW55O1xuICAgIHByaXZhdGUgbWFzdGVyTm9kZUhhc0NyYXNoZWQgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZXNzaW9uOiBTZXNzaW9uO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaXNoZXJzOiBQdWJsaXNoZXJbXSA9IFtdO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB3c1VyaTogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBodHRwVXJpOiBzdHJpbmc7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlY3JldCA9ICcnO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZWNvcmRlciA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaWNlU2VydmVyczogUlRDSWNlU2VydmVyW107XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJvbGU6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZmluYWxVc2VySWQ6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbWVkaWFTZXJ2ZXI6IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9TaW11bGNhc3Q6IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxpZmU6IG51bWJlciA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhZHZhbmNlZENvbmZpZ3VyYXRpb246IE9wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uID0ge307XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IG51bWJlciA9IC0xO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZW5kQnJvd3NlckxvZ3M6IE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbiA9IE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbi5kaXNhYmxlZDtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNBdExlYXN0UHJvOiBib29sZWFuID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzRW50ZXJwcmlzZTogYm9vbGVhbiA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBsaWJyYXJ5VmVyc2lvbjogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBwbGF0Zm9ybSA9IFBsYXRmb3JtVXRpbHMuZ2V0SW5zdGFuY2UoKTtcbiAgICAgICAgdGhpcy5saWJyYXJ5VmVyc2lvbiA9IHBhY2thZ2VKc29uLnZlcnNpb247XG4gICAgICAgIGxvZ2dlci5pbmZvKCdPcGVuVmlkdSBpbml0aWFsaXplZCcpO1xuICAgICAgICBsb2dnZXIuaW5mbygnUGxhdGZvcm0gZGV0ZWN0ZWQ6ICcgKyBwbGF0Zm9ybS5nZXREZXNjcmlwdGlvbigpKTtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ29wZW52aWR1LWJyb3dzZXIgdmVyc2lvbjogJyArIHRoaXMubGlicmFyeVZlcnNpb24pO1xuXG4gICAgICAgIGlmIChwbGF0Zm9ybS5pc01vYmlsZURldmljZSgpIHx8IHBsYXRmb3JtLmlzUmVhY3ROYXRpdmUoKSkge1xuICAgICAgICAgICAgLy8gTGlzdGVuIHRvIG9yaWVudGF0aW9uY2hhbmdlIG9ubHkgb24gbW9iaWxlIGRldmljZXNcbiAgICAgICAgICAgIHRoaXMub25PcmllbnRhdGlvbkNoYW5nZWQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucHVibGlzaGVycy5mb3JFYWNoKChwdWJsaXNoZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHB1Ymxpc2hlci5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJiAhIXB1Ymxpc2hlci5zdHJlYW0gJiYgISFwdWJsaXNoZXIuc3RyZWFtLmhhc1ZpZGVvKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmROZXdWaWRlb0RpbWVuc2lvbnNJZlJlcXVpcmVkKHB1Ymxpc2hlciwgJ2RldmljZVJvdGF0ZWQnLCA3NSwgMTApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgbmV3IHNlc3Npb25cbiAgICAgKi9cbiAgICBpbml0U2Vzc2lvbigpOiBTZXNzaW9uIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uID0gbmV3IFNlc3Npb24odGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzLnNlc3Npb247XG4gICAgfVxuXG4gICAgaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCk6IFB1Ymxpc2hlcjtcbiAgICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHVibGlzaGVyO1xuICAgIGluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQsIGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkKTogUHVibGlzaGVyO1xuICAgIGluaXRQdWJsaXNoZXIoXG4gICAgICAgIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLFxuICAgICAgICBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLFxuICAgICAgICBjb21wbGV0aW9uSGFuZGxlcjogKGVycm9yOiBFcnJvciB8IHVuZGVmaW5lZCkgPT4gdm9pZFxuICAgICk6IFB1Ymxpc2hlcjtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBuZXcgcHVibGlzaGVyXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhbiBgYWNjZXNzRGlhbG9nT3BlbmVkYCBldmVudCwgb25seSBpZiB0aGUgcG9wLXVwIHNob3duIGJ5IHRoZSBicm93c2VyIHRvIHJlcXVlc3QgcGVybWlzc2lvbnMgZm9yIHRoZSBjYW1lcmEgaXMgb3BlbmVkLiBZb3UgY2FuIHVzZSB0aGlzIGV2ZW50IHRvIGFsZXJ0IHRoZSB1c2VyIGFib3V0IGdyYW50aW5nIHBlcm1pc3Npb25zXG4gICAgICogZm9yIHlvdXIgd2Vic2l0ZS4gQW4gYGFjY2Vzc0RpYWxvZ0Nsb3NlZGAgZXZlbnQgd2lsbCBhbHNvIGJlIGRpc3BhdGNoZWQgYWZ0ZXIgdXNlciBjbGlja3Mgb24gXCJBbGxvd1wiIG9yIFwiQmxvY2tcIiBpbiB0aGUgcG9wLXVwLlxuICAgICAqXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYW4gYGFjY2Vzc0FsbG93ZWRgIG9yIGBhY2Nlc3NEZW5pZWRgIGV2ZW50IG9uY2UgaXQgaGFzIGJlZW4gZ3JhbnRlZCBhY2Nlc3MgdG8gdGhlIHJlcXVlc3RlZCBpbnB1dCBkZXZpY2VzIG9yIG5vdC5cbiAgICAgKlxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudENyZWF0ZWRgIGV2ZW50IG9uY2UgYSBIVE1MIHZpZGVvIGVsZW1lbnQgaGFzIGJlZW4gYWRkZWQgdG8gRE9NIChvbmx5IGlmIHlvdVxuICAgICAqIFtsZXQgT3BlblZpZHUgdGFrZSBjYXJlIG9mIHRoZSB2aWRlbyBwbGF5ZXJzXSgvZW4vc3RhYmxlL2NoZWF0c2hlZXQvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLiBTZWUgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1QbGF5aW5nYCBldmVudCBvbmNlIHRoZSBsb2NhbCBzdHJlYW1zIHN0YXJ0cyBwbGF5aW5nLiBTZWUgW1tTdHJlYW1NYW5hZ2VyRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgIEhUTUwgRE9NIGVsZW1lbnQgKG9yIGl0cyBgaWRgIGF0dHJpYnV0ZSkgaW4gd2hpY2ggdGhlIHZpZGVvIGVsZW1lbnQgb2YgdGhlIFB1Ymxpc2hlciB3aWxsIGJlIGluc2VydGVkIChzZWUgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLmluc2VydE1vZGVdXSkuIElmICpudWxsKiBvciAqdW5kZWZpbmVkKiBubyBkZWZhdWx0IHZpZGVvIHdpbGwgYmUgY3JlYXRlZCBmb3IgdGhpcyBQdWJsaXNoZXIuXG4gICAgICogWW91IGNhbiBhbHdheXMgY2FsbCBtZXRob2QgW1tQdWJsaXNoZXIuYWRkVmlkZW9FbGVtZW50XV0gb3IgW1tQdWJsaXNoZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0gdG8gbWFuYWdlIHRoZSB2aWRlbyBlbGVtZW50cyBvbiB5b3VyIG93biAoc2VlIFtNYW5hZ2UgdmlkZW8gcGxheWVyc10oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MpIHNlY3Rpb24pXG4gICAgICogQHBhcmFtIGNvbXBsZXRpb25IYW5kbGVyIGBlcnJvcmAgcGFyYW1ldGVyIGlzIG51bGwgaWYgYGluaXRQdWJsaXNoZXJgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgYGNvbXBsZXRpb25IYW5kbGVyYCBmdW5jdGlvbiBpcyBjYWxsZWQgYmVmb3JlIHRoZSBQdWJsaXNoZXIgZGlzcGF0Y2hlcyBhbiBgYWNjZXNzQWxsb3dlZGAgb3IgYW4gYGFjY2Vzc0RlbmllZGAgZXZlbnRcbiAgICAgKi9cbiAgICBpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLCBwYXJhbTI/LCBwYXJhbTM/KTogUHVibGlzaGVyIHtcbiAgICAgICAgbGV0IHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG5cbiAgICAgICAgaWYgKCEhcGFyYW0yICYmIHR5cGVvZiBwYXJhbTIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIC8vIE1hdGNoZXMgJ2luaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcyknIG9yICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMsIGNvbXBsZXRpb25IYW5kbGVyKSdcblxuICAgICAgICAgICAgcHJvcGVydGllcyA9IDxQdWJsaXNoZXJQcm9wZXJ0aWVzPnBhcmFtMjtcblxuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpb1NvdXJjZTogdHlwZW9mIHByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09ICd1bmRlZmluZWQnID8gcHJvcGVydGllcy5hdWRpb1NvdXJjZSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBmcmFtZVJhdGU6XG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFja1xuICAgICAgICAgICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwZW9mIHByb3BlcnRpZXMuZnJhbWVSYXRlICE9PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gcHJvcGVydGllcy5mcmFtZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOlxuICAgICAgICAgICAgICAgICAgICB0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlICE9PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgPyB0eXBlb2YgcHJvcGVydGllcy5pbnNlcnRNb2RlID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gVmlkZW9JbnNlcnRNb2RlW3Byb3BlcnRpZXMuaW5zZXJ0TW9kZV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHByb3BlcnRpZXMuaW5zZXJ0TW9kZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIG1pcnJvcjogdHlwZW9mIHByb3BlcnRpZXMubWlycm9yICE9PSAndW5kZWZpbmVkJyA/IHByb3BlcnRpZXMubWlycm9yIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBwdWJsaXNoQXVkaW86IHR5cGVvZiBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyAhPT0gJ3VuZGVmaW5lZCcgPyBwcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbyA6IHRydWUsXG4gICAgICAgICAgICAgICAgcHVibGlzaFZpZGVvOiB0eXBlb2YgcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gIT09ICd1bmRlZmluZWQnID8gcHJvcGVydGllcy5wdWJsaXNoVmlkZW8gOiB0cnVlLFxuICAgICAgICAgICAgICAgIHJlc29sdXRpb246XG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFja1xuICAgICAgICAgICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwZW9mIHByb3BlcnRpZXMucmVzb2x1dGlvbiAhPT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHByb3BlcnRpZXMucmVzb2x1dGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJzY0MHg0ODAnLFxuICAgICAgICAgICAgICAgIHZpZGVvU291cmNlOiB0eXBlb2YgcHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gJ3VuZGVmaW5lZCcgPyBwcm9wZXJ0aWVzLnZpZGVvU291cmNlIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIHZpZGVvU2ltdWxjYXN0OiBwcm9wZXJ0aWVzLnZpZGVvU2ltdWxjYXN0LFxuICAgICAgICAgICAgICAgIGZpbHRlcjogcHJvcGVydGllcy5maWx0ZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBNYXRjaGVzICdpbml0UHVibGlzaGVyKHRhcmdldEVsZW1lbnQpJyBvciAnaW5pdFB1Ymxpc2hlcih0YXJnZXRFbGVtZW50LCBjb21wbGV0aW9uSGFuZGxlciknXG5cbiAgICAgICAgICAgIHByb3BlcnRpZXMgPSB7XG4gICAgICAgICAgICAgICAgaW5zZXJ0TW9kZTogVmlkZW9JbnNlcnRNb2RlLkFQUEVORCxcbiAgICAgICAgICAgICAgICBtaXJyb3I6IHRydWUsXG4gICAgICAgICAgICAgICAgcHVibGlzaEF1ZGlvOiB0cnVlLFxuICAgICAgICAgICAgICAgIHB1Ymxpc2hWaWRlbzogdHJ1ZSxcbiAgICAgICAgICAgICAgICByZXNvbHV0aW9uOiAnNjQweDQ4MCdcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwdWJsaXNoZXI6IFB1Ymxpc2hlciA9IG5ldyBQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgdGhpcyk7XG5cbiAgICAgICAgbGV0IGNvbXBsZXRpb25IYW5kbGVyOiAoZXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkKSA9PiB2b2lkO1xuICAgICAgICBpZiAoISFwYXJhbTIgJiYgdHlwZW9mIHBhcmFtMiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTI7XG4gICAgICAgIH0gZWxzZSBpZiAoISFwYXJhbTMpIHtcbiAgICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW0zO1xuICAgICAgICB9XG5cbiAgICAgICAgcHVibGlzaGVyXG4gICAgICAgICAgICAuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIodW5kZWZpbmVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnYWNjZXNzQWxsb3dlZCcsIFtdKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdhY2Nlc3NEZW5pZWQnLCBbZXJyb3JdKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucHVibGlzaGVycy5wdXNoKHB1Ymxpc2hlcik7XG4gICAgICAgIHJldHVybiBwdWJsaXNoZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvbWlzaWZpZWQgdmVyc2lvbiBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqXG4gICAgICogPiBXQVJOSU5HOiBldmVudHMgYGFjY2Vzc0RpYWxvZ09wZW5lZGAgYW5kIGBhY2Nlc3NEaWFsb2dDbG9zZWRgIHdpbGwgbm90IGJlIGRpc3BhdGNoZWQgaWYgdXNpbmcgdGhpcyBtZXRob2QgaW5zdGVhZCBvZiBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXVxuICAgICAqL1xuICAgIGluaXRQdWJsaXNoZXJBc3luYyh0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCk6IFByb21pc2U8UHVibGlzaGVyPjtcbiAgICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQsIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQcm9taXNlPFB1Ymxpc2hlcj47XG5cbiAgICBpbml0UHVibGlzaGVyQXN5bmModGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQsIHByb3BlcnRpZXM/OiBQdWJsaXNoZXJQcm9wZXJ0aWVzKTogUHJvbWlzZTxQdWJsaXNoZXI+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPFB1Ymxpc2hlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbGV0IHB1Ymxpc2hlcjogUHVibGlzaGVyO1xuXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShwdWJsaXNoZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICghIXByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIgPSB0aGlzLmluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgcHJvcGVydGllcywgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIgPSB0aGlzLmluaXRQdWJsaXNoZXIodGFyZ2V0RWxlbWVudCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgbmV3IGxvY2FsIHJlY29yZGVyIGZvciByZWNvcmRpbmcgc3RyZWFtcyBzdHJhaWdodCBhd2F5IGZyb20gdGhlIGJyb3dzZXJcbiAgICAgKiBAcGFyYW0gc3RyZWFtICBTdHJlYW0gdG8gcmVjb3JkXG4gICAgICovXG4gICAgaW5pdExvY2FsUmVjb3JkZXIoc3RyZWFtOiBTdHJlYW0pOiBMb2NhbFJlY29yZGVyIHtcbiAgICAgICAgcmV0dXJuIG5ldyBMb2NhbFJlY29yZGVyKHN0cmVhbSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIHRoZSBicm93c2VyIHN1cHBvcnRzIE9wZW5WaWR1XG4gICAgICogQHJldHVybnMgMSBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBPcGVuVmlkdSwgMCBvdGhlcndpc2VcbiAgICAgKi9cbiAgICBjaGVja1N5c3RlbVJlcXVpcmVtZW50cygpOiBib29sZWFuIHtcbiAgICAgICAgLy8gU3BlY2lmaWMgaU9TIHBsYXRmb3JtIHN1cHBvcnQgKGlQaG9uZSwgaVBhZClcbiAgICAgICAgaWYgKHBsYXRmb3JtLmlzSVBob25lT3JJUGFkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNJT1NXaXRoU2FmYXJpKCkgfHxcbiAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0Nocm9tZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzRmlyZWZveE1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzT3BlcmFNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0VkZ2VNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0lvbmljSW9zKCkgLy8gSW9uaWMgYXBwcyBmb3IgaU9TXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2VuZXJhbCBwbGF0Zm9ybSBzdXBwb3J0IGZvciB3ZWIgY2xpZW50cyAoRGVza3RvcCwgTW9iaWxlKVxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNDaHJvbWVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzQ2hyb21lTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0ZpcmVmb3hCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzRmlyZWZveE1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNPcGVyYUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNPcGVyYU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNFZGdlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0VkZ2VNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzU2Ftc3VuZ0Jyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNTYWZhcmlCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzQW5kcm9pZEJyb3dzZXIoKSB8fCAvLyBBbmRyb2lkIFdlYlZpZXcgJiBJb25pYyBhcHBzIGZvciBBbmRyb2lkXG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0VsZWN0cm9uKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzTm9kZUpzKClcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgdGhlIGJyb3dzZXIgc3VwcG9ydHMgc2NyZWVuLXNoYXJpbmcuIERlc2t0b3AgQ2hyb21lLCBGaXJlZm94IGFuZCBPcGVyYSBzdXBwb3J0IHNjcmVlbi1zaGFyaW5nXG4gICAgICogQHJldHVybnMgMSBpZiB0aGUgYnJvd3NlciBzdXBwb3J0cyBzY3JlZW4tc2hhcmluZywgMCBvdGhlcndpc2VcbiAgICAgKi9cbiAgICBjaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5jYW5TY3JlZW5TaGFyZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbGxlY3RzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtZWRpYSBpbnB1dCBkZXZpY2VzIGF2YWlsYWJsZSBvbiB0aGUgc3lzdGVtLiBZb3UgY2FuIHBhc3MgcHJvcGVydHkgYGRldmljZUlkYCBvZiBhIFtbRGV2aWNlXV0gb2JqZWN0IGFzIHZhbHVlIG9mIGBhdWRpb1NvdXJjZWAgb3IgYHZpZGVvU291cmNlYCBwcm9wZXJ0aWVzIGluIFtbaW5pdFB1Ymxpc2hlcl1dIG1ldGhvZFxuICAgICAqL1xuICAgIGdldERldmljZXMoKTogUHJvbWlzZTxEZXZpY2VbXT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8RGV2aWNlW10+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXNcbiAgICAgICAgICAgICAgICAuZW51bWVyYXRlRGV2aWNlcygpXG4gICAgICAgICAgICAgICAgLnRoZW4oKGRldmljZUluZm9zKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRldmljZXM6IERldmljZVtdID0gW107XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gSW9uaWMgQW5kcm9pZCAgZGV2aWNlc1xuICAgICAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm0uaXNJb25pY0FuZHJvaWQoKSAmJiB0eXBlb2YgY29yZG92YSAhPSAndW5kZWZpbmVkJyAmJiBjb3Jkb3ZhPy5wbHVnaW5zPy5FbnVtZXJhdGVEZXZpY2VzUGx1Z2luKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb3Jkb3ZhLnBsdWdpbnMuRW51bWVyYXRlRGV2aWNlc1BsdWdpbi5nZXRFbnVtZXJhdGVEZXZpY2VzKCkudGhlbigocGx1Z2luRGV2aWNlczogRGV2aWNlW10pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcGx1Z2luQXVkaW9EZXZpY2VzOiBEZXZpY2VbXSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCB2aWRlb0RldmljZXM6IERldmljZVtdID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGF1ZGlvRGV2aWNlczogRGV2aWNlW10gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbHVnaW5BdWRpb0RldmljZXMgPSBwbHVnaW5EZXZpY2VzLmZpbHRlcigoZGV2aWNlOiBEZXZpY2UpID0+IGRldmljZS5raW5kID09PSAnYXVkaW9pbnB1dCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvRGV2aWNlcyA9IGRldmljZUluZm9zLmZpbHRlcigoZGV2aWNlOiBNZWRpYURldmljZUluZm8pID0+IGRldmljZS5raW5kID09PSAndmlkZW9pbnB1dCcpIGFzIGFueTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpb0RldmljZXMgPSBkZXZpY2VJbmZvcy5maWx0ZXIoKGRldmljZTogTWVkaWFEZXZpY2VJbmZvKSA9PiBkZXZpY2Uua2luZCA9PT0gJ2F1ZGlvaW5wdXQnKSBhcyBhbnk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW9EZXZpY2VzLmZvckVhY2goKGRldmljZUluZm8sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZGV2aWNlSW5mby5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGxhYmVsID0gJyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdGcm9udCBDYW1lcmEnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbmRleCA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gJ0JhY2sgQ2FtZXJhJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAnVW5rbm93biBDYW1lcmEnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBraW5kOiBkZXZpY2VJbmZvLmtpbmQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSWQ6IGRldmljZUluZm8uZGV2aWNlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGxhYmVsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBkZXZpY2VJbmZvLmxhYmVsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvRGV2aWNlcy5mb3JFYWNoKChkZXZpY2VJbmZvLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWRldmljZUluZm8ubGFiZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBsYWJlbCA9ICcnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMDogLy8gRGVmYXVsdCBNaWNyb3Bob25lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gJ0RlZmF1bHQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6IC8vIE1pY3JvcGhvbmUgKyBTcGVha2VycGhvbmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVmYXVsdE1hdGNoID0gcGx1Z2luQXVkaW9EZXZpY2VzLmZpbHRlcigoZCkgPT4gZC5sYWJlbC5pbmNsdWRlcygnQnVpbHQnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gZGVmYXVsdE1hdGNoID8gZGVmYXVsdE1hdGNoLmxhYmVsIDogJ0J1aWx0LWluIE1pY3JvcGhvbmUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IC8vIEhlYWRzZXQgTWljcm9waG9uZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB3aXJlZE1hdGNoID0gcGx1Z2luQXVkaW9EZXZpY2VzLmZpbHRlcigoZCkgPT4gZC5sYWJlbC5pbmNsdWRlcygnV2lyZWQnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3aXJlZE1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHdpcmVkTWF0Y2gubGFiZWw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdIZWFkc2V0IGVhcnBpZWNlJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHdpcmVsZXNzTWF0Y2ggPSBwbHVnaW5BdWRpb0RldmljZXMuZmlsdGVyKChkKSA9PiBkLmxhYmVsLmluY2x1ZGVzKCdCbHVldG9vdGgnKSlbMF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gd2lyZWxlc3NNYXRjaCA/IHdpcmVsZXNzTWF0Y2gubGFiZWwgOiAnV2lyZWxlc3MnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICdVbmtub3duIE1pY3JvcGhvbmUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2luZDogZGV2aWNlSW5mby5raW5kLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBsYWJlbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VJZDogZGV2aWNlSW5mby5kZXZpY2VJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogZGV2aWNlSW5mby5sYWJlbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShkZXZpY2VzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzdCBvZiBwbGF0Zm9ybXNcbiAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZUluZm9zLmZvckVhY2goKGRldmljZUluZm8pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGV2aWNlSW5mby5raW5kID09PSAnYXVkaW9pbnB1dCcgfHwgZGV2aWNlSW5mby5raW5kID09PSAndmlkZW9pbnB1dCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQ6IGRldmljZUluZm8ua2luZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZUlkOiBkZXZpY2VJbmZvLmRldmljZUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGRldmljZUluZm8ubGFiZWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShkZXZpY2VzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGdldHRpbmcgZGV2aWNlcycsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBhIE1lZGlhU3RyZWFtIG9iamVjdCB0aGF0IHlvdSBjYW4gY3VzdG9taXplIGJlZm9yZSBjYWxsaW5nIFtbaW5pdFB1Ymxpc2hlcl1dIChwYXNzIF9NZWRpYVN0cmVhbVRyYWNrXyBwcm9wZXJ0eSBvZiB0aGUgX01lZGlhU3RyZWFtXyB2YWx1ZSByZXNvbHZlZCBieSB0aGUgUHJvbWlzZSBhcyBgYXVkaW9Tb3VyY2VgIG9yIGB2aWRlb1NvdXJjZWAgcHJvcGVydGllcyBpbiBbW2luaXRQdWJsaXNoZXJdXSlcbiAgICAgKlxuICAgICAqIFBhcmFtZXRlciBgb3B0aW9uc2AgaXMgdGhlIHNhbWUgYXMgaW4gW1tpbml0UHVibGlzaGVyXV0gc2Vjb25kIHBhcmFtZXRlciAob2YgdHlwZSBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSksIGJ1dCBvbmx5IHRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyB3aWxsIGJlIGFwcGxpZWQ6IGBhdWRpb1NvdXJjZWAsIGB2aWRlb1NvdXJjZWAsIGBmcmFtZVJhdGVgLCBgcmVzb2x1dGlvbmBcbiAgICAgKlxuICAgICAqIFRvIGN1c3RvbWl6ZSB0aGUgUHVibGlzaGVyJ3MgdmlkZW8sIHRoZSBBUEkgZm9yIEhUTUxDYW52YXNFbGVtZW50IGlzIHZlcnkgdXNlZnVsLiBGb3IgZXhhbXBsZSwgdG8gZ2V0IGEgYmxhY2stYW5kLXdoaXRlIHZpZGVvIGF0IDEwIGZwcyBhbmQgSEQgcmVzb2x1dGlvbiB3aXRoIG5vIHNvdW5kOlxuICAgICAqIGBgYFxuICAgICAqIHZhciBPViA9IG5ldyBPcGVuVmlkdSgpO1xuICAgICAqIHZhciBGUkFNRV9SQVRFID0gMTA7XG4gICAgICpcbiAgICAgKiBPVi5nZXRVc2VyTWVkaWEoe1xuICAgICAqICAgIGF1ZGlvU291cmNlOiBmYWxzZSxcbiAgICAgKiAgICB2aWRlb1NvdXJjZTogdW5kZWZpbmVkLFxuICAgICAqICAgIHJlc29sdXRpb246ICcxMjgweDcyMCcsXG4gICAgICogICAgZnJhbWVSYXRlOiBGUkFNRV9SQVRFXG4gICAgICogfSlcbiAgICAgKiAudGhlbihtZWRpYVN0cmVhbSA9PiB7XG4gICAgICpcbiAgICAgKiAgICB2YXIgdmlkZW9UcmFjayA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAgICogICAgdmFyIHZpZGVvID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndmlkZW8nKTtcbiAgICAgKiAgICB2aWRlby5zcmNPYmplY3QgPSBuZXcgTWVkaWFTdHJlYW0oW3ZpZGVvVHJhY2tdKTtcbiAgICAgKlxuICAgICAqICAgIHZhciBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICAgKiAgICB2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICogICAgY3R4LmZpbHRlciA9ICdncmF5c2NhbGUoMTAwJSknO1xuICAgICAqXG4gICAgICogICAgdmlkZW8uYWRkRXZlbnRMaXN0ZW5lcigncGxheScsICgpID0+IHtcbiAgICAgKiAgICAgIHZhciBsb29wID0gKCkgPT4ge1xuICAgICAqICAgICAgICBpZiAoIXZpZGVvLnBhdXNlZCAmJiAhdmlkZW8uZW5kZWQpIHtcbiAgICAgKiAgICAgICAgICBjdHguZHJhd0ltYWdlKHZpZGVvLCAwLCAwLCAzMDAsIDE3MCk7XG4gICAgICogICAgICAgICAgc2V0VGltZW91dChsb29wLCAxMDAwLyBGUkFNRV9SQVRFKTsgLy8gRHJhd2luZyBhdCAxMCBmcHNcbiAgICAgKiAgICAgICAgfVxuICAgICAqICAgICAgfTtcbiAgICAgKiAgICAgIGxvb3AoKTtcbiAgICAgKiAgICB9KTtcbiAgICAgKiAgICB2aWRlby5wbGF5KCk7XG4gICAgICpcbiAgICAgKiAgICB2YXIgZ3JheVZpZGVvVHJhY2sgPSBjYW52YXMuY2FwdHVyZVN0cmVhbShGUkFNRV9SQVRFKS5nZXRWaWRlb1RyYWNrcygpWzBdO1xuICAgICAqICAgIHZhciBwdWJsaXNoZXIgPSB0aGlzLk9WLmluaXRQdWJsaXNoZXIoXG4gICAgICogICAgICBteUh0bWxUYXJnZXQsXG4gICAgICogICAgICB7XG4gICAgICogICAgICAgIGF1ZGlvU291cmNlOiBmYWxzZSxcbiAgICAgKiAgICAgICAgdmlkZW9Tb3VyY2U6IGdyYXlWaWRlb1RyYWNrXG4gICAgICogICAgICB9KTtcbiAgICAgKiB9KTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBnZXRVc2VyTWVkaWEob3B0aW9uczogUHVibGlzaGVyUHJvcGVydGllcyk6IFByb21pc2U8TWVkaWFTdHJlYW0+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPE1lZGlhU3RyZWFtPihhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhc2tGb3JBdWRpb1N0cmVhbU9ubHkgPSBhc3luYyAocHJldmlvdXNNZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGNvbnN0cmFpbnRzOiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCA9IGNvbnN0cmFpbnRzLmF1ZGlvID09PSB1bmRlZmluZWQgPyB0cnVlIDogY29uc3RyYWludHMuYXVkaW87XG4gICAgICAgICAgICAgICAgY29uc3QgY29uc3RyYWludHNBdXg6IE1lZGlhU3RyZWFtQ29uc3RyYWludHMgPSB7IGF1ZGlvOiBkZWZpbmVkQXVkaW9Db25zdHJhaW50LCB2aWRlbzogZmFsc2UgfTtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhdWRpb09ubHlTdHJlYW0gPSBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eCk7XG4gICAgICAgICAgICAgICAgICAgIHByZXZpb3VzTWVkaWFTdHJlYW0uYWRkVHJhY2soYXVkaW9Pbmx5U3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShwcmV2aW91c01lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBwcmV2aW91c01lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHByZXZpb3VzTWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCh0aGlzLmdlbmVyYXRlQXVkaW9EZXZpY2VFcnJvcihlcnJvciwgY29uc3RyYWludHNBdXgpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG15Q29uc3RyYWludHMgPSBhd2FpdCB0aGlzLmdlbmVyYXRlTWVkaWFDb25zdHJhaW50cyhvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICghIW15Q29uc3RyYWludHMudmlkZW9UcmFjayAmJiAhIW15Q29uc3RyYWludHMuYXVkaW9UcmFjaykgfHxcbiAgICAgICAgICAgICAgICAgICAgKCEhbXlDb25zdHJhaW50cy5hdWRpb1RyYWNrICYmIG15Q29uc3RyYWludHMuY29uc3RyYWludHM/LnZpZGVvID09PSBmYWxzZSkgfHxcbiAgICAgICAgICAgICAgICAgICAgKCEhbXlDb25zdHJhaW50cy52aWRlb1RyYWNrICYmIG15Q29uc3RyYWludHMuY29uc3RyYWludHM/LmF1ZGlvID09PSBmYWxzZSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTm8gbmVlZCB0byBjYWxsIGdldFVzZXJNZWRpYSBhdCBhbGwuIEJvdGggdHJhY2tzIHByb3ZpZGVkLCBvciBvbmx5IEFVRElPIHRyYWNrIHByb3ZpZGVkIG9yIG9ubHkgVklERU8gdHJhY2sgcHJvdmlkZWRcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUodGhpcy5hZGRBbHJlYWR5UHJvdmlkZWRUcmFja3MobXlDb25zdHJhaW50cywgbmV3IE1lZGlhU3RyZWFtKCkpKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBnZXRVc2VyTWVkaWEgbXVzdCBiZSBjYWxsZWQuIEFVRElPIG9yIFZJREVPIGFyZSByZXF1ZXN0aW5nIGEgbmV3IHRyYWNrXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRlIGFscmVhZHkgcHJvdmlkZWQgY29uc3RyYWludHMgZm9yIGF1ZGlvIG9yIHZpZGVvXG4gICAgICAgICAgICAgICAgICAgIGlmICghIW15Q29uc3RyYWludHMudmlkZW9UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIG15Q29uc3RyYWludHMuY29uc3RyYWludHMhLnZpZGVvO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghIW15Q29uc3RyYWludHMuYXVkaW9UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIG15Q29uc3RyYWludHMuY29uc3RyYWludHMhLmF1ZGlvO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IG11c3RBc2tGb3JBdWRpb1RyYWNrTGF0ZXIgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnZpZGVvU291cmNlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmlkZW8gaXMgZGV2aWNlSWQgb3Igc2NyZWVuIHNoYXJpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnZpZGVvU291cmNlID09PSAnc2NyZWVuJyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICd3aW5kb3cnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBsYXRmb3JtLmlzRWxlY3Ryb24oKSAmJiBvcHRpb25zLnZpZGVvU291cmNlLnN0YXJ0c1dpdGgoJ3NjcmVlbjonKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFZpZGVvIGlzIHNjcmVlbiBzaGFyaW5nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXVzdEFza0ZvckF1ZGlvVHJhY2tMYXRlciA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFteUNvbnN0cmFpbnRzLmF1ZGlvVHJhY2sgJiYgb3B0aW9ucy5hdWRpb1NvdXJjZSAhPT0gbnVsbCAmJiBvcHRpb25zLmF1ZGlvU291cmNlICE9PSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10gJiYgIXBsYXRmb3JtLmlzRWxlY3Ryb24oKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXREaXNwbGF5TWVkaWEgc3VwcG9ydGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZWRpYVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKHsgdmlkZW86IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZEFscmVhZHlQcm92aWRlZFRyYWNrcyhteUNvbnN0cmFpbnRzLCBtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobXVzdEFza0ZvckF1ZGlvVHJhY2tMYXRlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IGFza0ZvckF1ZGlvU3RyZWFtT25seShtZWRpYVN0cmVhbSwgPE1lZGlhU3RyZWFtQ29uc3RyYWludHM+bXlDb25zdHJhaW50cy5jb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lOiBPcGVuVmlkdUVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXREaXNwbGF5TWVkaWEgTk9UIHN1cHBvcnRlZC4gQ2FuIHBlcmZvcm0gZ2V0VXNlck1lZGlhIGJlbG93IHdpdGggYWxyZWFkeSBjYWxjdWxhdGVkIGNvbnN0cmFpbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWaWRlbyBpcyBkZXZpY2VJZC4gQ2FuIHBlcmZvcm0gZ2V0VXNlck1lZGlhIGJlbG93IHdpdGggYWxyZWFkeSBjYWxjdWxhdGVkIGNvbnN0cmFpbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gVXNlIGFscmVhZHkgY2FsY3VsYXRlZCBjb25zdHJhaW50c1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25zdHJhaW50c0F1eCA9IG11c3RBc2tGb3JBdWRpb1RyYWNrTGF0ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgID8geyB2aWRlbzogbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8gfVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzO1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW0gPSBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50c0F1eCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZEFscmVhZHlQcm92aWRlZFRyYWNrcyhteUNvbnN0cmFpbnRzLCBtZWRpYVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobXVzdEFza0ZvckF1ZGlvVHJhY2tMYXRlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IGFza0ZvckF1ZGlvU3RyZWFtT25seShtZWRpYVN0cmVhbSwgPE1lZGlhU3RyZWFtQ29uc3RyYWludHM+bXlDb25zdHJhaW50cy5jb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBlcnJvck5hbWU6IE9wZW5WaWR1RXJyb3JOYW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKG9wdGlvbnMudmlkZW9Tb3VyY2UgPT09ICdzY3JlZW4nKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qIHRzbGludDpkaXNhYmxlOm5vLWVtcHR5ICovXG4gICAgLyoqXG4gICAgICogRGlzYWJsZSBhbGwgbG9nZ2luZyBleGNlcHQgZXJyb3IgbGV2ZWxcbiAgICAgKi9cbiAgICBlbmFibGVQcm9kTW9kZSgpOiB2b2lkIHtcbiAgICAgICAgbG9nZ2VyLmVuYWJsZVByb2RNb2RlKCk7XG4gICAgfVxuICAgIC8qIHRzbGludDplbmFibGU6bm8tZW1wdHkgKi9cblxuICAgIC8qKlxuICAgICAqIFNldCBPcGVuVmlkdSBhZHZhbmNlZCBjb25maWd1cmF0aW9uIG9wdGlvbnMuIGBjb25maWd1cmF0aW9uYCBpcyBhbiBvYmplY3Qgb2YgdHlwZSBbW09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uXV0uIENhbGwgdGhpcyBtZXRob2QgdG8gb3ZlcnJpZGUgcHJldmlvdXMgdmFsdWVzIGF0IGFueSBtb21lbnQuXG4gICAgICovXG4gICAgc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uKGNvbmZpZ3VyYXRpb246IE9wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uKTogdm9pZCB7XG4gICAgICAgIHRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvbjtcbiAgICB9XG5cbiAgICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uT3JpZW50YXRpb25DaGFuZ2VkKGhhbmRsZXIpOiB2b2lkIHtcbiAgICAgICAgKGdsb2JhbFRoaXMgYXMgYW55KS5hZGRFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsIGhhbmRsZXIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZW5kTmV3VmlkZW9EaW1lbnNpb25zSWZSZXF1aXJlZChwdWJsaXNoZXI6IFB1Ymxpc2hlciwgcmVhc29uOiBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudFJlYXNvbiwgV0FJVF9JTlRFUlZBTDogbnVtYmVyLCBNQVhfQVRURU1QVFM6IG51bWJlcikge1xuICAgICAgICBsZXQgYXR0ZW1wdHMgPSAwO1xuICAgICAgICBjb25zdCBvbGRXaWR0aCA9IHB1Ymxpc2hlcj8uc3RyZWFtPy52aWRlb0RpbWVuc2lvbnM/LndpZHRoIHx8IDA7XG4gICAgICAgIGNvbnN0IG9sZEhlaWdodCA9IHB1Ymxpc2hlcj8uc3RyZWFtPy52aWRlb0RpbWVuc2lvbnM/LmhlaWdodCB8fCAwO1xuXG4gICAgICAgIGNvbnN0IHJlcGVhdFVudGlsQ2hhbmdlT3JNYXhBdHRlbXB0czogTm9kZUpTLlRpbWVvdXQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICBhdHRlbXB0cysrO1xuICAgICAgICAgICAgaWYgKGF0dGVtcHRzID4gTUFYX0FUVEVNUFRTKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlcGVhdFVudGlsQ2hhbmdlT3JNYXhBdHRlbXB0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwdWJsaXNoZXIuZ2V0VmlkZW9EaW1lbnNpb25zKCkudGhlbigobmV3RGltZW5zaW9ucykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChuZXdEaW1lbnNpb25zLndpZHRoICE9PSBvbGRXaWR0aCB8fCBuZXdEaW1lbnNpb25zLmhlaWdodCAhPT0gb2xkSGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXBlYXRVbnRpbENoYW5nZU9yTWF4QXR0ZW1wdHMpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmRWaWRlb0RpbWVuc2lvbnNDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCByZWFzb24sIG9sZFdpZHRoLCBvbGRIZWlnaHQsIG5ld0RpbWVuc2lvbnMud2lkdGgsIG5ld0RpbWVuc2lvbnMuaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgV0FJVF9JTlRFUlZBTCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlbmRWaWRlb0RpbWVuc2lvbnNDaGFuZ2VkRXZlbnQoXG4gICAgICAgIHB1Ymxpc2hlcjogUHVibGlzaGVyLFxuICAgICAgICByZWFzb246IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50UmVhc29uLFxuICAgICAgICBvbGRXaWR0aDogbnVtYmVyLFxuICAgICAgICBvbGRIZWlnaHQ6IG51bWJlcixcbiAgICAgICAgbmV3V2lkdGg6IG51bWJlcixcbiAgICAgICAgbmV3SGVpZ2h0OiBudW1iZXJcbiAgICApIHtcbiAgICAgICAgcHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICB3aWR0aDogbmV3V2lkdGggfHwgMCxcbiAgICAgICAgICAgIGhlaWdodDogbmV3SGVpZ2h0IHx8IDBcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHN0cmVhbUlkOiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgIHByb3BlcnR5OiAndmlkZW9EaW1lbnNpb25zJyxcbiAgICAgICAgICAgICAgICBuZXdWYWx1ZTogSlNPTi5zdHJpbmdpZnkocHVibGlzaGVyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMpLFxuICAgICAgICAgICAgICAgIHJlYXNvblxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuc3RyZWFtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgd2lkdGg6IG9sZFdpZHRoLCBoZWlnaHQ6IG9sZEhlaWdodCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvblxuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgcHVibGlzaGVyLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuc3RyZWFtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2aWRlb0RpbWVuc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW0udmlkZW9EaW1lbnNpb25zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgd2lkdGg6IG9sZFdpZHRoLCBoZWlnaHQ6IG9sZEhlaWdodCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvblxuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLnNlbmRWaWRlb0RhdGEocHVibGlzaGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlbmRUcmFja0NoYW5nZWRFdmVudChwdWJsaXNoZXI6IFB1Ymxpc2hlciwgb2xkTGFiZWw6IHN0cmluZywgbmV3TGFiZWw6IHN0cmluZywgcHJvcGVydHlUeXBlOiBDaGFuZ2VkUHJvcGVydHlUeXBlKSB7XG4gICAgICAgIGNvbnN0IG9sZFZhbHVlID0geyBsYWJlbDogb2xkTGFiZWwgfTtcbiAgICAgICAgY29uc3QgbmV3VmFsdWUgPSB7IGxhYmVsOiBuZXdMYWJlbCB9O1xuICAgICAgICBjb25zdCByZWFzb24gPSAndHJhY2tSZXBsYWNlZCc7XG5cbiAgICAgICAgaWYgKHB1Ymxpc2hlci5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCkge1xuICAgICAgICAgICAgdGhpcy5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiBwdWJsaXNoZXIuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogcHJvcGVydHlUeXBlLFxuICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogbmV3VmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHJlYXNvblxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcIkVycm9yIHNlbmRpbmcgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIiwgZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHB1Ymxpc2hlci5zdHJlYW0sIHByb3BlcnR5VHlwZSwgbmV3VmFsdWUsIG9sZFZhbHVlLCByZWFzb24pXG4gICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCBwdWJsaXNoZXIuc3RyZWFtLCBwcm9wZXJ0eVR5cGUsIG5ld1ZhbHVlLCBvbGRWYWx1ZSwgcmVhc29uKVxuICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHB1Ymxpc2hlci5zdHJlYW0sIHByb3BlcnR5VHlwZSwgbmV3VmFsdWUsIG9sZFZhbHVlLCByZWFzb24pXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIHB1Ymxpc2hlci5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQocHVibGlzaGVyLCBwdWJsaXNoZXIuc3RyZWFtLCBwcm9wZXJ0eVR5cGUsIG5ld1ZhbHVlLCBvbGRWYWx1ZSwgcmVhc29uKVxuICAgICAgICAgICAgXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2VuZXJhdGVNZWRpYUNvbnN0cmFpbnRzKHB1Ymxpc2hlclByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXMpOiBQcm9taXNlPEN1c3RvbU1lZGlhU3RyZWFtQ29uc3RyYWludHM+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPEN1c3RvbU1lZGlhU3RyZWFtQ29uc3RyYWludHM+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG15Q29uc3RyYWludHM6IEN1c3RvbU1lZGlhU3RyZWFtQ29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW9UcmFjazogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIHZpZGVvVHJhY2s6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBjb25zdHJhaW50czoge1xuICAgICAgICAgICAgICAgICAgICBhdWRpbzogdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICB2aWRlbzogdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvU291cmNlID0gcHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZTtcbiAgICAgICAgICAgIGNvbnN0IHZpZGVvU291cmNlID0gcHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZTtcblxuICAgICAgICAgICAgLy8gQ0FTRSAxOiBudWxsL2ZhbHNlXG4gICAgICAgICAgICBpZiAoYXVkaW9Tb3VyY2UgPT09IG51bGwgfHwgYXVkaW9Tb3VyY2UgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgLy8gTm8gYXVkaW8gdHJhY2tcbiAgICAgICAgICAgICAgICBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS5hdWRpbyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZpZGVvU291cmNlID09PSBudWxsIHx8IHZpZGVvU291cmNlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIC8vIE5vIHZpZGVvIHRyYWNrXG4gICAgICAgICAgICAgICAgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS5hdWRpbyA9PT0gZmFsc2UgJiYgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8gPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgLy8gRVJST1IhIGF1ZGlvU291cmNlIGFuZCB2aWRlb1NvdXJjZSBjYW5ub3QgYmUgYm90aCBmYWxzZSBhdCB0aGUgc2FtZSB0aW1lXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5OT19JTlBVVF9TT1VSQ0VfU0VULFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJQcm9wZXJ0aWVzICdhdWRpb1NvdXJjZScgYW5kICd2aWRlb1NvdXJjZScgY2Fubm90IGJlIHNldCB0byBmYWxzZSBvciBudWxsIGF0IHRoZSBzYW1lIHRpbWVcIlxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ0FTRSAyOiBNZWRpYVN0cmVhbVRyYWNrc1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJiBhdWRpb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAvLyBBbHJlYWR5IHByb3ZpZGVkIGF1ZGlvIHRyYWNrXG4gICAgICAgICAgICAgICAgbXlDb25zdHJhaW50cy5hdWRpb1RyYWNrID0gYXVkaW9Tb3VyY2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgIC8vIEFscmVhZHkgcHJvdmlkZWQgdmlkZW8gdHJhY2tcbiAgICAgICAgICAgICAgICBteUNvbnN0cmFpbnRzLnZpZGVvVHJhY2sgPSB2aWRlb1NvdXJjZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ0FTRSAzOiBEZWZhdWx0IHRyYWNrc1xuICAgICAgICAgICAgaWYgKGF1ZGlvU291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS5hdWRpbyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmlkZW9Tb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG15Q29uc3RyYWludHMuY29uc3RyYWludHMhLnZpZGVvID0ge1xuICAgICAgICAgICAgICAgICAgICB3aWR0aDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWRlYWw6IDY0MFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlkZWFsOiA0ODBcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENBU0UgMy41OiBnaXZlIHZhbHVlcyB0byByZXNvbHV0aW9uIGFuZCBmcmFtZVJhdGUgaWYgdmlkZW8gbm90IG51bGwvZmFsc2VcbiAgICAgICAgICAgIGlmICh2aWRlb1NvdXJjZSAhPT0gbnVsbCAmJiB2aWRlb1NvdXJjZSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBpZiAoISFwdWJsaXNoZXJQcm9wZXJ0aWVzLnJlc29sdXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2lkdGhBbmRIZWlnaHQgPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLnJlc29sdXRpb24udG9Mb3dlckNhc2UoKS5zcGxpdCgneCcpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZGVhbFdpZHRoID0gTnVtYmVyKHdpZHRoQW5kSGVpZ2h0WzBdKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaWRlYWxIZWlnaHQgPSBOdW1iZXIod2lkdGhBbmRIZWlnaHRbMV0pO1xuICAgICAgICAgICAgICAgICAgICBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS52aWRlbyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlYWw6IGlkZWFsV2lkdGhcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVhbDogaWRlYWxIZWlnaHRcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCEhcHVibGlzaGVyUHJvcGVydGllcy5mcmFtZVJhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgKDxNZWRpYVRyYWNrQ29uc3RyYWludHM+bXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8pLmZyYW1lUmF0ZSA9IHsgaWRlYWw6IHB1Ymxpc2hlclByb3BlcnRpZXMuZnJhbWVSYXRlIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDQVNFIDQ6IGRldmljZUlkIG9yIHNjcmVlbiBzaGFyaW5nXG4gICAgICAgICAgICB0aGlzLmNvbmZpZ3VyZURldmljZUlkT3JTY3JlZW5zaGFyaW5nKG15Q29uc3RyYWludHMsIHB1Ymxpc2hlclByb3BlcnRpZXMsIHJlc29sdmUsIHJlamVjdCk7XG5cbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG15Q29uc3RyYWludHMpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3RhcnRXcyhvbkNvbm5lY3RTdWNjZXM6IChlcnJvcjogRXJyb3IpID0+IHZvaWQpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY29uZmlnID0ge1xuICAgICAgICAgICAgaGVhcnRiZWF0OiA1MDAwLFxuICAgICAgICAgICAgd3M6IHtcbiAgICAgICAgICAgICAgICB1cmk6IHRoaXMud3NVcmkgKyAnP3Nlc3Npb25JZD0nICsgdGhpcy5zZXNzaW9uLnNlc3Npb25JZCxcbiAgICAgICAgICAgICAgICBvbmNvbm5lY3RlZDogb25Db25uZWN0U3VjY2VzLFxuICAgICAgICAgICAgICAgIG9uZGlzY29ubmVjdDogdGhpcy5kaXNjb25uZWN0Q2FsbGJhY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBvbnJlY29ubmVjdGluZzogdGhpcy5yZWNvbm5lY3RpbmdDYWxsYmFjay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIG9ucmVjb25uZWN0ZWQ6IHRoaXMucmVjb25uZWN0ZWRDYWxsYmFjay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIGlzbWFzdGVybm9kZWNyYXNoZWQ6IHRoaXMuaXNNYXN0ZXJOb2RlQ3Jhc2hlZC5iaW5kKHRoaXMpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcnBjOiB7XG4gICAgICAgICAgICAgICAgcmVxdWVzdFRpbWVvdXQ6IDEwMDAwLFxuICAgICAgICAgICAgICAgIGhlYXJ0YmVhdFJlcXVlc3RUaW1lb3V0OiA1MDAwLFxuICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50Sm9pbmVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEpvaW5lZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgcGFydGljaXBhbnRQdWJsaXNoZWQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50UHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudFVucHVibGlzaGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudFVucHVibGlzaGVkLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudExlZnQ6IHRoaXMuc2Vzc2lvbi5vblBhcnRpY2lwYW50TGVmdC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgcGFydGljaXBhbnRFdmljdGVkOiB0aGlzLnNlc3Npb24ub25QYXJ0aWNpcGFudEV2aWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIHJlY29yZGluZ1N0YXJ0ZWQ6IHRoaXMuc2Vzc2lvbi5vblJlY29yZGluZ1N0YXJ0ZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIHJlY29yZGluZ1N0b3BwZWQ6IHRoaXMuc2Vzc2lvbi5vblJlY29yZGluZ1N0b3BwZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIHNlbmRNZXNzYWdlOiB0aGlzLnNlc3Npb24ub25OZXdNZXNzYWdlLmJpbmQodGhpcy5zZXNzaW9uKSxcbiAgICAgICAgICAgICAgICBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQ6IHRoaXMuc2Vzc2lvbi5vblN0cmVhbVByb3BlcnR5Q2hhbmdlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZDogdGhpcy5zZXNzaW9uLm9uQ29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgbmV0d29ya1F1YWxpdHlMZXZlbENoYW5nZWQ6IHRoaXMuc2Vzc2lvbi5vbk5ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkQ2hhbmdlZC5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgZmlsdGVyRXZlbnREaXNwYXRjaGVkOiB0aGlzLnNlc3Npb24ub25GaWx0ZXJFdmVudERpc3BhdGNoZWQuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIGljZUNhbmRpZGF0ZTogdGhpcy5zZXNzaW9uLnJlY3ZJY2VDYW5kaWRhdGUuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIG1lZGlhRXJyb3I6IHRoaXMuc2Vzc2lvbi5vbk1lZGlhRXJyb3IuYmluZCh0aGlzLnNlc3Npb24pLFxuICAgICAgICAgICAgICAgIG1hc3Rlck5vZGVDcmFzaGVkTm90aWZpY2F0aW9uOiB0aGlzLm9uTWFzdGVyTm9kZUNyYXNoZWROb3RpZmljYXRpb24uYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBmb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXI6IHRoaXMuc2Vzc2lvbi5vbkZvcmNpYmx5UmVjb25uZWN0U3Vic2NyaWJlci5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgc3BlZWNoVG9UZXh0TWVzc2FnZTogdGhpcy5zZXNzaW9uLm9uU3BlZWNoVG9UZXh0TWVzc2FnZS5iaW5kKHRoaXMuc2Vzc2lvbiksXG4gICAgICAgICAgICAgICAgc3BlZWNoVG9UZXh0RGlzY29ubmVjdGVkOiB0aGlzLnNlc3Npb24ub25TcGVlY2hUb1RleHREaXNjb25uZWN0ZWQuYmluZCh0aGlzLnNlc3Npb24pXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuanNvblJwY0NsaWVudCA9IG5ldyBScGNCdWlsZGVyLmNsaWVudHMuSnNvblJwY0NsaWVudChjb25maWcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbk1hc3Rlck5vZGVDcmFzaGVkTm90aWZpY2F0aW9uKHJlc3BvbnNlKTogdm9pZCB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01hc3RlciBOb2RlIGhhcyBjcmFzaGVkJyk7XG4gICAgICAgIHRoaXMubWFzdGVyTm9kZUhhc0NyYXNoZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbignbm9kZUNyYXNoZWQnKTtcbiAgICAgICAgdGhpcy5qc29uUnBjQ2xpZW50LmNsb3NlKDQxMDMsICdNYXN0ZXIgTm9kZSBoYXMgY3Jhc2hlZCcpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRXc1JlYWR5U3RhdGUoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuanNvblJwY0NsaWVudC5nZXRSZWFkeVN0YXRlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNsb3NlV3MoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5jbG9zZSg0MTAyLCAnQ29ubmVjdGlvbiBjbG9zZWQgYnkgY2xpZW50Jyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlbmRSZXF1ZXN0KG1ldGhvZDogc3RyaW5nLCBwYXJhbXM6IGFueSwgY2FsbGJhY2s/KTogdm9pZCB7XG4gICAgICAgIGlmIChwYXJhbXMgJiYgcGFyYW1zIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gcGFyYW1zO1xuICAgICAgICAgICAgcGFyYW1zID0ge307XG4gICAgICAgIH1cbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdTZW5kaW5nIHJlcXVlc3Q6IHttZXRob2Q6XCInICsgbWV0aG9kICsgJ1wiLCBwYXJhbXM6ICcgKyBKU09OLnN0cmluZ2lmeShwYXJhbXMpICsgJ30nKTtcbiAgICAgICAgdGhpcy5qc29uUnBjQ2xpZW50Py5zZW5kKG1ldGhvZCwgcGFyYW1zLCBjYWxsYmFjayk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFdzVXJpKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB0aGlzLndzVXJpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRTZWNyZXQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VjcmV0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRSZWNvcmRlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVjb3JkZXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFN0dCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3R0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZW5lcmF0ZUF1ZGlvRGV2aWNlRXJyb3IoZXJyb3IsIGNvbnN0cmFpbnRzOiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzKTogT3BlblZpZHVFcnJvciB7XG4gICAgICAgIGlmIChlcnJvci5uYW1lID09PSAnRXJyb3InKSB7XG4gICAgICAgICAgICAvLyBTYWZhcmkgT3ZlckNvbnN0cmFpbmVkRXJyb3IgaGFzIGFzIG5hbWUgcHJvcGVydHkgJ0Vycm9yJyBpbnN0ZWFkIG9mICdPdmVyQ29uc3RyYWluZWRFcnJvcidcbiAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICB9XG4gICAgICAgIGxldCBlcnJvck5hbWUsIGVycm9yTWVzc2FnZTogc3RyaW5nO1xuICAgICAgICBzd2l0Y2ggKGVycm9yLm5hbWUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuSU5QVVRfQVVESU9fREVWSUNFX05PVF9GT1VORDtcbiAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSk7XG4gICAgICAgICAgICBjYXNlICdub3RhbGxvd2VkZXJyb3InOlxuICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BQ0NFU1NfREVOSUVEO1xuICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgICAgIGNhc2UgJ292ZXJjb25zdHJhaW5lZGVycm9yJzpcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29uc3RyYWludC50b0xvd2VyQ2FzZSgpID09PSAnZGV2aWNlaWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICBcIkF1ZGlvIGlucHV0IGRldmljZSB3aXRoIGRldmljZUlkICdcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAoPENvbnN0cmFpbkRPTVN0cmluZ1BhcmFtZXRlcnM+KDxNZWRpYVRyYWNrQ29uc3RyYWludHM+Y29uc3RyYWludHMuYXVkaW8pLmRldmljZUlkISEpLmV4YWN0ICtcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiJyBub3QgZm91bmRcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5QVUJMSVNIRVJfUFJPUEVSVElFU19FUlJPUjtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gXCJBdWRpbyBpbnB1dCBkZXZpY2UgZG9lc24ndCBzdXBwb3J0IHRoZSB2YWx1ZSBwYXNzZWQgZm9yIGNvbnN0cmFpbnQgJ1wiICsgZXJyb3IuY29uc3RyYWludCArIFwiJ1wiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpO1xuICAgICAgICAgICAgY2FzZSAnbm90cmVhZGFibGVlcnJvcic6XG4gICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FMUkVBRFlfSU5fVVNFO1xuICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9HRU5FUklDX0VSUk9SLCBlcnJvci50b1N0cmluZygpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhZGRBbHJlYWR5UHJvdmlkZWRUcmFja3MobXlDb25zdHJhaW50czogQ3VzdG9tTWVkaWFTdHJlYW1Db25zdHJhaW50cywgbWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtLCBzdHJlYW0/OiBTdHJlYW0pIHtcbiAgICAgICAgaWYgKCEhbXlDb25zdHJhaW50cy52aWRlb1RyYWNrKSB7XG4gICAgICAgICAgICBtZWRpYVN0cmVhbS5hZGRUcmFjayhteUNvbnN0cmFpbnRzLnZpZGVvVHJhY2spO1xuICAgICAgICAgICAgaWYgKCEhc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhbXlDb25zdHJhaW50cy5jb25zdHJhaW50cy52aWRlbykge1xuICAgICAgICAgICAgICAgICAgICBzdHJlYW0ubGFzdFZpZGVvVHJhY2tDb25zdHJhaW50cyA9IG15Q29uc3RyYWludHMuY29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmxhc3RWaWRlb1RyYWNrQ29uc3RyYWludHMgPSBteUNvbnN0cmFpbnRzLnZpZGVvVHJhY2suZ2V0Q29uc3RyYWludHMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhbXlDb25zdHJhaW50cy5hdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICBtZWRpYVN0cmVhbS5hZGRUcmFjayhteUNvbnN0cmFpbnRzLmF1ZGlvVHJhY2spO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZWRpYVN0cmVhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGNvbmZpZ3VyZURldmljZUlkT3JTY3JlZW5zaGFyaW5nKFxuICAgICAgICBteUNvbnN0cmFpbnRzOiBDdXN0b21NZWRpYVN0cmVhbUNvbnN0cmFpbnRzLFxuICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLFxuICAgICAgICByZXNvbHZlLFxuICAgICAgICByZWplY3RcbiAgICApIHtcbiAgICAgICAgY29uc3QgYXVkaW9Tb3VyY2UgPSBwdWJsaXNoZXJQcm9wZXJ0aWVzLmF1ZGlvU291cmNlO1xuICAgICAgICBjb25zdCB2aWRlb1NvdXJjZSA9IHB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2U7XG4gICAgICAgIGlmICh0eXBlb2YgYXVkaW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBteUNvbnN0cmFpbnRzLmNvbnN0cmFpbnRzIS5hdWRpbyA9IHsgZGV2aWNlSWQ6IHsgZXhhY3Q6IGF1ZGlvU291cmNlIH0gfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgdmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNTY3JlZW5TaGFyZSh2aWRlb1NvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFZpZGVvU291cmNlKG15Q29uc3RyYWludHMsIHZpZGVvU291cmNlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gU2NyZWVuIHNoYXJpbmdcblxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5jaGVja1NjcmVlblNoYXJpbmdDYXBhYmlsaXRpZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICdZb3UgY2FuIG9ubHkgc2NyZWVuIHNoYXJlIGluIGRlc2t0b3AgQ2hyb21lLCBGaXJlZm94LCBPcGVyYSwgU2FmYXJpICg+PTEzLjApLCBFZGdlICg+PSA4MCkgb3IgRWxlY3Ryb24uIERldGVjdGVkIGNsaWVudDogJyArXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5nZXROYW1lKCkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmdldFZlcnNpb24oKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAocGxhdGZvcm0uaXNFbGVjdHJvbigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmVmaXggPSAnc2NyZWVuOic7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2aWRlb1NvdXJjZVN0cmluZzogc3RyaW5nID0gdmlkZW9Tb3VyY2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbGVjdHJvblNjcmVlbklkID0gdmlkZW9Tb3VyY2VTdHJpbmcuc3Vic3RyKHZpZGVvU291cmNlU3RyaW5nLmluZGV4T2YocHJlZml4KSArIHByZWZpeC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgKDxhbnk+bXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8pID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hbmRhdG9yeToge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZTogJ2Rlc2t0b3AnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZUlkOiBlbGVjdHJvblNjcmVlbklkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG15Q29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICEhdGhpcy5hZHZhbmNlZENvbmZpZ3VyYXRpb24uc2NyZWVuU2hhcmVDaHJvbWVFeHRlbnNpb24gJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhKHBsYXRmb3JtLmlzRmlyZWZveEJyb3dzZXIoKSB8fCBwbGF0Zm9ybS5pc0ZpcmVmb3hNb2JpbGVCcm93c2VyKCkpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIW5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddXG4gICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDdXN0b20gc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGZvciBDaHJvbWUgKGFuZCBPcGVyYSkgYW5kIG5vIHN1cHBvcnQgZm9yIE1lZGlhRGV2aWNlcy5nZXREaXNwbGF5TWVkaWEoKVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NyZWVuU2hhcmluZy5nZXRTY3JlZW5Db25zdHJhaW50cygoZXJyb3IsIHNjcmVlbkNvbnN0cmFpbnRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICEhZXJyb3IgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICghIXNjcmVlbkNvbnN0cmFpbnRzLm1hbmRhdG9yeSAmJiBzY3JlZW5Db25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2UgPT09ICdzY3JlZW4nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciA9PT0gJ3Blcm1pc3Npb24tZGVuaWVkJyB8fCBlcnJvciA9PT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdZb3UgbXVzdCBhbGxvdyBhY2Nlc3MgdG8gb25lIHdpbmRvdyBvZiB5b3VyIGRlc2t0b3AnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleHRlbnNpb25JZCA9IHRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvbiEuc3BsaXQoJy8nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucG9wKCkhIVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudHJpbSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcmVlblNoYXJpbmcuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbklkLCAoc3RhdHVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgPT09ICdpbnN0YWxsZWQtZGlzYWJsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1lvdSBtdXN0IGVuYWJsZSB0aGUgc2NyZWVuIGV4dGVuc2lvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PT0gJ25vdC1pbnN0YWxsZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3RyaW5nPnRoaXMuYWR2YW5jZWRDb25maWd1cmF0aW9uLnNjcmVlblNoYXJlQ2hyb21lRXh0ZW5zaW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8gPSBzY3JlZW5Db25zdHJhaW50cztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG15Q29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmF2aWdhdG9yLm1lZGlhRGV2aWNlc1snZ2V0RGlzcGxheU1lZGlhJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2V0RGlzcGxheU1lZGlhIHN1cHBvcnQgKENocm9tZSA+PSA3MiwgRmlyZWZveCA+PSA2NiwgU2FmYXJpID49IDEzKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShteUNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEZWZhdWx0IHNjcmVlbiBzaGFyaW5nIGV4dGVuc2lvbiBmb3IgQ2hyb21lL09wZXJhLCBvciBpcyBGaXJlZm94IDwgNjZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyZWZveFN0cmluZyA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc0ZpcmVmb3hCcm93c2VyKCkgfHwgcGxhdGZvcm0uaXNGaXJlZm94TW9iaWxlQnJvd3NlcigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBwdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NyZWVuU2hhcmluZ0F1dG8uZ2V0U2NyZWVuSWQoZmlyZWZveFN0cmluZywgKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuQ29uc3RyYWludHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yID09PSAnbm90LWluc3RhbGxlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9uVXJsID0gISF0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0aGlzLmFkdmFuY2VkQ29uZmlndXJhdGlvbi5zY3JlZW5TaGFyZUNocm9tZUV4dGVuc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnaHR0cHM6Ly9jaHJvbWUuZ29vZ2xlLmNvbS93ZWJzdG9yZS9kZXRhaWwvb3BlbnZpZHUtc2NyZWVuc2hhcmluZy9sZmNnZmVwYWZub2JkbG9lY2NobmZhY2xpYmVuam9sZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCwgZXh0ZW5zaW9uVXJsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVycm9yID09PSAnaW5zdGFsbGVkLWRpc2FibGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9FWFRFTlNJT05fRElTQUJMRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnWW91IG11c3QgZW5hYmxlIHRoZSBzY3JlZW4gZXh0ZW5zaW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZXJyb3IgPT09ICdwZXJtaXNzaW9uLWRlbmllZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyID0gbmV3IE9wZW5WaWR1RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcGVuVmlkdUVycm9yTmFtZS5TQ1JFRU5fQ0FQVFVSRV9ERU5JRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnWW91IG11c3QgYWxsb3cgYWNjZXNzIHRvIG9uZSB3aW5kb3cgb2YgeW91ciBkZXNrdG9wJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdVbmtub3duIGVycm9yIHdoZW4gYWNjZXNzaW5nIHNjcmVlbiBzaGFyZSdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15Q29uc3RyYWludHMuY29uc3RyYWludHMhLnZpZGVvID0gc2NyZWVuQ29uc3RyYWludHMudmlkZW87XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobXlDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByb3RlY3RlZCBzZXRWaWRlb1NvdXJjZShteUNvbnN0cmFpbnRzOiBDdXN0b21NZWRpYVN0cmVhbUNvbnN0cmFpbnRzLCB2aWRlb1NvdXJjZTogc3RyaW5nKSB7XG4gICAgICAgIGlmICghbXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8pIHtcbiAgICAgICAgICAgIG15Q29uc3RyYWludHMuY29uc3RyYWludHMhLnZpZGVvID0ge307XG4gICAgICAgIH1cbiAgICAgICAgKDxNZWRpYVRyYWNrQ29uc3RyYWludHM+bXlDb25zdHJhaW50cy5jb25zdHJhaW50cyEudmlkZW8pWydkZXZpY2VJZCddID0geyBleGFjdDogdmlkZW9Tb3VyY2UgfTtcbiAgICB9XG5cbiAgICAvKiBQcml2YXRlIG1ldGhvZHMgKi9cblxuICAgIHByaXZhdGUgZGlzY29ubmVjdENhbGxiYWNrKCk6IHZvaWQge1xuICAgICAgICBsb2dnZXIud2FybignV2Vic29ja2V0IGNvbm5lY3Rpb24gbG9zdCcpO1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9uTG9zdENvbm5lY3Rpb24oJ25ldHdvcmtEaXNjb25uZWN0Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbGVydCgnQ29ubmVjdGlvbiBlcnJvci4gUGxlYXNlIHJlbG9hZCBwYWdlLicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZWNvbm5lY3RpbmdDYWxsYmFjaygpOiB2b2lkIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1dlYnNvY2tldCBjb25uZWN0aW9uIGxvc3QgKHJlY29ubmVjdGluZyknKTtcbiAgICAgICAgaWYgKCF0aGlzLmlzUm9vbUF2YWlsYWJsZSgpKSB7XG4gICAgICAgICAgICBhbGVydCgnQ29ubmVjdGlvbiBlcnJvci4gUGxlYXNlIHJlbG9hZCBwYWdlLicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncmVjb25uZWN0aW5nJywgW10pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZWNvbm5lY3RXZWJzb2NrZXRUaHJvdWdoUnBjQ29ubmVjdE1ldGhvZChycGNTZXNzaW9uSWQpIHtcbiAgICAgICAgLy8gVGhpcyBSUEMgbWV0aG9kIGFsbG93cyBjaGVja2luZzpcbiAgICAgICAgLy8gU2luZ2xlIE1hc3RlcjogaWYgc3VjY2VzcywgY29ubmVjdGlvbiByZWNvdmVyZWRcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgaWYgZXJyb3IsIG5vIE1hc3RlciBOb2RlIGNyYXNoZWQgYW5kIGxpZmUgd2lsbCBiZSAtMS4gb25Mb3N0Q29ubmVjdGlvbiB3aXRoIHJlYXNvbiBuZXR3b3JrRGlzY29ubmVjdCB3aWxsIGJlIHRyaWdnZXJlZFxuICAgICAgICAvLyBNdWx0aSBNYXN0ZXI6IGlmIHN1Y2Nlc3MsIGNvbm5lY3Rpb24gcmVjb3ZlcmVkXG4gICAgICAgIC8vICAgICAgICAgICAgICAgaWYgZXJyb3IgYW5kIE1hc3RlciBOb2RlIGNyYXNoZWQgbm90aWZpY2F0aW9uIHdhcyBhbHJlYWR5IHJlY2VpdmVkLCBub3RoaW5nIG11c3QgYmUgZG9uZVxuICAgICAgICAvLyAgICAgICAgICAgICAgIGlmIGVycm9yIGFuZCBNYXN0ZXIgTm9kZSBOT1QgY3Jhc2hlZCwgc2Vzc2lvblN0YXR1cyBtZXRob2QgbXVzdCBiZSBzZW50OlxuICAgICAgICAvLyAgICAgICAgICAgICAgICAgaWYgbGlmZSBpcyBlcXVhbCwgbmV0d29ya0Rpc2Nvbm5lY3RcbiAgICAgICAgLy8gICAgICAgICAgICAgICAgIGlmIGxpZmUgaXMgZ3JlYXRlciwgbm9kZUNyYXNoZWRcbiAgICAgICAgdGhpcy5zZW5kUmVxdWVzdCgnY29ubmVjdCcsIHsgc2Vzc2lvbklkOiBycGNTZXNzaW9uSWQsIHJlY29ubmVjdDogdHJ1ZSB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzTWFzdGVyTm9kZUNyYXNoZWQoKSkge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybignTWFzdGVyIE5vZGUgaGFzIGNyYXNoZWQhJyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVycm9yKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBub3RpZnlMb3N0Q29ubmVjdGlvbiA9IChyZWFzb24sIGVycm9yTXNnKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybihlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub25Mb3N0Q29ubmVjdGlvbihyZWFzb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5qc29uUnBjQ2xpZW50LmNsb3NlKDQxMDEsICdSZWNvbm5lY3Rpb24gZmF1bHQ6ICcgKyBlcnJvck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcnBjU2Vzc2lvblN0YXR1cyA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmxpZmUgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2luZ2xlIE1hc3RlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGlmeUxvc3RDb25uZWN0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbmV0d29ya0Rpc2Nvbm5lY3QnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnV1Mgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdGVkIGJ1dCB0aGUgdXNlciB3YXMgYWxyZWFkeSBldmljdGVkIGR1ZSB0byB0aW1lb3V0J1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE11bHRpIE1hc3RlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgUlBDIG1ldGhvZCBpcyBvbmx5IHJlcXVpcmVkIHRvIGZpbmQgb3V0IHRoZSByZWFzb24gb2YgdGhlIGRpc2Nvbm5lY3Rpb246XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2hldGhlciB0aGUgY2xpZW50IGxvc3QgaXRzIG5ldHdvcmsgY29ubmVjdGlvbiBvciBhIE1hc3RlciBOb2RlIGNyYXNoZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmRSZXF1ZXN0KCdzZXNzaW9uU3RhdHVzJywgeyBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbi5zZXNzaW9uSWQgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgY2hlY2tpbmcgc2Vzc2lvbiBzdGF0dXMnLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5saWZlID09PSByZXNwb25zZS5saWZlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGxpZmUgc3RvcmVkIGluIHRoZSBjbGllbnQgbWF0Y2hlcyB0aGUgbGlmZSBzdG9yZWQgaW4gdGhlIHNlcnZlciwgaXQgbWVhbnMgdGhhdCB0aGUgY2xpZW50IGxvc3QgaXRzIG5ldHdvcmsgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGlmeUxvc3RDb25uZWN0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbmV0d29ya0Rpc2Nvbm5lY3QnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnV1Mgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdGVkIGJ1dCB0aGUgdXNlciB3YXMgYWxyZWFkeSBldmljdGVkIGR1ZSB0byB0aW1lb3V0J1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBsaWZlIHN0b3JlZCBpbiB0aGUgY2xpZW50IGlzIGJlbG93IHRoZSBsaWZlIHN0b3JlZCBpbiB0aGUgc2VydmVyLCBpdCBtZWFucyB0aGF0IHRoZSBNYXN0ZXIgTm9kZSBoYXMgY3Jhc2hlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGlmeUxvc3RDb25uZWN0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbm9kZUNyYXNoZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnV1Mgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdGVkIHRvIE9wZW5WaWR1IFNlcnZlciBidXQgeW91ciBNYXN0ZXIgTm9kZSBjcmFzaGVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAwMDcgJiYgZXJyb3IubWVzc2FnZSA9PT0gJ3JlY29ubmVjdGlvbiBlcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEt1cmVudG8gZXJyb3I6IGludmFsaWQgUlBDIHNlc3Npb25JZC4gVGhpcyBtZWFucyB0aGF0IHRoZSBrdXJlbnRvLWpzb25ycGMtc2VydmVyIG9mIG9wZW52aWR1LXNlcnZlciB3aGVyZSBrdXJlbnRvLWpzb25ycGMtY2xpZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpcyB0cnlpbmcgdG8gcmVjb25uZWN0IGRvZXMgbm90IGtub3cgYWJvdXQgdGhpcyBzZXNzaW9uSWQuIFRoaXMgY2FuIG1lYW4gdHdvIHRoaW5nczpcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIDEpIG9wZW52aWR1LWJyb3dzZXIgbWFuYWdlZCB0byByZWNvbm5lY3QgYWZ0ZXIgYSB3aGlsZSwgYnV0IG9wZW52aWR1LXNlcnZlciBhbHJlYWR5IGV2aWN0ZWQgdGhlIHVzZXIgZm9yIG5vdCByZWNlaXZpbmcgcGluZy5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIDIpIG9wZW52aWR1LXNlcnZlciBwcm9jZXNzIGlzIGEgZGlmZmVyZW50IG9uZSBiZWNhdXNlIG9mIGEgbm9kZSBjcmFzaC5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNlbmQgYSBcInNlc3Npb25TdGF0dXNcIiBtZXRob2QgdG8gY2hlY2sgdGhlIHJlYXNvblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignSW52YWxpZCBSUEMgc2Vzc2lvbklkLiBDbGllbnQgbmV0d29yayBkaXNjb25uZWN0aW9uIG9yIE1hc3RlciBOb2RlIGNyYXNoJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBycGNTZXNzaW9uU3RhdHVzKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBycGNTZXNzaW9uU3RhdHVzKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuanNvblJwY0NsaWVudC5yZXNldFBpbmcoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub25SZWNvdmVyZWRDb25uZWN0aW9uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVjb25uZWN0ZWRDYWxsYmFjaygpOiB2b2lkIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1dlYnNvY2tldCByZWNvbm5lY3RlZCcpO1xuICAgICAgICBpZiAodGhpcy5pc1Jvb21BdmFpbGFibGUoKSkge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlY29ubmVjdFdlYnNvY2tldFRocm91Z2hScGNDb25uZWN0TWV0aG9kKHRoaXMuc2Vzc2lvbi5jb25uZWN0aW9uLnJwY1Nlc3Npb25JZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKCdUaGVyZSB3YXMgbm8gcHJldmlvdXMgY29ubmVjdGlvbiB3aGVuIHJ1bm5pbmcgcmVjb25uZWN0aW9uIGNhbGxiYWNrJyk7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBTZXNzaW9uIG9iamVjdCBkaXNwYXRjaCAnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcgZXZlbnRcbiAgICAgICAgICAgICAgICBjb25zdCBzZXNzaW9uRGlzY29ubmVjdEV2ZW50ID0gbmV3IFNlc3Npb25EaXNjb25uZWN0ZWRFdmVudCh0aGlzLnNlc3Npb24sICduZXR3b3JrRGlzY29ubmVjdCcpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lZS5lbWl0RXZlbnQoJ3Nlc3Npb25EaXNjb25uZWN0ZWQnLCBbc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudF0pO1xuICAgICAgICAgICAgICAgIHNlc3Npb25EaXNjb25uZWN0RXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWxlcnQoJ0Nvbm5lY3Rpb24gZXJyb3IuIFBsZWFzZSByZWxvYWQgcGFnZS4nKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaXNNYXN0ZXJOb2RlQ3Jhc2hlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFzdGVyTm9kZUhhc0NyYXNoZWQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1Jvb21BdmFpbGFibGUoKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLnNlc3Npb24gIT09IHVuZGVmaW5lZCAmJiB0aGlzLnNlc3Npb24gaW5zdGFuY2VvZiBTZXNzaW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKCdTZXNzaW9uIGluc3RhbmNlIG5vdCBmb3VuZCcpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1NjcmVlblNoYXJlKHZpZGVvU291cmNlOiBzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIHZpZGVvU291cmNlID09PSAnc2NyZWVuJyB8fCB2aWRlb1NvdXJjZSA9PT0gJ3dpbmRvdycgfHwgKHBsYXRmb3JtLmlzRWxlY3Ryb24oKSAmJiB2aWRlb1NvdXJjZS5zdGFydHNXaXRoKCdzY3JlZW46JykpO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBPcGVuVmlkdSB9IGZyb20gJy4vT3BlblZpZHUnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4vU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFB1Ymxpc2hlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1B1Ymxpc2hlclByb3BlcnRpZXMnO1xuaW1wb3J0IHsgUHVibGlzaGVyRXZlbnRNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudE1hcC9QdWJsaXNoZXJFdmVudE1hcCc7XG5pbXBvcnQgeyBTdHJlYW1FdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbUV2ZW50JztcbmltcG9ydCB7IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5pbXBvcnQgeyBQbGF0Zm9ybVV0aWxzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9VdGlscy9QbGF0Zm9ybSc7XG5pbXBvcnQgeyBUeXBlT2ZWaWRlbyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRW51bXMvVHlwZU9mVmlkZW8nO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnRSZWFzb24gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9UeXBlcy9UeXBlcyc7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmxldCBwbGF0Zm9ybTogUGxhdGZvcm1VdGlscztcblxuLyoqXG4gKiBQYWNrcyBsb2NhbCBtZWRpYSBzdHJlYW1zLiBQYXJ0aWNpcGFudHMgY2FuIHB1Ymxpc2ggaXQgdG8gYSBzZXNzaW9uLiBJbml0aWFsaXplZCB3aXRoIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG1ldGhvZC5cbiAqXG4gKiBTZWUgYXZhaWxhYmxlIGV2ZW50IGxpc3RlbmVycyBhdCBbW1B1Ymxpc2hlckV2ZW50TWFwXV0uXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWJsaXNoZXIgZXh0ZW5kcyBTdHJlYW1NYW5hZ2VyIHtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBQdWJsaXNoZXIgaGFzIGJlZW4gZ3JhbnRlZCBhY2Nlc3MgdG8gdGhlIHJlcXVlc3RlZCBpbnB1dCBkZXZpY2VzIG9yIG5vdFxuICAgICAqL1xuICAgIGFjY2Vzc0FsbG93ZWQgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgeW91IGhhdmUgY2FsbGVkIFtbUHVibGlzaGVyLnN1YnNjcmliZVRvUmVtb3RlXV0gd2l0aCB2YWx1ZSBgdHJ1ZWAgb3IgYGZhbHNlYCAoKmZhbHNlKiBieSBkZWZhdWx0KVxuICAgICAqL1xuICAgIGlzU3Vic2NyaWJlZFRvUmVtb3RlID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gdG8gd2hpY2ggdGhlIFB1Ymxpc2hlciBiZWxvbmdzXG4gICAgICovXG4gICAgc2Vzc2lvbjogU2Vzc2lvbjsgLy8gSW5pdGlhbGl6ZWQgYnkgU2Vzc2lvbi5wdWJsaXNoKFB1Ymxpc2hlcilcblxuICAgIHByaXZhdGUgYWNjZXNzRGVuaWVkID0gZmFsc2U7XG4gICAgcHJvdGVjdGVkIHByb3BlcnRpZXM6IFB1Ymxpc2hlclByb3BlcnRpZXM7XG4gICAgcHJpdmF0ZSBwZXJtaXNzaW9uRGlhbG9nVGltZW91dDogTm9kZUpTLlRpbWVyO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9wZW52aWR1OiBPcGVuVmlkdTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdmlkZW9SZWZlcmVuY2U6IEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWw6IE5vZGVKUy5UaW1lcjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnRWw6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLCBwcm9wZXJ0aWVzOiBQdWJsaXNoZXJQcm9wZXJ0aWVzLCBvcGVudmlkdTogT3BlblZpZHUpIHtcbiAgICAgICAgc3VwZXIoXG4gICAgICAgICAgICBuZXcgU3RyZWFtKCEhb3BlbnZpZHUuc2Vzc2lvbiA/IG9wZW52aWR1LnNlc3Npb24gOiBuZXcgU2Vzc2lvbihvcGVudmlkdSksIHtcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXJQcm9wZXJ0aWVzOiBwcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAgIG1lZGlhQ29uc3RyYWludHM6IHt9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHRhcmdFbFxuICAgICAgICApO1xuICAgICAgICBwbGF0Zm9ybSA9IFBsYXRmb3JtVXRpbHMuZ2V0SW5zdGFuY2UoKTtcbiAgICAgICAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgICAgICAgdGhpcy5vcGVudmlkdSA9IG9wZW52aWR1O1xuXG4gICAgICAgIHRoaXMuc3RyZWFtLmVlLm9uKCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgKHJlYXNvbjogU3RyZWFtRXZlbnRSZWFzb24pID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCB0aGlzLnN0cmVhbSwgcmVhc29uKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHVibGlzaCBvciB1bnB1Ymxpc2ggdGhlIGF1ZGlvIHN0cmVhbSAoaWYgYXZhaWxhYmxlKS4gQ2FsbGluZyB0aGlzIG1ldGhvZCB0d2ljZSBpbiBhIHJvdyBwYXNzaW5nIHNhbWUgYGVuYWJsZWRgIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqID4gX09ubHkgaWYgYFNlc3Npb24ucHVibGlzaChQdWJsaXNoZXIpYCBoYXMgYmVlbiBjYWxsZWQgZm9yIHRoaXMgUHVibGlzaGVyX1xuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWRgIGV2ZW50IHdpdGggYGNoYW5nZWRQcm9wZXJ0eWAgc2V0IHRvIGBcImF1ZGlvQWN0aXZlXCJgIGFuZCBgcmVhc29uYCBzZXQgdG8gYFwicHVibGlzaEF1ZGlvXCJgXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGFsc28gZGlzcGF0Y2ggdGhlIGV4YWN0IHNhbWUgZXZlbnRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJhdWRpb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIFRoZSByZXNwZWN0aXZlIFtbU3Vic2NyaWJlcl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCByZWNlaXZpbmcgdGhpcyBQdWJsaXNoZXIncyBzdHJlYW0gd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW5hYmxlZCBgdHJ1ZWAgdG8gcHVibGlzaCB0aGUgYXVkaW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVucHVibGlzaCBpdFxuICAgICAqL1xuICAgIHB1Ymxpc2hBdWRpbyhlbmFibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSAhPT0gZW5hYmxlZCkge1xuICAgICAgICAgICAgY29uc3QgYWZmZWN0ZWRNZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0gPSB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKVxuICAgICAgICAgICAgICAgID8gdGhpcy5zdHJlYW0ubG9jYWxNZWRpYVN0cmVhbVdoZW5TdWJzY3JpYmVkVG9SZW1vdGUhXG4gICAgICAgICAgICAgICAgOiB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgYWZmZWN0ZWRNZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbiAmJiAhIXRoaXMuc3RyZWFtLnN0cmVhbUlkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KFxuICAgICAgICAgICAgICAgICAgICAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtSWQ6IHRoaXMuc3RyZWFtLnN0cmVhbUlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk6ICdhdWRpb0FjdGl2ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogZW5hYmxlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlYXNvbjogJ3B1Ymxpc2hBdWRpbydcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc2Vzc2lvbiwgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIGVuYWJsZWQsICFlbmFibGVkLCAncHVibGlzaEF1ZGlvJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcywgdGhpcy5zdHJlYW0sICdhdWRpb0FjdGl2ZScsIGVuYWJsZWQsICFlbmFibGVkLCAncHVibGlzaEF1ZGlvJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uc2VuZFZpZGVvRGF0YSh0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IGVuYWJsZWQ7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhcIidQdWJsaXNoZXInIGhhcyBcIiArIChlbmFibGVkID8gJ3B1Ymxpc2hlZCcgOiAndW5wdWJsaXNoZWQnKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHVibGlzaCBvciB1bnB1Ymxpc2ggdGhlIHZpZGVvIHN0cmVhbSAoaWYgYXZhaWxhYmxlKS4gQ2FsbGluZyB0aGlzIG1ldGhvZCB0d2ljZSBpbiBhIHJvdyBwYXNzaW5nIHNhbWUgYGVuYWJsZWRgIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqID4gX09ubHkgaWYgYFNlc3Npb24ucHVibGlzaChQdWJsaXNoZXIpYCBoYXMgYmVlbiBjYWxsZWQgZm9yIHRoaXMgUHVibGlzaGVyX1xuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1Qcm9wZXJ0eUNoYW5nZWRgIGV2ZW50IHdpdGggYGNoYW5nZWRQcm9wZXJ0eWAgc2V0IHRvIGBcInZpZGVvQWN0aXZlXCJgIGFuZCBgcmVhc29uYCBzZXQgdG8gYFwicHVibGlzaFZpZGVvXCJgXG4gICAgICogVGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGFsc28gZGlzcGF0Y2ggdGhlIGV4YWN0IHNhbWUgZXZlbnRcbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtUHJvcGVydHlDaGFuZ2VkYCBldmVudCB3aXRoIGBjaGFuZ2VkUHJvcGVydHlgIHNldCB0byBgXCJ2aWRlb0FjdGl2ZVwiYCBhbmQgYHJlYXNvbmAgc2V0IHRvIGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIFRoZSByZXNwZWN0aXZlIFtbU3Vic2NyaWJlcl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCByZWNlaXZpbmcgdGhpcyBQdWJsaXNoZXIncyBzdHJlYW0gd2lsbCBhbHNvIGRpc3BhdGNoIHRoZSBleGFjdCBzYW1lIGV2ZW50XG4gICAgICpcbiAgICAgKiBTZWUgW1tTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZW5hYmxlZCBgdHJ1ZWAgdG8gcHVibGlzaCB0aGUgdmlkZW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVucHVibGlzaCBpdFxuICAgICAqIEBwYXJhbSByZXNvdXJjZVxuICAgICAqIC0gSWYgcGFyYW1ldGVyICoqYGVuYWJsZWRgKiogaXMgYGZhbHNlYCwgdGhpcyBvcHRpb25hbCBwYXJhbWV0ZXIgaXMgb2YgdHlwZSBib29sZWFuLiBJdCBjYW4gYmUgc2V0IHRvIGB0cnVlYCB0byBmb3JjaWJseSBmcmVlIHRoZSBoYXJkd2FyZSByZXNvdXJjZSBhc3NvY2lhdGVkIHRvIHRoZSB2aWRlbyB0cmFjaywgb3IgY2FuIGJlIHNldCB0byBgZmFsc2VgIHRvIGtlZXAgdGhlIGFjY2VzcyB0byB0aGUgaGFyZHdhcmUgcmVzb3VyY2UuXG4gICAgICogTm90IGZyZWVpbmcgdGhlIHJlc291cmNlIG1ha2VzIHRoZSBvcGVyYXRpb24gbXVjaCBtb3JlIGVmZmljaWVudCwgYnV0IGRlcGVuZGluZyBvbiB0aGUgcGxhdGZvcm0gdHdvIHNpZGUtZWZmZWN0cyBjYW4gYmUgaW50cm9kdWNlZDogdGhlIHZpZGVvIGRldmljZSBtYXkgbm90IGJlIGFjY2Vzc2libGUgYnkgb3RoZXIgYXBwbGljYXRpb25zIGFuZCB0aGUgYWNjZXNzIGxpZ2h0IG9mXG4gICAgICogd2ViY2FtcyBtYXkgcmVtYWluIG9uLiBUaGlzIGlzIHBsYXRmb3JtLWRlcGVuZGVudDogc29tZSBicm93c2VycyB3aWxsIG5vdCBwcmVzZW50IHRoZSBzaWRlLWVmZmVjdHMgZXZlbiB3aGVuIG5vdCBmcmVlaW5nIHRoZSByZXNvdXJjZS48L2xpPlxuICAgICAqIC0gSWYgcGFyYW1ldGVyICoqYGVuYWJsZWRgKiogaXMgYHRydWVgLCB0aGlzIG9wdGlvbmFsIHBhcmFtZXRlciBpcyBvZiB0eXBlIFtNZWRpYVN0cmVhbVRyYWNrXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9kb2NzL1dlYi9BUEkvTWVkaWFTdHJlYW1UcmFjaykuIEl0IGNhbiBiZSBzZXQgdG8gZm9yY2UgdGhlIHJlc3RvcmF0aW9uIG9mIHRoZSB2aWRlbyB0cmFjayB3aXRoIGEgY3VzdG9tIHRyYWNrLiBUaGlzIG1heSBiZVxuICAgICAqIHVzZWZ1bCBpZiB0aGUgUHVibGlzaGVyIHdhcyB1bnB1Ymxpc2hlZCBmcmVlaW5nIHRoZSBoYXJkd2FyZSByZXNvdXJjZSwgYW5kIG9wZW52aWR1LWJyb3dzZXIgaXMgbm90IGFibGUgdG8gc3VjY2Vzc2Z1bGx5IHJlLWNyZWF0ZSB0aGUgdmlkZW8gdHJhY2sgYXMgaXQgd2FzIGJlZm9yZSB1bnB1Ymxpc2hpbmcuIEluIHRoaXMgd2F5IHByZXZpb3VzIHRyYWNrIHNldHRpbmdzIHdpbGwgYmUgaWdub3JlZCBhbmQgdGhpcyBNZWRpYVN0cmVhbVRyYWNrXG4gICAgICogd2lsbCBiZSB1c2VkIGluc3RlYWQuXG4gICAgICovXG4gICAgcHVibGlzaFZpZGVvPFQgZXh0ZW5kcyBib29sZWFuPihlbmFibGVkOiBULCByZXNvdXJjZT86IFQgZXh0ZW5kcyBmYWxzZSA/IGJvb2xlYW4gOiBNZWRpYVN0cmVhbVRyYWNrKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IGVuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhZmZlY3RlZE1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSA9IHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpXG4gICAgICAgICAgICAgICAgICAgID8gdGhpcy5zdHJlYW0ubG9jYWxNZWRpYVN0cmVhbVdoZW5TdWJzY3JpYmVkVG9SZW1vdGUhXG4gICAgICAgICAgICAgICAgICAgIDogdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICBsZXQgbXVzdFJlc3RhcnRNZWRpYVN0cmVhbSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGFmZmVjdGVkTWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0cmFjay5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFlbmFibGVkICYmIHJlc291cmNlID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZW5hYmxlZCAmJiB0cmFjay5yZWFkeVN0YXRlID09PSAnZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXNvdXJjZSB3YXMgZnJlZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIG11c3RSZXN0YXJ0TWVkaWFTdHJlYW0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAvLyBUaGVyZSBpcyBhIFZpcnR1YWwgQmFja2dyb3VuZCBmaWx0ZXIgYXBwbGllZCB0aGF0IG11c3QgYmUgcmVtb3ZlZCBpbiBjYXNlIHRoZSBoYXJkd2FyZSBtdXN0IGJlIGZyZWVkXG4gICAgICAgICAgICAgICAgaWYgKCFlbmFibGVkICYmIHJlc291cmNlID09PSB0cnVlICYmICEhdGhpcy5zdHJlYW0uZmlsdGVyICYmIHRoaXMuc3RyZWFtLmZpbHRlci50eXBlLnN0YXJ0c1dpdGgoJ1ZCOicpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmxhc3RWQkZpbHRlciA9IHRoaXMuc3RyZWFtLmZpbHRlcjsgLy8gU2F2ZSB0aGUgZmlsdGVyIHRvIGJlIHJlLWFwcGxpZWQgaW4gY2FzZSBvZiB1bm11dGVcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zdHJlYW0ucmVtb3ZlRmlsdGVyQXV4KHRydWUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChtdXN0UmVzdGFydE1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9sZFZpZGVvVHJhY2sgPSBhZmZlY3RlZE1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAgICAgICAgICAgICAgICAgIGFmZmVjdGVkTWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sob2xkVmlkZW9UcmFjayk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVwbGFjZVZpZGVvVHJhY2sgPSBhc3luYyAodHI6IE1lZGlhU3RyZWFtVHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFmZmVjdGVkTWVkaWFTdHJlYW0uYWRkVHJhY2sodHIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlcGxhY2VUcmFja0luUnRjUnRwU2VuZGVyKHRyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtLmxhc3RWQkZpbHRlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgb3B0aW9ucyA9IHRoaXMuc3RyZWFtLmxhc3RWQkZpbHRlciEub3B0aW9ucztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbGFzdEV4ZWNNZXRob2QgPSB0aGlzLnN0cmVhbS5sYXN0VkJGaWx0ZXIhLmxhc3RFeGVjTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFsYXN0RXhlY01ldGhvZCAmJiBsYXN0RXhlY01ldGhvZC5tZXRob2QgPT09ICd1cGRhdGUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgb3B0aW9ucywgbGFzdEV4ZWNNZXRob2QucGFyYW1zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnN0cmVhbS5hcHBseUZpbHRlcih0aGlzLnN0cmVhbS5sYXN0VkJGaWx0ZXIhLnR5cGUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5zdHJlYW0ubGFzdFZCRmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICghIXJlc291cmNlICYmIHJlc291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgcmVwbGFjZVZpZGVvVHJhY2socmVzb3VyY2UpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZWRpYVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5zdHJlYW0ubGFzdFZpZGVvVHJhY2tDb25zdHJhaW50c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHJlcGxhY2VWaWRlb1RyYWNrKG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbiAmJiAhIXRoaXMuc3RyZWFtLnN0cmVhbUlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUlkOiB0aGlzLnN0cmVhbS5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogJ3ZpZGVvQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdWYWx1ZTogZW5hYmxlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb246ICdwdWJsaXNoVmlkZW8nXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXCJFcnJvciBzZW5kaW5nICdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnIGV2ZW50XCIsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd2aWRlb0FjdGl2ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5hYmxlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhZW5hYmxlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncHVibGlzaFZpZGVvJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLCB0aGlzLnN0cmVhbSwgJ3ZpZGVvQWN0aXZlJywgZW5hYmxlZCwgIWVuYWJsZWQsICdwdWJsaXNoVmlkZW8nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLnNlbmRWaWRlb0RhdGEodGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0FjdGl2ZSA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oXCInUHVibGlzaGVyJyBoYXMgXCIgKyAoZW5hYmxlZCA/ICdwdWJsaXNoZWQnIDogJ3VucHVibGlzaGVkJykgKyAnIGl0cyB2aWRlbyBzdHJlYW0nKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIGJlZm9yZSBbW1Nlc3Npb24ucHVibGlzaF1dIGlmIHlvdSBwcmVmZXIgdG8gc3Vic2NyaWJlIHRvIHlvdXIgUHVibGlzaGVyJ3MgcmVtb3RlIHN0cmVhbSBpbnN0ZWFkIG9mIHVzaW5nIHRoZSBsb2NhbCBzdHJlYW0sIGFzIGFueSBvdGhlciB1c2VyIHdvdWxkIGRvLlxuICAgICAqL1xuICAgIHN1YnNjcmliZVRvUmVtb3RlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICB2YWx1ZSA9IHZhbHVlICE9PSB1bmRlZmluZWQgPyB2YWx1ZSA6IHRydWU7XG4gICAgICAgIHRoaXMuaXNTdWJzY3JpYmVkVG9SZW1vdGUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5zdHJlYW0uc3Vic2NyaWJlVG9NeVJlbW90ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uXV1cbiAgICAgKi9cbiAgICBvbjxLIGV4dGVuZHMga2V5b2YgUHVibGlzaGVyRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI6IChldmVudDogUHVibGlzaGVyRXZlbnRNYXBbS10pID0+IHZvaWQpOiB0aGlzIHtcbiAgICAgICAgc3VwZXIub24oPGFueT50eXBlLCBoYW5kbGVyKTtcblxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUNyZWF0ZWQnKSB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLnN0cmVhbSAmJiB0aGlzLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHRoaXMuc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZWUub24oJ3N0cmVhbS1jcmVhdGVkLWJ5LXB1Ymxpc2hlcicsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHRoaXMuc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbmNlXV1cbiAgICAgKi9cbiAgICBvbmNlPEsgZXh0ZW5kcyBrZXlvZiBQdWJsaXNoZXJFdmVudE1hcD4odHlwZTogSywgaGFuZGxlcjogKGV2ZW50OiBQdWJsaXNoZXJFdmVudE1hcFtLXSkgPT4gdm9pZCk6IHRoaXMge1xuICAgICAgICBzdXBlci5vbmNlKDxhbnk+dHlwZSwgaGFuZGxlcik7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1DcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdEV2ZW50KCdzdHJlYW1DcmVhdGVkJywgW25ldyBTdHJlYW1FdmVudChmYWxzZSwgdGhpcywgJ3N0cmVhbUNyZWF0ZWQnLCB0aGlzLnN0cmVhbSwgJycpXSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLm9uY2UoJ3N0cmVhbS1jcmVhdGVkLWJ5LXB1Ymxpc2hlcicsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ3N0cmVhbUNyZWF0ZWQnLCBbbmV3IFN0cmVhbUV2ZW50KGZhbHNlLCB0aGlzLCAnc3RyZWFtQ3JlYXRlZCcsIHRoaXMuc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ2FjY2Vzc0FsbG93ZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0FsbG93ZWQnLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdhY2Nlc3NEZW5pZWQnKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5hY2Nlc3NEZW5pZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGVuaWVkJywgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vZmZdXVxuICAgICAqL1xuICAgIG9mZjxLIGV4dGVuZHMga2V5b2YgUHVibGlzaGVyRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI/OiAoZXZlbnQ6IFB1Ymxpc2hlckV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9mZig8YW55PnR5cGUsIGhhbmRsZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXBsYWNlcyB0aGUgY3VycmVudCB2aWRlbyBvciBhdWRpbyB0cmFjayB3aXRoIGEgZGlmZmVyZW50IG9uZS4gVGhpcyBhbGxvd3MgeW91IHRvIHJlcGxhY2UgYW4gb25nb2luZyB0cmFjayB3aXRoIGEgZGlmZmVyZW50IG9uZVxuICAgICAqIHdpdGhvdXQgaGF2aW5nIHRvIHJlbmVnb3RpYXRlIHRoZSB3aG9sZSBXZWJSVEMgY29ubmVjdGlvbiAodGhhdCBpcywgaW5pdGlhbGl6aW5nIGEgbmV3IFB1Ymxpc2hlciwgdW5wdWJsaXNoaW5nIHRoZSBwcmV2aW91cyBvbmVcbiAgICAgKiBhbmQgcHVibGlzaGluZyB0aGUgbmV3IG9uZSkuXG4gICAgICpcbiAgICAgKiBZb3UgY2FuIGdldCB0aGlzIG5ldyBNZWRpYVN0cmVhbVRyYWNrIGJ5IHVzaW5nIHRoZSBuYXRpdmUgV2ViIEFQSSBvciBzaW1wbHkgd2l0aCBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dIG1ldGhvZC5cbiAgICAgKlxuICAgICAqICoqV0FSTklORzogdGhpcyBtZXRob2QgaGFzIGJlZW4gcHJvdmVuIHRvIHdvcmsgaW4gdGhlIG1ham9yaXR5IG9mIGNhc2VzLCBidXQgdGhlcmUgbWF5IGJlIHNvbWUgY29tYmluYXRpb25zIG9mIHB1Ymxpc2hlZC9yZXBsYWNlZCB0cmFja3MgdGhhdCBtYXkgYmUgaW5jb21wYXRpYmxlXG4gICAgICogYmV0d2VlbiB0aGVtIGFuZCBicmVhayB0aGUgY29ubmVjdGlvbiBpbiBPcGVuVmlkdSBTZXJ2ZXIuIEEgY29tcGxldGUgcmVuZWdvdGlhdGlvbiBtYXkgYmUgdGhlIG9ubHkgc29sdXRpb24gaW4gdGhpcyBjYXNlLlxuICAgICAqIFZpc2l0IFtSVENSdHBTZW5kZXIucmVwbGFjZVRyYWNrXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUlRDUnRwU2VuZGVyL3JlcGxhY2VUcmFjaykgZG9jdW1lbnRhdGlvbiBmb3IgZnVydGhlciBkZXRhaWxzLioqXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdHJhY2sgVGhlIFtNZWRpYVN0cmVhbVRyYWNrXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTWVkaWFTdHJlYW1UcmFjaykgb2JqZWN0IHRvIHJlcGxhY2UgdGhlIGN1cnJlbnQgb25lLlxuICAgICAqIElmIGl0IGlzIGFuIGF1ZGlvIHRyYWNrLCB0aGUgY3VycmVudCBhdWRpbyB0cmFjayB3aWxsIGJlIHRoZSByZXBsYWNlZCBvbmUuIElmIGl0IGlzIGEgdmlkZW8gdHJhY2ssIHRoZSBjdXJyZW50IHZpZGVvIHRyYWNrIHdpbGwgYmUgdGhlIHJlcGxhY2VkIG9uZS5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSAodG8gd2hpY2ggeW91IGNhbiBvcHRpb25hbGx5IHN1YnNjcmliZSB0bykgdGhhdCBpcyByZXNvbHZlZCBpZiB0aGUgdHJhY2sgd2FzIHN1Y2Nlc3NmdWxseSByZXBsYWNlZCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaW4gb3RoZXIgY2FzZVxuICAgICAqL1xuICAgIGFzeW5jIHJlcGxhY2VUcmFjayh0cmFjazogTWVkaWFTdHJlYW1UcmFjayk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXBsYWNlVHJhY2tBdXgodHJhY2ssIHRydWUpO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxldCBjb25zdHJhaW50czogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgICAgICAgICAgbGV0IGNvbnN0cmFpbnRzQXV4OiBNZWRpYVN0cmVhbUNvbnN0cmFpbnRzID0ge307XG4gICAgICAgICAgICBjb25zdCB0aW1lRm9yRGlhbG9nRXZlbnQgPSAyMDAwO1xuICAgICAgICAgICAgbGV0IHN0YXJ0VGltZTtcblxuICAgICAgICAgICAgY29uc3QgZXJyb3JDYWxsYmFjayA9IChvcGVuVmlkdUVycm9yOiBPcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgUHVibGlzaGVyIGluaXRpYWxpemF0aW9uIGZhaWxlZC4gJHtvcGVuVmlkdUVycm9yLm5hbWV9OiAke29wZW5WaWR1RXJyb3IubWVzc2FnZX1gKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3Qgc3VjY2Vzc0NhbGxiYWNrID0gKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXNzQWxsb3dlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5hY2Nlc3NEZW5pZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgTWVkaWFTdHJlYW1UcmFjayAhPT0gJ3VuZGVmaW5lZCcgJiYgdGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5yZW1vdmVUcmFjayhtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2soPE1lZGlhU3RyZWFtVHJhY2s+dGhpcy5wcm9wZXJ0aWVzLmF1ZGlvU291cmNlKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIE1lZGlhU3RyZWFtVHJhY2sgIT09ICd1bmRlZmluZWQnICYmIHRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSBpbnN0YW5jZW9mIE1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sobWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKDxNZWRpYVN0cmVhbVRyYWNrPnRoaXMucHJvcGVydGllcy52aWRlb1NvdXJjZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQXBwbHkgUHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoQXVkaW8gYW5kIFB1Ymxpc2hlclByb3BlcnRpZXMucHVibGlzaFZpZGVvXG4gICAgICAgICAgICAgICAgaWYgKCEhbWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmF1ZGlvQWN0aXZlICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zdHJlYW0uYXVkaW9BY3RpdmUgIT09IG51bGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRoaXMuc3RyZWFtLmF1ZGlvQWN0aXZlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAhIXRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbztcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXS5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCEhbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlICE9PSB1bmRlZmluZWQgJiYgdGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgIT09IG51bGxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRoaXMuc3RyZWFtLnZpZGVvQWN0aXZlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAhIXRoaXMuc3RyZWFtLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hWaWRlbztcbiAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXS5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBTZXQgQ29udGVudCBIaW50IG9uIGFsbCBNZWRpYVN0cmVhbVRyYWNrc1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdHJhY2sgb2YgbWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRyYWNrLmNvbnRlbnRIaW50Py5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnRlbnRIaW50IGZvciBhdWRpbzogXCJcIiwgXCJzcGVlY2hcIiwgXCJzcGVlY2gtcmVjb2duaXRpb25cIiwgXCJtdXNpY1wiLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly93M2MuZ2l0aHViLmlvL21zdC1jb250ZW50LWhpbnQvI2F1ZGlvLWNvbnRlbnQtaGludHNcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrLmNvbnRlbnRIaW50ID0gJyc7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhgQXVkaW8gdHJhY2sgQ29udGVudCBIaW50IHNldDogJyR7dHJhY2suY29udGVudEhpbnR9J2ApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdHJhY2sgb2YgbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRyYWNrLmNvbnRlbnRIaW50Py5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnRlbnRIaW50IGZvciB2aWRlbzogXCJcIiwgXCJtb3Rpb25cIiwgXCJkZXRhaWxcIiwgXCJ0ZXh0XCIuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBodHRwczovL3czYy5naXRodWIuaW8vbXN0LWNvbnRlbnQtaGludC8jdmlkZW8tY29udGVudC1oaW50c1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoICh0aGlzLnN0cmVhbS50eXBlT2ZWaWRlbykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgVHlwZU9mVmlkZW8uU0NSRUVOOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFjay5jb250ZW50SGludCA9ICdkZXRhaWwnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFR5cGVPZlZpZGVvLkNVU1RPTTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0NVU1RPTSB0eXBlIHZpZGVvIHRyYWNrIHdhcyBwcm92aWRlZCB3aXRob3V0IENvbnRlbnQgSGludCEnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suY29udGVudEhpbnQgPSAnbW90aW9uJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBUeXBlT2ZWaWRlby5DQU1FUkE6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBUeXBlT2ZWaWRlby5JUENBTTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFjay5jb250ZW50SGludCA9ICdtb3Rpb24nO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBWaWRlbyB0cmFjayBDb250ZW50IEhpbnQgc2V0OiAnJHt0cmFjay5jb250ZW50SGludH0nYCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmluaXRpYWxpemVWaWRlb1JlZmVyZW5jZShtZWRpYVN0cmVhbSk7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gd2UgYXJlIHN1YnNjcmliZWQgdG8gb3VyIHJlbW90ZSB3ZSBkb24ndCBzdGlsbCBzZXQgdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpbiB0aGUgdmlkZW8gZWxlbWVudHMgdG9cbiAgICAgICAgICAgICAgICAgICAgLy8gYXZvaWQgZWFybHkgJ3N0cmVhbVBsYXlpbmcnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBIYXMgdmlkZW8gdHJhY2tcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRWaWRlb0RpbWVuc2lvbnMoKS50aGVuKChkaW1lbnNpb25zKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGRpbWVuc2lvbnMud2lkdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBkaW1lbnNpb25zLmhlaWdodFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IGludGVydmFsIHRvIGxpc3RlbiBmb3Igc2NyZWVuIHJlc2l6ZSBldmVudHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNldHRpbmdzOiBNZWRpYVRyYWNrU2V0dGluZ3MgPSBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpWzBdLmdldFNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld1dpZHRoID0gc2V0dGluZ3Mud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IHNldHRpbmdzLmhlaWdodDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2lkdGhDaGFuZ2VkID0gbmV3V2lkdGggIT0gbnVsbCAmJiBuZXdXaWR0aCAhPT0gdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zLndpZHRoO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBoZWlnaHRDaGFuZ2VkID0gbmV3SGVpZ2h0ICE9IG51bGwgJiYgbmV3SGVpZ2h0ICE9PSB0aGlzLnN0cmVhbS52aWRlb0RpbWVuc2lvbnMuaGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCAmJiAod2lkdGhDaGFuZ2VkIHx8IGhlaWdodENoYW5nZWQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRWaWRlb0RpbWVuc2lvbnNDaGFuZ2VkRXZlbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2NyZWVuUmVzaXplZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9EaW1lbnNpb25zLndpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnZpZGVvRGltZW5zaW9ucy5oZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3V2lkdGggfHwgMCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdIZWlnaHQgfHwgMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDY1MCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1yZWFkeS10by1wdWJsaXNoJywgW10pO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGF1ZGlvIHRyYWNrIChubyB2aWRlb0RpbWVuc2lvbnMpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVlLmVtaXRFdmVudCgnc3RyZWFtLXJlYWR5LXRvLXB1Ymxpc2gnLCBbXSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGdldE1lZGlhU3VjY2VzcyA9IGFzeW5jIChtZWRpYVN0cmVhbTogTWVkaWFTdHJlYW0sIGRlZmluZWRBdWRpb0NvbnN0cmFpbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyUGVybWlzc2lvbkRpYWxvZ1RpbWVyKHN0YXJ0VGltZSwgdGltZUZvckRpYWxvZ0V2ZW50KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKCkgJiYgdGhpcy5zdHJlYW0uaXNTZW5kQXVkaW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGdldHRpbmcgZGVza3RvcCBhcyB1c2VyIG1lZGlhIGF1ZGlvIGNvbnN0cmFpbnQgbXVzdCBiZSBmYWxzZS4gTm93IHdlIGNhbiBhc2sgZm9yIGl0IGlmIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzQXV4LmF1ZGlvID0gZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXVkaW9Pbmx5U3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHNBdXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5hZGRUcmFjayhhdWRpb09ubHlTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKVswXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2sobWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbS5nZXRWaWRlb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKHRoaXMub3BlbnZpZHUuZ2VuZXJhdGVBdWRpb0RldmljZUVycm9yKGVycm9yLCBjb25zdHJhaW50cykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBnZXRNZWRpYUVycm9yID0gYXN5bmMgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBnZXRNZWRpYUVycm9yOiAke2Vycm9yLnRvU3RyaW5nKCl9YCk7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWUsIHRpbWVGb3JEaWFsb2dFdmVudCk7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yLm5hbWUgPT09ICdFcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU2FmYXJpIE92ZXJDb25zdHJhaW5lZEVycm9yIGhhcyBhcyBuYW1lIHByb3BlcnR5ICdFcnJvcicgaW5zdGVhZCBvZiAnT3ZlckNvbnN0cmFpbmVkRXJyb3InXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLm5hbWUgPSBlcnJvci5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlcnJvci5uYW1lLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbm90Zm91bmRlcnJvcic6XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdWRpbzogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvOiBjb25zdHJhaW50cy52aWRlb1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLklOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdub3RhbGxvd2VkZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gdGhpcy5zdHJlYW0uaXNTZW5kU2NyZWVuKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IE9wZW5WaWR1RXJyb3JOYW1lLlNDUkVFTl9DQVBUVVJFX0RFTklFRFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogT3BlblZpZHVFcnJvck5hbWUuREVWSUNFX0FDQ0VTU19ERU5JRUQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ292ZXJjb25zdHJhaW5lZGVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW0gPSBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1ZGlvOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW86IGNvbnN0cmFpbnRzLnZpZGVvXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5JTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJBdWRpbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDxDb25zdHJhaW5ET01TdHJpbmdQYXJhbWV0ZXJzPig8TWVkaWFUcmFja0NvbnN0cmFpbnRzPmNvbnN0cmFpbnRzLmF1ZGlvKS5kZXZpY2VJZCEhKS5leGFjdCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1I7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIkF1ZGlvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvbnN0cmFpbnQudG9Mb3dlckNhc2UoKSA9PT0gJ2RldmljZWlkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck5hbWUgPSBPcGVuVmlkdUVycm9yTmFtZS5JTlBVVF9WSURFT19ERVZJQ0VfTk9UX0ZPVU5EO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJWaWRlbyBpbnB1dCBkZXZpY2Ugd2l0aCBkZXZpY2VJZCAnXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDxDb25zdHJhaW5ET01TdHJpbmdQYXJhbWV0ZXJzPig8TWVkaWFUcmFja0NvbnN0cmFpbnRzPmNvbnN0cmFpbnRzLnZpZGVvKS5kZXZpY2VJZCEhKS5leGFjdCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIicgbm90IGZvdW5kXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JOYW1lID0gT3BlblZpZHVFcnJvck5hbWUuUFVCTElTSEVSX1BST1BFUlRJRVNfRVJST1I7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIlZpZGVvIGlucHV0IGRldmljZSBkb2Vzbid0IHN1cHBvcnQgdGhlIHZhbHVlIHBhc3NlZCBmb3IgY29uc3RyYWludCAnXCIgKyBlcnJvci5jb25zdHJhaW50ICsgXCInXCI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2sobmV3IE9wZW5WaWR1RXJyb3IoZXJyb3JOYW1lLCBlcnJvck1lc3NhZ2UpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2Fib3J0ZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICBjYXNlICdub3RyZWFkYWJsZWVycm9yJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkRFVklDRV9BTFJFQURZX0lOX1VTRTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKG5ldyBPcGVuVmlkdUVycm9yKGVycm9yTmFtZSwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yTmFtZSA9IE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1I7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgPSBlcnJvci50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhuZXcgT3BlblZpZHVFcnJvcihlcnJvck5hbWUsIGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBteUNvbnN0cmFpbnRzID0gYXdhaXQgdGhpcy5vcGVudmlkdS5nZW5lcmF0ZU1lZGlhQ29uc3RyYWludHModGhpcy5wcm9wZXJ0aWVzKTtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICghIW15Q29uc3RyYWludHMudmlkZW9UcmFjayAmJiAhIW15Q29uc3RyYWludHMuYXVkaW9UcmFjaykgfHxcbiAgICAgICAgICAgICAgICAgICAgKCEhbXlDb25zdHJhaW50cy5hdWRpb1RyYWNrICYmIG15Q29uc3RyYWludHMuY29uc3RyYWludHM/LnZpZGVvID09PSBmYWxzZSkgfHxcbiAgICAgICAgICAgICAgICAgICAgKCEhbXlDb25zdHJhaW50cy52aWRlb1RyYWNrICYmIG15Q29uc3RyYWludHMuY29uc3RyYWludHM/LmF1ZGlvID09PSBmYWxzZSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTm8gbmVlZCB0byBjYWxsIGdldFVzZXJNZWRpYSBhdCBhbGwuIE1lZGlhU3RyZWFtVHJhY2tzIGFscmVhZHkgcHJvdmlkZWRcbiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKHRoaXMub3BlbnZpZHUuYWRkQWxyZWFkeVByb3ZpZGVkVHJhY2tzKG15Q29uc3RyYWludHMsIG5ldyBNZWRpYVN0cmVhbSgpLCB0aGlzLnN0cmVhbSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzID0gbXlDb25zdHJhaW50cy5jb25zdHJhaW50cztcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBvdXRib3VuZFN0cmVhbU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzOiBjb25zdHJhaW50cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlclByb3BlcnRpZXM6IHRoaXMucHJvcGVydGllc1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRpb25zKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWZpbmVkQXVkaW9Db25zdHJhaW50ID0gY29uc3RyYWludHMuYXVkaW8gPT09IHVuZGVmaW5lZCA/IHRydWUgOiBjb25zdHJhaW50cy5hdWRpbztcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXguYXVkaW8gPSB0aGlzLnN0cmVhbS5pc1NlbmRTY3JlZW4oKSA/IGZhbHNlIDogZGVmaW5lZEF1ZGlvQ29uc3RyYWludDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3RyYWludHNBdXgudmlkZW8gPSBjb25zdHJhaW50cy52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIodGltZUZvckRpYWxvZ0V2ZW50KTtcblxuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpICYmIG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddICYmICFwbGF0Zm9ybS5pc0VsZWN0cm9uKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZWRpYVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXNbJ2dldERpc3BsYXlNZWRpYSddKHsgdmlkZW86IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5hZGRBbHJlYWR5UHJvdmlkZWRUcmFja3MobXlDb25zdHJhaW50cywgbWVkaWFTdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmxhc3RWaWRlb1RyYWNrQ29uc3RyYWludHMgPSBjb25zdHJhaW50c0F1eC52aWRlbztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBtZWRpYVN0cmVhbSA9IGF3YWl0IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzQXV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LmFkZEFscmVhZHlQcm92aWRlZFRyYWNrcyhteUNvbnN0cmFpbnRzLCBtZWRpYVN0cmVhbSwgdGhpcy5zdHJlYW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IGdldE1lZGlhU3VjY2VzcyhtZWRpYVN0cmVhbSwgZGVmaW5lZEF1ZGlvQ29uc3RyYWludCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBnZXRNZWRpYUVycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhc3luYyByZXBsYWNlVHJhY2tBdXgodHJhY2s6IE1lZGlhU3RyZWFtVHJhY2ssIHVwZGF0ZUxhc3RDb25zdHJhaW50czogYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICAvLyBTZXQgZmllbGQgXCJlbmFibGVkXCIgb2YgdGhlIG5ldyB0cmFjayB0byB0aGUgcHJldmlvdXMgdmFsdWVcbiAgICAgICAgY29uc3QgdHJhY2tPcmlnaW5hbEVuYWJsZWRWYWx1ZTogYm9vbGVhbiA9IHRyYWNrLmVuYWJsZWQ7XG4gICAgICAgIGlmICh0cmFjay5raW5kID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICB0cmFjay5lbmFibGVkID0gdGhpcy5zdHJlYW0udmlkZW9BY3RpdmU7XG4gICAgICAgIH0gZWxzZSBpZiAodHJhY2sua2luZCA9PT0gJ2F1ZGlvJykge1xuICAgICAgICAgICAgdHJhY2suZW5hYmxlZCA9IHRoaXMuc3RyZWFtLmF1ZGlvQWN0aXZlO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCkge1xuICAgICAgICAgICAgICAgIC8vIE9ubHkgaWYgdGhlIFB1Ymxpc2hlciBoYXMgYmVlbiBwdWJsaXNoZWQgaXMgbmVjZXNzYXJ5IHRvIGNhbGwgbmF0aXZlIFdlYiBBUEkgUlRDUnRwU2VuZGVyLnJlcGxhY2VUcmFja1xuICAgICAgICAgICAgICAgIC8vIElmIGl0IGhhcyBub3QgYmVlbiBwdWJsaXNoZWQgeWV0LCByZXBsYWNpbmcgaXQgb24gdGhlIE1lZGlhU3RyZWFtIG9iamVjdCBpcyBlbm91Z2hcbiAgICAgICAgICAgICAgICB0aGlzLnJlcGxhY2VUcmFja0luTWVkaWFTdHJlYW0odHJhY2ssIHVwZGF0ZUxhc3RDb25zdHJhaW50cyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmVwbGFjZVRyYWNrSW5SdGNSdHBTZW5kZXIodHJhY2spO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBQdWJsaXNoZXIgbm90IHB1Ymxpc2hlZC4gU2ltcGx5IHJlcGxhY2UgdGhlIHRyYWNrIG9uIHRoZSBsb2NhbCBNZWRpYVN0cmVhbVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VUcmFja0luTWVkaWFTdHJlYW0odHJhY2ssIHVwZGF0ZUxhc3RDb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICB0cmFjay5lbmFibGVkID0gdHJhY2tPcmlnaW5hbEVuYWJsZWRWYWx1ZTtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqXG4gICAgICogVG8gb2J0YWluIHRoZSB2aWRlb0RpbWVuc2lvbnMgd2Ugd2FpdCBmb3IgdGhlIHZpZGVvIHJlZmVyZW5jZSB0byBoYXZlIGVub3VnaCBtZXRhZGF0YVxuICAgICAqIGFuZCB0aGVuIHRyeSB0byB1c2UgTWVkaWFTdHJlYW1UcmFjay5nZXRTZXR0aW5nc01ldGhvZCgpLiBJZiBub3QgYXZhaWxhYmxlLCB0aGVuIHdlXG4gICAgICogdXNlIHRoZSBIVE1MVmlkZW9FbGVtZW50IHByb3BlcnRpZXMgdmlkZW9XaWR0aCBhbmQgdmlkZW9IZWlnaHRcbiAgICAgKi9cbiAgICBnZXRWaWRlb0RpbWVuc2lvbnMoKTogUHJvbWlzZTx7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIC8vIElvbmljIGlPUyBhbmQgU2FmYXJpIGlPUyBzdXBwb3NlZGx5IHJlcXVpcmUgdGhlIHZpZGVvIGVsZW1lbnQgdG8gYWN0dWFsbHkgZXhpc3QgaW5zaWRlIHRoZSBET01cbiAgICAgICAgICAgIGNvbnN0IHJlcXVpcmVzRG9tSW5zZXJ0aW9uOiBib29sZWFuID0gcGxhdGZvcm0uaXNJb25pY0lvcygpIHx8IHBsYXRmb3JtLmlzSU9TV2l0aFNhZmFyaSgpO1xuXG4gICAgICAgICAgICBsZXQgbG9hZGVkbWV0YWRhdGFMaXN0ZW5lcjtcbiAgICAgICAgICAgIGNvbnN0IHJlc29sdmVEaW1lbnNpb25zID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCB3aWR0aDogbnVtYmVyO1xuICAgICAgICAgICAgICAgIGxldCBoZWlnaHQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKVswXS5nZXRTZXR0aW5ncyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXR0aW5ncyA9IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkuZ2V0VmlkZW9UcmFja3MoKVswXS5nZXRTZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IHNldHRpbmdzLndpZHRoIHx8IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aDtcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gc2V0dGluZ3MuaGVpZ2h0IHx8IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9IZWlnaHQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ01lZGlhU3RyZWFtVHJhY2sgZG9lcyBub3QgaGF2ZSBnZXRTZXR0aW5ncyBtZXRob2Qgb24gJyArIHBsYXRmb3JtLmdldERlc2NyaXB0aW9uKCkpO1xuICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IHRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aDtcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gdGhpcy52aWRlb1JlZmVyZW5jZS52aWRlb0hlaWdodDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAobG9hZGVkbWV0YWRhdGFMaXN0ZW5lciAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UucmVtb3ZlRXZlbnRMaXN0ZW5lcignbG9hZGVkbWV0YWRhdGEnLCBsb2FkZWRtZXRhZGF0YUxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlcXVpcmVzRG9tSW5zZXJ0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoeyB3aWR0aCwgaGVpZ2h0IH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9SZWZlcmVuY2UucmVhZHlTdGF0ZSA+PSAxKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIHZpZGVvIGFscmVhZHkgaGFzIG1ldGFkYXRhIGF2YWlsYWJsZVxuICAgICAgICAgICAgICAgIC8vIE5vIG5lZWQgb2YgbG9hZGVkbWV0YWRhdGEgZXZlbnRcbiAgICAgICAgICAgICAgICByZXNvbHZlRGltZW5zaW9ucygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBUaGUgdmlkZW8gZG9lcyBub3QgaGF2ZSBtZXRhZGF0YSBhdmFpbGFibGUgeWV0XG4gICAgICAgICAgICAgICAgLy8gTXVzdCBsaXN0ZW4gdG8gbG9hZGVkbWV0YWRhdGEgZXZlbnRcbiAgICAgICAgICAgICAgICBsb2FkZWRtZXRhZGF0YUxpc3RlbmVyID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXRoaXMudmlkZW9SZWZlcmVuY2UudmlkZW9XaWR0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKGludGVydmFsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZURpbWVuc2lvbnMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9LCA0MCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlRGltZW5zaW9ucygpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRlZG1ldGFkYXRhJywgbG9hZGVkbWV0YWRhdGFMaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgaWYgKHJlcXVpcmVzRG9tSW5zZXJ0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGhpcy52aWRlb1JlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKSB7XG4gICAgICAgIGlmICh0aGlzLmVlLmdldExpc3RlbmVycygnc3RyZWFtUGxheWluZycpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZVZpZGVvUmVmZXJlbmNlKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSkge1xuICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndmlkZW8nKTtcbiAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZS5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICB0aGlzLnZpZGVvUmVmZXJlbmNlLm11dGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZS5hdXRvcGxheSA9IHRydWU7XG4gICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2UuY29udHJvbHMgPSBmYWxzZTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNTYWZhcmlCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIChwbGF0Zm9ybS5pc0lQaG9uZU9ySVBhZCgpICYmXG4gICAgICAgICAgICAgICAgKHBsYXRmb3JtLmlzQ2hyb21lTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzRWRnZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc09wZXJhTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzRmlyZWZveE1vYmlsZUJyb3dzZXIoKSkpXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy52aWRlb1JlZmVyZW5jZS5wbGF5c0lubGluZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdHJlYW0uc2V0TWVkaWFTdHJlYW0obWVkaWFTdHJlYW0pO1xuICAgICAgICBpZiAoISF0aGlzLmZpcnN0VmlkZW9FbGVtZW50KSB7XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZVZpZGVvRWxlbWVudCh0aGlzLmZpcnN0VmlkZW9FbGVtZW50LnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+dGhpcy5wcm9wZXJ0aWVzLmluc2VydE1vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudmlkZW9SZWZlcmVuY2Uuc3JjT2JqZWN0ID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVwbGFjZVRyYWNrSW5NZWRpYVN0cmVhbSh0cmFjazogTWVkaWFTdHJlYW1UcmFjaywgdXBkYXRlTGFzdENvbnN0cmFpbnRzOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSA9IHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpXG4gICAgICAgICAgICA/IHRoaXMuc3RyZWFtLmxvY2FsTWVkaWFTdHJlYW1XaGVuU3Vic2NyaWJlZFRvUmVtb3RlIVxuICAgICAgICAgICAgOiB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICBsZXQgcmVtb3ZlZFRyYWNrOiBNZWRpYVN0cmVhbVRyYWNrO1xuICAgICAgICBpZiAodHJhY2sua2luZCA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgcmVtb3ZlZFRyYWNrID0gbWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXTtcbiAgICAgICAgICAgIGlmICh1cGRhdGVMYXN0Q29uc3RyYWludHMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5sYXN0VmlkZW9UcmFja0NvbnN0cmFpbnRzID0gdHJhY2suZ2V0Q29uc3RyYWludHMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlbW92ZWRUcmFjayA9IG1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF07XG4gICAgICAgIH1cbiAgICAgICAgcmVtb3ZlZFRyYWNrLmVuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgcmVtb3ZlZFRyYWNrLnN0b3AoKTtcbiAgICAgICAgbWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2socmVtb3ZlZFRyYWNrKTtcbiAgICAgICAgbWVkaWFTdHJlYW0uYWRkVHJhY2sodHJhY2spO1xuICAgICAgICBjb25zdCB0cmFja0luZm8gPSB7XG4gICAgICAgICAgICBvbGRMYWJlbDogcmVtb3ZlZFRyYWNrPy5sYWJlbCB8fCAnJyxcbiAgICAgICAgICAgIG5ld0xhYmVsOiB0cmFjaz8ubGFiZWwgfHwgJydcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHRyYWNrLmtpbmQgPT09ICd2aWRlbycgJiYgdXBkYXRlTGFzdENvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmROZXdWaWRlb0RpbWVuc2lvbnNJZlJlcXVpcmVkKHRoaXMsICd0cmFja1JlcGxhY2VkJywgNTAsIDMwKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFRyYWNrQ2hhbmdlZEV2ZW50KHRoaXMsIHRyYWNrSW5mby5vbGRMYWJlbCwgdHJhY2tJbmZvLm5ld0xhYmVsLCAndmlkZW9UcmFjaycpO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1QdWJsaXNoZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uc2VuZFZpZGVvRGF0YSh0aGlzLnN0cmVhbS5zdHJlYW1NYW5hZ2VyLCA1LCB0cnVlLCA1KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0cmFjay5raW5kID09PSAnYXVkaW8nICYmIHVwZGF0ZUxhc3RDb25zdHJhaW50cykge1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kVHJhY2tDaGFuZ2VkRXZlbnQodGhpcywgdHJhY2tJbmZvLm9sZExhYmVsLCB0cmFja0luZm8ubmV3TGFiZWwsICdhdWRpb1RyYWNrJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRyYWNrLmtpbmQgPT09ICdhdWRpbycpIHtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc2FibGVIYXJrU3BlYWtpbmdFdmVudChmYWxzZSk7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNhYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KGZhbHNlKTtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc2FibGVIYXJrVm9sdW1lQ2hhbmdlRXZlbnQoZmFsc2UpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uaW5pdEhhcmtFdmVudHMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBzZXRQZXJtaXNzaW9uRGlhbG9nVGltZXIod2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnBlcm1pc3Npb25EaWFsb2dUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXRFdmVudCgnYWNjZXNzRGlhbG9nT3BlbmVkJywgW10pO1xuICAgICAgICB9LCB3YWl0VGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclBlcm1pc3Npb25EaWFsb2dUaW1lcihzdGFydFRpbWU6IG51bWJlciwgd2FpdFRpbWU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5wZXJtaXNzaW9uRGlhbG9nVGltZW91dCk7XG4gICAgICAgIGlmIChEYXRlLm5vdygpIC0gc3RhcnRUaW1lID4gd2FpdFRpbWUpIHtcbiAgICAgICAgICAgIC8vIFBlcm1pc3Npb24gZGlhbG9nIHdhcyBzaG93biBhbmQgbm93IGlzIGNsb3NlZFxuICAgICAgICAgICAgdGhpcy5lbWl0RXZlbnQoJ2FjY2Vzc0RpYWxvZ0Nsb3NlZCcsIFtdKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmVwbGFjZVRyYWNrSW5SdGNSdHBTZW5kZXIodHJhY2s6IE1lZGlhU3RyZWFtVHJhY2spOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3Qgc2VuZGVyczogUlRDUnRwU2VuZGVyW10gPSB0aGlzLnN0cmVhbS5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmdldFNlbmRlcnMoKTtcbiAgICAgICAgbGV0IHNlbmRlcjogUlRDUnRwU2VuZGVyIHwgdW5kZWZpbmVkO1xuICAgICAgICBpZiAodHJhY2sua2luZCA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgc2VuZGVyID0gc2VuZGVycy5maW5kKChzKSA9PiAhIXMudHJhY2sgJiYgcy50cmFjay5raW5kID09PSAndmlkZW8nKTtcbiAgICAgICAgICAgIGlmICghc2VuZGVyKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlcmUncyBubyByZXBsYWNlYWJsZSB0cmFjayBmb3IgdGhhdCBraW5kIG9mIE1lZGlhU3RyZWFtVHJhY2sgaW4gdGhpcyBQdWJsaXNoZXIgb2JqZWN0XCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRyYWNrLmtpbmQgPT09ICdhdWRpbycpIHtcbiAgICAgICAgICAgIHNlbmRlciA9IHNlbmRlcnMuZmluZCgocykgPT4gISFzLnRyYWNrICYmIHMudHJhY2sua2luZCA9PT0gJ2F1ZGlvJyk7XG4gICAgICAgICAgICBpZiAoIXNlbmRlcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZXJlJ3Mgbm8gcmVwbGFjZWFibGUgdHJhY2sgZm9yIHRoYXQga2luZCBvZiBNZWRpYVN0cmVhbVRyYWNrIGluIHRoaXMgUHVibGlzaGVyIG9iamVjdFwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biB0cmFjayBraW5kICcgKyB0cmFjay5raW5kKTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCAoc2VuZGVyIGFzIFJUQ1J0cFNlbmRlcikucmVwbGFjZVRyYWNrKHRyYWNrKTtcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4vQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuL0ZpbHRlcic7XG5pbXBvcnQgeyBPcGVuVmlkdSB9IGZyb20gJy4vT3BlblZpZHUnO1xuaW1wb3J0IHsgUHVibGlzaGVyIH0gZnJvbSAnLi9QdWJsaXNoZXInO1xuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTdWJzY3JpYmVyIH0gZnJvbSAnLi9TdWJzY3JpYmVyJztcbmltcG9ydCB7IENhcGFiaWxpdGllcyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9QdWJsaWMvQ2FwYWJpbGl0aWVzJztcbmltcG9ydCB7IEV2ZW50RGlzcGF0Y2hlciB9IGZyb20gJy4vRXZlbnREaXNwYXRjaGVyJztcbmltcG9ydCB7IFNpZ25hbE9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1NpZ25hbE9wdGlvbnMnO1xuaW1wb3J0IHsgU3Vic2NyaWJlclByb3BlcnRpZXMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHVibGljL1N1YnNjcmliZXJQcm9wZXJ0aWVzJztcbmltcG9ydCB7IFJlbW90ZUNvbm5lY3Rpb25PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvUmVtb3RlQ29ubmVjdGlvbk9wdGlvbnMnO1xuaW1wb3J0IHsgTG9jYWxDb25uZWN0aW9uT3B0aW9ucyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvSW50ZXJmYWNlcy9Qcml2YXRlL0xvY2FsQ29ubmVjdGlvbk9wdGlvbnMnO1xuaW1wb3J0IHsgU2Vzc2lvbk9wdGlvbnMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0ludGVyZmFjZXMvUHJpdmF0ZS9TZXNzaW9uT3B0aW9ucyc7XG5pbXBvcnQgeyBTZXNzaW9uRXZlbnRNYXAgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FdmVudE1hcC9TZXNzaW9uRXZlbnRNYXAnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbkV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvQ29ubmVjdGlvbkV2ZW50JztcbmltcG9ydCB7IEZpbHRlckV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRmlsdGVyRXZlbnQnO1xuaW1wb3J0IHsgUmVjb3JkaW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9SZWNvcmRpbmdFdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TZXNzaW9uRGlzY29ubmVjdGVkRXZlbnQnO1xuaW1wb3J0IHsgU2lnbmFsRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TaWduYWxFdmVudCc7XG5pbXBvcnQgeyBTcGVlY2hUb1RleHRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1NwZWVjaFRvVGV4dEV2ZW50JztcbmltcG9ydCB7IFN0cmVhbUV2ZW50IH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvU3RyZWFtRXZlbnQnO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9TdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uUHJvcGVydHlDaGFuZ2VkRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9Db25uZWN0aW9uUHJvcGVydHlDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgTmV0d29ya1F1YWxpdHlMZXZlbENoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL05ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkRXZlbnQnO1xuaW1wb3J0IHsgT3BlblZpZHVFcnJvciwgT3BlblZpZHVFcnJvck5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL09wZW5WaWR1RXJyb3InO1xuaW1wb3J0IHsgVmlkZW9JbnNlcnRNb2RlIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9WaWRlb0luc2VydE1vZGUnO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXIgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5pbXBvcnQgeyBQbGF0Zm9ybVV0aWxzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9VdGlscy9QbGF0Zm9ybSc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudFJlYXNvbiwgQ2hhbmdlZFByb3BlcnR5VHlwZSwgUmVjb3JkaW5nRXZlbnRSZWFzb24sIENvbm5lY3Rpb25FdmVudFJlYXNvbiwgU3RyZWFtRXZlbnRSZWFzb24gfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9UeXBlcy9UeXBlcyc7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuaW1wb3J0IHNlbXZlck1ham9yID0gcmVxdWlyZSgnc2VtdmVyL2Z1bmN0aW9ucy9tYWpvcicpO1xuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmltcG9ydCBzZW12ZXJNaW5vciA9IHJlcXVpcmUoJ3NlbXZlci9mdW5jdGlvbnMvbWlub3InKTtcbmltcG9ydCB7IEV4Y2VwdGlvbkV2ZW50LCBFeGNlcHRpb25FdmVudE5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FeGNlcHRpb25FdmVudCc7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmxldCBwbGF0Zm9ybTogUGxhdGZvcm1VdGlscztcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgdmlkZW8gY2FsbC4gSXQgY2FuIGFsc28gYmUgc2VlbiBhcyBhIHZpZGVvY29uZmVyZW5jZSByb29tIHdoZXJlIG11bHRpcGxlIHVzZXJzIGNhbiBjb25uZWN0LlxuICogUGFydGljaXBhbnRzIHdobyBwdWJsaXNoIHRoZWlyIHZpZGVvcyB0byBhIHNlc3Npb24gY2FuIGJlIHNlZW4gYnkgdGhlIHJlc3Qgb2YgdXNlcnMgY29ubmVjdGVkIHRvIHRoYXQgc3BlY2lmaWMgc2Vzc2lvbi5cbiAqIEluaXRpYWxpemVkIHdpdGggW1tPcGVuVmlkdS5pbml0U2Vzc2lvbl1dIG1ldGhvZC5cbiAqXG4gKiBTZWUgYXZhaWxhYmxlIGV2ZW50IGxpc3RlbmVycyBhdCBbW1Nlc3Npb25FdmVudE1hcF1dLlxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbiBleHRlbmRzIEV2ZW50RGlzcGF0Y2hlciB7XG4gICAgLyoqXG4gICAgICogTG9jYWwgY29ubmVjdGlvbiB0byB0aGUgU2Vzc2lvbi4gVGhpcyBvYmplY3QgaXMgZGVmaW5lZCBvbmx5IGFmdGVyIFtbU2Vzc2lvbi5jb25uZWN0XV0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGV4ZWN1dGVkLCBhbmQgY2FuIGJlIHJldHJpZXZlZCBzdWJzY3JpYmluZyB0byBgY29ubmVjdGlvbkNyZWF0ZWRgIGV2ZW50XG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIFVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBTZXNzaW9uXG4gICAgICovXG4gICAgc2Vzc2lvbklkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBDb2xsZWN0aW9uIG9mIGFsbCBTdHJlYW1NYW5hZ2VycyBvZiB0aGlzIFNlc3Npb24gKFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dKVxuICAgICAqL1xuICAgIHN0cmVhbU1hbmFnZXJzOiBTdHJlYW1NYW5hZ2VyW10gPSBbXTtcblxuICAgIC8qKlxuICAgICAqIE9iamVjdCBkZWZpbmluZyB0aGUgbWV0aG9kcyB0aGF0IHRoZSBjbGllbnQgaXMgYWJsZSB0byBjYWxsLiBUaGVzZSBhcmUgZGVmaW5lZCBieSB0aGUgW1tDb25uZWN0aW9uLnJvbGVdXS5cbiAgICAgKiBUaGlzIG9iamVjdCBpcyBvbmx5IGRlZmluZWQgYWZ0ZXIgW1tTZXNzaW9uLmNvbm5lY3RdXSBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVzb2x2ZWRcbiAgICAgKi9cbiAgICBjYXBhYmlsaXRpZXM6IENhcGFiaWxpdGllcztcblxuICAgIC8vIFRoaXMgbWFwIGlzIG9ubHkgdXNlZCB0byBhdm9pZCByYWNlIGNvbmRpdGlvbiBiZXR3ZWVuICdqb2luUm9vbScgcmVzcG9uc2UgYW5kICdvblBhcnRpY2lwYW50UHVibGlzaGVkJyBub3RpZmljYXRpb25cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlU3RyZWFtc0NyZWF0ZWQ6IE1hcDxzdHJpbmcsIGJvb2xlYW4+ID0gbmV3IE1hcCgpO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW90ZUNvbm5lY3Rpb25zOiBNYXA8c3RyaW5nLCBDb25uZWN0aW9uPiA9IG5ldyBNYXAoKTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb3BlbnZpZHU6IE9wZW5WaWR1O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvcHRpb25zOiBTZXNzaW9uT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdG9rZW46IHN0cmluZztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJpdmF0ZSB2aWRlb0RhdGFJbnRlcnZhbDogTm9kZUpTLlRpbWVvdXQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByaXZhdGUgdmlkZW9EYXRhVGltZW91dDogTm9kZUpTLlRpbWVvdXQ7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3Iob3BlbnZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHBsYXRmb3JtID0gUGxhdGZvcm1VdGlscy5nZXRJbnN0YW5jZSgpO1xuICAgICAgICB0aGlzLm9wZW52aWR1ID0gb3BlbnZpZHU7XG4gICAgfVxuXG4gICAgY29ubmVjdCh0b2tlbjogc3RyaW5nKTogUHJvbWlzZTxhbnk+O1xuICAgIGNvbm5lY3QodG9rZW46IHN0cmluZywgbWV0YWRhdGE6IGFueSk6IFByb21pc2U8YW55PjtcblxuICAgIC8qKlxuICAgICAqIENvbm5lY3RzIHRvIHRoZSBzZXNzaW9uIHVzaW5nIGB0b2tlbmAuIFBhcmFtZXRlciBgbWV0YWRhdGFgIGFsbG93cyB5b3UgdG8gcGFzcyBleHRyYSBkYXRhIHRvIHNoYXJlIHdpdGggb3RoZXIgdXNlcnMgd2hlblxuICAgICAqIHRoZXkgcmVjZWl2ZSBgc3RyZWFtQ3JlYXRlZGAgZXZlbnQuIFRoZSBzdHJ1Y3R1cmUgb2YgYG1ldGFkYXRhYCBzdHJpbmcgaXMgdXAgdG8geW91IChtYXliZSBzb21lIHN0YW5kYXJkaXplZCBmb3JtYXRcbiAgICAgKiBhcyBKU09OIG9yIFhNTCBpcyBhIGdvb2QgaWRlYSkuXG4gICAgICpcbiAgICAgKiBUaGlzIG1ldGFkYXRhIGlzIG5vdCBjb25zaWRlcmVkIHNlY3VyZSwgYXMgaXQgaXMgZ2VuZXJhdGVkIGluIHRoZSBjbGllbnQgc2lkZS4gVG8gcGFzcyBzZWN1cmUgZGF0YSwgYWRkIGl0IGFzIGEgcGFyYW1ldGVyIGluIHRoZVxuICAgICAqIHRva2VuIGdlbmVyYXRpb24gb3BlcmF0aW9uICh0aHJvdWdoIHRoZSBBUEkgUkVTVCwgb3BlbnZpZHUtamF2YS1jbGllbnQgb3Igb3BlbnZpZHUtbm9kZS1jbGllbnQpLlxuICAgICAqXG4gICAgICogT25seSBhZnRlciB0aGUgcmV0dXJuZWQgUHJvbWlzZSBpcyBzdWNjZXNzZnVsbHkgcmVzb2x2ZWQgW1tTZXNzaW9uLmNvbm5lY3Rpb25dXSBvYmplY3Qgd2lsbCBiZSBhdmFpbGFibGUgYW5kIHByb3Blcmx5IGRlZmluZWQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGZpcnN0IGRpc3BhdGNoIG9uZSBvciBtb3JlIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnRzIHVwb24gc3VjY2Vzc2Z1bCB0ZXJtaW5hdGlvbiBvZiB0aGlzIG1ldGhvZDpcbiAgICAgKiAtIEZpcnN0IG9uZSBmb3IgeW91ciBvd24gbG9jYWwgQ29ubmVjdGlvbiBvYmplY3QsIHNvIHlvdSBjYW4gcmV0cmlldmUgW1tTZXNzaW9uLmNvbm5lY3Rpb25dXSBwcm9wZXJ0eS5cbiAgICAgKiAtIFRoZW4gb25lIGZvciBlYWNoIHJlbW90ZSBDb25uZWN0aW9uIHByZXZpb3VzbHkgY29ubmVjdGVkIHRvIHRoZSBTZXNzaW9uLCBpZiBhbnkuIEFueSBvdGhlciByZW1vdGUgdXNlciBjb25uZWN0aW5nIHRvIHRoZSBTZXNzaW9uIGFmdGVyIHlvdSBoYXZlXG4gICAgICogc3VjY2Vzc2Z1bGx5IGNvbm5lY3RlZCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkNyZWF0ZWRgIGV2ZW50IHdoZW4gdGhleSBkbyBzby5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgdGhlIGxvY2FsIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCBmb3IgZWFjaCByZW1vdGUgYWN0aXZlIFtbUHVibGlzaGVyXV0gdGhhdCB3YXMgYWxyZWFkeSBzdHJlYW1pbmdcbiAgICAgKiB3aGVuIGNvbm5lY3RpbmcsIGp1c3QgYWZ0ZXIgZGlzcGF0Y2hpbmcgYWxsIHJlbW90ZSBgY29ubmVjdGlvbkNyZWF0ZWRgIGV2ZW50cy5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkNyZWF0ZWRgIGV2ZW50LlxuICAgICAqXG4gICAgICogU2VlIFtbQ29ubmVjdGlvbkV2ZW50XV0gYW5kIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlIHRvIHdoaWNoIHlvdSBtdXN0IHN1YnNjcmliZSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSB0aGUgY29ubmVjdGlvbiB0byB0aGUgU2Vzc2lvbiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90XG4gICAgICpcbiAgICAgKi9cbiAgICBjb25uZWN0KHRva2VuOiBzdHJpbmcsIG1ldGFkYXRhPzogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2tlbih0b2tlbik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wZW52aWR1LmNoZWNrU3lzdGVtUmVxdWlyZW1lbnRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBFYXJseSBjb25maWd1cmF0aW9uIHRvIGRlYWN0aXZhdGUgYXV0b21hdGljIHN1YnNjcmlwdGlvbiB0byBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudElkOiB0b2tlbixcbiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6ICEhbWV0YWRhdGEgPyB0aGlzLnN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhKSA6ICcnXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RBdXgodG9rZW4pXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHJlc29sdmUoKSlcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuQlJPV1NFUl9OT1RfU1VQUE9SVEVELFxuICAgICAgICAgICAgICAgICAgICAgICAgJ0Jyb3dzZXIgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5nZXROYW1lKCkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyAodmVyc2lvbiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmdldFZlcnNpb24oKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAnKSBmb3IgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5nZXRGYW1pbHkoKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAnIGlzIG5vdCBzdXBwb3J0ZWQgaW4gT3BlblZpZHUnXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMZWF2ZXMgdGhlIHNlc3Npb24sIGRlc3Ryb3lpbmcgYWxsIHN0cmVhbXMgYW5kIGRlbGV0aW5nIHRoZSB1c2VyIGFzIGEgcGFydGljaXBhbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBsb2NhbCBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHNlc3Npb25EaXNjb25uZWN0ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlIHRoZSBsZWF2aW5nIHBhcnRpY2lwYW50IGZyb20gZXZlcnkgU3Vic2NyaWJlciBvYmplY3Qgb2YgdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgUlRDUGVlckNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpXG4gICAgICogYW5kIGFsc28gZGVsZXRlcyBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gZWFjaCBTdWJzY3JpYmVyIChvbmx5IHRob3NlIFtjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXJdKC9lbi9zdGFibGUvY2hlYXRzaGVldC9tYW5hZ2UtdmlkZW9zLyNsZXQtb3BlbnZpZHUtdGFrZS1jYXJlLW9mLXRoZS12aWRlby1wbGF5ZXJzKSkuXG4gICAgICogRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIGVhY2ggU3Vic2NyaWJlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHNlc3Npb25EaXNjb25uZWN0ZWRgIHRvIGF2b2lkIHRoaXMgYmVoYXZpb3IgYW5kIHRha2UgY2FyZSBvZiBkaXNwb3NpbmcgYW5kIGNsZWFuaW5nIGFsbCB0aGUgU3Vic2NyaWJlciBvYmplY3RzIHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1Nlc3Npb25EaXNjb25uZWN0ZWRFdmVudF1dIGFuZCBbW1ZpZGVvRWxlbWVudEV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IGlmIHRoZXJlIGlzIGEgW1tQdWJsaXNoZXJdXSBvYmplY3QgcHVibGlzaGluZyB0byB0aGUgc2Vzc2lvbi5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSBzdG9wIGFsbCBtZWRpYSB0cmFja3MgYW5kIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFB1Ymxpc2hlciBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIENhbGwgYGV2ZW50LnByZXZlbnREZWZhdWx0KClgIHVwb24gZXZlbnQgYHN0cmVhbURlc3Ryb3llZGAgaWYgeW91IHdhbnQgdG8gY2xlYW4gdGhlIFB1Ymxpc2hlciBvYmplY3Qgb24geW91ciBvd24gb3IgcmUtcHVibGlzaCBpdCBpbiBhIGRpZmZlcmVudCBTZXNzaW9uICh0byBkbyBzbyBpdCBpcyBhIG1hbmRhdG9yeSByZXF1aXJlbWVudCB0byBjYWxsIGBTZXNzaW9uLnVucHVibGlzaCgpYFxuICAgICAqIG9yL2FuZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgIGluIHRoZSBwcmV2aW91cyBzZXNzaW9uKS4gU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgaWYgdGhlIGRpc2Nvbm5lY3RlZCBwYXJ0aWNpcGFudCB3YXMgcHVibGlzaGluZy5cbiAgICAgKiBUaGlzIGV2ZW50IHdpbGwgYXV0b21hdGljYWxseSB1bnN1YnNjcmliZSB0aGUgU3Vic2NyaWJlciBvYmplY3QgZnJvbSB0aGUgc2Vzc2lvbiAodGhpcyBpbmNsdWRlcyBjbG9zaW5nIHRoZSBSVENQZWVyQ29ubmVjdGlvbiBhbmQgZGlzcG9zaW5nIGFsbCBNZWRpYVN0cmVhbVRyYWNrcylcbiAgICAgKiBhbmQgYWxzbyBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGF0IFN1YnNjcmliZXIgKG9ubHkgdGhvc2UgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHlvdXJzZWxmLlxuICAgICAqIFNlZSBbW1N0cmVhbUV2ZW50XV0gYW5kIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBvdGhlciBwYXJ0aWNpcGFudCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gd2lsbCBkaXNwYXRjaCBhIGBjb25uZWN0aW9uRGVzdHJveWVkYCBldmVudCBpbiBhbnkgY2FzZS4gU2VlIFtbQ29ubmVjdGlvbkV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKi9cbiAgICBkaXNjb25uZWN0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmxlYXZlKGZhbHNlLCAnZGlzY29ubmVjdCcpO1xuICAgIH1cblxuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQpOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQsIHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzKTogU3Vic2NyaWJlcjtcbiAgICBzdWJzY3JpYmUoXG4gICAgICAgIHN0cmVhbTogU3RyZWFtLFxuICAgICAgICB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCxcbiAgICAgICAgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWRcbiAgICApOiBTdWJzY3JpYmVyO1xuICAgIHN1YnNjcmliZShcbiAgICAgICAgc3RyZWFtOiBTdHJlYW0sXG4gICAgICAgIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50IHwgdW5kZWZpbmVkLFxuICAgICAgICBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyxcbiAgICAgICAgY29tcGxldGlvbkhhbmRsZXI6IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWRcbiAgICApOiBTdWJzY3JpYmVyO1xuXG4gICAgLyoqXG4gICAgICogU3Vic2NyaWJlcyB0byBhIGBzdHJlYW1gLCBhZGRpbmcgYSBuZXcgSFRNTCB2aWRlbyBlbGVtZW50IHRvIERPTSB3aXRoIGBzdWJzY3JpYmVyUHJvcGVydGllc2Agc2V0dGluZ3MuIFRoaXMgbWV0aG9kIGlzIHVzdWFsbHkgY2FsbGVkIGluIHRoZSBjYWxsYmFjayBvZiBgc3RyZWFtQ3JlYXRlZGAgZXZlbnQuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSB0aGUgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGFkZGVkIHRvIERPTSAob25seSBpZiB5b3VcbiAgICAgKiBbbGV0IE9wZW5WaWR1IHRha2UgY2FyZSBvZiB0aGUgdmlkZW8gcGxheWVyc10oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS4gU2VlIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogVGhlIFtbU3Vic2NyaWJlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVBsYXlpbmdgIGV2ZW50IG9uY2UgdGhlIHJlbW90ZSBzdHJlYW0gc3RhcnRzIHBsYXlpbmcuIFNlZSBbW1N0cmVhbU1hbmFnZXJFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc3RyZWFtIFN0cmVhbSBvYmplY3QgdG8gc3Vic2NyaWJlIHRvXG4gICAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgSFRNTCBET00gZWxlbWVudCAob3IgaXRzIGBpZGAgYXR0cmlidXRlKSBpbiB3aGljaCB0aGUgdmlkZW8gZWxlbWVudCBvZiB0aGUgU3Vic2NyaWJlciB3aWxsIGJlIGluc2VydGVkIChzZWUgW1tTdWJzY3JpYmVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0pLiBJZiAqbnVsbCogb3IgKnVuZGVmaW5lZCogbm8gZGVmYXVsdCB2aWRlbyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoaXMgU3Vic2NyaWJlci5cbiAgICAgKiBZb3UgY2FuIGFsd2F5cyBjYWxsIG1ldGhvZCBbW1N1YnNjcmliZXIuYWRkVmlkZW9FbGVtZW50XV0gb3IgW1tTdWJzY3JpYmVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dIHRvIG1hbmFnZSB0aGUgdmlkZW8gZWxlbWVudHMgb24geW91ciBvd24gKHNlZSBbTWFuYWdlIHZpZGVvIHBsYXllcnNdKC9lbi9zdGFibGUvY2hlYXRzaGVldC9tYW5hZ2UtdmlkZW9zKSBzZWN0aW9uKVxuICAgICAqIEBwYXJhbSBjb21wbGV0aW9uSGFuZGxlciBgZXJyb3JgIHBhcmFtZXRlciBpcyBudWxsIGlmIGBzdWJzY3JpYmVgIHN1Y2NlZWRzLCBhbmQgaXMgZGVmaW5lZCBpZiBpdCBmYWlscy5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUoXG4gICAgICAgIHN0cmVhbTogU3RyZWFtLFxuICAgICAgICB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCxcbiAgICAgICAgcGFyYW0zPzogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpIHwgU3Vic2NyaWJlclByb3BlcnRpZXMsXG4gICAgICAgIHBhcmFtND86IChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWRcbiAgICApOiBTdWJzY3JpYmVyIHtcbiAgICAgICAgbGV0IHByb3BlcnRpZXM6IFN1YnNjcmliZXJQcm9wZXJ0aWVzID0ge307XG4gICAgICAgIGlmICghIXBhcmFtMyAmJiB0eXBlb2YgcGFyYW0zICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAgICAgIGluc2VydE1vZGU6XG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiBwYXJhbTMuaW5zZXJ0TW9kZSAhPT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICAgICAgICAgICAgICAgID8gdHlwZW9mIHBhcmFtMy5pbnNlcnRNb2RlID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gVmlkZW9JbnNlcnRNb2RlW3BhcmFtMy5pbnNlcnRNb2RlXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogcHJvcGVydGllcy5pbnNlcnRNb2RlXG4gICAgICAgICAgICAgICAgICAgICAgICA6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9BdWRpbzogdHlwZW9mIHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvICE9PSAndW5kZWZpbmVkJyA/IHBhcmFtMy5zdWJzY3JpYmVUb0F1ZGlvIDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVUb1ZpZGVvOiB0eXBlb2YgcGFyYW0zLnN1YnNjcmliZVRvVmlkZW8gIT09ICd1bmRlZmluZWQnID8gcGFyYW0zLnN1YnNjcmliZVRvVmlkZW8gOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnRNb2RlOiBWaWRlb0luc2VydE1vZGUuQVBQRU5ELFxuICAgICAgICAgICAgICAgIHN1YnNjcmliZVRvQXVkaW86IHRydWUsXG4gICAgICAgICAgICAgICAgc3Vic2NyaWJlVG9WaWRlbzogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjb21wbGV0aW9uSGFuZGxlcjogKChlcnJvcjogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoISFwYXJhbTMgJiYgdHlwZW9mIHBhcmFtMyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgY29tcGxldGlvbkhhbmRsZXIgPSBwYXJhbTM7XG4gICAgICAgIH0gZWxzZSBpZiAoISFwYXJhbTQpIHtcbiAgICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyID0gcGFyYW00O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLnNlc3Npb25Db25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgaWYgKGNvbXBsZXRpb25IYW5kbGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcih0aGlzLm5vdENvbm5lY3RlZEVycm9yKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgdGhpcy5ub3RDb25uZWN0ZWRFcnJvcigpO1xuICAgICAgICB9XG5cbiAgICAgICAgbG9nZ2VyLmluZm8oJ1N1YnNjcmliaW5nIHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuXG4gICAgICAgIHN0cmVhbVxuICAgICAgICAgICAgLnN1YnNjcmliZSgpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ1N1YnNjcmliZWQgY29ycmVjdGx5IHRvICcgKyBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgIGlmIChjb21wbGV0aW9uSGFuZGxlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRpb25IYW5kbGVyKHVuZGVmaW5lZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGlvbkhhbmRsZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0aW9uSGFuZGxlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXIgPSBuZXcgU3Vic2NyaWJlcihzdHJlYW0sIHRhcmdldEVsZW1lbnQsIHByb3BlcnRpZXMpO1xuICAgICAgICBpZiAoISFzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHN0cmVhbS5zdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudChzdWJzY3JpYmVyLnRhcmdldEVsZW1lbnQsIDxWaWRlb0luc2VydE1vZGU+cHJvcGVydGllcy5pbnNlcnRNb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3Vic2NyaWJlcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcm9taXNpZmllZCB2ZXJzaW9uIG9mIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXVxuICAgICAqL1xuICAgIHN1YnNjcmliZUFzeW5jKHN0cmVhbTogU3RyZWFtLCB0YXJnZXRFbGVtZW50OiBzdHJpbmcgfCBIVE1MRWxlbWVudCk6IFByb21pc2U8U3Vic2NyaWJlcj47XG4gICAgc3Vic2NyaWJlQXN5bmMoc3RyZWFtOiBTdHJlYW0sIHRhcmdldEVsZW1lbnQ6IHN0cmluZyB8IEhUTUxFbGVtZW50LCBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFByb21pc2U8U3Vic2NyaWJlcj47XG5cbiAgICBzdWJzY3JpYmVBc3luYyhzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudDogc3RyaW5nIHwgSFRNTEVsZW1lbnQsIHByb3BlcnRpZXM/OiBTdWJzY3JpYmVyUHJvcGVydGllcyk6IFByb21pc2U8U3Vic2NyaWJlcj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8U3Vic2NyaWJlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNlc3Npb25Db25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QodGhpcy5ub3RDb25uZWN0ZWRFcnJvcigpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHN1YnNjcmliZXI6IFN1YnNjcmliZXI7XG5cbiAgICAgICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHN1YnNjcmliZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICghIXByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyID0gdGhpcy5zdWJzY3JpYmUoc3RyZWFtLCB0YXJnZXRFbGVtZW50LCBwcm9wZXJ0aWVzLCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIgPSB0aGlzLnN1YnNjcmliZShzdHJlYW0sIHRhcmdldEVsZW1lbnQsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVW5zdWJzY3JpYmVzIGZyb20gYHN1YnNjcmliZXJgLCBhdXRvbWF0aWNhbGx5IHJlbW92aW5nIGl0cyBhc3NvY2lhdGVkIEhUTUwgdmlkZW8gZWxlbWVudHMuXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgW1tTdWJzY3JpYmVyXV0gb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudCBmb3IgZWFjaCB2aWRlbyBhc3NvY2lhdGVkIHRvIGl0IHRoYXQgd2FzIHJlbW92ZWQgZnJvbSBET00uXG4gICAgICogT25seSB2aWRlb3MgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgcmVtb3ZlZFxuICAgICAqXG4gICAgICogU2VlIFtbVmlkZW9FbGVtZW50RXZlbnRdXSB0byBsZWFybiBtb3JlXG4gICAgICovXG4gICAgdW5zdWJzY3JpYmUoc3Vic2NyaWJlcjogU3Vic2NyaWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNlc3Npb25Db25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QodGhpcy5ub3RDb25uZWN0ZWRFcnJvcigpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbklkID0gc3Vic2NyaWJlci5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQ7XG5cbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnVW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgJ3Vuc3Vic2NyaWJlRnJvbVZpZGVvJyxcbiAgICAgICAgICAgICAgICAgICAgeyBzZW5kZXI6IHN1YnNjcmliZXIuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkIH0sXG4gICAgICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgdW5zdWJzY3JpYmluZyBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnVW5zdWJzY3JpYmVkIGNvcnJlY3RseSBmcm9tICcgKyBjb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmliZXIuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlci5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLnN0cmVhbS5kaXNwb3NlTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHVibGlzaGVzIHRvIHRoZSBTZXNzaW9uIHRoZSBQdWJsaXNoZXIgb2JqZWN0XG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgbG9jYWwgW1tQdWJsaXNoZXJdXSBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1DcmVhdGVkYCBldmVudCB1cG9uIHN1Y2Nlc3NmdWwgdGVybWluYXRpb24gb2YgdGhpcyBtZXRob2QuIFNlZSBbW1N0cmVhbUV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBsb2NhbCBbW1B1Ymxpc2hlcl1dIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbVBsYXlpbmdgIG9uY2UgdGhlIG1lZGlhIHN0cmVhbSBzdGFydHMgcGxheWluZy4gU2VlIFtbU3RyZWFtTWFuYWdlckV2ZW50XV0gdG8gbGVhcm4gbW9yZS5cbiAgICAgKlxuICAgICAqIFRoZSBbW1Nlc3Npb25dXSBvYmplY3Qgb2YgZXZlcnkgb3RoZXIgcGFydGljaXBhbnQgY29ubmVjdGVkIHRvIHRoZSBzZXNzaW9uIHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtQ3JlYXRlZGAgZXZlbnQgc28gdGhleSBjYW4gc3Vic2NyaWJlIHRvIGl0LiBTZWUgW1tTdHJlYW1FdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgb25seSBhZnRlciB0aGUgcHVibGlzaGVyIHdhcyBzdWNjZXNzZnVsbHkgcHVibGlzaGVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBwdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2Vzc2lvbkNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCh0aGlzLm5vdENvbm5lY3RlZEVycm9yKCkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwdWJsaXNoZXIuc2Vzc2lvbiA9IHRoaXM7XG4gICAgICAgICAgICBwdWJsaXNoZXIuc3RyZWFtLnNlc3Npb24gPSB0aGlzO1xuXG4gICAgICAgICAgICBpZiAoIXB1Ymxpc2hlci5zdHJlYW0ucHVibGlzaGVkT25jZSkge1xuICAgICAgICAgICAgICAgIC8vICdTZXNzaW9uLnVucHVibGlzaChQdWJsaXNoZXIpJyBoYXMgTk9UIGJlZW4gY2FsbGVkXG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmFkZFN0cmVhbShwdWJsaXNoZXIuc3RyZWFtKTtcbiAgICAgICAgICAgICAgICBwdWJsaXNoZXIuc3RyZWFtXG4gICAgICAgICAgICAgICAgICAgIC5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZW5kVmlkZW9EYXRhKHB1Ymxpc2hlciwgOCwgdHJ1ZSwgNSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gJ1Nlc3Npb24udW5wdWJsaXNoKFB1Ymxpc2hlciknIGhhcyBiZWVuIGNhbGxlZC4gTXVzdCBpbml0aWFsaXplIGFnYWluIFB1Ymxpc2hlclxuICAgICAgICAgICAgICAgIHB1Ymxpc2hlclxuICAgICAgICAgICAgICAgICAgICAuaW5pdGlhbGl6ZSgpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5hZGRTdHJlYW0ocHVibGlzaGVyLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIucmVlc3RhYmxpc2hTdHJlYW1QbGF5aW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2hlci5zdHJlYW1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucHVibGlzaCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbmRWaWRlb0RhdGEocHVibGlzaGVyLCA4LCB0cnVlLCA1KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVW5wdWJsaXNoZXMgZnJvbSB0aGUgU2Vzc2lvbiB0aGUgUHVibGlzaGVyIG9iamVjdC5cbiAgICAgKlxuICAgICAqICMjIyMgRXZlbnRzIGRpc3BhdGNoZWRcbiAgICAgKlxuICAgICAqIFRoZSBbW1B1Ymxpc2hlcl1dIG9iamVjdCBvZiB0aGUgbG9jYWwgcGFydGljaXBhbnQgd2lsbCBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqIFRoaXMgZXZlbnQgd2lsbCBhdXRvbWF0aWNhbGx5IHN0b3AgYWxsIG1lZGlhIHRyYWNrcyBhbmQgZGVsZXRlIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byB0aGlzIFB1Ymxpc2hlclxuICAgICAqIChvbmx5IHRob3NlIHZpZGVvcyBbY3JlYXRlZCBieSBPcGVuVmlkdSBCcm93c2VyXSgvZW4vc3RhYmxlL2NoZWF0c2hlZXQvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLlxuICAgICAqIEZvciBldmVyeSB2aWRlbyByZW1vdmVkLCB0aGUgUHVibGlzaGVyIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgYHZpZGVvRWxlbWVudERlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogQ2FsbCBgZXZlbnQucHJldmVudERlZmF1bHQoKWAgdXBvbiBldmVudCBgc3RyZWFtRGVzdHJveWVkYCBpZiB5b3Ugd2FudCB0byBjbGVhbiB0aGUgUHVibGlzaGVyIG9iamVjdCBvbiB5b3VyIG93biBvciByZS1wdWJsaXNoIGl0IGluIGEgZGlmZmVyZW50IFNlc3Npb24uXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IG90aGVyIHBhcnRpY2lwYW50IGNvbm5lY3RlZCB0byB0aGUgc2Vzc2lvbiB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQuXG4gICAgICogVGhpcyBldmVudCB3aWxsIGF1dG9tYXRpY2FsbHkgdW5zdWJzY3JpYmUgdGhlIFN1YnNjcmliZXIgb2JqZWN0IGZyb20gdGhlIHNlc3Npb24gKHRoaXMgaW5jbHVkZXMgY2xvc2luZyB0aGUgUlRDUGVlckNvbm5lY3Rpb24gYW5kIGRpc3Bvc2luZyBhbGwgTWVkaWFTdHJlYW1UcmFja3MpIGFuZFxuICAgICAqIGRlbGV0ZSBhbnkgSFRNTCB2aWRlbyBlbGVtZW50IGFzc29jaWF0ZWQgdG8gaXQgKG9ubHkgdGhvc2UgW2NyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3Nlcl0oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI2xldC1vcGVudmlkdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKiBDYWxsIGBldmVudC5wcmV2ZW50RGVmYXVsdCgpYCB1cG9uIGV2ZW50IGBzdHJlYW1EZXN0cm95ZWRgIHRvIGF2b2lkIHRoaXMgZGVmYXVsdCBiZWhhdmlvciBhbmQgdGFrZSBjYXJlIG9mIGRpc3Bvc2luZyBhbmQgY2xlYW5pbmcgdGhlIFN1YnNjcmliZXIgb2JqZWN0IG9uIHlvdXIgb3duLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSBhbmQgW1tWaWRlb0VsZW1lbnRFdmVudF1dIHRvIGxlYXJuIG1vcmUuXG4gICAgICovXG4gICAgdW5wdWJsaXNoKHB1Ymxpc2hlcjogUHVibGlzaGVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2Vzc2lvbkNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgdGhpcy5ub3RDb25uZWN0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBwdWJsaXNoZXIuc3RyZWFtO1xuXG4gICAgICAgICAgICBpZiAoIXN0cmVhbS5jb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJ1RoZSBhc3NvY2lhdGVkIENvbm5lY3Rpb24gb2JqZWN0IG9mIHRoaXMgUHVibGlzaGVyIGlzIG51bGwnKSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmVhbS5jb25uZWN0aW9uICE9PSB0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgICAgICAgICAgICBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAnVGhlIGFzc29jaWF0ZWQgQ29ubmVjdGlvbiBvYmplY3Qgb2YgdGhpcyBQdWJsaXNoZXIgaXMgbm90IHlvdXIgbG9jYWwgQ29ubmVjdGlvbi4gICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgXCJPbmx5IG1vZGVyYXRvcnMgY2FuIGZvcmNlIHVucHVibGlzaCBvbiByZW1vdGUgU3RyZWFtcyB2aWEgJ2ZvcmNlVW5wdWJsaXNoJyBtZXRob2RcIlxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ1VucHVibGlzaGluZyBsb2NhbCBtZWRpYSAoJyArIHN0cmVhbS5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCArICcpJyk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCd1bnB1Ymxpc2hWaWRlbycsIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdNZWRpYSB1bnB1Ymxpc2hlZCBjb3JyZWN0bHknKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdHJlYW0uY29ubmVjdGlvbi5zdHJlYW0gPT0gc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIENvbm5lY3Rpb24uc3RyZWFtIG1heSBoYXZlIGNoYW5nZWQgaWYgU2Vzc2lvbi5wdWJsaXNoIHdhcyBjYWxsZWQgd2l0aCBvdGhlciBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgc3RyZWFtLmNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW1FdmVudCA9IG5ldyBTdHJlYW1FdmVudCh0cnVlLCBwdWJsaXNoZXIsICdzdHJlYW1EZXN0cm95ZWQnLCBwdWJsaXNoZXIuc3RyZWFtLCAndW5wdWJsaXNoJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoZXIuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbUV2ZW50LmNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIGxlYXZlIHRoZSBzZXNzaW9uXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgYmVoYXZpb3IgaXMgdGhlIHNhbWUgYXMgd2hlbiBzb21lIHVzZXIgY2FsbHMgW1tTZXNzaW9uLmRpc2Nvbm5lY3RdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICpcbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIGV2ZXJ5IHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc3RyZWFtRGVzdHJveWVkYCBldmVudCBpZiB0aGUgZXZpY3RlZCB1c2VyIHdhcyBwdWJsaXNoaW5nIGEgc3RyZWFtLCB3aXRoIHByb3BlcnR5IGByZWFzb25gIHNldCB0byBgXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcImAuXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCBleGNlcHQgdGhlIGV2aWN0ZWQgb25lIHdpbGwgZGlzcGF0Y2ggYSBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQgZm9yIHRoZSBldmljdGVkIHVzZXIsIHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKlxuICAgICAqIElmIGFueSwgdGhlIFtbUHVibGlzaGVyXV0gb2JqZWN0IG9mIHRoZSBldmljdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYC5cbiAgICAgKiBUaGUgW1tTZXNzaW9uXV0gb2JqZWN0IG9mIHRoZSBldmljdGVkIHBhcnRpY2lwYW50IHdpbGwgZGlzcGF0Y2ggYSBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgLlxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSwgW1tDb25uZWN0aW9uRXZlbnRdXSBhbmQgW1tTZXNzaW9uRGlzY29ubmVjdGVkRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHBhcnRpY2lwYW50IGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBldmljdGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlRGlzY29ubmVjdChjb25uZWN0aW9uOiBDb25uZWN0aW9uKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2Vzc2lvbkNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCh0aGlzLm5vdENvbm5lY3RlZEVycm9yKCkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsb2dnZXIuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGZvciBjb25uZWN0aW9uICcgKyBjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdmb3JjZURpc2Nvbm5lY3QnLCB7IGNvbm5lY3Rpb25JZDogY29ubmVjdGlvbi5jb25uZWN0aW9uSWQgfSwgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGZvcmNpbmcgZGlzY29ubmVjdCBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYSBkaXNjb25uZWN0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnRm9yY2luZyBkaXNjb25uZWN0IGNvcnJlY3RseSBmb3IgQ29ubmVjdGlvbiAnICsgY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb3JjZXMgc29tZSB1c2VyIHRvIHVucHVibGlzaCBhIFN0cmVhbVxuICAgICAqXG4gICAgICogIyMjIyBFdmVudHMgZGlzcGF0Y2hlZFxuICAgICAqXG4gICAgICogVGhlIGJlaGF2aW9yIGlzIHRoZSBzYW1lIGFzIHdoZW4gc29tZSB1c2VyIGNhbGxzIFtbU2Vzc2lvbi51bnB1Ymxpc2hdXSwgYnV0IGByZWFzb25gIHByb3BlcnR5IGluIGFsbCBldmVudHMgd2lsbCBiZSBgXCJmb3JjZVVucHVibGlzaEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogVGhlIFtbU2Vzc2lvbl1dIG9iamVjdCBvZiBldmVyeSBwYXJ0aWNpcGFudCB3aWxsIGRpc3BhdGNoIGEgYHN0cmVhbURlc3Ryb3llZGAgZXZlbnQgd2l0aCBwcm9wZXJ0eSBgcmVhc29uYCBzZXQgdG8gYFwiZm9yY2VEaXNjb25uZWN0QnlVc2VyXCJgXG4gICAgICpcbiAgICAgKiBUaGUgW1tQdWJsaXNoZXJdXSBvYmplY3Qgb2YgdGhlIGFmZmVjdGVkIHBhcnRpY2lwYW50IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGBzdHJlYW1EZXN0cm95ZWRgIGV2ZW50IHdpdGggcHJvcGVydHkgYHJlYXNvbmAgc2V0IHRvIGBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiYFxuICAgICAqXG4gICAgICogU2VlIFtbU3RyZWFtRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIG9ubHkgYWZ0ZXIgdGhlIHJlbW90ZSBTdHJlYW0gaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHVucHVibGlzaGVkIGZyb20gdGhlIHNlc3Npb24gYW5kIHJlamVjdGVkIHdpdGggYW4gRXJyb3Igb2JqZWN0IGlmIG5vdFxuICAgICAqL1xuICAgIGZvcmNlVW5wdWJsaXNoKHN0cmVhbTogU3RyZWFtKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2Vzc2lvbkNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCh0aGlzLm5vdENvbm5lY3RlZEVycm9yKCkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsb2dnZXIuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggZm9yIHN0cmVhbSAnICsgc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ2ZvcmNlVW5wdWJsaXNoJywgeyBzdHJlYW1JZDogc3RyZWFtLnN0cmVhbUlkIH0sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBmb3JjaW5nIHVucHVibGlzaCBmb3IgU3RyZWFtICcgKyBzdHJlYW0uc3RyZWFtSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gZm9yY2UgYW4gdW5wdWJsaXNoaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnRm9yY2luZyB1bnB1Ymxpc2ggY29ycmVjdGx5IGZvciBTdHJlYW0gJyArIHN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlbmRzIG9uZSBzaWduYWwuIGBzaWduYWxgIG9iamVjdCBoYXMgdGhlIGZvbGxvd2luZyBvcHRpb25hbCBwcm9wZXJ0aWVzOlxuICAgICAqIGBgYGpzb25cbiAgICAgKiB7ZGF0YTpzdHJpbmcsIHRvOkNvbm5lY3Rpb25bXSwgdHlwZTpzdHJpbmd9XG4gICAgICogYGBgXG4gICAgICogQWxsIHVzZXJzIHN1YnNjcmliZWQgdG8gdGhhdCBzaWduYWwgKGBzZXNzaW9uLm9uKCdzaWduYWw6dHlwZScsIC4uLilgIG9yIGBzZXNzaW9uLm9uKCdzaWduYWwnLCAuLi4pYCBmb3IgYWxsIHNpZ25hbHMpIGFuZCB3aG9zZSBDb25uZWN0aW9uIG9iamVjdHMgYXJlIGluIGB0b2AgYXJyYXkgd2lsbCByZWNlaXZlIGl0LiBUaGVpciBsb2NhbFxuICAgICAqIFNlc3Npb24gb2JqZWN0cyB3aWxsIGRpc3BhdGNoIGEgYHNpZ25hbGAgb3IgYHNpZ25hbDp0eXBlYCBldmVudC4gU2VlIFtbU2lnbmFsRXZlbnRdXSB0byBsZWFybiBtb3JlLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSBtZXNzYWdlIHN1Y2Nlc3NmdWxseSByZWFjaGVkIG9wZW52aWR1LXNlcnZlciBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90LiBfVGhpcyBkb2Vzbid0XG4gICAgICogbWVhbiB0aGF0IG9wZW52aWR1LXNlcnZlciBjb3VsZCByZXNlbmQgdGhlIG1lc3NhZ2UgdG8gYWxsIHRoZSBsaXN0ZWQgcmVjZWl2ZXJzLl9cbiAgICAgKi9cbiAgICBzaWduYWwoc2lnbmFsOiBTaWduYWxPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2Vzc2lvbkNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCh0aGlzLm5vdENvbm5lY3RlZEVycm9yKCkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBzaWduYWxNZXNzYWdlID0ge307XG5cbiAgICAgICAgICAgIGlmIChzaWduYWwudG8gJiYgc2lnbmFsLnRvLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uSWRzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgICAgIHNpZ25hbC50by5mb3JFYWNoKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uSWRzLnB1c2goY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgc2lnbmFsTWVzc2FnZVsndG8nXSA9IGNvbm5lY3Rpb25JZHM7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3RvJ10gPSBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2lnbmFsTWVzc2FnZVsnZGF0YSddID0gc2lnbmFsLmRhdGEgPyBzaWduYWwuZGF0YSA6ICcnO1xuXG4gICAgICAgICAgICBsZXQgdHlwZUF1eDogc3RyaW5nID0gc2lnbmFsLnR5cGUgPyBzaWduYWwudHlwZSA6ICdzaWduYWwnO1xuICAgICAgICAgICAgaWYgKCEhdHlwZUF1eCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlQXV4LnN1YnN0cmluZygwLCA3KSAhPT0gJ3NpZ25hbDonKSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGVBdXggPSAnc2lnbmFsOicgKyB0eXBlQXV4O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNpZ25hbE1lc3NhZ2VbJ3R5cGUnXSA9IHR5cGVBdXg7XG5cbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ3NlbmRNZXNzYWdlJyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IEpTT04uc3RyaW5naWZ5KHNpZ25hbE1lc3NhZ2UpXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgdG8gdGhlIFNwZWVjaC1Uby1UZXh0IGV2ZW50cyBmb3IgdGhpcyBbW1N0cmVhbV1dLiBUaGUgU2Vzc2lvbiBvYmplY3Qgd2lsbCBlbWl0IFtbU3BlZWNoVG9UZXh0RXZlbnRdXSBmb3IgdGhlIFN0cmVhbVxuICAgICAqIHdoZW4gc3BlZWNoIGlzIGRldGVjdGVkIGluIGl0cyBhdWRpbyB0cmFjay5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzdHJlYW0gLSBUaGUgU3RyZWFtIGZvciB3aGljaCB5b3Ugd2FudCB0byBzdGFydCByZWNlaXZpbmcgW1tTcGVlY2hUb1RleHRFdmVudF1dLlxuICAgICAqIEBwYXJhbSBsYW5nIC0gVGhlIGxhbmd1YWdlIG9mIHRoZSBTdHJlYW0ncyBhdWRpbyB0cmFjay4gSXQgbXVzdCBiZSBhIHZhbGlkIFtCQ1AtNDddKGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9iY3A0NykgbGFuZ3VhZ2UgdGFnIGxpa2UgXCJlbi1VU1wiIG9yIFwiZXMtRVNcIi5cbiAgICAgKiBcbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2UgKHRvIHdoaWNoIHlvdSBjYW4gb3B0aW9uYWxseSBzdWJzY3JpYmUgdG8pIHRoYXQgaXMgcmVzb2x2ZWQgaWYgdGhlIHNwZWVjaC10by10ZXh0IHN1YnNjcmlwdGlvblxuICAgICAqIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3QuXG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9TcGVlY2hUb1RleHQoc3RyZWFtOiBTdHJlYW0sIGxhbmc6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAnc3Vic2NyaWJlVG9TcGVlY2hUb1RleHQnLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbklkOiBzdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQsXG4gICAgICAgICAgICAgICAgICAgIGxhbmdcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVuc3Vic2NyaWJlIGZyb20gdGhlIFNwZWVjaC1Uby1UZXh0IGV2ZW50cyBmb3IgdGhpcyBbW1N0cmVhbV1dLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSBzcGVlY2gtdG8tdGV4dCBzdWJzY3JpcHRpb25cbiAgICAgKiB3YXMgc3VjY2Vzc2Z1bCBhbmQgcmVqZWN0ZWQgd2l0aCBhbiBFcnJvciBvYmplY3QgaWYgbm90LlxuICAgICAqL1xuICAgIHVuc3Vic2NyaWJlRnJvbVNwZWVjaFRvVGV4dChzdHJlYW06IFN0cmVhbSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAndW5zdWJzY3JpYmVGcm9tU3BlZWNoVG9UZXh0JyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25JZDogc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWUgW1tFdmVudERpc3BhdGNoZXIub25dXVxuICAgICAqL1xuICAgIG9uPEsgZXh0ZW5kcyBrZXlvZiBTZXNzaW9uRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI6IChldmVudDogU2Vzc2lvbkV2ZW50TWFwW0tdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgICAgIHN1cGVyLm9uQXV4KHR5cGUsIFwiRXZlbnQgJ1wiICsgdHlwZSArIFwiJyB0cmlnZ2VyZWQgYnkgJ1Nlc3Npb24nXCIsIGhhbmRsZXIpO1xuXG4gICAgICAgIGlmICh0eXBlID09PSAncHVibGlzaGVyU3RhcnRTcGVha2luZycpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBhbHJlYWR5IGF2YWlsYWJsZSByZW1vdGUgc3RyZWFtcyB3aXRoIGF1ZGlvLCBlbmFibGUgaGFyayAnc3BlYWtpbmcnIGV2ZW50IGluIGFsbCBvZiB0aGVtXG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmZvckVhY2goKHJlbW90ZUNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uLnN0cmVhbT8uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0uZW5hYmxlSGFya1NwZWFraW5nRXZlbnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghIXRoaXMuY29ubmVjdGlvbj8uc3RyZWFtPy5oYXNBdWRpbykge1xuICAgICAgICAgICAgICAgIC8vIElmIGNvbm5lY3RlZCB0byB0aGUgU2Vzc2lvbiBhbmQgcHVibGlzaGluZyB3aXRoIGF1ZGlvLCBhbHNvIGVuYWJsZSBoYXJrICdzcGVha2luZycgZXZlbnQgZm9yIHRoZSBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmVuYWJsZUhhcmtTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMgd2l0aCBhdWRpbywgZW5hYmxlIGhhcmsgJ3N0b3BwZWRfc3BlYWtpbmcnIGV2ZW50IGluIGFsbCBvZiB0aGVtXG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmZvckVhY2goKHJlbW90ZUNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uLnN0cmVhbT8uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0uZW5hYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24/LnN0cmVhbT8uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24gYW5kIHB1Ymxpc2hpbmcgd2l0aCBhdWRpbywgYWxzbyBlbmFibGUgaGFyayAnc3RvcHBlZF9zcGVha2luZycgZXZlbnQgZm9yIHRoZSBQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmVuYWJsZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uY2VdXVxuICAgICAqL1xuICAgIG9uY2U8SyBleHRlbmRzIGtleW9mIFNlc3Npb25FdmVudE1hcD4odHlwZTogSywgaGFuZGxlcjogKGV2ZW50OiBTZXNzaW9uRXZlbnRNYXBbS10pID0+IHZvaWQpOiB0aGlzIHtcbiAgICAgICAgc3VwZXIub25jZUF1eCh0eXBlLCBcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgJ1Nlc3Npb24nXCIsIGhhbmRsZXIpO1xuXG4gICAgICAgIGlmICh0eXBlID09PSAncHVibGlzaGVyU3RhcnRTcGVha2luZycpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBhbHJlYWR5IGF2YWlsYWJsZSByZW1vdGUgc3RyZWFtcyB3aXRoIGF1ZGlvLCBlbmFibGUgaGFyayAnc3BlYWtpbmcnIGV2ZW50IChvbmNlKSBpbiBhbGwgb2YgdGhlbSBvbmNlXG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmZvckVhY2goKHJlbW90ZUNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uLnN0cmVhbT8uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0uZW5hYmxlT25jZUhhcmtTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24/LnN0cmVhbT8uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBjb25uZWN0ZWQgdG8gdGhlIFNlc3Npb24gYW5kIHB1Ymxpc2hpbmcgd2l0aCBhdWRpbywgYWxzbyBlbmFibGUgaGFyayAnc3BlYWtpbmcnIGV2ZW50IChvbmNlKSBmb3IgdGhlIFB1Ymxpc2hlclxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZW5hYmxlT25jZUhhcmtTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWxyZWFkeSBhdmFpbGFibGUgcmVtb3RlIHN0cmVhbXMgd2l0aCBhdWRpbywgZW5hYmxlIGhhcmsgJ3N0b3BwZWRfc3BlYWtpbmcnIGV2ZW50IChvbmNlKSBpbiBhbGwgb2YgdGhlbSBvbmNlXG4gICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLmZvckVhY2goKHJlbW90ZUNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uLnN0cmVhbT8uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0uZW5hYmxlT25jZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uPy5zdHJlYW0/Lmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgY29ubmVjdGVkIHRvIHRoZSBTZXNzaW9uIGFuZCBwdWJsaXNoaW5nIHdpdGggYXVkaW8sIGFsc28gZW5hYmxlIGhhcmsgJ3N0b3BwZWRfc3BlYWtpbmcnIGV2ZW50IChvbmNlKSBmb3IgdGhlIFB1Ymxpc2hlclxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZW5hYmxlT25jZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9mZl1dXG4gICAgICovXG4gICAgb2ZmPEsgZXh0ZW5kcyBrZXlvZiBTZXNzaW9uRXZlbnRNYXA+KHR5cGU6IEssIGhhbmRsZXI/OiAoZXZlbnQ6IFNlc3Npb25FdmVudE1hcFtLXSkgPT4gdm9pZCk6IHRoaXMge1xuICAgICAgICBzdXBlci5vZmZBdXgodHlwZSwgaGFuZGxlcik7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJykge1xuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgU2Vzc2lvbiBvYmplY3Qgc3RpbGwgaGFzIHNvbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudFxuICAgICAgICAgICAgaWYgKCF0aGlzLmFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgZmFsc2UpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVDb25uZWN0aW9ucy5mb3JFYWNoKChyZW1vdGVDb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIXJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtPy5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBTdWJzY3JpYmVyIG9iamVjdCBzdGlsbCBoYXMgc29tZSBsaXN0ZW5lciBmb3IgdGhlIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuYW55U3BlZWNoRXZlbnRMaXN0ZW5lckVuYWJsZWQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBmYWxzZSwgcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtTWFuYWdlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5kaXNhYmxlSGFya1NwZWFraW5nRXZlbnQoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uPy5zdHJlYW0/LnN0cmVhbU1hbmFnZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgUHVibGlzaGVyIG9iamVjdCBzdGlsbCBoYXMgc29tZSBsaXN0ZW5lciBmb3IgdGhlIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5hbnlTcGVlY2hFdmVudExpc3RlbmVyRW5hYmxlZCgncHVibGlzaGVyU3RhcnRTcGVha2luZycsIGZhbHNlLCB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbU1hbmFnZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc2FibGVIYXJrU3BlYWtpbmdFdmVudChmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAvLyBDaGVjayBpZiBTZXNzaW9uIG9iamVjdCBzdGlsbCBoYXMgc29tZSBsaXN0ZW5lciBmb3IgdGhlIGV2ZW50XG4gICAgICAgICAgICBpZiAoIXRoaXMuYW55U3BlZWNoRXZlbnRMaXN0ZW5lckVuYWJsZWQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIGZhbHNlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuZm9yRWFjaCgocmVtb3RlQ29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoISFyZW1vdGVDb25uZWN0aW9uLnN0cmVhbT8uc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgU3Vic2NyaWJlciBvYmplY3Qgc3RpbGwgaGFzIHNvbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aGlzLmFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBmYWxzZSwgcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtTWFuYWdlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5kaXNhYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuY29ubmVjdGlvbj8uc3RyZWFtPy5zdHJlYW1NYW5hZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIFB1Ymxpc2hlciBvYmplY3Qgc3RpbGwgaGFzIHNvbWUgbGlzdGVuZXIgZm9yIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuYW55U3BlZWNoRXZlbnRMaXN0ZW5lckVuYWJsZWQoJ3B1Ymxpc2hlclN0b3BTcGVha2luZycsIGZhbHNlLCB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbU1hbmFnZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc2FibGVIYXJrU3RvcHBlZFNwZWFraW5nRXZlbnQoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEpvaW5lZChldmVudDogUmVtb3RlQ29ubmVjdGlvbk9wdGlvbnMpOiB2b2lkIHtcbiAgICAgICAgLy8gQ29ubmVjdGlvbiBzaG91bGRuJ3QgZXhpc3RcbiAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKGV2ZW50LmlkLCAnJylcbiAgICAgICAgICAgIC50aGVuKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0Nvbm5lY3Rpb24gJyArIGNvbm5lY3Rpb24uY29ubmVjdGlvbklkICsgJyBhbHJlYWR5IGV4aXN0cyBpbiBjb25uZWN0aW9ucyBsaXN0Jyk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChvcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IG5ldyBDb25uZWN0aW9uKHRoaXMsIGV2ZW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLnNldChldmVudC5pZCwgY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW25ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIGNvbm5lY3Rpb24sICcnKV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRMZWZ0KGV2ZW50OiB7IGNvbm5lY3Rpb25JZDogc3RyaW5nOyByZWFzb246IENvbm5lY3Rpb25FdmVudFJlYXNvbiB9KTogdm9pZCB7XG4gICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihldmVudC5jb25uZWN0aW9uSWQsICdvblBhcnRpY2lwYW50TGVmdCcpXG4gICAgICAgICAgICAudGhlbigoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCBzdHJlYW0sIGV2ZW50LnJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtRXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQuZGVsZXRlKHN0cmVhbS5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuZGVsZXRlKGNvbm5lY3Rpb24uY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnY29ubmVjdGlvbkRlc3Ryb3llZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgbmV3IENvbm5lY3Rpb25FdmVudChmYWxzZSwgdGhpcywgJ2Nvbm5lY3Rpb25EZXN0cm95ZWQnLCBjb25uZWN0aW9uLCBldmVudC5yZWFzb24pXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChvcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUGFydGljaXBhbnRQdWJsaXNoZWQoZXZlbnQ6IFJlbW90ZUNvbm5lY3Rpb25PcHRpb25zKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGFmdGVyQ29ubmVjdGlvbkZvdW5kID0gKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuc2V0KGNvbm5lY3Rpb24uY29ubmVjdGlvbklkLCBjb25uZWN0aW9uKTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLnJlbW90ZVN0cmVhbXNDcmVhdGVkLmdldChjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZCkpIHtcbiAgICAgICAgICAgICAgICAvLyBBdm9pZCByYWNlIGNvbmRpdGlvbiBiZXR3ZWVuIHN0cmVhbS5zdWJzY3JpYmUoKSBpbiBcIm9uUGFydGljaXBhbnRQdWJsaXNoZWRcIiBhbmQgaW4gXCJqb2luUm9vbVwiIHJwYyBjYWxsYmFja1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgY29uZGl0aW9uIGlzIGZhbHNlIGlmIG9wZW52aWR1LXNlcnZlciBzZW5kcyBcInBhcnRpY2lwYW50UHVibGlzaGVkXCIgZXZlbnQgdG8gYSBzdWJzY3JpYmVyIHBhcnRpY2lwYW50IHRoYXQgaGFzXG4gICAgICAgICAgICAgICAgLy8gYWxyZWFkeSBzdWJzY3JpYmVkIHRvIGNlcnRhaW4gc3RyZWFtIGluIHRoZSBjYWxsYmFjayBvZiBcImpvaW5Sb29tXCIgbWV0aG9kXG5cbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgY29ubmVjdGlvbi5zdHJlYW0sICcnKV0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnJlbW90ZVN0cmVhbXNDcmVhdGVkLnNldChjb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JZCwgdHJ1ZSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gR2V0IHRoZSBleGlzdGluZyBDb25uZWN0aW9uIGNyZWF0ZWQgb24gJ29uUGFydGljaXBhbnRKb2luZWQnIGZvclxuICAgICAgICAvLyBleGlzdGluZyBwYXJ0aWNpcGFudHMgb3IgY3JlYXRlIGEgbmV3IG9uZSBmb3IgbmV3IHBhcnRpY2lwYW50c1xuICAgICAgICBsZXQgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKGV2ZW50LmlkLCAnb25QYXJ0aWNpcGFudFB1Ymxpc2hlZCcpXG5cbiAgICAgICAgICAgIC50aGVuKChjb24pID0+IHtcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgZXhpc3RpbmcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBjb247XG4gICAgICAgICAgICAgICAgZXZlbnQubWV0YWRhdGEgPSBjb24uZGF0YTtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLnJlbW90ZU9wdGlvbnMgPSBldmVudDtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmluaXRSZW1vdGVTdHJlYW1zKGV2ZW50LnN0cmVhbXMpO1xuICAgICAgICAgICAgICAgIGFmdGVyQ29ubmVjdGlvbkZvdW5kKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgob3BlblZpZHVFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBuZXcgQ29ubmVjdGlvblxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCBldmVudCk7XG4gICAgICAgICAgICAgICAgYWZ0ZXJDb25uZWN0aW9uRm91bmQoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudFVucHVibGlzaGVkKGV2ZW50OiB7IGNvbm5lY3Rpb25JZDogc3RyaW5nOyByZWFzb246IFN0cmVhbUV2ZW50UmVhc29uIH0pOiB2b2lkIHtcbiAgICAgICAgaWYgKGV2ZW50LmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91ciBzdHJlYW0gaGFzIGJlZW4gZm9yY2VkbHkgdW5wdWJsaXNoZWQgZnJvbSB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgdGhpcy5zdG9wUHVibGlzaGVyU3RyZWFtKGV2ZW50LnJlYXNvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmdldFJlbW90ZUNvbm5lY3Rpb24oZXZlbnQuY29ubmVjdGlvbklkLCAnb25QYXJ0aWNpcGFudFVucHVibGlzaGVkJylcblxuICAgICAgICAgICAgICAgIC50aGVuKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUV2ZW50ID0gbmV3IFN0cmVhbUV2ZW50KHRydWUsIHRoaXMsICdzdHJlYW1EZXN0cm95ZWQnLCBjb25uZWN0aW9uLnN0cmVhbSEsIGV2ZW50LnJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1EZXN0cm95ZWQnLCBbc3RyZWFtRXZlbnRdKTtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtRXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIERlbGV0aW5nIHRoZSByZW1vdGUgc3RyZWFtIGlmIGl0IGV4aXN0c1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvbi5zdHJlYW0gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtSWQ6IHN0cmluZyA9IGNvbm5lY3Rpb24uc3RyZWFtIS5zdHJlYW1JZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlU3RyZWFtc0NyZWF0ZWQuZGVsZXRlKHN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24ucmVtb3ZlU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgob3BlblZpZHVFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25QYXJ0aWNpcGFudEV2aWN0ZWQoZXZlbnQ6IHsgY29ubmVjdGlvbklkOiBzdHJpbmc7IHJlYXNvbjogQ29ubmVjdGlvbkV2ZW50UmVhc29uIH0pOiB2b2lkIHtcbiAgICAgICAgaWYgKGV2ZW50LmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91IGhhdmUgYmVlbiBldmljdGVkIGZyb20gdGhlIHNlc3Npb25cbiAgICAgICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxlYXZlKHRydWUsIGV2ZW50LnJlYXNvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25OZXdNZXNzYWdlKGV2ZW50OiB7IHR5cGU/OiBzdHJpbmc7IGRhdGE/OiBzdHJpbmc7IGZyb20/OiBzdHJpbmcgfSk6IHZvaWQge1xuICAgICAgICBsb2dnZXIuaW5mbygnTmV3IHNpZ25hbDogJyArIEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG5cbiAgICAgICAgY29uc3Qgc3RyaXBwZWRUeXBlID0gISFldmVudC50eXBlID8gZXZlbnQudHlwZS5yZXBsYWNlKC9eKHNpZ25hbDopLywgJycpIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmICghIWV2ZW50LmZyb20pIHtcbiAgICAgICAgICAgIC8vIFNpZ25hbCBzZW50IGJ5IG90aGVyIGNsaWVudFxuICAgICAgICAgICAgdGhpcy5nZXRDb25uZWN0aW9uKFxuICAgICAgICAgICAgICAgIGV2ZW50LmZyb20sXG4gICAgICAgICAgICAgICAgXCJDb25uZWN0aW9uICdcIiArXG4gICAgICAgICAgICAgICAgZXZlbnQuZnJvbSArXG4gICAgICAgICAgICAgICAgXCInIHVua25vd24gd2hlbiAnb25OZXdNZXNzYWdlJy4gRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiBcIiArXG4gICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5yZW1vdGVDb25uZWN0aW9ucy5rZXlzKCkpICtcbiAgICAgICAgICAgICAgICAnLiBFeGlzdGluZyBsb2NhbCBjb25uZWN0aW9uOiAnICtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkXG4gICAgICAgICAgICApXG5cbiAgICAgICAgICAgICAgICAudGhlbigoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBzdHJpcHBlZFR5cGUsIGV2ZW50LmRhdGEsIGNvbm5lY3Rpb24pXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWV2ZW50LnR5cGUgJiYgZXZlbnQudHlwZSAhPT0gJ3NpZ25hbCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KGV2ZW50LnR5cGUsIFtuZXcgU2lnbmFsRXZlbnQodGhpcywgc3RyaXBwZWRUeXBlLCBldmVudC5kYXRhLCBjb25uZWN0aW9uKV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKG9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2lnbmFsIHNlbnQgYnkgc2VydmVyXG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2lnbmFsJywgW25ldyBTaWduYWxFdmVudCh0aGlzLCBzdHJpcHBlZFR5cGUsIGV2ZW50LmRhdGEsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgICAgIGlmICghIWV2ZW50LnR5cGUgJiYgZXZlbnQudHlwZSAhPT0gJ3NpZ25hbCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudChldmVudC50eXBlLCBbbmV3IFNpZ25hbEV2ZW50KHRoaXMsIHN0cmlwcGVkVHlwZSwgZXZlbnQuZGF0YSwgdW5kZWZpbmVkKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU3RyZWFtUHJvcGVydHlDaGFuZ2VkKGV2ZW50OiB7IGNvbm5lY3Rpb25JZDogc3RyaW5nOyBzdHJlYW1JZDogc3RyaW5nOyBwcm9wZXJ0eTogQ2hhbmdlZFByb3BlcnR5VHlwZTsgbmV3VmFsdWU6IGFueTsgcmVhc29uOiBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudFJlYXNvbiB9KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKGNvbm5lY3Rpb246IENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24uc3RyZWFtICYmIGNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkID09PSBldmVudC5zdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IGNvbm5lY3Rpb24uc3RyZWFtO1xuICAgICAgICAgICAgICAgIGxldCBvbGRWYWx1ZTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LnByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2F1ZGlvQWN0aXZlJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIG9sZFZhbHVlID0gc3RyZWFtLmF1ZGlvQWN0aXZlO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQubmV3VmFsdWUgPSBldmVudC5uZXdWYWx1ZSA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLmF1ZGlvQWN0aXZlID0gZXZlbnQubmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAndmlkZW9BY3RpdmUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBzdHJlYW0udmlkZW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5uZXdWYWx1ZSA9IGV2ZW50Lm5ld1ZhbHVlID09PSAndHJ1ZSc7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0udmlkZW9BY3RpdmUgPSBldmVudC5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd2aWRlb1RyYWNrJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Lm5ld1ZhbHVlID0gSlNPTi5wYXJzZShldmVudC5uZXdWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnYXVkaW9UcmFjayc6XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5uZXdWYWx1ZSA9IEpTT04ucGFyc2UoZXZlbnQubmV3VmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3ZpZGVvRGltZW5zaW9ucyc6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5uZXdWYWx1ZSA9IEpTT04ucGFyc2UoSlNPTi5wYXJzZShldmVudC5uZXdWYWx1ZSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnZpZGVvRGltZW5zaW9ucyA9IGV2ZW50Lm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHN0cmVhbS5maWx0ZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5uZXdWYWx1ZSA9IE9iamVjdC5rZXlzKGV2ZW50Lm5ld1ZhbHVlKS5sZW5ndGggPiAwID8gZXZlbnQubmV3VmFsdWUgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQubmV3VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIgPSBuZXcgRmlsdGVyKGV2ZW50Lm5ld1ZhbHVlLnR5cGUsIGV2ZW50Lm5ld1ZhbHVlLm9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5maWx0ZXIuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudC5uZXdWYWx1ZS5sYXN0RXhlY01ldGhvZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmlsdGVyLmxhc3RFeGVjTWV0aG9kID0gZXZlbnQubmV3VmFsdWUubGFzdEV4ZWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgc3RyZWFtLmZpbHRlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50Lm5ld1ZhbHVlID0gc3RyZWFtLmZpbHRlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcywgc3RyZWFtLCBldmVudC5wcm9wZXJ0eSwgZXZlbnQubmV3VmFsdWUsIG9sZFZhbHVlLCBldmVudC5yZWFzb24pXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgaWYgKCEhc3RyZWFtLnN0cmVhbU1hbmFnZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQoc3RyZWFtLnN0cmVhbU1hbmFnZXIsIHN0cmVhbSwgZXZlbnQucHJvcGVydHksIGV2ZW50Lm5ld1ZhbHVlLCBvbGRWYWx1ZSwgZXZlbnQucmVhc29uKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICAgICAgXCJObyBzdHJlYW0gd2l0aCBzdHJlYW1JZCAnXCIgK1xuICAgICAgICAgICAgICAgICAgICBldmVudC5zdHJlYW1JZCArXG4gICAgICAgICAgICAgICAgICAgIFwiJyBmb3VuZCBmb3IgY29ubmVjdGlvbiAnXCIgK1xuICAgICAgICAgICAgICAgICAgICBldmVudC5jb25uZWN0aW9uSWQgK1xuICAgICAgICAgICAgICAgICAgICBcIicgb24gJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcgZXZlbnRcIlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGV2ZW50LmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgLy8gWW91ciBzdHJlYW0gaGFzIGJlZW4gZm9yY2VkbHkgY2hhbmdlZCAoZmlsdGVyIGZlYXR1cmUpXG4gICAgICAgICAgICBjYWxsYmFjayh0aGlzLmNvbm5lY3Rpb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5nZXRSZW1vdGVDb25uZWN0aW9uKGV2ZW50LmNvbm5lY3Rpb25JZCwgJ29uU3RyZWFtUHJvcGVydHlDaGFuZ2VkJylcbiAgICAgICAgICAgICAgICAudGhlbigoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhjb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgob3BlblZpZHVFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgb25Db25uZWN0aW9uUHJvcGVydHlDaGFuZ2VkKGV2ZW50OiB7IHByb3BlcnR5OiBzdHJpbmc7IG5ld1ZhbHVlOiBhbnkgfSk6IHZvaWQge1xuICAgICAgICBsZXQgb2xkVmFsdWU7XG4gICAgICAgIHN3aXRjaCAoZXZlbnQucHJvcGVydHkpIHtcbiAgICAgICAgICAgIGNhc2UgJ3JvbGUnOlxuICAgICAgICAgICAgICAgIG9sZFZhbHVlID0gdGhpcy5jb25uZWN0aW9uLnJvbGUuc2xpY2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24ucm9sZSA9IGV2ZW50Lm5ld1ZhbHVlO1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5sb2NhbE9wdGlvbnMhLnJvbGUgPSBldmVudC5uZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3JlY29yZCc6XG4gICAgICAgICAgICAgICAgb2xkVmFsdWUgPSB0aGlzLmNvbm5lY3Rpb24ucmVjb3JkO1xuICAgICAgICAgICAgICAgIGV2ZW50Lm5ld1ZhbHVlID0gZXZlbnQubmV3VmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24ucmVjb3JkID0gZXZlbnQubmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLmxvY2FsT3B0aW9ucyEucmVjb3JkID0gZXZlbnQubmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICBuZXcgQ29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMsIHRoaXMuY29ubmVjdGlvbiwgZXZlbnQucHJvcGVydHksIGV2ZW50Lm5ld1ZhbHVlLCBvbGRWYWx1ZSlcbiAgICAgICAgXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uTmV0d29ya1F1YWxpdHlMZXZlbENoYW5nZWRDaGFuZ2VkKGV2ZW50OiB7IGNvbm5lY3Rpb25JZDogc3RyaW5nOyBuZXdWYWx1ZTogbnVtYmVyOyBvbGRWYWx1ZTogbnVtYmVyIH0pOiB2b2lkIHtcbiAgICAgICAgaWYgKGV2ZW50LmNvbm5lY3Rpb25JZCA9PT0gdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCkge1xuICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ25ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgIG5ldyBOZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZEV2ZW50KHRoaXMsIGV2ZW50Lm5ld1ZhbHVlLCBldmVudC5vbGRWYWx1ZSwgdGhpcy5jb25uZWN0aW9uKVxuICAgICAgICAgICAgXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmdldENvbm5lY3Rpb24oZXZlbnQuY29ubmVjdGlvbklkLCAnQ29ubmVjdGlvbiBub3QgZm91bmQgZm9yIGNvbm5lY3Rpb25JZCAnICsgZXZlbnQuY29ubmVjdGlvbklkKVxuICAgICAgICAgICAgICAgIC50aGVuKChjb25uZWN0aW9uOiBDb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCduZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBOZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZEV2ZW50KHRoaXMsIGV2ZW50Lm5ld1ZhbHVlLCBldmVudC5vbGRWYWx1ZSwgY29ubmVjdGlvbilcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKG9wZW5WaWR1RXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlY3ZJY2VDYW5kaWRhdGUoZXZlbnQ6IHtcbiAgICAgICAgc2VuZGVyQ29ubmVjdGlvbklkOiBzdHJpbmc7XG4gICAgICAgIGVuZHBvaW50TmFtZTogc3RyaW5nO1xuICAgICAgICBzZHBNTGluZUluZGV4OiBudW1iZXI7XG4gICAgICAgIHNkcE1pZDogc3RyaW5nO1xuICAgICAgICBjYW5kaWRhdGU6IHN0cmluZztcbiAgICB9KTogdm9pZCB7XG4gICAgICAgIC8vIFRoZSBldmVudCBjb250YWlucyBmaWVsZHMgdGhhdCBjYW4gYmUgdXNlZCB0byBvYnRhaW4gYSBwcm9wZXIgY2FuZGlkYXRlLFxuICAgICAgICAvLyB1c2luZyB0aGUgUlRDSWNlQ2FuZGlkYXRlIGNvbnN0cnVjdG9yOlxuICAgICAgICAvLyBodHRwczovL3czYy5naXRodWIuaW8vd2VicnRjLXBjLyNkb20tcnRjaWNlY2FuZGlkYXRlLWNvbnN0cnVjdG9yXG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZUluaXQ6IFJUQ0ljZUNhbmRpZGF0ZUluaXQgPSB7XG4gICAgICAgICAgICBjYW5kaWRhdGU6IGV2ZW50LmNhbmRpZGF0ZSxcbiAgICAgICAgICAgIHNkcE1MaW5lSW5kZXg6IGV2ZW50LnNkcE1MaW5lSW5kZXgsXG4gICAgICAgICAgICBzZHBNaWQ6IGV2ZW50LnNkcE1pZFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBpY2VDYW5kaWRhdGUgPSBuZXcgUlRDSWNlQ2FuZGlkYXRlKGNhbmRpZGF0ZUluaXQpO1xuXG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihcbiAgICAgICAgICAgIGV2ZW50LnNlbmRlckNvbm5lY3Rpb25JZCxcbiAgICAgICAgICAgICdDb25uZWN0aW9uIG5vdCBmb3VuZCBmb3IgY29ubmVjdGlvbklkICcgK1xuICAgICAgICAgICAgZXZlbnQuc2VuZGVyQ29ubmVjdGlvbklkICtcbiAgICAgICAgICAgICcgb3duaW5nIGVuZHBvaW50ICcgK1xuICAgICAgICAgICAgZXZlbnQuZW5kcG9pbnROYW1lICtcbiAgICAgICAgICAgICcuIEljZSBjYW5kaWRhdGUgd2lsbCBiZSBpZ25vcmVkOiAnICtcbiAgICAgICAgICAgIGljZUNhbmRpZGF0ZVxuICAgICAgICApXG4gICAgICAgICAgICAudGhlbigoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbTogU3RyZWFtID0gY29ubmVjdGlvbi5zdHJlYW0hO1xuICAgICAgICAgICAgICAgIHN0cmVhbVxuICAgICAgICAgICAgICAgICAgICAuZ2V0V2ViUnRjUGVlcigpXG4gICAgICAgICAgICAgICAgICAgIC5hZGRJY2VDYW5kaWRhdGUoaWNlQ2FuZGlkYXRlKVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0Vycm9yIGFkZGluZyBjYW5kaWRhdGUgZm9yICcgKyBzdHJlYW0hLnN0cmVhbUlkICsgJyBzdHJlYW0gb2YgZW5kcG9pbnQgJyArIGV2ZW50LmVuZHBvaW50TmFtZSArICc6ICcgKyBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKChvcGVuVmlkdUVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKG9wZW5WaWR1RXJyb3IpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uU2Vzc2lvbkNsb3NlZChtc2cpOiB2b2lkIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ1Nlc3Npb24gY2xvc2VkOiAnICsgSlNPTi5zdHJpbmdpZnkobXNnKSk7XG4gICAgICAgIGNvbnN0IHMgPSBtc2cuc2Vzc2lvbklkO1xuICAgICAgICBpZiAocyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc2Vzc2lvbi1jbG9zZWQnLCBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uOiBzXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dnZXIud2FybignU2Vzc2lvbiB1bmRlZmluZWQgb24gc2Vzc2lvbiBjbG9zZWQnLCBtc2cpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uTG9zdENvbm5lY3Rpb24ocmVhc29uOiBDb25uZWN0aW9uRXZlbnRSZWFzb24pOiB2b2lkIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ0xvc3QgY29ubmVjdGlvbiBpbiBTZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCk7XG4gICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbklkICYmICEhdGhpcy5jb25uZWN0aW9uICYmICF0aGlzLmNvbm5lY3Rpb24uZGlzcG9zZWQpIHtcbiAgICAgICAgICAgIHRoaXMubGVhdmUodHJ1ZSwgcmVhc29uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY292ZXJlZENvbm5lY3Rpb24oKTogdm9pZCB7XG4gICAgICAgIGxvZ2dlci5pbmZvKCdSZWNvdmVyZWQgY29ubmVjdGlvbiBpbiBTZXNzaW9uICcgKyB0aGlzLnNlc3Npb25JZCk7XG4gICAgICAgIHRoaXMucmVjb25uZWN0QnJva2VuU3RyZWFtcygpO1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncmVjb25uZWN0ZWQnLCBbXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uTWVkaWFFcnJvcihldmVudDogeyBlcnJvcjogc3RyaW5nIH0pOiB2b2lkIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdNZWRpYSBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG4gICAgICAgIGNvbnN0IGVyciA9IGV2ZW50LmVycm9yO1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnZXJyb3ItbWVkaWEnLCBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcjogZXJyXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dnZXIud2FybignUmVjZWl2ZWQgdW5kZWZpbmVkIG1lZGlhIGVycm9yOicsIGV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvblJlY29yZGluZ1N0YXJ0ZWQoZXZlbnQ6IHsgaWQ6IHN0cmluZzsgbmFtZTogc3RyaW5nIH0pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3JlY29yZGluZ1N0YXJ0ZWQnLCBbbmV3IFJlY29yZGluZ0V2ZW50KHRoaXMsICdyZWNvcmRpbmdTdGFydGVkJywgZXZlbnQuaWQsIGV2ZW50Lm5hbWUpXSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uUmVjb3JkaW5nU3RvcHBlZChldmVudDogeyBpZDogc3RyaW5nOyBuYW1lOiBzdHJpbmc7IHJlYXNvbjogUmVjb3JkaW5nRXZlbnRSZWFzb24gfSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncmVjb3JkaW5nU3RvcHBlZCcsIFtuZXcgUmVjb3JkaW5nRXZlbnQodGhpcywgJ3JlY29yZGluZ1N0b3BwZWQnLCBldmVudC5pZCwgZXZlbnQubmFtZSwgZXZlbnQucmVhc29uKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvbkZpbHRlckV2ZW50RGlzcGF0Y2hlZChldmVudDogeyBjb25uZWN0aW9uSWQ6IHN0cmluZzsgc3RyZWFtSWQ6IHN0cmluZzsgZmlsdGVyVHlwZTogc3RyaW5nOyBldmVudFR5cGU6IHN0cmluZzsgZGF0YTogc3RyaW5nIH0pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbklkOiBzdHJpbmcgPSBldmVudC5jb25uZWN0aW9uSWQ7XG4gICAgICAgIHRoaXMuZ2V0Q29ubmVjdGlvbihjb25uZWN0aW9uSWQsICdObyBjb25uZWN0aW9uIGZvdW5kIGZvciBjb25uZWN0aW9uSWQgJyArIGNvbm5lY3Rpb25JZCkudGhlbigoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oYEZpbHRlciBldmVudCBvZiB0eXBlIFwiJHtldmVudC5ldmVudFR5cGV9XCIgZGlzcGF0Y2hlZGApO1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtOiBTdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbSE7XG4gICAgICAgICAgICBpZiAoIXN0cmVhbSB8fCAhc3RyZWFtLmZpbHRlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIGBGaWx0ZXIgZXZlbnQgb2YgdHlwZSBcIiR7ZXZlbnQuZXZlbnRUeXBlfVwiIGRpc3BhdGNoZWQgZm9yIHN0cmVhbSAke3N0cmVhbS5zdHJlYW1JZH0gYnV0IHRoZXJlIGlzIG5vICR7IXN0cmVhbSA/ICdzdHJlYW0nIDogJ2ZpbHRlcidcbiAgICAgICAgICAgICAgICAgICAgfSBkZWZpbmVkYFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBldmVudEhhbmRsZXIgPSBzdHJlYW0uZmlsdGVyLmhhbmRsZXJzLmdldChldmVudC5ldmVudFR5cGUpO1xuICAgICAgICAgICAgaWYgKCFldmVudEhhbmRsZXIgfHwgdHlwZW9mIGV2ZW50SGFuZGxlciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFjdHVhbEhhbmRsZXJzOiBzdHJpbmdbXSA9IEFycmF5LmZyb20oc3RyZWFtLmZpbHRlci5oYW5kbGVycy5rZXlzKCkpO1xuICAgICAgICAgICAgICAgIHJldHVybiBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIGBGaWx0ZXIgZXZlbnQgb2YgdHlwZSBcIiR7ZXZlbnQuZXZlbnRUeXBlfVwiIG5vdCBoYW5kbGVkIG9yIG5vdCBhIGZ1bmN0aW9uISBBY3RpdmUgZmlsdGVyIGV2ZW50czogJHthY3R1YWxIYW5kbGVycy5qb2luKFxuICAgICAgICAgICAgICAgICAgICAgICAgJywnXG4gICAgICAgICAgICAgICAgICAgICl9YFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGV2ZW50SGFuZGxlci5jYWxsKHRoaXMsIG5ldyBGaWx0ZXJFdmVudChzdHJlYW0uZmlsdGVyLCBldmVudC5ldmVudFR5cGUsIGV2ZW50LmRhdGEpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIG9uRm9yY2libHlSZWNvbm5lY3RTdWJzY3JpYmVyKGV2ZW50OiB7IGNvbm5lY3Rpb25JZDogc3RyaW5nOyBzdHJlYW1JZDogc3RyaW5nOyBzZHBPZmZlcjogc3RyaW5nIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ2V0UmVtb3RlQ29ubmVjdGlvbihldmVudC5jb25uZWN0aW9uSWQsICdvbkZvcmNpYmx5UmVjb25uZWN0U3Vic2NyaWJlcicpXG4gICAgICAgICAgICAgICAgLnRoZW4oKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEhY29ubmVjdGlvbi5zdHJlYW0gJiYgY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWQgPT09IGV2ZW50LnN0cmVhbUlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHJlYW0gPSBjb25uZWN0aW9uLnN0cmVhbTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0cmVhbS5zZXR1cFJlY29ubmVjdGlvbkV2ZW50RW1pdHRlcihyZXNvbHZlLCByZWplY3QpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25nb2luZyByZWNvbm5lY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXYWl0IGZvciB0aGUgZXZlbnQgZW1pdHRlciB0byBiZSBmcmVlICh3aXRoIHN1Y2Nlc3Mgb3IgZXJyb3IpIGFuZCBjYWxsIHRoZSBtZXRob2QgYWdhaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RyZWFtLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlciFbJ29uRm9yY2libHlSZWNvbm5lY3RTdWJzY3JpYmVyTGFzdEV2ZW50J10gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUd28gb3IgbW9yZSBvbkZvcmNpYmx5UmVjb25uZWN0U3Vic2NyaWJlciBldmVudHMgd2VyZSByZWNlaXZlZCB3aGlsZSBhIHJlY29ubmVjdGlvbiBwcm9jZXNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9mIHRoZSBzdWJzY3JpYmVyIHdhcyBhbHJlYWR5IHRha2luZyBwbGFjZS4gQWx3YXlzIHVzZSB0aGUgbGFzdCBvbmUgdG8gcmV0cnkgdGhlIHJlLXN1YnNjcmlwdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBwcm9jZXNzLCBhcyB0aGF0IFNEUCBvZmZlciB3aWxsIGJlIHRoZSBvbmx5IG9uZSBhdmFpbGFibGUgYXQgdGhlIHNlcnZlciBzaWRlLiBJZ25vcmUgcHJldmlvdXMgb25lc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0ucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyIVsnb25Gb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXJMYXN0RXZlbnQnXSA9IGV2ZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KCdPbmdvaW5nIGZvcmNlZCBzdWJzY3JpYmVyIHJlY29ubmVjdGlvbicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSBvbkZvcmNpYmx5UmVjb25uZWN0U3Vic2NyaWJlciBldmVuIGhhcyBiZWVuIHJlY2VpdmVkIHdoaWxlIGEgcmVjb25uZWN0aW9uIHByb2Nlc3NcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb2YgdGhlIHN1YnNjcmliZXIgd2FzIGFscmVhZHkgdGFraW5nIHBsYWNlLiBTZXQgdXAgYSBsaXN0ZW5lciB0byB3YWl0IGZvciBpdCB0byByZXRyeSB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZm9yY2VkIHJlY29ubmVjdGlvbiBwcm9jZXNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIhWydvbkZvcmNpYmx5UmVjb25uZWN0U3Vic2NyaWJlckxhc3RFdmVudCddID0gZXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXZlbnRBdXggPSBzdHJlYW0ucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyIVsnb25Gb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXJMYXN0RXZlbnQnXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBzdHJlYW0ucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyIVsnb25Gb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXJMYXN0RXZlbnQnXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25Gb3JjaWJseVJlY29ubmVjdFN1YnNjcmliZXIoZXZlbnRBdXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0ucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyIS5vbmNlKCdzdWNjZXNzJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbS5yZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIhLm9uY2UoJ2Vycm9yJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyZWFtXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbXBsZXRlV2ViUnRjUGVlclJlY2VpdmUodHJ1ZSwgdHJ1ZSwgZXZlbnQuc2RwT2ZmZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gc3RyZWFtLmZpbmFsUmVzb2x2ZUZvclN1YnNjcmlwdGlvbih0cnVlLCByZXNvbHZlKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0uZmluYWxSZWplY3RGb3JTdWJzY3JpcHRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYEVycm9yIHdoaWxlIGZvcmNpYmx5IHJlY29ubmVjdGluZyByZW1vdGUgc3RyZWFtICR7ZXZlbnQuc3RyZWFtSWR9OiAke2Vycm9yLnRvU3RyaW5nKCl9YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVyck1zZyA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJObyBzdHJlYW0gd2l0aCBzdHJlYW1JZCAnXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnN0cmVhbUlkICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcIicgZm91bmQgZm9yIGNvbm5lY3Rpb24gJ1wiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5jb25uZWN0aW9uSWQgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiJyBvbiAnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJyBldmVudFwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGVyck1zZyk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVyck1zZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgob3BlblZpZHVFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3Iob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3Qob3BlblZpZHVFcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZWNvbm5lY3RCcm9rZW5TdHJlYW1zKCk6IHZvaWQge1xuICAgICAgICBsb2dnZXIuaW5mbygnUmUtZXN0YWJsaXNoaW5nIG1lZGlhIGNvbm5lY3Rpb25zLi4uJyk7XG4gICAgICAgIGxldCBzb21lUmVjb25uZWN0aW9uID0gZmFsc2U7XG4gICAgICAgIC8vIFJlLWVzdGFibGlzaCBQdWJsaXNoZXIgc3RyZWFtXG4gICAgICAgIGlmICghIXRoaXMuY29ubmVjdGlvbi5zdHJlYW0gJiYgdGhpcy5jb25uZWN0aW9uLnN0cmVhbS5zdHJlYW1JY2VDb25uZWN0aW9uU3RhdGVCcm9rZW4oKSkge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1JlLWVzdGFibGlzaGluZyBQdWJsaXNoZXIgJyArIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWQpO1xuICAgICAgICAgICAgdGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pbml0V2ViUnRjUGVlclNlbmQodHJ1ZSk7XG4gICAgICAgICAgICBzb21lUmVjb25uZWN0aW9uID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBSZS1lc3RhYmxpc2ggU3Vic2NyaWJlciBzdHJlYW1zXG4gICAgICAgIHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuZm9yRWFjaCgocmVtb3RlQ29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgaWYgKCEhcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0gJiYgcmVtb3RlQ29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWNlQ29ubmVjdGlvblN0YXRlQnJva2VuKCkpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIud2FybignUmUtZXN0YWJsaXNoaW5nIFN1YnNjcmliZXIgJyArIHJlbW90ZUNvbm5lY3Rpb24uc3RyZWFtLnN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICByZW1vdGVDb25uZWN0aW9uLnN0cmVhbS5pbml0V2ViUnRjUGVlclJlY2VpdmUodHJ1ZSk7XG4gICAgICAgICAgICAgICAgc29tZVJlY29ubmVjdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIXNvbWVSZWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdUaGVyZSB3ZXJlIG5vIG1lZGlhIHN0cmVhbXMgaW4gbmVlZCBvZiBhIHJlY29ubmVjdGlvbicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFzeW5jIG9uU3BlZWNoVG9UZXh0TWVzc2FnZShldmVudDoge1xuICAgICAgICB0aW1lc3RhbXA/OiBEYXRlO1xuICAgICAgICBzdHJlYW1JZDogc3RyaW5nO1xuICAgICAgICBjb25uZWN0aW9uSWQ6IHN0cmluZztcbiAgICAgICAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gICAgICAgIHRleHQ6IHN0cmluZztcbiAgICAgICAgcmVhc29uOiBzdHJpbmc7XG4gICAgICAgIHJhdzogc3RyaW5nO1xuICAgICAgICBsYW5nOiBzdHJpbmc7XG4gICAgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5nZXRDb25uZWN0aW9uKGV2ZW50LmNvbm5lY3Rpb25JZCwgJ05vIGNvbm5lY3Rpb24gZm91bmQgZm9yIGNvbm5lY3Rpb25JZCAnICsgZXZlbnQuY29ubmVjdGlvbklkKTtcbiAgICAgICAgY29uc3QgZXYgPSBuZXcgU3BlZWNoVG9UZXh0RXZlbnQodGhpcywgY29ubmVjdGlvbiwgZXZlbnQudGV4dCwgPGFueT4oZXZlbnQucmVhc29uKS50b0xvd2VyQ2FzZSgpLCBldmVudC5yYXcsIGV2ZW50LmxhbmcpO1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3BlZWNoVG9UZXh0TWVzc2FnZScsIFtldl0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhc3luYyBvblNwZWVjaFRvVGV4dERpc2Nvbm5lY3RlZChldmVudDogeyBtZXNzYWdlOiBzdHJpbmcgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLmVtaXRFdmVudCgnZXhjZXB0aW9uJywgW25ldyBFeGNlcHRpb25FdmVudCh0aGlzLCBFeGNlcHRpb25FdmVudE5hbWUuU1BFRUNIX1RPX1RFWFRfRElTQ09OTkVDVEVELCB0aGlzLCBldmVudC5tZXNzYWdlKV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbWl0RXZlbnQodHlwZTogc3RyaW5nLCBldmVudEFycmF5OiBhbnlbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCh0eXBlLCBldmVudEFycmF5KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbGVhdmUoZm9yY2VkOiBib29sZWFuLCByZWFzb246IENvbm5lY3Rpb25FdmVudFJlYXNvbik6IHZvaWQge1xuICAgICAgICBmb3JjZWQgPSAhIWZvcmNlZDtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ0xlYXZpbmcgU2Vzc2lvbiAoZm9yY2VkPScgKyBmb3JjZWQgKyAnKScpO1xuICAgICAgICB0aGlzLnN0b3BWaWRlb0RhdGFJbnRlcnZhbHMoKTtcblxuICAgICAgICBpZiAoISF0aGlzLmNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkICYmICFmb3JjZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdsZWF2ZVJvb20nLCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBsZWF2ZVJvb20gZXJyb3I6ICR7SlNPTi5zdHJpbmdpZnkoZXJyb3IpfWApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuY2xvc2VXcygpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LmNsb3NlV3MoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5zdG9wUHVibGlzaGVyU3RyZWFtKHJlYXNvbik7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5jb25uZWN0aW9uLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBTZXNzaW9uIG9iamVjdCBkaXNwYXRjaCAnc2Vzc2lvbkRpc2Nvbm5lY3RlZCcgZXZlbnQgKGlmIGl0IGlzIG5vdCBhbHJlYWR5IGRpc3Bvc2VkKVxuICAgICAgICAgICAgICAgIGNvbnN0IHNlc3Npb25EaXNjb25uZWN0RXZlbnQgPSBuZXcgU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50KHRoaXMsIHJlYXNvbik7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3Nlc3Npb25EaXNjb25uZWN0ZWQnLCBbc2Vzc2lvbkRpc2Nvbm5lY3RFdmVudF0pO1xuICAgICAgICAgICAgICAgIHNlc3Npb25EaXNjb25uZWN0RXZlbnQuY2FsbERlZmF1bHRCZWhhdmlvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1lvdSB3ZXJlIG5vdCBjb25uZWN0ZWQgdG8gdGhlIHNlc3Npb24gJyArIHRoaXMuc2Vzc2lvbklkKTtcbiAgICAgICAgfVxuICAgICAgICBsb2dnZXIuZmx1c2goKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZVBhcmFtcyh0b2tlbjogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IGpvaW5QYXJhbXMgPSB7XG4gICAgICAgICAgICB0b2tlbjogISF0b2tlbiA/IHRva2VuIDogJycsXG4gICAgICAgICAgICBzZXNzaW9uOiB0aGlzLnNlc3Npb25JZCxcbiAgICAgICAgICAgIHBsYXRmb3JtOiAhIXBsYXRmb3JtLmdldERlc2NyaXB0aW9uKCkgPyBwbGF0Zm9ybS5nZXREZXNjcmlwdGlvbigpIDogJ3Vua25vd24nLFxuICAgICAgICAgICAgc2RrVmVyc2lvbjogdGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbixcbiAgICAgICAgICAgIG1ldGFkYXRhOiAhIXRoaXMub3B0aW9ucy5tZXRhZGF0YSA/IHRoaXMub3B0aW9ucy5tZXRhZGF0YSA6ICcnLFxuICAgICAgICAgICAgc2VjcmV0OiB0aGlzLm9wZW52aWR1LmdldFNlY3JldCgpLFxuICAgICAgICAgICAgcmVjb3JkZXI6IHRoaXMub3BlbnZpZHUuZ2V0UmVjb3JkZXIoKSxcbiAgICAgICAgICAgIHN0dDogdGhpcy5vcGVudmlkdS5nZXRTdHQoKVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gam9pblBhcmFtcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2VuZFZpZGVvRGF0YShzdHJlYW1NYW5hZ2VyOiBTdHJlYW1NYW5hZ2VyLCBpbnRlcnZhbFNlY29uZHM6IG51bWJlciA9IDEsIGRvSW50ZXJ2YWw6IGJvb2xlYW4gPSBmYWxzZSwgbWF4TG9vcHM6IG51bWJlciA9IDEpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNDaHJvbWVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzQ2hyb21lTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc09wZXJhQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc09wZXJhTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0VkZ2VCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzRWRnZU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNFbGVjdHJvbigpIHx8XG4gICAgICAgICAgICAocGxhdGZvcm0uaXNTYWZhcmlCcm93c2VyKCkgJiYgIXBsYXRmb3JtLmlzSW9uaWNJb3MoKSkgfHxcbiAgICAgICAgICAgIHBsYXRmb3JtLmlzQW5kcm9pZEJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgcGxhdGZvcm0uaXNTYW1zdW5nQnJvd3NlcigpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0lvbmljQW5kcm9pZCgpIHx8XG4gICAgICAgICAgICBwbGF0Zm9ybS5pc0lPU1dpdGhTYWZhcmkoKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IG9idGFpbkFuZFNlbmRWaWRlbyA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYyA9IHN0cmVhbU1hbmFnZXIuc3RyZWFtLmdldFJUQ1BlZXJDb25uZWN0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKHBjLmNvbm5lY3Rpb25TdGF0ZSA9PT0gJ2Nvbm5lY3RlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdHNNYXAgPSBhd2FpdCBwYy5nZXRTdGF0cygpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhcnI6IGFueVtdID0gW107XG4gICAgICAgICAgICAgICAgICAgIHN0YXRzTWFwLmZvckVhY2goKHN0YXRzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoJ2ZyYW1lV2lkdGgnIGluIHN0YXRzICYmICdmcmFtZUhlaWdodCcgaW4gc3RhdHMgJiYgYXJyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyci5wdXNoKHN0YXRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhcnIubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAndmlkZW9EYXRhJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogYXJyWzBdLmZyYW1lSGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogYXJyWzBdLmZyYW1lV2lkdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBzdHJlYW1NYW5hZ2VyLnN0cmVhbS52aWRlb0FjdGl2ZSAhPSBudWxsID8gc3RyZWFtTWFuYWdlci5zdHJlYW0udmlkZW9BY3RpdmUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVkaW9BY3RpdmU6IHN0cmVhbU1hbmFnZXIuc3RyZWFtLmF1ZGlvQWN0aXZlICE9IG51bGwgPyBzdHJlYW1NYW5hZ2VyLnN0cmVhbS5hdWRpb0FjdGl2ZSA6IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyAndmlkZW9EYXRhJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChkb0ludGVydmFsKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxvb3BzID0gMTtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvRGF0YUludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAobG9vcHMgPCBtYXhMb29wcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9vcHMrKztcbiAgICAgICAgICAgICAgICAgICAgICAgIG9idGFpbkFuZFNlbmRWaWRlbygpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnZpZGVvRGF0YUludGVydmFsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sIGludGVydmFsU2Vjb25kcyAqIDEwMDApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvRGF0YVRpbWVvdXQgPSBzZXRUaW1lb3V0KG9idGFpbkFuZFNlbmRWaWRlbywgaW50ZXJ2YWxTZWNvbmRzICogMTAwMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAocGxhdGZvcm0uaXNGaXJlZm94QnJvd3NlcigpIHx8IHBsYXRmb3JtLmlzRmlyZWZveE1vYmlsZUJyb3dzZXIoKSB8fCBwbGF0Zm9ybS5pc0lvbmljSW9zKCkgfHwgcGxhdGZvcm0uaXNSZWFjdE5hdGl2ZSgpKSB7XG4gICAgICAgICAgICAvLyBCYXNpYyB2ZXJzaW9uIGZvciBGaXJlZm94IGFuZCBJb25pYyBpT1MuIFRoZXkgZG8gbm90IHN1cHBvcnQgc3RhdHNcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgJ3ZpZGVvRGF0YScsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHN0cmVhbU1hbmFnZXIuc3RyZWFtLnZpZGVvRGltZW5zaW9ucz8uaGVpZ2h0IHx8IDAsXG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiBzdHJlYW1NYW5hZ2VyLnN0cmVhbS52aWRlb0RpbWVuc2lvbnM/LndpZHRoIHx8IDAsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiBzdHJlYW1NYW5hZ2VyLnN0cmVhbS52aWRlb0FjdGl2ZSAhPSBudWxsID8gc3RyZWFtTWFuYWdlci5zdHJlYW0udmlkZW9BY3RpdmUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9BY3RpdmU6IHN0cmVhbU1hbmFnZXIuc3RyZWFtLmF1ZGlvQWN0aXZlICE9IG51bGwgPyBzdHJlYW1NYW5hZ2VyLnN0cmVhbS5hdWRpb0FjdGl2ZSA6IGZhbHNlXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFwiRXJyb3Igc2VuZGluZyAndmlkZW9EYXRhJyBldmVudFwiLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICdCcm93c2VyICcgK1xuICAgICAgICAgICAgICAgIHBsYXRmb3JtLmdldE5hbWUoKSArXG4gICAgICAgICAgICAgICAgJyAodmVyc2lvbiAnICtcbiAgICAgICAgICAgICAgICBwbGF0Zm9ybS5nZXRWZXJzaW9uKCkgK1xuICAgICAgICAgICAgICAgICcpIGZvciAnICtcbiAgICAgICAgICAgICAgICBwbGF0Zm9ybS5nZXRGYW1pbHkoKSArXG4gICAgICAgICAgICAgICAgJyBpcyBub3Qgc3VwcG9ydGVkIGluIE9wZW5WaWR1IGZvciBOZXR3b3JrIFF1YWxpdHknXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNlc3Npb25Db25uZWN0ZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb24gIT0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgbm90Q29ubmVjdGVkRXJyb3IoKTogT3BlblZpZHVFcnJvciB7XG4gICAgICAgIHJldHVybiBuZXcgT3BlblZpZHVFcnJvcihcbiAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX05PVF9DT05ORUNURUQsXG4gICAgICAgICAgICBcIlRoZXJlIGlzIG5vIGNvbm5lY3Rpb24gdG8gdGhlIHNlc3Npb24uIE1ldGhvZCAnU2Vzc2lvbi5jb25uZWN0JyBtdXN0IGJlIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgZmlyc3RcIlxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhbnlTcGVlY2hFdmVudExpc3RlbmVyRW5hYmxlZChldmVudDogc3RyaW5nLCBvbmx5T25jZTogYm9vbGVhbiwgc3RyZWFtTWFuYWdlcj86IFN0cmVhbU1hbmFnZXIpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IGhhbmRsZXJzSW5TZXNzaW9uID0gdGhpcy5lZS5nZXRMaXN0ZW5lcnMoZXZlbnQpO1xuICAgICAgICBpZiAob25seU9uY2UpIHtcbiAgICAgICAgICAgIGhhbmRsZXJzSW5TZXNzaW9uID0gaGFuZGxlcnNJblNlc3Npb24uZmlsdGVyKChoKSA9PiAoaCBhcyBhbnkpLm9uY2UpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBsaXN0ZW5lcnNJblNlc3Npb24gPSBoYW5kbGVyc0luU2Vzc2lvbi5sZW5ndGg7XG4gICAgICAgIGlmIChsaXN0ZW5lcnNJblNlc3Npb24gPiAwKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgbGV0IGxpc3RlbmVyc0luU3RyZWFtTWFuYWdlciA9IDA7XG4gICAgICAgIGlmICghIXN0cmVhbU1hbmFnZXIpIHtcbiAgICAgICAgICAgIGxldCBoYW5kbGVyc0luU3RyZWFtTWFuYWdlciA9IHN0cmVhbU1hbmFnZXIuZWUuZ2V0TGlzdGVuZXJzKGV2ZW50KTtcbiAgICAgICAgICAgIGlmIChvbmx5T25jZSkge1xuICAgICAgICAgICAgICAgIGhhbmRsZXJzSW5TdHJlYW1NYW5hZ2VyID0gaGFuZGxlcnNJblN0cmVhbU1hbmFnZXIuZmlsdGVyKChoKSA9PiAoaCBhcyBhbnkpLm9uY2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGlzdGVuZXJzSW5TdHJlYW1NYW5hZ2VyID0gaGFuZGxlcnNJblN0cmVhbU1hbmFnZXIubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsaXN0ZW5lcnNJblN0cmVhbU1hbmFnZXIgPiAwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRUb2tlblBhcmFtcyh0b2tlbjogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IG1hdGNoID0gdG9rZW4ubWF0Y2goL14od3NzPylcXDpcXC9cXC8oKFteOlxcLz8jXSopKD86XFw6KFswLTldKykpPykoW1xcL117MCwxfVtePyNdKikoXFw/W14jXSp8KSgjLip8KSQvKTtcbiAgICAgICAgaWYgKCEhbWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IHtcbiAgICAgICAgICAgICAgICBwcm90b2NvbDogbWF0Y2hbMV0sXG4gICAgICAgICAgICAgICAgaG9zdDogbWF0Y2hbMl0sXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IG1hdGNoWzNdLFxuICAgICAgICAgICAgICAgIHBvcnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICAgIHBhdGhuYW1lOiBtYXRjaFs1XSxcbiAgICAgICAgICAgICAgICBzZWFyY2g6IG1hdGNoWzZdLFxuICAgICAgICAgICAgICAgIGhhc2g6IG1hdGNoWzddXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0b2tlbi5zcGxpdCgnPycpO1xuICAgICAgICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBkZWNvZGVVUkkocGFyYW1zWzFdKVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnJicpXG4gICAgICAgICAgICAgICAgLm1hcCgocGFyYW0pID0+IHBhcmFtLnNwbGl0KCc9JykpXG4gICAgICAgICAgICAgICAgLnJlZHVjZSgodmFsdWVzLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICAgICAgICAgICAgICB9LCB7fSk7XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbklkOiBxdWVyeVBhcmFtc1snc2Vzc2lvbklkJ10sXG4gICAgICAgICAgICAgICAgc2VjcmV0OiBxdWVyeVBhcmFtc1snc2VjcmV0J10sXG4gICAgICAgICAgICAgICAgcmVjb3JkZXI6IHF1ZXJ5UGFyYW1zWydyZWNvcmRlciddLFxuICAgICAgICAgICAgICAgIHN0dDogcXVlcnlQYXJhbXNbJ3N0dCddLFxuICAgICAgICAgICAgICAgIHdlYnJ0Y1N0YXRzSW50ZXJ2YWw6IHF1ZXJ5UGFyYW1zWyd3ZWJydGNTdGF0c0ludGVydmFsJ10sXG4gICAgICAgICAgICAgICAgc2VuZEJyb3dzZXJMb2dzOiBxdWVyeVBhcmFtc1snc2VuZEJyb3dzZXJMb2dzJ10sXG4gICAgICAgICAgICAgICAgZWRpdGlvbjogcXVlcnlQYXJhbXNbJ2VkaXRpb24nXSxcbiAgICAgICAgICAgICAgICB3c1VyaTogdXJsLnByb3RvY29sICsgJzovLycgKyB1cmwuaG9zdCArICcvb3BlbnZpZHUnLFxuICAgICAgICAgICAgICAgIGh0dHBVcmk6ICdodHRwczovLycgKyB1cmwuaG9zdFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVG9rZW4gbm90IHZhbGlkOiBcIiR7dG9rZW59XCJgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qIFByaXZhdGUgbWV0aG9kcyAqL1xuXG4gICAgcHJpdmF0ZSBjb25uZWN0QXV4KHRva2VuOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc3RhcnRXcygoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoISFlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBqb2luUGFyYW1zID0gdGhpcy5pbml0aWFsaXplUGFyYW1zKHRva2VuKTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdqb2luUm9vbScsIGpvaW5QYXJhbXMsIChlcnJvciwgcmVzcG9uc2U6IExvY2FsQ29ubmVjdGlvbk9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFByb2Nlc3Mgam9pbiByb29tIHJlc3BvbnNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzSm9pblJvb21SZXNwb25zZShyZXNwb25zZSwgdG9rZW4pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSBsb2NhbCBDb25uZWN0aW9uIG9iamVjdCB3aXRoIHZhbHVlcyByZXR1cm5lZCBieSBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBuZXcgQ29ubmVjdGlvbih0aGlzLCByZXNwb25zZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplIHJlbW90ZSBDb25uZWN0aW9ucyB3aXRoIHZhbHVlIHJldHVybmVkIGJ5IG9wZW52aWR1LXNlcnZlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50cyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnM6IG5ldyBBcnJheTxDb25uZWN0aW9uPigpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBuZXcgQXJyYXk8U3RyZWFtPigpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1BhcnRpY2lwYW50czogUmVtb3RlQ29ubmVjdGlvbk9wdGlvbnNbXSA9IHJlc3BvbnNlLnZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUGFydGljaXBhbnRzLmZvckVhY2goKHJlbW90ZUNvbm5lY3Rpb25PcHRpb25zOiBSZW1vdGVDb25uZWN0aW9uT3B0aW9ucykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gbmV3IENvbm5lY3Rpb24odGhpcywgcmVtb3RlQ29ubmVjdGlvbk9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlbW90ZUNvbm5lY3Rpb25zLnNldChjb25uZWN0aW9uLmNvbm5lY3Rpb25JZCwgY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW1vdGVTdHJlYW1zQ3JlYXRlZC5zZXQoY29ubmVjdGlvbi5zdHJlYW0uc3RyZWFtSWQsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRzLnN0cmVhbXMucHVzaChjb25uZWN0aW9uLnN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE93biAnY29ubmVjdGlvbkNyZWF0ZWQnIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ2Nvbm5lY3Rpb25DcmVhdGVkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ29ubmVjdGlvbkV2ZW50KGZhbHNlLCB0aGlzLCAnY29ubmVjdGlvbkNyZWF0ZWQnLCB0aGlzLmNvbm5lY3Rpb24sICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25lICdjb25uZWN0aW9uQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggZXhpc3RpbmcgY29ubmVjdGlvbiBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5jb25uZWN0aW9ucy5mb3JFYWNoKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdjb25uZWN0aW9uQ3JlYXRlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDb25uZWN0aW9uRXZlbnQoZmFsc2UsIHRoaXMsICdjb25uZWN0aW9uQ3JlYXRlZCcsIGNvbm5lY3Rpb24sICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9uZSAnc3RyZWFtQ3JlYXRlZCcgZXZlbnQgZm9yIGVhY2ggYWN0aXZlIHN0cmVhbSBpbiB0aGUgc2Vzc2lvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cy5zdHJlYW1zLmZvckVhY2goKHN0cmVhbSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtQ3JlYXRlZCcsIFtuZXcgU3RyZWFtRXZlbnQoZmFsc2UsIHRoaXMsICdzdHJlYW1DcmVhdGVkJywgc3RyZWFtLCAnJyldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghIXJlc3BvbnNlLnJlY29yZGluZ0lkICYmICEhcmVzcG9uc2UucmVjb3JkaW5nTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgncmVjb3JkaW5nU3RhcnRlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSZWNvcmRpbmdFdmVudCh0aGlzLCAncmVjb3JkaW5nU3RhcnRlZCcsIHJlc3BvbnNlLnJlY29yZGluZ0lkLCByZXNwb25zZS5yZWNvcmRpbmdOYW1lKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdG9wUHVibGlzaGVyU3RyZWFtKHJlYXNvbjogU3RyZWFtRXZlbnRSZWFzb24pIHtcbiAgICAgICAgaWYgKCEhdGhpcy5jb25uZWN0aW9uLnN0cmVhbSkge1xuICAgICAgICAgICAgLy8gRGlzcG9zZSBQdWJsaXNoZXIncyAgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3Rpb24uc3RyZWFtLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLnN0cmVhbS5pc0xvY2FsU3RyZWFtUHVibGlzaGVkKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFrZSBQdWJsaXNoZXIgb2JqZWN0IGRpc3BhdGNoICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50IGlmIHRoZSBTdHJlYW0gd2FzIHB1Ymxpc2hlZFxuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdGlvbi5zdHJlYW0uZWUuZW1pdEV2ZW50KCdsb2NhbC1zdHJlYW0tZGVzdHJveWVkJywgW3JlYXNvbl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdG9wVmlkZW9EYXRhSW50ZXJ2YWxzKCk6IHZvaWQge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMudmlkZW9EYXRhSW50ZXJ2YWwpO1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy52aWRlb0RhdGFUaW1lb3V0KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0cmluZ0NsaWVudE1ldGFkYXRhKG1ldGFkYXRhOiBhbnkpOiBzdHJpbmcge1xuICAgICAgICBpZiAodHlwZW9mIG1ldGFkYXRhICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KG1ldGFkYXRhKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBtZXRhZGF0YTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXRDb25uZWN0aW9uKGNvbm5lY3Rpb25JZDogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZyk6IFByb21pc2U8Q29ubmVjdGlvbj4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8Q29ubmVjdGlvbj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMucmVtb3RlQ29ubmVjdGlvbnMuZ2V0KGNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICBpZiAoISFjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVzb2x2ZSByZW1vdGUgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCA9PT0gY29ubmVjdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgbG9jYWwgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSh0aGlzLmNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIENvbm5lY3Rpb24gbm90IGZvdW5kLiBSZWplY3Qgd2l0aCBPcGVuVmlkdUVycm9yXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUiwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFJlbW90ZUNvbm5lY3Rpb24oY29ubmVjdGlvbklkOiBzdHJpbmcsIG9wZXJhdGlvbjogc3RyaW5nKTogUHJvbWlzZTxDb25uZWN0aW9uPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxDb25uZWN0aW9uPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5yZW1vdGVDb25uZWN0aW9ucy5nZXQoY29ubmVjdGlvbklkKTtcbiAgICAgICAgICAgIGlmICghIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHJlbW90ZSBjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoY29ubmVjdGlvbik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFJlbW90ZSBjb25uZWN0aW9uIG5vdCBmb3VuZC4gUmVqZWN0IHdpdGggT3BlblZpZHVFcnJvclxuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9XG4gICAgICAgICAgICAgICAgICAgICdSZW1vdGUgY29ubmVjdGlvbiAnICtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbklkICtcbiAgICAgICAgICAgICAgICAgICAgXCIgdW5rbm93biB3aGVuICdcIiArXG4gICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbiArXG4gICAgICAgICAgICAgICAgICAgIFwiJy4gXCIgK1xuICAgICAgICAgICAgICAgICAgICAnRXhpc3RpbmcgcmVtb3RlIGNvbm5lY3Rpb25zOiAnICtcbiAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5yZW1vdGVDb25uZWN0aW9ucy5rZXlzKCkpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuR0VORVJJQ19FUlJPUiwgZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcHJvY2Vzc1Rva2VuKHRva2VuOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdG9rZW5QYXJhbXMgPSB0aGlzLmdldFRva2VuUGFyYW1zKHRva2VuKTtcbiAgICAgICAgdGhpcy5zZXNzaW9uSWQgPSB0b2tlblBhcmFtcy5zZXNzaW9uSWQ7XG5cbiAgICAgICAgaWYgKCEhdG9rZW5QYXJhbXMuc2VjcmV0KSB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnNlY3JldCA9IHRva2VuUGFyYW1zLnNlY3JldDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISF0b2tlblBhcmFtcy5yZWNvcmRlcikge1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS5yZWNvcmRlciA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdG9rZW5QYXJhbXMuc3R0KSB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LnN0dCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdG9rZW5QYXJhbXMud2VicnRjU3RhdHNJbnRlcnZhbCkge1xuICAgICAgICAgICAgdGhpcy5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID0gdG9rZW5QYXJhbXMud2VicnRjU3RhdHNJbnRlcnZhbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISF0b2tlblBhcmFtcy5zZW5kQnJvd3NlckxvZ3MpIHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuc2VuZEJyb3dzZXJMb2dzID0gdG9rZW5QYXJhbXMuc2VuZEJyb3dzZXJMb2dzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3BlbnZpZHUuaXNBdExlYXN0UHJvID0gdG9rZW5QYXJhbXMuZWRpdGlvbiA9PT0gJ3BybycgfHwgdG9rZW5QYXJhbXMuZWRpdGlvbiA9PT0gJ2VudGVycHJpc2UnO1xuICAgICAgICB0aGlzLm9wZW52aWR1LmlzRW50ZXJwcmlzZSA9IHRva2VuUGFyYW1zLmVkaXRpb24gPT09ICdlbnRlcnByaXNlJztcblxuICAgICAgICB0aGlzLm9wZW52aWR1LndzVXJpID0gdG9rZW5QYXJhbXMud3NVcmk7XG4gICAgICAgIHRoaXMub3BlbnZpZHUuaHR0cFVyaSA9IHRva2VuUGFyYW1zLmh0dHBVcmk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwcm9jZXNzSm9pblJvb21SZXNwb25zZShvcHRzOiBMb2NhbENvbm5lY3Rpb25PcHRpb25zLCB0b2tlbjogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc2Vzc2lvbklkID0gb3B0cy5zZXNzaW9uO1xuICAgICAgICBpZiAob3B0cy5jdXN0b21JY2VTZXJ2ZXJzICE9IG51bGwgJiYgb3B0cy5jdXN0b21JY2VTZXJ2ZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuaWNlU2VydmVycyA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBpY2VTZXJ2ZXIgb2Ygb3B0cy5jdXN0b21JY2VTZXJ2ZXJzKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJ0Y0ljZVNlcnZlcjogUlRDSWNlU2VydmVyID0ge1xuICAgICAgICAgICAgICAgICAgICB1cmxzOiBbaWNlU2VydmVyLnVybF1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coJ1NUVU4vVFVSTiBzZXJ2ZXIgSVA6ICcgKyBpY2VTZXJ2ZXIudXJsKTtcbiAgICAgICAgICAgICAgICBpZiAoaWNlU2VydmVyLnVzZXJuYW1lICE9IG51bGwgJiYgaWNlU2VydmVyLmNyZWRlbnRpYWwgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBydGNJY2VTZXJ2ZXIudXNlcm5hbWUgPSBpY2VTZXJ2ZXIudXNlcm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIHJ0Y0ljZVNlcnZlci5jcmVkZW50aWFsID0gaWNlU2VydmVyLmNyZWRlbnRpYWw7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coJ1RVUk4gY3JlZGVudGlhbHMgWycgKyBpY2VTZXJ2ZXIudXNlcm5hbWUgKyAnOicgKyBpY2VTZXJ2ZXIuY3JlZGVudGlhbCArICddJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMub3BlbnZpZHUuaWNlU2VydmVycy5wdXNoKHJ0Y0ljZVNlcnZlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcGVudmlkdS5yb2xlID0gb3B0cy5yb2xlO1xuICAgICAgICB0aGlzLm9wZW52aWR1LmZpbmFsVXNlcklkID0gb3B0cy5maW5hbFVzZXJJZDtcbiAgICAgICAgdGhpcy5vcGVudmlkdS5tZWRpYVNlcnZlciA9IG9wdHMubWVkaWFTZXJ2ZXI7XG4gICAgICAgIHRoaXMub3BlbnZpZHUudmlkZW9TaW11bGNhc3QgPSBvcHRzLnZpZGVvU2ltdWxjYXN0O1xuICAgICAgICB0aGlzLmNhcGFiaWxpdGllcyA9IHtcbiAgICAgICAgICAgIHN1YnNjcmliZTogdHJ1ZSxcbiAgICAgICAgICAgIHB1Ymxpc2g6IHRoaXMub3BlbnZpZHUucm9sZSAhPT0gJ1NVQlNDUklCRVInLFxuICAgICAgICAgICAgZm9yY2VVbnB1Ymxpc2g6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUicsXG4gICAgICAgICAgICBmb3JjZURpc2Nvbm5lY3Q6IHRoaXMub3BlbnZpZHUucm9sZSA9PT0gJ01PREVSQVRPUidcbiAgICAgICAgfTtcbiAgICAgICAgbG9nZ2VyLmluZm8oJ29wZW52aWR1LXNlcnZlciB2ZXJzaW9uOiAnICsgb3B0cy52ZXJzaW9uKTtcbiAgICAgICAgaWYgKG9wdHMubGlmZSAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLm9wZW52aWR1LmxpZmUgPSBvcHRzLmxpZmU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWlub3JEaWZmZXJlbmNlOiBudW1iZXIgPSBzZW12ZXJNaW5vcihvcHRzLnZlcnNpb24pIC0gc2VtdmVyTWlub3IodGhpcy5vcGVudmlkdS5saWJyYXJ5VmVyc2lvbik7XG4gICAgICAgIGlmIChzZW12ZXJNYWpvcihvcHRzLnZlcnNpb24pICE9PSBzZW12ZXJNYWpvcih0aGlzLm9wZW52aWR1LmxpYnJhcnlWZXJzaW9uKSB8fCAhKG1pbm9yRGlmZmVyZW5jZSA9PSAwIHx8IG1pbm9yRGlmZmVyZW5jZSA9PSAxKSkge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgIGBvcGVudmlkdS1icm93c2VyICgke3RoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb259KSBhbmQgb3BlbnZpZHUtc2VydmVyICgke29wdHMudmVyc2lvbn0pIHZlcnNpb25zIGFyZSBpbmNvbXBhdGlibGUuIGAgK1xuICAgICAgICAgICAgICAgICdFcnJvcnMgYXJlIGxpa2VseSB0byBvY2N1ci4gb3BlbnZpZHUtYnJvd3NlciBTREsgaXMgb25seSBjb21wYXRpYmxlIHdpdGggdGhlIHNhbWUgdmVyc2lvbiBvciB0aGUgaW1tZWRpYXRlbHkgZm9sbG93aW5nIG1pbm9yIHZlcnNpb24gb2YgYW4gT3BlblZpZHUgZGVwbG95bWVudCdcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAobWlub3JEaWZmZXJlbmNlID09IDEpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgICAgICAgIGBvcGVudmlkdS1icm93c2VyIHZlcnNpb24gJHt0aGlzLm9wZW52aWR1LmxpYnJhcnlWZXJzaW9ufSBkb2VzIG5vdCBtYXRjaCBvcGVudmlkdS1zZXJ2ZXIgdmVyc2lvbiAke29wdHMudmVyc2lvbn0uIGAgK1xuICAgICAgICAgICAgICAgIGBUaGVzZSB2ZXJzaW9ucyBhcmUgc3RpbGwgY29tcGF0aWJsZSB3aXRoIGVhY2ggb3RoZXIsIGJ1dCBvcGVudmlkdS1icm93c2VyIHZlcnNpb24gbXVzdCBiZSB1cGRhdGVkIGFzIHNvb24gYXMgcG9zc2libGUgdG8gJHtzZW12ZXJNYWpvcihcbiAgICAgICAgICAgICAgICAgICAgb3B0cy52ZXJzaW9uXG4gICAgICAgICAgICAgICAgKX0uJHtzZW12ZXJNaW5vcihvcHRzLnZlcnNpb24pfS54LiBgICtcbiAgICAgICAgICAgICAgICBgVGhpcyBjbGllbnQgdXNpbmcgb3BlbnZpZHUtYnJvd3NlciAke3RoaXMub3BlbnZpZHUubGlicmFyeVZlcnNpb259IHdpbGwgYmVjb21lIGluY29tcGF0aWJsZSB3aXRoIHRoZSBuZXh0IHJlbGVhc2Ugb2Ygb3BlbnZpZHUtc2VydmVyYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvbmZpZ3VyZSBKU05Mb2dzXG4gICAgICAgIE9wZW5WaWR1TG9nZ2VyLmNvbmZpZ3VyZUpTTkxvZyh0aGlzLm9wZW52aWR1LCB0b2tlbik7XG5cbiAgICAgICAgLy8gU3RvcmUgdG9rZW5cbiAgICAgICAgdGhpcy50b2tlbiA9IHRva2VuO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi9Db25uZWN0aW9uJztcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4vRmlsdGVyJztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4vUHVibGlzaGVyJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuL1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4vU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTdWJzY3JpYmVyIH0gZnJvbSAnLi9TdWJzY3JpYmVyJztcbmltcG9ydCB7IEluYm91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvSW5ib3VuZFN0cmVhbU9wdGlvbnMnO1xuaW1wb3J0IHsgT3V0Ym91bmRTdHJlYW1PcHRpb25zIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1ByaXZhdGUvT3V0Ym91bmRTdHJlYW1PcHRpb25zJztcbmltcG9ydCB7XG4gICAgV2ViUnRjUGVlcixcbiAgICBXZWJSdGNQZWVyU2VuZG9ubHksXG4gICAgV2ViUnRjUGVlclJlY3Zvbmx5LFxuICAgIFdlYlJ0Y1BlZXJTZW5kcmVjdixcbiAgICBXZWJSdGNQZWVyQ29uZmlndXJhdGlvblxufSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1dlYlJ0Y1BlZXIvV2ViUnRjUGVlcic7XG5pbXBvcnQgeyBXZWJSdGNTdGF0cyB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvV2ViUnRjU3RhdHMvV2ViUnRjU3RhdHMnO1xuaW1wb3J0IHsgRXhjZXB0aW9uRXZlbnQsIEV4Y2VwdGlvbkV2ZW50TmFtZSB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL0V4Y2VwdGlvbkV2ZW50JztcbmltcG9ydCB7IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9QdWJsaXNoZXJTcGVha2luZ0V2ZW50JztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1RXJyb3IsIE9wZW5WaWR1RXJyb3JOYW1lIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9PcGVuVmlkdUVycm9yJztcbmltcG9ydCB7IFR5cGVPZlZpZGVvIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FbnVtcy9UeXBlT2ZWaWRlbyc7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IFBsYXRmb3JtVXRpbHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1V0aWxzL1BsYXRmb3JtJztcblxuaW1wb3J0IHsgdjQgYXMgdXVpZHY0IH0gZnJvbSAndXVpZCc7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5pbXBvcnQgaGFyayA9IHJlcXVpcmUoJ2hhcmsnKTtcbi8qKlxuICogQGhpZGRlblxuICovXG5pbXBvcnQgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnd29sZnk4Ny1ldmVudGVtaXR0ZXInKTtcbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmxldCBwbGF0Zm9ybTogUGxhdGZvcm1VdGlscztcblxuLyoqXG4gKiBSZXByZXNlbnRzIGVhY2ggb25lIG9mIHRoZSBtZWRpYSBzdHJlYW1zIGF2YWlsYWJsZSBpbiBPcGVuVmlkdSBTZXJ2ZXIgZm9yIGNlcnRhaW4gc2Vzc2lvbi5cbiAqIEVhY2ggW1tQdWJsaXNoZXJdXSBhbmQgW1tTdWJzY3JpYmVyXV0gaGFzIGFuIGF0dHJpYnV0ZSBvZiB0eXBlIFN0cmVhbSwgYXMgdGhleSBnaXZlIGFjY2Vzc1xuICogdG8gb25lIG9mIHRoZW0gKHNlbmRpbmcgYW5kIHJlY2VpdmluZyBpdCwgcmVzcGVjdGl2ZWx5KVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtIHtcbiAgICAvKipcbiAgICAgKiBUaGUgQ29ubmVjdGlvbiBvYmplY3QgdGhhdCBpcyBwdWJsaXNoaW5nIHRoZSBzdHJlYW1cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogRnJhbWUgcmF0ZSBvZiB0aGUgdmlkZW8gaW4gZnJhbWVzIHBlciBzZWNvbmQuIFRoaXMgcHJvcGVydHkgaXMgb25seSBkZWZpbmVkIGlmIHRoZSBbW1B1Ymxpc2hlcl1dIG9mXG4gICAgICogdGhlIHN0cmVhbSB3YXMgaW5pdGlhbGl6ZWQgcGFzc2luZyBhIF9mcmFtZVJhdGVfIHByb3BlcnR5IG9uIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG1ldGhvZFxuICAgICAqL1xuICAgIGZyYW1lUmF0ZT86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgYSB2aWRlbyB0cmFjayBvciBub3RcbiAgICAgKi9cbiAgICBoYXNWaWRlbzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIHN0cmVhbSBoYXMgYW4gYXVkaW8gdHJhY2sgb3Igbm90XG4gICAgICovXG4gICAgaGFzQXVkaW86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBzdHJlYW0gaGFzIHRoZSB2aWRlbyB0cmFjayBtdXRlZCBvciB1bm11dGVkLiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkLlxuICAgICAqXG4gICAgICogVGhpcyBwcm9wZXJ0eSBtYXkgY2hhbmdlIGlmIHRoZSBQdWJsaXNoZXIgcHVibGlzaGluZyB0aGUgc3RyZWFtIGNhbGxzIFtbUHVibGlzaGVyLnB1Ymxpc2hWaWRlb11dLiBXaGVuZXZlciB0aGlzIGhhcHBlbnMgYSBbW1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50XV0gd2lsbCBiZSBkaXNwYXRjaGVkXG4gICAgICogYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIHZpZGVvQWN0aXZlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgc3RyZWFtIGhhcyB0aGUgYXVkaW8gdHJhY2sgbXV0ZWQgb3IgdW5tdXRlZC4gSWYgW1toYXNBdWRpb11dIGlzIGZhbHNlLCB0aGlzIHByb3BlcnR5IGlzIHVuZGVmaW5lZFxuICAgICAqXG4gICAgICogVGhpcyBwcm9wZXJ0eSBtYXkgY2hhbmdlIGlmIHRoZSBQdWJsaXNoZXIgcHVibGlzaGluZyB0aGUgc3RyZWFtIGNhbGxzIFtbUHVibGlzaGVyLnB1Ymxpc2hBdWRpb11dLiBXaGVuZXZlciB0aGlzIGhhcHBlbnMgYSBbW1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50XV0gd2lsbCBiZSBkaXNwYXRjaGVkXG4gICAgICogYnkgdGhlIFNlc3Npb24gb2JqZWN0IGFzIHdlbGwgYXMgYnkgdGhlIGFmZmVjdGVkIFN1YnNjcmliZXIvUHVibGlzaGVyIG9iamVjdFxuICAgICAqL1xuICAgIGF1ZGlvQWN0aXZlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIHN0cmVhbS4gSWYgdGhlIHN0cmVhbSBiZWxvbmdzIHRvIGEuLi5cbiAgICAgKiAtIFN1YnNjcmliZXIgb2JqZWN0OiBwcm9wZXJ0eSBgc3RyZWFtSWRgIGlzIGFsd2F5cyBkZWZpbmVkXG4gICAgICogLSBQdWJsaXNoZXIgb2JqZWN0OiBwcm9wZXJ0eSBgc3RyZWFtSWRgIGlzIG9ubHkgZGVmaW5lZCBhZnRlciBzdWNjZXNzZnVsIGV4ZWN1dGlvbiBvZiBbW1Nlc3Npb24ucHVibGlzaF1dXG4gICAgICovXG4gICAgc3RyZWFtSWQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRpbWUgd2hlbiB0aGlzIHN0cmVhbSB3YXMgY3JlYXRlZCBpbiBPcGVuVmlkdSBTZXJ2ZXIgKFVUQyBtaWxsaXNlY29uZHMpLiBEZXBlbmRpbmcgb24gdGhlIG93bmVyIG9mIHRoaXMgc3RyZWFtOlxuICAgICAqIC0gU3Vic2NyaWJlciBvYmplY3Q6IHByb3BlcnR5IGBjcmVhdGlvblRpbWVgIGlzIGFsd2F5cyBkZWZpbmVkXG4gICAgICogLSBQdWJsaXNoZXIgb2JqZWN0OiBwcm9wZXJ0eSBgY3JlYXRpb25UaW1lYCBpcyBvbmx5IGRlZmluZWQgYWZ0ZXIgc3VjY2Vzc2Z1bCBleGVjdXRpb24gb2YgW1tTZXNzaW9uLnB1Ymxpc2hdXVxuICAgICAqL1xuICAgIGNyZWF0aW9uVGltZTogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogQ2FuIGJlOlxuICAgICAqIC0gYFwiQ0FNRVJBXCJgOiB3aGVuIHRoZSB2aWRlbyBzb3VyY2UgY29tZXMgZnJvbSBhIHdlYmNhbS5cbiAgICAgKiAtIGBcIlNDUkVFTlwiYDogd2hlbiB0aGUgdmlkZW8gc291cmNlIGNvbWVzIGZyb20gc2NyZWVuLXNoYXJpbmcuXG4gICAgICogLSBgXCJDVVNUT01cImA6IHdoZW4gW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgaW4gdGhlIFB1Ymxpc2hlciBzaWRlIHdpdGggYSBjdXN0b20gTWVkaWFTdHJlYW1UcmFjayB3aGVuIGNhbGxpbmcgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0pLlxuICAgICAqIC0gYFwiSVBDQU1cImA6IHdoZW4gdGhlIHZpZGVvIHNvdXJjZSBjb21lcyBmcm9tIGFuIElQIGNhbWVyYSBwYXJ0aWNpcGFudCBpbnN0ZWFkIG9mIGEgcmVndWxhciBwYXJ0aWNpcGFudCAoc2VlIFtJUCBjYW1lcmFzXSgvZW4vc3RhYmxlL2FkdmFuY2VkLWZlYXR1cmVzL2lwLWNhbWVyYXMvKSkuXG4gICAgICpcbiAgICAgKiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICovXG4gICAgdHlwZU9mVmlkZW8/OiBrZXlvZiB0eXBlb2YgVHlwZU9mVmlkZW87IC8vIFRPRE86IENoYW5nZSB0aGlzIHR5cGUgdG8gZW51bSBUeXBlT2ZWaWRlbyBvbiB0aGUgbmV4dCBicmVha2luZy1jaGFuZ2UgcmVsZWFzZVxuXG4gICAgLyoqXG4gICAgICogU3RyZWFtTWFuYWdlciBvYmplY3QgKFtbUHVibGlzaGVyXV0gb3IgW1tTdWJzY3JpYmVyXV0pIGluIGNoYXJnZSBvZiBkaXNwbGF5aW5nIHRoaXMgc3RyZWFtIGluIHRoZSBET01cbiAgICAgKi9cbiAgICBzdHJlYW1NYW5hZ2VyOiBTdHJlYW1NYW5hZ2VyO1xuXG4gICAgLyoqXG4gICAgICogV2lkdGggYW5kIGhlaWdodCBpbiBwaXhlbHMgb2YgdGhlIGVuY29kZWQgdmlkZW8gc3RyZWFtLiBJZiBbW2hhc1ZpZGVvXV0gaXMgZmFsc2UsIHRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkXG4gICAgICpcbiAgICAgKiBUaGlzIHByb3BlcnR5IG1heSBjaGFuZ2UgaWYgdGhlIFB1Ymxpc2hlciB0aGF0IGlzIHB1Ymxpc2hpbmc6XG4gICAgICogLSBJZiBpdCBpcyBhIG1vYmlsZSBkZXZpY2UsIHdoZW5ldmVyIHRoZSB1c2VyIHJvdGF0ZXMgdGhlIGRldmljZS5cbiAgICAgKiAtIElmIGl0IGlzIHNjcmVlbi1zaGFyaW5nLCB3aGVuZXZlciB0aGUgdXNlciBjaGFuZ2VzIHRoZSBzaXplIG9mIHRoZSBjYXB0dXJlZCB3aW5kb3cuXG4gICAgICpcbiAgICAgKiBXaGVuZXZlciB0aGlzIGhhcHBlbnMgYSBbW1N0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50XV0gd2lsbCBiZSBkaXNwYXRjaGVkIGJ5IHRoZSBTZXNzaW9uIG9iamVjdCBhcyB3ZWxsIGFzIGJ5IHRoZSBhZmZlY3RlZCBTdWJzY3JpYmVyL1B1Ymxpc2hlciBvYmplY3RcbiAgICAgKi9cbiAgICB2aWRlb0RpbWVuc2lvbnM6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfTtcblxuICAgIC8qKlxuICAgICAqICoqV0FSTklORyoqOiBleHBlcmltZW50YWwgb3B0aW9uLiBUaGlzIGludGVyZmFjZSBtYXkgY2hhbmdlIGluIHRoZSBuZWFyIGZ1dHVyZVxuICAgICAqXG4gICAgICogRmlsdGVyIGFwcGxpZWQgdG8gdGhlIFN0cmVhbS4gWW91IGNhbiBhcHBseSBmaWx0ZXJzIGJ5IGNhbGxpbmcgW1tTdHJlYW0uYXBwbHlGaWx0ZXJdXSwgZXhlY3V0ZSBtZXRob2RzIG9mIHRoZSBhcHBsaWVkIGZpbHRlciB3aXRoXG4gICAgICogW1tGaWx0ZXIuZXhlY01ldGhvZF1dIGFuZCByZW1vdmUgaXQgd2l0aCBbW1N0cmVhbS5yZW1vdmVGaWx0ZXJdXS4gQmUgYXdhcmUgdGhhdCB0aGUgY2xpZW50IGNhbGxpbmcgdGhpcyBtZXRob2RzIG11c3QgaGF2ZSB0aGVcbiAgICAgKiBuZWNlc3NhcnkgcGVybWlzc2lvbnM6IHRoZSB0b2tlbiBvd25lZCBieSB0aGUgY2xpZW50IG11c3QgaGF2ZSBiZWVuIGluaXRpYWxpemVkIHdpdGggdGhlIGFwcHJvcHJpYXRlZCBgYWxsb3dlZEZpbHRlcnNgIGFycmF5LlxuICAgICAqL1xuICAgIGZpbHRlcj86IEZpbHRlcjtcblxuICAgIHByb3RlY3RlZCB3ZWJSdGNQZWVyOiBXZWJSdGNQZWVyO1xuICAgIHByb3RlY3RlZCBtZWRpYVN0cmVhbT86IE1lZGlhU3RyZWFtO1xuICAgIHByaXZhdGUgd2ViUnRjU3RhdHM6IFdlYlJ0Y1N0YXRzO1xuXG4gICAgcHJpdmF0ZSBpc1N1YnNjcmliZVRvUmVtb3RlID0gZmFsc2U7XG5cbiAgICBwcml2YXRlIHZpcnR1YWxCYWNrZ3JvdW5kU291cmNlRWxlbWVudHM/OiB7IHZpZGVvQ2xvbmU6IEhUTUxWaWRlb0VsZW1lbnQ7IG1lZGlhU3RyZWFtQ2xvbmU6IE1lZGlhU3RyZWFtIH07XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHZpcnR1YWxCYWNrZ3JvdW5kU2lua0VsZW1lbnRzPzogeyBWQjogYW55OyB2aWRlbzogSFRNTFZpZGVvRWxlbWVudCB9O1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsU3RyZWFtUHVibGlzaGVkID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2hlZE9uY2UgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc2Vzc2lvbjogU2Vzc2lvbjtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5ib3VuZFN0cmVhbU9wdHM6IEluYm91bmRTdHJlYW1PcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBvdXRib3VuZFN0cmVhbU9wdHM6IE91dGJvdW5kU3RyZWFtT3B0aW9ucztcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgc3BlZWNoRXZlbnQ6IGFueTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFya1NwZWFraW5nRW5hYmxlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXJrU3BlYWtpbmdFbmFibGVkT25jZSA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZCA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBoYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZE9uY2UgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWRPbmNlID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGhhcmtPcHRpb25zO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBsb2NhbE1lZGlhU3RyZWFtV2hlblN1YnNjcmliZWRUb1JlbW90ZT86IE1lZGlhU3RyZWFtO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyOiBFdmVudEVtaXR0ZXIgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhc3RWaWRlb1RyYWNrQ29uc3RyYWludHM6IE1lZGlhVHJhY2tDb25zdHJhaW50cyB8IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxhc3RWQkZpbHRlcj86IEZpbHRlcjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzZXNzaW9uOiBTZXNzaW9uLCBvcHRpb25zOiBJbmJvdW5kU3RyZWFtT3B0aW9ucyB8IE91dGJvdW5kU3RyZWFtT3B0aW9ucyB8IHt9KSB7XG4gICAgICAgIHBsYXRmb3JtID0gUGxhdGZvcm1VdGlscy5nZXRJbnN0YW5jZSgpO1xuICAgICAgICB0aGlzLnNlc3Npb24gPSBzZXNzaW9uO1xuXG4gICAgICAgIGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KCdpZCcpKSB7XG4gICAgICAgICAgICAvLyBJbmJvdW5kU3RyZWFtT3B0aW9uczogc3RyZWFtIGJlbG9uZ3MgdG8gYSBTdWJzY3JpYmVyXG4gICAgICAgICAgICB0aGlzLmluYm91bmRTdHJlYW1PcHRzID0gPEluYm91bmRTdHJlYW1PcHRpb25zPm9wdGlvbnM7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbUlkID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5pZDtcbiAgICAgICAgICAgIHRoaXMuY3JlYXRpb25UaW1lID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5jcmVhdGVkQXQ7XG4gICAgICAgICAgICB0aGlzLmhhc0F1ZGlvID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5oYXNBdWRpbztcbiAgICAgICAgICAgIHRoaXMuaGFzVmlkZW8gPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmhhc1ZpZGVvO1xuICAgICAgICAgICAgaWYgKHRoaXMuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvQWN0aXZlID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy5hdWRpb0FjdGl2ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc1ZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb0FjdGl2ZSA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMudmlkZW9BY3RpdmU7XG4gICAgICAgICAgICAgICAgdGhpcy50eXBlT2ZWaWRlbyA9ICF0aGlzLmluYm91bmRTdHJlYW1PcHRzLnR5cGVPZlZpZGVvID8gdW5kZWZpbmVkIDogdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy50eXBlT2ZWaWRlbztcbiAgICAgICAgICAgICAgICB0aGlzLmZyYW1lUmF0ZSA9IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlID09PSAtMSA/IHVuZGVmaW5lZCA6IHRoaXMuaW5ib3VuZFN0cmVhbU9wdHMuZnJhbWVSYXRlO1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9EaW1lbnNpb25zID0gdGhpcy5pbmJvdW5kU3RyZWFtT3B0cy52aWRlb0RpbWVuc2lvbnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlciAmJiBPYmplY3Qua2V5cyh0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlcikubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgISF0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlci5sYXN0RXhlY01ldGhvZCAmJlxuICAgICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyh0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlci5sYXN0RXhlY01ldGhvZCkubGVuZ3RoID09PSAwXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlci5sYXN0RXhlY01ldGhvZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLmluYm91bmRTdHJlYW1PcHRzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIE91dGJvdW5kU3RyZWFtT3B0aW9uczogc3RyZWFtIGJlbG9uZ3MgdG8gYSBQdWJsaXNoZXJcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID0gPE91dGJvdW5kU3RyZWFtT3B0aW9ucz5vcHRpb25zO1xuXG4gICAgICAgICAgICB0aGlzLmhhc0F1ZGlvID0gdGhpcy5pc1NlbmRBdWRpbygpO1xuICAgICAgICAgICAgdGhpcy5oYXNWaWRlbyA9IHRoaXMuaXNTZW5kVmlkZW8oKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzQXVkaW8pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmF1ZGlvQWN0aXZlID0gISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnB1Ymxpc2hBdWRpbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmhhc1ZpZGVvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb0FjdGl2ZSA9ICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5wdWJsaXNoVmlkZW87XG4gICAgICAgICAgICAgICAgdGhpcy5mcmFtZVJhdGUgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZyYW1lUmF0ZTtcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFja1xuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnR5cGVPZlZpZGVvID0gVHlwZU9mVmlkZW8uQ1VTVE9NO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudHlwZU9mVmlkZW8gPSB0aGlzLmlzU2VuZFNjcmVlbigpID8gVHlwZU9mVmlkZW8uU0NSRUVOIDogVHlwZU9mVmlkZW8uQ0FNRVJBO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXIgPSB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLmZpbHRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZWUub24oJ21lZGlhc3RyZWFtLXVwZGF0ZWQnLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIudXBkYXRlTWVkaWFTdHJlYW0odGhpcy5tZWRpYVN0cmVhbSEpO1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdWaWRlbyBzcmNPYmplY3QgWycgKyB0aGlzLm1lZGlhU3RyZWFtPy5pZCArICddIHVwZGF0ZWQgaW4gc3RyZWFtIFsnICsgdGhpcy5zdHJlYW1JZCArICddJyk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlY3JlYXRlcyB0aGUgbWVkaWEgY29ubmVjdGlvbiB3aXRoIHRoZSBzZXJ2ZXIuIFRoaXMgZW50YWlscyB0aGUgZGlzcG9zYWwgb2YgdGhlIHByZXZpb3VzIFJUQ1BlZXJDb25uZWN0aW9uIGFuZCB0aGUgcmUtbmVnb3RpYXRpb25cbiAgICAgKiBvZiBhIG5ldyBvbmUsIHRoYXQgd2lsbCBhcHBseSB0aGUgc2FtZSBwcm9wZXJ0aWVzLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgY2FuIGJlIHVzZWZ1bCBpbiB0aG9zZSBzaXR1YXRpb25zIHdlcmUgdGhlcmUgdGhlIG1lZGlhIGNvbm5lY3Rpb24gYnJlYWtzIGFuZCBPcGVuVmlkdSBpcyBub3QgYWJsZSB0byByZWNvdmVyIG9uIGl0cyBvd25cbiAgICAgKiBmb3IgYW55IGtpbmQgb2YgdW5hbnRpY2lwYXRlZCByZWFzb24gKHNlZSBbQXV0b21hdGljIHJlY29ubmVjdGlvbl0oL2VuL3N0YWJsZS9hZHZhbmNlZC1mZWF0dXJlcy9hdXRvbWF0aWMtcmVjb25uZWN0aW9uLykpLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSByZWNvbm5lY3Rpb24gb3BlcmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBwdWJsaWMgcmVjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWNvbm5lY3RTdHJlYW0oJ0FQSScpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFwcGxpZXMgYW4gYXVkaW8vdmlkZW8gZmlsdGVyIHRvIHRoZSBzdHJlYW0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdHlwZSBUeXBlIG9mIGZpbHRlciBhcHBsaWVkLiBTZWUgW1tGaWx0ZXIudHlwZV1dXG4gICAgICogQHBhcmFtIG9wdGlvbnMgUGFyYW1ldGVycyB1c2VkIHRvIGluaXRpYWxpemUgdGhlIGZpbHRlci4gU2VlIFtbRmlsdGVyLm9wdGlvbnNdXVxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIHRvIHRoZSBhcHBsaWVkIGZpbHRlciBpZiBzdWNjZXNzIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpZiBub3RcbiAgICAgKi9cbiAgICBhcHBseUZpbHRlcih0eXBlOiBzdHJpbmcsIG9wdGlvbnM6IE9iamVjdCk6IFByb21pc2U8RmlsdGVyPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAoISF0aGlzLmZpbHRlcikge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsICdUaGVyZSBpcyBhbHJlYWR5IGEgZmlsdGVyIGFwcGxpZWQgdG8gU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHJlc29sdmVBcHBseUZpbHRlciA9IChlcnJvciwgdHJpZ2dlckV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgYXBwbHlpbmcgZmlsdGVyIGZvciBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDQwMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgT3BlblZpZHVFcnJvcihPcGVuVmlkdUVycm9yTmFtZS5PUEVOVklEVV9QRVJNSVNTSU9OX0RFTklFRCwgXCJZb3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9ucyB0byBhcHBseSBhIGZpbHRlclwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ0ZpbHRlciBzdWNjZXNzZnVsbHkgYXBwbGllZCBvbiBTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZTogRmlsdGVyID0gdGhpcy5maWx0ZXIhO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbHRlciA9IG5ldyBGaWx0ZXIodHlwZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyLnN0cmVhbSA9IHRoaXM7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0cmlnZ2VyRXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnQodGhpcy5zZXNzaW9uLCB0aGlzLCAnZmlsdGVyJywgdGhpcy5maWx0ZXIsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKVxuICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyLCBvbGRWYWx1ZSwgJ2FwcGx5RmlsdGVyJylcbiAgICAgICAgICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHRoaXMuZmlsdGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodHlwZS5zdGFydHNXaXRoKCdWQjonKSkge1xuICAgICAgICAgICAgICAgIC8vIENsaWVudCBmaWx0ZXJzXG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaGFzVmlkZW8pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVGhlIFZpcnR1YWwgQmFja2dyb3VuZCBmaWx0ZXIgcmVxdWlyZXMgYSB2aWRlbyB0cmFjayB0byBiZSBhcHBsaWVkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMubWVkaWFTdHJlYW0gfHwgdGhpcy5zdHJlYW1NYW5hZ2VyLnZpZGVvcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVGhlIFN0cmVhbU1hbmFnZXIgcmVxdWlyZXMgc29tZSB2aWRlbyBlbGVtZW50IHRvIGJlIGF0dGFjaGVkIHRvIGl0IGluIG9yZGVyIHRvIGFwcGx5IGEgVmlydHVhbCBCYWNrZ3JvdW5kIGZpbHRlcidcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgb3BlbnZpZHVUb2tlbjogc3RyaW5nO1xuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuc2Vzc2lvbi50b2tlbikge1xuICAgICAgICAgICAgICAgICAgICBvcGVudmlkdVRva2VuID0gdGhpcy5zZXNzaW9uLnRva2VuO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG9wZW52aWR1VG9rZW4gPSBvcHRpb25zWyd0b2tlbiddO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIW9wZW52aWR1VG9rZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVmlydHVhbCBCYWNrZ3JvdW5kIHJlcXVpcmVzIHRoZSBjbGllbnQgdG8gYmUgY29ubmVjdGVkIHRvIGEgU2Vzc2lvbiBvciB0byBoYXZlIGEgXCJ0b2tlblwiIHByb3BlcnR5IGF2YWlsYWJsZSBpbiBcIm9wdGlvbnNcIiBwYXJhbWV0ZXIgd2l0aCBhIHZhbGlkIE9wZW5WaWR1IHRva2VuJ1xuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHRva2VuUGFyYW1zID0gdGhpcy5zZXNzaW9uLmdldFRva2VuUGFyYW1zKG9wZW52aWR1VG9rZW4pO1xuICAgICAgICAgICAgICAgIGlmICh0b2tlblBhcmFtcy5lZGl0aW9uICE9PSAncHJvJyAmJiB0b2tlblBhcmFtcy5lZGl0aW9uICE9PSAnZW50ZXJwcmlzZScpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnT3BlblZpZHUgVmlydHVhbCBCYWNrZ3JvdW5kIEFQSSBpcyBhdmFpbGFibGUgZnJvbSBPcGVuVmlkdSBQcm8gZWRpdGlvbiBvbndhcmRzJ1xuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG9wZW52aWR1VG9rZW4gPSBlbmNvZGVVUklDb21wb25lbnQoYnRvYShvcGVudmlkdVRva2VuKSk7XG5cbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnQXBwbHlpbmcgVmlydHVhbCBCYWNrZ3JvdW5kIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBhZnRlclNjcmlwdExvYWRlZCA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gdGhpcy5zdHJlYW1JZCArICdfJyArIHV1aWR2NCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW1DbG9uZSA9IHRoaXMubWVkaWFTdHJlYW0hLmNsb25lKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2aWRlb0Nsb25lID0gdGhpcy5zdHJlYW1NYW5hZ2VyLnZpZGVvc1swXS52aWRlby5jbG9uZU5vZGUoZmFsc2UpIGFzIEhUTUxWaWRlb0VsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgICAgICB2aWRlb0Nsb25lLmlkID0gVmlydHVhbEJhY2tncm91bmQuVmlydHVhbEJhY2tncm91bmQuU09VUkNFX1ZJREVPX1BSRUZJWCArIGlkO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW9DbG9uZS5zcmNPYmplY3QgPSBtZWRpYVN0cmVhbUNsb25lO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW9DbG9uZS5tdXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpcnR1YWxCYWNrZ3JvdW5kU291cmNlRWxlbWVudHMgPSB7IHZpZGVvQ2xvbmUsIG1lZGlhU3RyZWFtQ2xvbmUgfTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgVmlydHVhbEJhY2tncm91bmQuVmlydHVhbEJhY2tncm91bmQuaGlkZUh0bWxFbGVtZW50KHZpZGVvQ2xvbmUsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIFZpcnR1YWxCYWNrZ3JvdW5kLlZpcnR1YWxCYWNrZ3JvdW5kLmFwcGVuZEh0bWxFbGVtZW50VG9IaWRkZW5Db250YWluZXIodmlkZW9DbG9uZSwgaWQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB2aWRlb0Nsb25lLnBsYXkoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVkIgPSBuZXcgVmlydHVhbEJhY2tncm91bmQuVmlydHVhbEJhY2tncm91bmQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZW52aWR1U2VydmVyVXJsOiBuZXcgVVJMKHRva2VuUGFyYW1zLmh0dHBVcmkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZW52aWR1VG9rZW4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRWaWRlbzogdmlkZW9DbG9uZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFJlc29sdXRpb246ICcxNjB4OTYnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dEZyYW1lcmF0ZTogMjRcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZmlsdGVyZWRWaWRlbzogSFRNTFZpZGVvRWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1ZCOmJsdXInOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcmVkVmlkZW8gPSBhd2FpdCBWQi5iYWNrZ3JvdW5kQmx1cihvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ1ZCOmltYWdlJzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJlZFZpZGVvID0gYXdhaXQgVkIuYmFja2dyb3VuZEltYWdlKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIFZpcnR1YWwgQmFja2dyb3VuZCBmaWx0ZXI6ICcgKyB0eXBlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52aXJ0dWFsQmFja2dyb3VuZFNpbmtFbGVtZW50cyA9IHsgVkIsIHZpZGVvOiBmaWx0ZXJlZFZpZGVvIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvQ2xvbmUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtTWFuYWdlci5yZW1vdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIucmVwbGFjZVRyYWNrSW5NZWRpYVN0cmVhbShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRoaXMudmlydHVhbEJhY2tncm91bmRTaW5rRWxlbWVudHMudmlkZW8uc3JjT2JqZWN0IGFzIE1lZGlhU3RyZWFtKS5nZXRWaWRlb1RyYWNrcygpWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLnN0cmVhbU1hbmFnZXIgYXMgUHVibGlzaGVyKS5yZXBsYWNlVHJhY2tBdXgoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0aGlzLnZpcnR1YWxCYWNrZ3JvdW5kU2lua0VsZW1lbnRzLnZpZGVvLnNyY09iamVjdCBhcyBNZWRpYVN0cmVhbSkuZ2V0VmlkZW9UcmFja3MoKVswXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlQXBwbHlGaWx0ZXIodW5kZWZpbmVkLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gT3BlblZpZHVFcnJvck5hbWUuVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZUFwcGx5RmlsdGVyKG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLlZJUlRVQUxfQkFDS0dST1VORF9FUlJPUiwgZXJyb3IubWVzc2FnZSksIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZUFwcGx5RmlsdGVyKGVycm9yLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgVmlydHVhbEJhY2tncm91bmQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBzY3JpcHQ6IEhUTUxTY3JpcHRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICAgICAgICAgICAgICAgIHNjcmlwdC50eXBlID0gJ3RleHQvamF2YXNjcmlwdCc7XG4gICAgICAgICAgICAgICAgICAgIHNjcmlwdC5zcmMgPSB0b2tlblBhcmFtcy5odHRwVXJpICsgJy9vcGVudmlkdS92aXJ0dWFsLWJhY2tncm91bmQvb3BlbnZpZHUtdmlydHVhbC1iYWNrZ3JvdW5kLmpzP3Rva2VuPScgKyBvcGVudmlkdVRva2VuO1xuICAgICAgICAgICAgICAgICAgICBzY3JpcHQub25sb2FkID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBhZnRlclNjcmlwdExvYWRlZCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IEZpbHRlcih0eXBlLCBvcHRpb25zKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBhZnRlclNjcmlwdExvYWRlZCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiByZXNvbHZlKG5ldyBGaWx0ZXIodHlwZSwgb3B0aW9ucykpKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTZXJ2ZXIgZmlsdGVyc1xuXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnNlc3Npb24uc2Vzc2lvbkNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QodGhpcy5zZXNzaW9uLm5vdENvbm5lY3RlZEVycm9yKCkpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdBcHBseWluZyBzZXJ2ZXIgZmlsdGVyIHRvIHN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgIT0gbnVsbCA/IG9wdGlvbnMgOiB7fTtcbiAgICAgICAgICAgICAgICBsZXQgb3B0aW9uc1N0cmluZyA9IG9wdGlvbnM7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zU3RyaW5nICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkob3B0aW9uc1N0cmluZyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChcbiAgICAgICAgICAgICAgICAgICAgJ2FwcGx5RmlsdGVyJyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCwgdHlwZSwgb3B0aW9uczogb3B0aW9uc1N0cmluZyB9LFxuICAgICAgICAgICAgICAgICAgICAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlQXBwbHlGaWx0ZXIoZXJyb3IsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbiBhdWRpby92aWRlbyBmaWx0ZXIgcHJldmlvdXNseSBhcHBsaWVkLlxuICAgICAqXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlICh0byB3aGljaCB5b3UgY2FuIG9wdGlvbmFsbHkgc3Vic2NyaWJlIHRvKSB0aGF0IGlzIHJlc29sdmVkIGlmIHRoZSBwcmV2aW91c2x5IGFwcGxpZWQgZmlsdGVyIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSByZW1vdmVkIGFuZCByZWplY3RlZCB3aXRoIGFuIEVycm9yIG9iamVjdCBpbiBvdGhlciBjYXNlXG4gICAgICovXG4gICAgYXN5bmMgcmVtb3ZlRmlsdGVyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5yZW1vdmVGaWx0ZXJBdXgoZmFsc2UpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGludGVybmFsIFJUQ1BlZXJDb25uZWN0aW9uIG9iamVjdCBhc3NvY2lhdGVkIHRvIHRoaXMgc3RyZWFtIChodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUlRDUGVlckNvbm5lY3Rpb24pXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBOYXRpdmUgUlRDUGVlckNvbm5lY3Rpb24gV2ViIEFQSSBvYmplY3RcbiAgICAgKi9cbiAgICBnZXRSVENQZWVyQ29ubmVjdGlvbigpOiBSVENQZWVyQ29ubmVjdGlvbiB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIucGM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaW50ZXJuYWwgTWVkaWFTdHJlYW0gb2JqZWN0IGFzc29jaWF0ZWQgdG8gdGhpcyBzdHJlYW0gKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9NZWRpYVN0cmVhbSlcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIE5hdGl2ZSBNZWRpYVN0cmVhbSBXZWIgQVBJIG9iamVjdFxuICAgICAqL1xuICAgIGdldE1lZGlhU3RyZWFtKCk6IE1lZGlhU3RyZWFtIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWVkaWFTdHJlYW0hO1xuICAgIH1cblxuICAgIC8qIEhpZGRlbiBtZXRob2RzICovXG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3ZlRmlsdGVyQXV4KGlzRGlzcG9zaW5nOiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlUmVtb3ZlRmlsdGVyID0gKGVycm9yLCB0cmlnZ2VyRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGZpbHRlciBmb3IgU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5jb2RlID09PSA0MDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IE9wZW5WaWR1RXJyb3IoT3BlblZpZHVFcnJvck5hbWUuT1BFTlZJRFVfUEVSTUlTU0lPTl9ERU5JRUQsIFwiWW91IGRvbid0IGhhdmUgcGVybWlzc2lvbnMgdG8gcmVtb3ZlIGEgZmlsdGVyXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnRmlsdGVyIHN1Y2Nlc3NmdWxseSByZW1vdmVkIGZyb20gU3RyZWFtICcgKyB0aGlzLnN0cmVhbUlkKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLmZpbHRlciE7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmZpbHRlcjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRyaWdnZXJFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgnc3RyZWFtUHJvcGVydHlDaGFuZ2VkJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudCh0aGlzLnNlc3Npb24sIHRoaXMsICdmaWx0ZXInLCB0aGlzLmZpbHRlciEsIG9sZFZhbHVlLCAnYXBwbHlGaWx0ZXInKVxuICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgdGhpcywgJ2ZpbHRlcicsIHRoaXMuZmlsdGVyISwgb2xkVmFsdWUsICdhcHBseUZpbHRlcicpXG4gICAgICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICghIXRoaXMuZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlcmUgaXMgYSBmaWx0ZXIgYXBwbGllZFxuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZmlsdGVyPy50eXBlLnN0YXJ0c1dpdGgoJ1ZCOicpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIENsaWVudCBmaWx0ZXJzXG5cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtQ2xvbmUgPSB0aGlzLnZpcnR1YWxCYWNrZ3JvdW5kU291cmNlRWxlbWVudHMhLm1lZGlhU3RyZWFtQ2xvbmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzRGlzcG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtTWFuYWdlci5yZW1vdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLnJlcGxhY2VUcmFja0luTWVkaWFTdHJlYW0obWVkaWFTdHJlYW1DbG9uZS5nZXRWaWRlb1RyYWNrcygpWzBdLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgKHRoaXMuc3RyZWFtTWFuYWdlciBhcyBQdWJsaXNoZXIpLnJlcGxhY2VUcmFja0F1eChtZWRpYVN0cmVhbUNsb25lLmdldFZpZGVvVHJhY2tzKClbMF0sIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhU3RyZWFtQ2xvbmUuZ2V0VHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlydHVhbEJhY2tncm91bmRTaW5rRWxlbWVudHMhLlZCLmNsZWFuVXAoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMudmlydHVhbEJhY2tncm91bmRTaW5rRWxlbWVudHM7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy52aXJ0dWFsQmFja2dyb3VuZFNvdXJjZUVsZW1lbnRzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZVJlbW92ZUZpbHRlcih1bmRlZmluZWQsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlUmVtb3ZlRmlsdGVyKGVycm9yLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBTZXJ2ZXIgZmlsdGVyc1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5zZXNzaW9uLnNlc3Npb25Db25uZWN0ZWQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCh0aGlzLnNlc3Npb24ubm90Q29ubmVjdGVkRXJyb3IoKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnUmVtb3ZpbmcgZmlsdGVyIG9mIHN0cmVhbSAnICsgdGhpcy5zdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdCgncmVtb3ZlRmlsdGVyJywgeyBzdHJlYW1JZDogdGhpcy5zdHJlYW1JZCB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZVJlbW92ZUZpbHRlcihlcnJvciwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gZmlsdGVyIGFwcGxpZWRcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLkdFTkVSSUNfRVJST1IsICdTdHJlYW0gJyArIHRoaXMuc3RyZWFtSWQgKyAnIGhhcyBubyBmaWx0ZXIgYXBwbGllZCcpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNldE1lZGlhU3RyZWFtKG1lZGlhU3RyZWFtOiBNZWRpYVN0cmVhbSk6IHZvaWQge1xuICAgICAgICB0aGlzLm1lZGlhU3RyZWFtID0gbWVkaWFTdHJlYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHVwZGF0ZU1lZGlhU3RyZWFtSW5WaWRlb3MoKSB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdtZWRpYXN0cmVhbS11cGRhdGVkJywgW10pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRXZWJSdGNQZWVyKCk6IFdlYlJ0Y1BlZXIge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNQZWVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb015UmVtb3RlKHZhbHVlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaXNTdWJzY3JpYmVUb1JlbW90ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzZXRPdXRib3VuZFN0cmVhbU9wdGlvbnMob3V0Ym91bmRTdHJlYW1PcHRzOiBPdXRib3VuZFN0cmVhbU9wdGlvbnMpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgPSBvdXRib3VuZFN0cmVhbU9wdHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN1YnNjcmliZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKGZhbHNlKVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHJlc29sdmUoKSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1Ymxpc2goKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0xvY2FsU3RyZWFtUmVhZHlUb1B1Ymxpc2gpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZChmYWxzZSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5vbmNlKCdzdHJlYW0tcmVhZHktdG8tcHVibGlzaCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wdWJsaXNoKClcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHJlc29sdmUoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcG9zZVdlYlJ0Y1BlZXIoKTogdm9pZCB7XG4gICAgICAgIGxldCB3ZWJydGNJZDtcbiAgICAgICAgaWYgKCEhdGhpcy53ZWJSdGNQZWVyKSB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuZGlzcG9zZSgpO1xuICAgICAgICAgICAgd2VicnRjSWQgPSB0aGlzLndlYlJ0Y1BlZXIuZ2V0SWQoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0b3BXZWJSdGNTdGF0cygpO1xuICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ091dGJvdW5kICcgOiAnSW5ib3VuZCAnKSArXG4gICAgICAgICAgICAnUlRDUGVlckNvbm5lY3Rpb24gd2l0aCBpZCBbJyArXG4gICAgICAgICAgICB3ZWJydGNJZCArXG4gICAgICAgICAgICBcIl0gZnJvbSAnU3RyZWFtJyB3aXRoIGlkIFtcIiArXG4gICAgICAgICAgICB0aGlzLnN0cmVhbUlkICtcbiAgICAgICAgICAgICddIGlzIG5vdyBjbG9zZWQnXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFzeW5jIGRpc3Bvc2VNZWRpYVN0cmVhbSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKCEhdGhpcy5maWx0ZXIgJiYgdGhpcy5maWx0ZXIudHlwZS5zdGFydHNXaXRoKCdWQjonKSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUZpbHRlckF1eCh0cnVlKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKGBTdWNjZXNzIHJlbW92aW5nIFZpcnR1YWwgQmFja2dyb3VuZCBmaWx0ZXIgZm9yIHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9YCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIHJlbW92aW5nIFZpcnR1YWwgQmFja2dyb3VuZCBmaWx0ZXIgZm9yIHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9YCwgZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMubWVkaWFTdHJlYW07XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgc3Vic2NyaWJlVG9SZW1vdGUgbG9jYWwgTWVkaWFTdHJlYW0gbXVzdCBiZSBzdG9wcGVkXG4gICAgICAgIGlmICh0aGlzLmxvY2FsTWVkaWFTdHJlYW1XaGVuU3Vic2NyaWJlZFRvUmVtb3RlKSB7XG4gICAgICAgICAgICB0aGlzLmxvY2FsTWVkaWFTdHJlYW1XaGVuU3Vic2NyaWJlZFRvUmVtb3RlLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMubG9jYWxNZWRpYVN0cmVhbVdoZW5TdWJzY3JpYmVkVG9SZW1vdGUuZ2V0VmlkZW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMubG9jYWxNZWRpYVN0cmVhbVdoZW5TdWJzY3JpYmVkVG9SZW1vdGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudC5zdG9wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5zcGVlY2hFdmVudDtcbiAgICAgICAgfVxuICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICghIXRoaXMub3V0Ym91bmRTdHJlYW1PcHRzID8gJ0xvY2FsICcgOiAnUmVtb3RlICcpICsgXCJNZWRpYVN0cmVhbSBmcm9tICdTdHJlYW0nIHdpdGggaWQgW1wiICsgdGhpcy5zdHJlYW1JZCArICddIGlzIG5vdyBkaXNwb3NlZCdcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzcGxheU15UmVtb3RlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1N1YnNjcmliZVRvUmVtb3RlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc1NlbmRBdWRpbygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuYXVkaW9Tb3VyY2UgIT09IGZhbHNlXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGlzU2VuZFZpZGVvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgISF0aGlzLm91dGJvdW5kU3RyZWFtT3B0cyAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSAhPT0gZmFsc2VcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaXNTZW5kU2NyZWVuKCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgc2NyZWVuID0gdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZSA9PT0gJ3NjcmVlbic7XG4gICAgICAgIGlmIChwbGF0Zm9ybS5pc0VsZWN0cm9uKCkpIHtcbiAgICAgICAgICAgIHNjcmVlbiA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMudmlkZW9Tb3VyY2UgPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgICAgICAgdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy52aWRlb1NvdXJjZS5zdGFydHNXaXRoKCdzY3JlZW46Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHMgJiYgc2NyZWVuO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVIYXJrU3BlYWtpbmdFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRIYXJrTGlzdGVuZXJJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMuaGFya1NwZWFraW5nRW5hYmxlZCAmJiAhIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuaGFya1NwZWFraW5nRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uKCdzcGVha2luZycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgW1xuICAgICAgICAgICAgICAgICAgICBuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKVxuICAgICAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgIG5ldyBQdWJsaXNoZXJTcGVha2luZ0V2ZW50KHRoaXMuc3RyZWFtTWFuYWdlciwgJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5oYXJrU3BlYWtpbmdFbmFibGVkT25jZSA9IGZhbHNlOyAvLyBEaXNhYmxlICdvbmNlJyB2ZXJzaW9uIGlmICdvbicgdmVyc2lvbiB3YXMgdHJpZ2dlcmVkXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlbmFibGVPbmNlSGFya1NwZWFraW5nRXZlbnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0SGFya0xpc3RlbmVySWZOb3RFeGlzdHMoKTtcbiAgICAgICAgaWYgKCF0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWRPbmNlICYmICEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgdGhpcy5oYXJrU3BlYWtpbmdFbmFibGVkT25jZSA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uY2UoJ3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWRPbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBsaXN0ZW5lciBoYXMgYmVlbiBkaXNhYmxlZCBpbiB0aGUgbWVhbnRpbWUgKGZvciBleGFtcGxlIGJ5IHRoZSAnb24nIHZlcnNpb24pIGRvIG5vdCB0cmlnZ2VyIHRoZSBldmVudFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24uZW1pdEV2ZW50KCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RhcnRTcGVha2luZycsIHRoaXMuY29ubmVjdGlvbiwgdGhpcy5zdHJlYW1JZClcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtTWFuYWdlci5lbWl0RXZlbnQoJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnLCBbXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlSGFya1NwZWFraW5nRXZlbnQodHJ1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBkaXNhYmxlSGFya1NwZWFraW5nRXZlbnQoZGlzYWJsZWRCeU9uY2U6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgdGhpcy5oYXJrU3BlYWtpbmdFbmFibGVkT25jZSA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKGRpc2FibGVkQnlPbmNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFya1NwZWFraW5nRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgJ29uJyB2ZXJzaW9uIG9mIHRoaXMgc2FtZSBldmVudCBpcyBlbmFibGVkIHRvby4gRG8gbm90IHJlbW92ZSB0aGUgaGFyayBsaXN0ZW5lclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFNodXR0aW5nIGRvd24gdGhlIGhhcmsgZXZlbnRcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkIHx8XG4gICAgICAgICAgICAgICAgdGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZE9uY2UgfHxcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTdG9wcGVkU3BlYWtpbmdFbmFibGVkIHx8XG4gICAgICAgICAgICAgICAgdGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZE9uY2VcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIC8vIFNvbWUgb3RoZXIgaGFyayBldmVudCBpcyBlbmFibGVkLiBDYW5ub3Qgc3RvcCB0aGUgaGFyayBwcm9jZXNzLCBqdXN0IHJlbW92ZSB0aGUgc3BlY2lmaWMgbGlzdGVuZXJcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9mZignc3BlYWtpbmcnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gTm8gb3RoZXIgaGFyayBldmVudCBpcyBlbmFibGVkLiBXZSBjYW4gZ2V0IGVudGlyZWx5IHJpZCBvZiBpdFxuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRIYXJrTGlzdGVuZXJJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWQgJiYgISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhhcmtTdG9wcGVkU3BlYWtpbmdFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub24oJ3N0b3BwZWRfc3BlYWtpbmcnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgW1xuICAgICAgICAgICAgICAgICAgICBuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnNlc3Npb24sICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgW1xuICAgICAgICAgICAgICAgICAgICBuZXcgUHVibGlzaGVyU3BlYWtpbmdFdmVudCh0aGlzLnN0cmVhbU1hbmFnZXIsICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0aGlzLmNvbm5lY3Rpb24sIHRoaXMuc3RyZWFtSWQpXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZE9uY2UgPSBmYWxzZTsgLy8gRGlzYWJsZSAnb25jZScgdmVyc2lvbiBpZiAnb24nIHZlcnNpb24gd2FzIHRyaWdnZXJlZFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudCgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXRIYXJrTGlzdGVuZXJJZk5vdEV4aXN0cygpO1xuICAgICAgICBpZiAoIXRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWRPbmNlICYmICEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgdGhpcy5oYXJrU3RvcHBlZFNwZWFraW5nRW5hYmxlZE9uY2UgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbmNlKCdzdG9wcGVkX3NwZWFraW5nJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhcmtTdG9wcGVkU3BlYWtpbmdFbmFibGVkT25jZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbGlzdGVuZXIgaGFzIGJlZW4gZGlzYWJsZWQgaW4gdGhlIG1lYW50aW1lIChmb3IgZXhhbXBsZSBieSB0aGUgJ29uJyB2ZXJzaW9uKSBkbyBub3QgdHJpZ2dlciB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLmVtaXRFdmVudCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zZXNzaW9uLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1NYW5hZ2VyLmVtaXRFdmVudCgncHVibGlzaGVyU3RvcFNwZWFraW5nJywgW1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFB1Ymxpc2hlclNwZWFraW5nRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAncHVibGlzaGVyU3RvcFNwZWFraW5nJywgdGhpcy5jb25uZWN0aW9uLCB0aGlzLnN0cmVhbUlkKVxuICAgICAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KHRydWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzYWJsZUhhcmtTdG9wcGVkU3BlYWtpbmdFdmVudChkaXNhYmxlZEJ5T25jZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLnNwZWVjaEV2ZW50KSB7XG4gICAgICAgICAgICB0aGlzLmhhcmtTdG9wcGVkU3BlYWtpbmdFbmFibGVkT25jZSA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKGRpc2FibGVkQnlPbmNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gV2UgYXJlIGNhbmNlbGxpbmcgdGhlICdvbmNlJyBsaXN0ZW5lciBmb3IgdGhpcyBldmVudCwgYnV0IHRoZSAnb24nIHZlcnNpb25cbiAgICAgICAgICAgICAgICAgICAgLy8gb2YgdGhpcyBzYW1lIGV2ZW50IGlzIGVuYWJsZWQgdG9vLiBEbyBub3QgcmVtb3ZlIHRoZSBoYXJrIGxpc3RlbmVyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFNodXR0aW5nIGRvd24gdGhlIGhhcmsgZXZlbnRcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkIHx8XG4gICAgICAgICAgICAgICAgdGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZE9uY2UgfHxcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTcGVha2luZ0VuYWJsZWRPbmNlXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAvLyBTb21lIG90aGVyIGhhcmsgZXZlbnQgaXMgZW5hYmxlZC4gQ2Fubm90IHN0b3AgdGhlIGhhcmsgcHJvY2VzcywganVzdCByZW1vdmUgdGhlIHNwZWNpZmljIGxpc3RlbmVyXG4gICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vZmYoJ3N0b3BwZWRfc3BlYWtpbmcnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gTm8gb3RoZXIgaGFyayBldmVudCBpcyBlbmFibGVkLiBXZSBjYW4gZ2V0IGVudGlyZWx5IHJpZCBvZiBpdFxuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnNwZWVjaEV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVuYWJsZUhhcmtWb2x1bWVDaGFuZ2VFdmVudChmb3JjZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5zZXRIYXJrTGlzdGVuZXJJZk5vdEV4aXN0cygpKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWQgfHwgZm9yY2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9uKCd2b2x1bWVfY2hhbmdlJywgKGhhcmtFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRWYWx1ZSA9IHRoaXMuc3BlZWNoRXZlbnQub2xkVm9sdW1lVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0geyBuZXdWYWx1ZTogaGFya0V2ZW50LCBvbGRWYWx1ZSB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlID0gaGFya0V2ZW50O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBUaGlzIHdheSB3aGVuZXZlciB0aGUgTWVkaWFTdHJlYW0gb2JqZWN0IGlzIGF2YWlsYWJsZSwgdGhlIGV2ZW50IGxpc3RlbmVyIHdpbGwgYmUgYXV0b21hdGljYWxseSBhZGRlZFxuICAgICAgICAgICAgdGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZW5hYmxlT25jZUhhcmtWb2x1bWVDaGFuZ2VFdmVudChmb3JjZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5zZXRIYXJrTGlzdGVuZXJJZk5vdEV4aXN0cygpKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaGFya1ZvbHVtZUNoYW5nZUVuYWJsZWRPbmNlIHx8IGZvcmNlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZE9uY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub25jZSgndm9sdW1lX2NoYW5nZScsIChoYXJrRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkVmFsdWUgPSB0aGlzLnNwZWVjaEV2ZW50Lm9sZFZvbHVtZVZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHsgbmV3VmFsdWU6IGhhcmtFdmVudCwgb2xkVmFsdWUgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGVlY2hFdmVudC5vbGRWb2x1bWVWYWx1ZSA9IGhhcmtFdmVudDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNhYmxlSGFya1ZvbHVtZUNoYW5nZUV2ZW50KHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbU1hbmFnZXIuZW1pdEV2ZW50KCdzdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZScsIFtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcy5zdHJlYW1NYW5hZ2VyLCAnc3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2UnLCB2YWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBUaGlzIHdheSB3aGVuZXZlciB0aGUgTWVkaWFTdHJlYW0gb2JqZWN0IGlzIGF2YWlsYWJsZSwgdGhlIGV2ZW50IGxpc3RlbmVyIHdpbGwgYmUgYXV0b21hdGljYWxseSBhZGRlZFxuICAgICAgICAgICAgdGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZE9uY2UgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGRpc2FibGVIYXJrVm9sdW1lQ2hhbmdlRXZlbnQoZGlzYWJsZWRCeU9uY2U6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgdGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZE9uY2UgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChkaXNhYmxlZEJ5T25jZSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFdlIGFyZSBjYW5jZWxsaW5nIHRoZSAnb25jZScgbGlzdGVuZXIgZm9yIHRoaXMgZXZlbnQsIGJ1dCB0aGUgJ29uJyB2ZXJzaW9uXG4gICAgICAgICAgICAgICAgICAgIC8vIG9mIHRoaXMgc2FtZSBldmVudCBpcyBlbmFibGVkIHRvby4gRG8gbm90IHJlbW92ZSB0aGUgaGFyayBsaXN0ZW5lclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtWb2x1bWVDaGFuZ2VFbmFibGVkID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBTaHV0dGluZyBkb3duIHRoZSBoYXJrIGV2ZW50XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgdGhpcy5oYXJrU3BlYWtpbmdFbmFibGVkIHx8XG4gICAgICAgICAgICAgICAgdGhpcy5oYXJrU3BlYWtpbmdFbmFibGVkT25jZSB8fFxuICAgICAgICAgICAgICAgIHRoaXMuaGFya1N0b3BwZWRTcGVha2luZ0VuYWJsZWQgfHxcbiAgICAgICAgICAgICAgICB0aGlzLmhhcmtTdG9wcGVkU3BlYWtpbmdFbmFibGVkT25jZVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgLy8gU29tZSBvdGhlciBoYXJrIGV2ZW50IGlzIGVuYWJsZWQuIENhbm5vdCBzdG9wIHRoZSBoYXJrIHByb2Nlc3MsIGp1c3QgcmVtb3ZlIHRoZSBzcGVjaWZpYyBsaXN0ZW5lclxuICAgICAgICAgICAgICAgIHRoaXMuc3BlZWNoRXZlbnQub2ZmKCd2b2x1bWVfY2hhbmdlJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIE5vIG90aGVyIGhhcmsgZXZlbnQgaXMgZW5hYmxlZC4gV2UgY2FuIGdldCBlbnRpcmVseSByaWQgb2YgaXRcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50LnN0b3AoKTtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5zcGVlY2hFdmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpc0xvY2FsKCk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBpbmJvdW5kIG9wdGlvbnMgdW5kZWZpbmVkIGFuZCBvdXRib3VuZCBvcHRpb25zIGRlZmluZWRcbiAgICAgICAgcmV0dXJuICF0aGlzLmluYm91bmRTdHJlYW1PcHRzICYmICEhdGhpcy5vdXRib3VuZFN0cmVhbU9wdHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzXG4gICAgICAgICAgICAgICAgLmdldFNlbGVjdGVkSWNlQ2FuZGlkYXRlSW5mbygpXG4gICAgICAgICAgICAgICAgLnRoZW4oKHJlcG9ydCkgPT4gcmVzb2x2ZShyZXBvcnQpKVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpOiBSVENJY2VDYW5kaWRhdGVbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLndlYlJ0Y1BlZXIucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZXRMb2NhbEljZUNhbmRpZGF0ZUxpc3QoKTogUlRDSWNlQ2FuZGlkYXRlW10ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNQZWVyLmxvY2FsQ2FuZGlkYXRlc1F1ZXVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBzdHJlYW1JY2VDb25uZWN0aW9uU3RhdGVCcm9rZW4oKSB7XG4gICAgICAgIGlmICghdGhpcy5nZXRXZWJSdGNQZWVyKCkgfHwgIXRoaXMuZ2V0UlRDUGVlckNvbm5lY3Rpb24oKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmlzTG9jYWwoKSAmJiAhIXRoaXMuc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24uZm9yY2VNZWRpYVJlY29ubmVjdGlvbkFmdGVyTmV0d29ya0Ryb3ApIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgICAgICAgIGBPcGVuVmlkdSBCcm93c2VyIGFkdmFuY2VkIGNvbmZpZ3VyYXRpb24gb3B0aW9uIFwiZm9yY2VNZWRpYVJlY29ubmVjdGlvbkFmdGVyTmV0d29ya0Ryb3BcIiBpcyBlbmFibGVkLiBTdHJlYW0gJHt0aGlzLnN0cmVhbUlkXG4gICAgICAgICAgICAgICAgfSAoJHt0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInfSkgd2lsbCBmb3JjZSBhIHJlY29ubmVjdGlvbmBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpY2VDb25uZWN0aW9uU3RhdGU6IFJUQ0ljZUNvbm5lY3Rpb25TdGF0ZSA9IHRoaXMuZ2V0UlRDUGVlckNvbm5lY3Rpb24oKS5pY2VDb25uZWN0aW9uU3RhdGU7XG4gICAgICAgIHJldHVybiBpY2VDb25uZWN0aW9uU3RhdGUgIT09ICdjb25uZWN0ZWQnICYmIGljZUNvbm5lY3Rpb25TdGF0ZSAhPT0gJ2NvbXBsZXRlZCc7XG4gICAgfVxuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcml2YXRlIHNldEhhcmtMaXN0ZW5lcklmTm90RXhpc3RzKCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3BlZWNoRXZlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBoYXJrT3B0aW9ucyA9ICEhdGhpcy5oYXJrT3B0aW9uc1xuICAgICAgICAgICAgICAgICAgICA/IHRoaXMuaGFya09wdGlvbnNcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgICAgICBoYXJrT3B0aW9ucy5pbnRlcnZhbCA9IHR5cGVvZiBoYXJrT3B0aW9ucy5pbnRlcnZhbCA9PT0gJ251bWJlcicgPyBoYXJrT3B0aW9ucy5pbnRlcnZhbCA6IDEwMDtcbiAgICAgICAgICAgICAgICBoYXJrT3B0aW9ucy50aHJlc2hvbGQgPSB0eXBlb2YgaGFya09wdGlvbnMudGhyZXNob2xkID09PSAnbnVtYmVyJyA/IGhhcmtPcHRpb25zLnRocmVzaG9sZCA6IC01MDtcbiAgICAgICAgICAgICAgICB0aGlzLnNwZWVjaEV2ZW50ID0gaGFyayh0aGlzLm1lZGlhU3RyZWFtLCBoYXJrT3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHNldHVwUmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyKHJlc29sdmU6ICh2YWx1ZTogdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+KSA9PiB2b2lkLCByZWplY3Q6IChyZWFzb24/OiBhbnkpID0+IHZvaWQpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyID09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gb25nb2luZyByZWNvbm5lY3Rpb25cbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gT25nb2luZyByZWNvbm5lY3Rpb25cbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICBgVHJ5aW5nIHRvIHJlY29ubmVjdCBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHt0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInXG4gICAgICAgICAgICAgICAgfSkgYnV0IGFuIG9uZ29pbmcgcmVjb25uZWN0aW9uIHByb2Nlc3MgaXMgYWN0aXZlLiBXYWl0aW5nIGZvciByZXNwb25zZS4uLmBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlci5vbmNlKCdzdWNjZXNzJywgKCkgPT4gcmVzb2x2ZSgpKTtcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyLm9uY2UoJ2Vycm9yJywgKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRXZWJSdGNQZWVyU2VuZChyZWNvbm5lY3Q6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zZXR1cFJlY29ubmVjdGlvbkV2ZW50RW1pdHRlcihyZXNvbHZlLCByZWplY3QpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE9uZ29pbmcgcmVjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIE1lZGlhU3RyZWFtIHdpbGwgYWxyZWFkeSBoYXZlIGhhcmsgZXZlbnRzIGZvciByZWNvbm5lY3RlZCBzdHJlYW1zXG4gICAgICAgICAgICAgICAgdGhpcy5pbml0SGFya0V2ZW50cygpOyAvLyBJbml0IGhhcmsgZXZlbnRzIGZvciB0aGUgbG9jYWwgc3RyZWFtXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVzb2x2ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocmVjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyPy5lbWl0RXZlbnQoJ3N1Y2Nlc3MnKTtcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgZmluYWxSZWplY3QgPSAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocmVjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyPy5lbWl0RXZlbnQoJ2Vycm9yJywgW2Vycm9yXSk7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBjb25zdCBzdWNjZXNzT2ZmZXJDYWxsYmFjayA9IChzZHBPZmZlclBhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdTZW5kaW5nIFNEUCBvZmZlciB0byBwdWJsaXNoIGFzICcgKyB0aGlzLnN0cmVhbUlkLCBzZHBPZmZlclBhcmFtKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IG1ldGhvZCA9IHJlY29ubmVjdCA/ICdyZWNvbm5lY3RTdHJlYW0nIDogJ3B1Ymxpc2hWaWRlbyc7XG4gICAgICAgICAgICAgICAgbGV0IHBhcmFtcztcbiAgICAgICAgICAgICAgICBpZiAocmVjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbTogdGhpcy5zdHJlYW1JZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNkcFN0cmluZzogc2RwT2ZmZXJQYXJhbVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB0eXBlT2ZWaWRlbztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNTZW5kVmlkZW8oKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8gPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiBNZWRpYVN0cmVhbVRyYWNrICE9PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlIGluc3RhbmNlb2YgTWVkaWFTdHJlYW1UcmFja1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IFR5cGVPZlZpZGVvLkNVU1RPTVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuaXNTZW5kU2NyZWVuKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gVHlwZU9mVmlkZW8uU0NSRUVOXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFR5cGVPZlZpZGVvLkNBTUVSQTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkb0xvb3BiYWNrOiB0aGlzLmRpc3BsYXlNeVJlbW90ZSgpIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzQXVkaW86IHRoaXMuaXNTZW5kQXVkaW8oKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc1ZpZGVvOiB0aGlzLmlzU2VuZFZpZGVvKCksXG4gICAgICAgICAgICAgICAgICAgICAgICBhdWRpb0FjdGl2ZTogdGhpcy5hdWRpb0FjdGl2ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZGVvQWN0aXZlOiB0aGlzLnZpZGVvQWN0aXZlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZU9mVmlkZW8sXG4gICAgICAgICAgICAgICAgICAgICAgICBmcmFtZVJhdGU6ICEhdGhpcy5mcmFtZVJhdGUgPyB0aGlzLmZyYW1lUmF0ZSA6IC0xLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmlkZW9EaW1lbnNpb25zOiBKU09OLnN0cmluZ2lmeSh0aGlzLnZpZGVvRGltZW5zaW9ucyksXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXI6IHRoaXMub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMuZmlsdGVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2RwT2ZmZXI6IHNkcE9mZmVyUGFyYW1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QobWV0aG9kLCBwYXJhbXMsIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gNDAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZWplY3QoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBPcGVuVmlkdUVycm9yKE9wZW5WaWR1RXJyb3JOYW1lLk9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVELCBcIllvdSBkb24ndCBoYXZlIHBlcm1pc3Npb25zIHRvIHB1Ymxpc2hcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlamVjdCgnRXJyb3Igb24gcHVibGlzaFZpZGVvOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wcm9jZXNzUmVtb3RlQW5zd2VyKHJlc3BvbnNlLnNkcEFuc3dlcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgPSByZXNwb25zZS5pZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jcmVhdGlvblRpbWUgPSByZXNwb25zZS5jcmVhdGVkQXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNMb2NhbFN0cmVhbVB1Ymxpc2hlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHVibGlzaGVkT25jZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvY2FsTWVkaWFTdHJlYW1XaGVuU3Vic2NyaWJlZFRvUmVtb3RlID0gdGhpcy5tZWRpYVN0cmVhbTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKHJlY29ubmVjdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlY29ubmVjdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbS1yZWNvbm5lY3RlZC1ieS1wdWJsaXNoZXInLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtLWNyZWF0ZWQtYnktcHVibGlzaGVyJywgW10pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1N0YXRzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCInUHVibGlzaGVyJyAoXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdHJlYW1JZCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnKSBzdWNjZXNzZnVsbHkgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVjb25uZWN0ID8gJ3JlY29ubmVjdGVkJyA6ICdwdWJsaXNoZWQnKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnIHRvIHNlc3Npb24nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgY29uZmlnOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzOiB7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvOiB0aGlzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5oYXNWaWRlb1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiB0aGlzLm91dGJvdW5kU3RyZWFtT3B0cy5wdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU2ltdWxjYXN0ID8/IHRoaXMuc2Vzc2lvbi5vcGVudmlkdS52aWRlb1NpbXVsY2FzdCxcbiAgICAgICAgICAgICAgICBvbkljZUNhbmRpZGF0ZTogdGhpcy5jb25uZWN0aW9uLnNlbmRJY2VDYW5kaWRhdGUuYmluZCh0aGlzLmNvbm5lY3Rpb24pLFxuICAgICAgICAgICAgICAgIG9uSWNlQ29ubmVjdGlvblN0YXRlRXhjZXB0aW9uOiB0aGlzLm9uSWNlQ29ubmVjdGlvblN0YXRlRXhjZXB0aW9uSGFuZGxlci5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIGljZVNlcnZlcnM6IHRoaXMuZ2V0SWNlU2VydmVyc0NvbmYoKSxcbiAgICAgICAgICAgICAgICBtZWRpYVN0cmVhbTogdGhpcy5tZWRpYVN0cmVhbSxcbiAgICAgICAgICAgICAgICBtZWRpYVNlcnZlcjogdGhpcy5zZXNzaW9uLm9wZW52aWR1Lm1lZGlhU2VydmVyLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiB0aGlzLnR5cGVPZlZpZGVvID8gVHlwZU9mVmlkZW9bdGhpcy50eXBlT2ZWaWRlb10gOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24ub3BlbnZpZHUubWVkaWFTZXJ2ZXIgIT09ICdtZWRpYXNvdXAnKSB7XG4gICAgICAgICAgICAgICAgLy8gU2ltdWxjYXN0IGlzIG9ubHkgc3VwcG9ydGVkIGJ5IG1lZGlhc291cFxuICAgICAgICAgICAgICAgIGNvbmZpZy5zaW11bGNhc3QgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlY29ubmVjdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmRpc3BsYXlNeVJlbW90ZSgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyID0gbmV3IFdlYlJ0Y1BlZXJTZW5kcmVjdihjb25maWcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIgPSBuZXcgV2ViUnRjUGVlclNlbmRvbmx5KGNvbmZpZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXIuYWRkSWNlQ29ubmVjdGlvblN0YXRlQ2hhbmdlTGlzdGVuZXIoJ3B1Ymxpc2hlciBvZiAnICsgdGhpcy5jb25uZWN0aW9uLmNvbm5lY3Rpb25JZCk7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXJcbiAgICAgICAgICAgICAgICAuY3JlYXRlT2ZmZXIoKVxuICAgICAgICAgICAgICAgIC50aGVuKChzZHBPZmZlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLndlYlJ0Y1BlZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5wcm9jZXNzTG9jYWxPZmZlcihzZHBPZmZlcilcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzT2ZmZXJDYWxsYmFjayhzZHBPZmZlci5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlamVjdChuZXcgRXJyb3IoJyhwdWJsaXNoKSBTRFAgcHJvY2VzcyBsb2NhbCBvZmZlciBlcnJvcjogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGZpbmFsUmVqZWN0KG5ldyBFcnJvcignKHB1Ymxpc2gpIFNEUCBjcmVhdGUgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGZpbmFsUmVzb2x2ZUZvclN1YnNjcmlwdGlvbihyZWNvbm5lY3Q6IGJvb2xlYW4sIHJlc29sdmU6ICh2YWx1ZTogdm9pZCB8IFByb21pc2VMaWtlPHZvaWQ+KSA9PiB2b2lkKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKFwiJ1N1YnNjcmliZXInIChcIiArIHRoaXMuc3RyZWFtSWQgKyAnKSBzdWNjZXNzZnVsbHkgJyArIChyZWNvbm5lY3QgPyAncmVjb25uZWN0ZWQnIDogJ3N1YnNjcmliZWQnKSk7XG4gICAgICAgIHRoaXMucmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKHJlY29ubmVjdCk7XG4gICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1N0YXRzKCk7XG4gICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyPy5lbWl0RXZlbnQoJ3N1Y2Nlc3MnKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBmaW5hbFJlamVjdEZvclN1YnNjcmlwdGlvbihyZWNvbm5lY3Q6IGJvb2xlYW4sIGVycm9yOiBhbnksIHJlamVjdDogKHJlYXNvbj86IGFueSkgPT4gdm9pZCkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICBcIkVycm9yIGZvciAnU3Vic2NyaWJlcicgKFwiICtcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtSWQgK1xuICAgICAgICAgICAgJykgd2hpbGUgdHJ5aW5nIHRvICcgK1xuICAgICAgICAgICAgKHJlY29ubmVjdCA/ICdyZWNvbm5lY3QnIDogJ3N1YnNjcmliZScpICtcbiAgICAgICAgICAgICc6ICcgK1xuICAgICAgICAgICAgZXJyb3IudG9TdHJpbmcoKVxuICAgICAgICApO1xuICAgICAgICBpZiAocmVjb25uZWN0KSB7XG4gICAgICAgICAgICB0aGlzLnJlY29ubmVjdGlvbkV2ZW50RW1pdHRlcj8uZW1pdEV2ZW50KCdlcnJvcicsIFtlcnJvcl0pO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMucmVjb25uZWN0aW9uRXZlbnRFbWl0dGVyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0V2ViUnRjUGVlclJlY2VpdmUocmVjb25uZWN0OiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAocmVjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2V0dXBSZWNvbm5lY3Rpb25FdmVudEVtaXR0ZXIocmVzb2x2ZSwgcmVqZWN0KSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBPbmdvaW5nIHJlY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLm9wZW52aWR1Lm1lZGlhU2VydmVyID09PSAnbWVkaWFzb3VwJykge1xuICAgICAgICAgICAgICAgIC8vIFNlcnZlciBpbml0aWF0ZXMgbmVnb3RpYXRpb25cblxuICAgICAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlRnJvbVNlcnZlcihyZWNvbm5lY3QpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMuZmluYWxSZXNvbHZlRm9yU3Vic2NyaXB0aW9uKHJlY29ubmVjdCwgcmVzb2x2ZSkpXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHRoaXMuZmluYWxSZWplY3RGb3JTdWJzY3JpcHRpb24ocmVjb25uZWN0LCBlcnJvciwgcmVqZWN0KSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIENsaWVudCBpbml0aWF0ZXMgbmVnb3RpYXRpb25cblxuICAgICAgICAgICAgICAgIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlRnJvbUNsaWVudChyZWNvbm5lY3QpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMuZmluYWxSZXNvbHZlRm9yU3Vic2NyaXB0aW9uKHJlY29ubmVjdCwgcmVzb2x2ZSkpXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHRoaXMuZmluYWxSZWplY3RGb3JTdWJzY3JpcHRpb24ocmVjb25uZWN0LCBlcnJvciwgcmVqZWN0KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0V2ViUnRjUGVlclJlY2VpdmVGcm9tQ2xpZW50KHJlY29ubmVjdDogYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jb21wbGV0ZVdlYlJ0Y1BlZXJSZWNlaXZlKHJlY29ubmVjdCwgZmFsc2UpXG4gICAgICAgICAgICAgICAgLnRoZW4oKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlclxuICAgICAgICAgICAgICAgICAgICAgICAgLnByb2Nlc3NSZW1vdGVBbnN3ZXIocmVzcG9uc2Uuc2RwQW5zd2VyKVxuICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRXZWJSdGNQZWVyUmVjZWl2ZUZyb21TZXJ2ZXIocmVjb25uZWN0OiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAvLyBTZXJ2ZXIgaW5pdGlhdGVzIG5lZ290aWF0aW9uXG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ub3BlbnZpZHUuc2VuZFJlcXVlc3QoJ3ByZXBhcmVSZWNlaXZlVmlkZW9Gcm9tJywgeyBzZW5kZXI6IHRoaXMuc3RyZWFtSWQsIHJlY29ubmVjdCB9LCAoZXJyb3IsIHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdFcnJvciBvbiBwcmVwYXJlUmVjZWl2ZVZpZGVvRnJvbTogJyArIEpTT04uc3RyaW5naWZ5KGVycm9yKSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29tcGxldGVXZWJSdGNQZWVyUmVjZWl2ZShyZWNvbm5lY3QsIGZhbHNlLCByZXNwb25zZS5zZHBPZmZlcilcbiAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHJlc29sdmUoKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29tcGxldGVXZWJSdGNQZWVyUmVjZWl2ZShyZWNvbm5lY3Q6IGJvb2xlYW4sIGZvcmNpYmx5UmVjb25uZWN0OiBib29sZWFuLCBzZHBPZmZlckJ5U2VydmVyPzogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhcIidTZXNzaW9uLnN1YnNjcmliZShTdHJlYW0pJyBjYWxsZWRcIik7XG5cbiAgICAgICAgICAgIGNvbnN0IHNlbmRTZHBUb1NlcnZlciA9IChzZHBTdHJpbmc6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgU2VuZGluZyBsb2NhbCBTRFAgJHshIXNkcE9mZmVyQnlTZXJ2ZXIgPyAnYW5zd2VyJyA6ICdvZmZlcid9IHRvIHN1YnNjcmliZSB0byAke3RoaXMuc3RyZWFtSWR9YCwgc2RwU3RyaW5nKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IG1ldGhvZCA9IHJlY29ubmVjdCA/ICdyZWNvbm5lY3RTdHJlYW0nIDogJ3JlY2VpdmVWaWRlb0Zyb20nO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHt9O1xuICAgICAgICAgICAgICAgIHBhcmFtc1tyZWNvbm5lY3QgPyAnc3RyZWFtJyA6ICdzZW5kZXInXSA9IHRoaXMuc3RyZWFtSWQ7XG4gICAgICAgICAgICAgICAgaWYgKCEhc2RwT2ZmZXJCeVNlcnZlcikge1xuICAgICAgICAgICAgICAgICAgICBwYXJhbXNbcmVjb25uZWN0ID8gJ3NkcFN0cmluZycgOiAnc2RwQW5zd2VyJ10gPSBzZHBTdHJpbmc7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zWydzZHBPZmZlciddID0gc2RwU3RyaW5nO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocmVjb25uZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmFtc1snZm9yY2libHlSZWNvbm5lY3QnXSA9IGZvcmNpYmx5UmVjb25uZWN0O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5zZW5kUmVxdWVzdChtZXRob2QsIHBhcmFtcywgKGVycm9yLCByZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdFcnJvciBvbiAnICsgbWV0aG9kICsgJyA6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgY29uZmlnOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBtZWRpYUNvbnN0cmFpbnRzOiB7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvOiB0aGlzLmhhc0F1ZGlvLFxuICAgICAgICAgICAgICAgICAgICB2aWRlbzogdGhpcy5oYXNWaWRlb1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc2ltdWxjYXN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgICBvbkljZUNhbmRpZGF0ZTogdGhpcy5jb25uZWN0aW9uLnNlbmRJY2VDYW5kaWRhdGUuYmluZCh0aGlzLmNvbm5lY3Rpb24pLFxuICAgICAgICAgICAgICAgIG9uSWNlQ29ubmVjdGlvblN0YXRlRXhjZXB0aW9uOiB0aGlzLm9uSWNlQ29ubmVjdGlvblN0YXRlRXhjZXB0aW9uSGFuZGxlci5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIGljZVNlcnZlcnM6IHRoaXMuZ2V0SWNlU2VydmVyc0NvbmYoKSxcbiAgICAgICAgICAgICAgICBtZWRpYVNlcnZlcjogdGhpcy5zZXNzaW9uLm9wZW52aWR1Lm1lZGlhU2VydmVyLFxuICAgICAgICAgICAgICAgIHR5cGVPZlZpZGVvOiB0aGlzLnR5cGVPZlZpZGVvID8gVHlwZU9mVmlkZW9bdGhpcy50eXBlT2ZWaWRlb10gOiB1bmRlZmluZWRcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmIChyZWNvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3Bvc2VXZWJSdGNQZWVyKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlciA9IG5ldyBXZWJSdGNQZWVyUmVjdm9ubHkoY29uZmlnKTtcbiAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlci5hZGRJY2VDb25uZWN0aW9uU3RhdGVDaGFuZ2VMaXN0ZW5lcih0aGlzLnN0cmVhbUlkKTtcblxuICAgICAgICAgICAgaWYgKCEhc2RwT2ZmZXJCeVNlcnZlcikge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlclxuICAgICAgICAgICAgICAgICAgICAucHJvY2Vzc1JlbW90ZU9mZmVyKHNkcE9mZmVyQnlTZXJ2ZXIpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jcmVhdGVBbnN3ZXIoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKChzZHBBbnN3ZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53ZWJSdGNQZWVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucHJvY2Vzc0xvY2FsQW5zd2VyKHNkcEFuc3dlcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kU2RwVG9TZXJ2ZXIoc2RwQW5zd2VyLnNkcCEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignKHN1YnNjcmliZSkgU0RQIHByb2Nlc3MgbG9jYWwgYW5zd2VyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBjcmVhdGUgYW5zd2VyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCcoc3Vic2NyaWJlKSBTRFAgcHJvY2VzcyByZW1vdGUgb2ZmZXIgZXJyb3I6ICcgKyBKU09OLnN0cmluZ2lmeShlcnJvcikpKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlclxuICAgICAgICAgICAgICAgICAgICAuY3JlYXRlT2ZmZXIoKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoc2RwT2ZmZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2ViUnRjUGVlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5wcm9jZXNzTG9jYWxPZmZlcihzZHBPZmZlcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRTZHBUb1NlcnZlcihzZHBPZmZlci5zZHAhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdChuZXcgRXJyb3IoJyhzdWJzY3JpYmUpIFNEUCBwcm9jZXNzIGxvY2FsIG9mZmVyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCcoc3Vic2NyaWJlKSBTRFAgY3JlYXRlIG9mZmVyIGVycm9yOiAnICsgSlNPTi5zdHJpbmdpZnkoZXJyb3IpKSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3RlUGVlclN1Y2Nlc3NmdWxseUVzdGFibGlzaGVkKHJlY29ubmVjdDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAocmVjb25uZWN0ICYmIHRoaXMubWVkaWFTdHJlYW0gIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gTm93IHdlIGNhbiBkZXN0cm95IHRoZSBleGlzdGluZyBNZWRpYVN0cmVhbVxuICAgICAgICAgICAgdGhpcy5kaXNwb3NlTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0gPSBuZXcgTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgbGV0IHJlY2VpdmVyOiBSVENSdHBSZWNlaXZlcjtcbiAgICAgICAgZm9yIChyZWNlaXZlciBvZiB0aGlzLndlYlJ0Y1BlZXIucGMuZ2V0UmVjZWl2ZXJzKCkpIHtcbiAgICAgICAgICAgIGlmICghIXJlY2VpdmVyLnRyYWNrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tZWRpYVN0cmVhbS5hZGRUcmFjayhyZWNlaXZlci50cmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdQZWVyIHJlbW90ZSBzdHJlYW0nLCB0aGlzLm1lZGlhU3RyZWFtKTtcblxuICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW1NYW5hZ2VyIGluc3RhbmNlb2YgU3Vic2NyaWJlcikge1xuICAgICAgICAgICAgICAgIC8vIEFwcGx5IFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvQXVkaW8gYW5kIFN1YnNjcmliZXJQcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW9cbiAgICAgICAgICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5hYmxlZCA9IHJlY29ubmVjdCA/IHRoaXMuYXVkaW9BY3RpdmUgOiAhISh0aGlzLnN0cmVhbU1hbmFnZXIgYXMgU3Vic2NyaWJlcikucHJvcGVydGllcy5zdWJzY3JpYmVUb0F1ZGlvO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKClbMF0uZW5hYmxlZCA9IGVuYWJsZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmFibGVkID0gcmVjb25uZWN0ID8gdGhpcy52aWRlb0FjdGl2ZSA6ICEhKHRoaXMuc3RyZWFtTWFuYWdlciBhcyBTdWJzY3JpYmVyKS5wcm9wZXJ0aWVzLnN1YnNjcmliZVRvVmlkZW87XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXS5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMudXBkYXRlTWVkaWFTdHJlYW1JblZpZGVvcygpO1xuICAgICAgICAgICAgdGhpcy5pbml0SGFya0V2ZW50cygpOyAvLyBJbml0IGhhcmsgZXZlbnRzIGZvciB0aGUgcmVtb3RlIHN0cmVhbVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRIYXJrRXZlbnRzKCk6IHZvaWQge1xuICAgICAgICBpZiAoISF0aGlzLm1lZGlhU3RyZWFtIS5nZXRBdWRpb1RyYWNrcygpWzBdKSB7XG4gICAgICAgICAgICAvLyBIYXJrIGV2ZW50cyBjYW4gb25seSBiZSBzZXQgaWYgYXVkaW8gdHJhY2sgaXMgYXZhaWxhYmxlXG4gICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgdHJ1ZSwgdGhpcy5zdHJlYW1NYW5hZ2VyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlT25jZUhhcmtTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKCdwdWJsaXNoZXJTdGFydFNwZWFraW5nJywgZmFsc2UsIHRoaXMuc3RyZWFtTWFuYWdlcikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZUhhcmtTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCB0cnVlLCB0aGlzLnN0cmVhbU1hbmFnZXIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbmFibGVPbmNlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5zZXNzaW9uLmFueVNwZWVjaEV2ZW50TGlzdGVuZXJFbmFibGVkKCdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnLCBmYWxzZSwgdGhpcy5zdHJlYW1NYW5hZ2VyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZE9uY2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZU9uY2VIYXJrVm9sdW1lQ2hhbmdlRXZlbnQodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5oYXJrVm9sdW1lQ2hhbmdlRW5hYmxlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlSGFya1ZvbHVtZUNoYW5nZUV2ZW50KHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkljZUNvbm5lY3Rpb25TdGF0ZUV4Y2VwdGlvbkhhbmRsZXIoZXhjZXB0aW9uTmFtZTogRXhjZXB0aW9uRXZlbnROYW1lLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiBhbnkpOiB2b2lkIHtcbiAgICAgICAgc3dpdGNoIChleGNlcHRpb25OYW1lKSB7XG4gICAgICAgICAgICBjYXNlIEV4Y2VwdGlvbkV2ZW50TmFtZS5JQ0VfQ09OTkVDVElPTl9GQUlMRUQ6XG4gICAgICAgICAgICAgICAgdGhpcy5vbkljZUNvbm5lY3Rpb25GYWlsZWQoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgRXhjZXB0aW9uRXZlbnROYW1lLklDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRDpcbiAgICAgICAgICAgICAgICB0aGlzLm9uSWNlQ29ubmVjdGlvbkRpc2Nvbm5lY3RlZCgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2Vzc2lvbi5lbWl0RXZlbnQoJ2V4Y2VwdGlvbicsIFtuZXcgRXhjZXB0aW9uRXZlbnQodGhpcy5zZXNzaW9uLCBleGNlcHRpb25OYW1lLCB0aGlzLCBtZXNzYWdlLCBkYXRhKV0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25JY2VDb25uZWN0aW9uRmFpbGVkKCkge1xuICAgICAgICAvLyBJbW1lZGlhdGVseSByZWNvbm5lY3QsIGFzIHRoaXMgaXMgYSB0ZXJtaW5hbCBlcnJvclxuICAgICAgICBsb2dnZXIubG9nKFxuICAgICAgICAgICAgYFtJQ0VfQ09OTkVDVElPTl9GQUlMRURdIEhhbmRsaW5nIElDRV9DT05ORUNUSU9OX0ZBSUxFRCBldmVudC4gUmVjb25uZWN0aW5nIHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcidcbiAgICAgICAgICAgIH0pYFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlY29ubmVjdFN0cmVhbUFuZExvZ1Jlc3VsdGluZ0ljZUNvbm5lY3Rpb25TdGF0ZShFeGNlcHRpb25FdmVudE5hbWUuSUNFX0NPTk5FQ1RJT05fRkFJTEVEKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uSWNlQ29ubmVjdGlvbkRpc2Nvbm5lY3RlZCgpIHtcbiAgICAgICAgLy8gV2FpdCB0byBzZWUgaWYgdGhlIElDRSBjb25uZWN0aW9uIGlzIGFibGUgdG8gcmVjb25uZWN0XG4gICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICBgW0lDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRF0gSGFuZGxpbmcgSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVEIGV2ZW50LiBXYWl0aW5nIGZvciBJQ0UgdG8gYmUgcmVzdG9yZWQgYW5kIHJlY29ubmVjdCBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkXG4gICAgICAgICAgICB9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcid9KSBpZiBub3QgcG9zc2libGVgXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IHRpbWVvdXQgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZUNvbm5lY3Rpb25EaXNjb25uZWN0ZWRFeGNlcHRpb25UaW1lb3V0IHx8IDQwMDA7XG4gICAgICAgIHRoaXMuYXdhaXRXZWJSdGNQZWVyQ29ubmVjdGlvblN0YXRlKHRpbWVvdXQpLnRoZW4oKHN0YXRlKSA9PiB7XG4gICAgICAgICAgICBzd2l0Y2ggKHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnZmFpbGVkJzpcbiAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90aGluZywgYXMgYW4gSUNFX0NPTk5FQ1RJT05fRkFJTEVEIGV2ZW50IHdpbGwgaGF2ZSBhbHJlYWR5IHJhaXNlZFxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgIGBbSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVEXSBJQ0UgY29ubmVjdGlvbiBvZiBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHt0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSBpcyBub3cgZmFpbGVkIGFmdGVyIElDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRGBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnY29ubmVjdGVkJzpcbiAgICAgICAgICAgICAgICBjYXNlICdjb21wbGV0ZWQnOlxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKFxuICAgICAgICAgICAgICAgICAgICAgICAgYFtJQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURURdIElDRSBjb25uZWN0aW9uIG9mIHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcidcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pIGF1dG9tYXRpY2FsbHkgcmVzdG9yZWQgYWZ0ZXIgSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVELiBDdXJyZW50IElDRSBjb25uZWN0aW9uIHN0YXRlOiAke3N0YXRlfWBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnY2xvc2VkJzpcbiAgICAgICAgICAgICAgICBjYXNlICdjaGVja2luZyc6XG4gICAgICAgICAgICAgICAgY2FzZSAnbmV3JzpcbiAgICAgICAgICAgICAgICBjYXNlICdkaXNjb25uZWN0ZWQnOlxuICAgICAgICAgICAgICAgICAgICAvLyBSZXN0IG9mIHN0YXRlc1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICAgICAgICAgICAgICAgIGBbSUNFX0NPTk5FQ1RJT05fRElTQ09OTkVDVEVEXSBJQ0UgY29ubmVjdGlvbiBvZiBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHt0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSBjb3VsZG4ndCBiZSByZXN0b3JlZCBhZnRlciBJQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURUQgZXZlbnQuIEN1cnJlbnQgSUNFIGNvbm5lY3Rpb24gc3RhdGUgYWZ0ZXIgJHt0aW1lb3V0fSBtczogJHtzdGF0ZX1gXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVjb25uZWN0U3RyZWFtQW5kTG9nUmVzdWx0aW5nSWNlQ29ubmVjdGlvblN0YXRlKEV4Y2VwdGlvbkV2ZW50TmFtZS5JQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURUQpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZWNvbm5lY3RTdHJlYW1BbmRMb2dSZXN1bHRpbmdJY2VDb25uZWN0aW9uU3RhdGUoZXZlbnQ6IHN0cmluZykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZmluYWxJY2VTdGF0ZUFmdGVyUmVjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5yZWNvbm5lY3RTdHJlYW1BbmRSZXR1cm5JY2VDb25uZWN0aW9uU3RhdGUoZXZlbnQpO1xuICAgICAgICAgICAgc3dpdGNoIChmaW5hbEljZVN0YXRlQWZ0ZXJSZWNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjb25uZWN0ZWQnOlxuICAgICAgICAgICAgICAgIGNhc2UgJ2NvbXBsZXRlZCc6XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICBgWyR7ZXZlbnR9XSBTdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHt0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSBzdWNjZXNzZnVsbHkgcmVjb25uZWN0ZWQgYWZ0ZXIgJHtldmVudH0uIEN1cnJlbnQgSUNFIGNvbm5lY3Rpb24gc3RhdGU6ICR7ZmluYWxJY2VTdGF0ZUFmdGVyUmVjb25uZWN0aW9ufWBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgYFske2V2ZW50fV0gU3RyZWFtICR7dGhpcy5zdHJlYW1JZH0gKCR7dGhpcy5pc0xvY2FsKCkgPyAnUHVibGlzaGVyJyA6ICdTdWJzY3JpYmVyJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkgZmFpbGVkIHRvIHJlY29ubmVjdCBhZnRlciAke2V2ZW50fS4gQ3VycmVudCBJQ0UgY29ubmVjdGlvbiBzdGF0ZTogJHtmaW5hbEljZVN0YXRlQWZ0ZXJSZWNvbm5lY3Rpb259YFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICBgWyR7ZXZlbnR9XSBFcnJvciByZWNvbm5lY3Rpbmcgc3RyZWFtICR7dGhpcy5zdHJlYW1JZH0gKCR7dGhpcy5pc0xvY2FsKCkgPyAnUHVibGlzaGVyJyA6ICdTdWJzY3JpYmVyJ1xuICAgICAgICAgICAgICAgIH0pIGFmdGVyICR7ZXZlbnR9OiAke2Vycm9yfWBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlY29ubmVjdFN0cmVhbUFuZFJldHVybkljZUNvbm5lY3Rpb25TdGF0ZShldmVudDogc3RyaW5nKTogUHJvbWlzZTxSVENJY2VDb25uZWN0aW9uU3RhdGU+IHtcbiAgICAgICAgbG9nZ2VyLmxvZyhgWyR7ZXZlbnR9XSBSZWNvbm5lY3Rpbmcgc3RyZWFtICR7dGhpcy5zdHJlYW1JZH0gKCR7dGhpcy5pc0xvY2FsKCkgPyAnUHVibGlzaGVyJyA6ICdTdWJzY3JpYmVyJ30pIGFmdGVyIGV2ZW50ICR7ZXZlbnR9YCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlY29ubmVjdFN0cmVhbShldmVudCk7XG4gICAgICAgICAgICBjb25zdCB0aW1lb3V0ID0gdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VDb25uZWN0aW9uRGlzY29ubmVjdGVkRXhjZXB0aW9uVGltZW91dCB8fCA0MDAwO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYXdhaXRXZWJSdGNQZWVyQ29ubmVjdGlvblN0YXRlKHRpbWVvdXQpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgICAgICAgYFske2V2ZW50fV0gRXJyb3IgcmVjb25uZWN0aW5nIHN0cmVhbSAke3RoaXMuc3RyZWFtSWR9ICgke3RoaXMuaXNMb2NhbCgpID8gJ1B1Ymxpc2hlcicgOiAnU3Vic2NyaWJlcid9KS4gUmVhc29uOiAke2Vycm9yfWBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hd2FpdFdlYlJ0Y1BlZXJDb25uZWN0aW9uU3RhdGUoMSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGF3YWl0V2ViUnRjUGVlckNvbm5lY3Rpb25TdGF0ZSh0aW1lb3V0OiBudW1iZXIpOiBQcm9taXNlPFJUQ0ljZUNvbm5lY3Rpb25TdGF0ZT4ge1xuICAgICAgICBsZXQgc3RhdGUgPSB0aGlzLmdldFJUQ1BlZXJDb25uZWN0aW9uKCkuaWNlQ29ubmVjdGlvblN0YXRlO1xuICAgICAgICBjb25zdCBpbnRlcnZhbCA9IDE1MDtcbiAgICAgICAgY29uc3QgaW50ZXJ2YWxzID0gTWF0aC5jZWlsKHRpbWVvdXQgLyBpbnRlcnZhbCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW50ZXJ2YWxzOyBpKyspIHtcbiAgICAgICAgICAgIHN0YXRlID0gdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpLmljZUNvbm5lY3Rpb25TdGF0ZTtcbiAgICAgICAgICAgIGlmIChzdGF0ZSA9PT0gJ2Nvbm5lY3RlZCcgfHwgc3RhdGUgPT09ICdjb21wbGV0ZWQnKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBTbGVlcFxuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgaW50ZXJ2YWwpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyByZWNvbm5lY3RTdHJlYW0oZXZlbnQ6IHN0cmluZykge1xuICAgICAgICBjb25zdCBpc1dzQ29ubmVjdGVkID0gYXdhaXQgdGhpcy5pc1dlYnNvY2tldENvbm5lY3RlZChldmVudCwgMzAwMCk7XG4gICAgICAgIGlmIChpc1dzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAvLyBUaGVyZSBpcyBjb25uZWN0aW9uIHRvIG9wZW52aWR1LXNlcnZlci4gVGhlIFJUQ1BlZXJDb25uZWN0aW9uIGlzIHRoZSBvbmx5IG9uZSBicm9rZW5cbiAgICAgICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICAgICAgYFske2V2ZW50fV0gVHJ5aW5nIHRvIHJlY29ubmVjdCBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHt0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInXG4gICAgICAgICAgICAgICAgfSkgYW5kIHRoZSB3ZWJzb2NrZXQgaXMgb3BlbmVkYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmluaXRXZWJSdGNQZWVyU2VuZCh0cnVlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5pdFdlYlJ0Y1BlZXJSZWNlaXZlKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gVGhlcmUgaXMgbm8gY29ubmVjdGlvbiB0byBvcGVudmlkdS1zZXJ2ZXIuIE5vdGhpbmcgY2FuIGJlIGRvbmUuIFRoZSBhdXRvbWF0aWMgcmVjb25uZWN0aW9uXG4gICAgICAgICAgICAvLyBmZWF0dXJlIHNob3VsZCBoYW5kbGUgYSBwb3NzaWJsZSByZWNvbm5lY3Rpb24gb2YgUlRDUGVlckNvbm5lY3Rpb24gaW4gY2FzZSBuZXR3b3JrIGNvbWVzIGJhY2tcbiAgICAgICAgICAgIGNvbnN0IGVycm9yTXNnID0gYFske2V2ZW50fV0gVHJ5aW5nIHRvIHJlY29ubmVjdCBzdHJlYW0gJHt0aGlzLnN0cmVhbUlkfSAoJHt0aGlzLmlzTG9jYWwoKSA/ICdQdWJsaXNoZXInIDogJ1N1YnNjcmliZXInXG4gICAgICAgICAgICAgICAgfSkgYnV0IHRoZSB3ZWJzb2NrZXQgd2Fzbid0IG9wZW5lZGA7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1dlYnNvY2tldENvbm5lY3RlZChldmVudDogc3RyaW5nLCBtc1Jlc3BvbnNlVGltZW91dDogbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB3c1JlYWR5U3RhdGUgPSB0aGlzLnNlc3Npb24ub3BlbnZpZHUuZ2V0V3NSZWFkeVN0YXRlKCk7XG4gICAgICAgICAgICBpZiAod3NSZWFkeVN0YXRlID09PSAxKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2VUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgWyR7ZXZlbnR9XSBXZWJzb2NrZXQgdGltZW91dCBvZiAke21zUmVzcG9uc2VUaW1lb3V0fW1zYCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9LCBtc1Jlc3BvbnNlVGltZW91dCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LnNlbmRSZXF1ZXN0KCdlY2hvJywge30sIChlcnJvciwgcmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHJlc3BvbnNlVGltZW91dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYFske2V2ZW50fV0gV2Vic29ja2V0ICdlY2hvJyByZXR1cm5lZCBlcnJvcjogJHtlcnJvcn1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgWyR7ZXZlbnR9XSBXZWJzb2NrZXQgcmVhZHlTdGF0ZSBpcyAke3dzUmVhZHlTdGF0ZX1gKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbml0V2ViUnRjU3RhdHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMgPSBuZXcgV2ViUnRjU3RhdHModGhpcyk7XG4gICAgICAgIHRoaXMud2ViUnRjU3RhdHMuaW5pdFdlYlJ0Y1N0YXRzKCk7XG5cbiAgICAgICAgLy9UT0RPOiBzZW5kIGNvbW1vbiB3ZWJydGMgc3RhdHMgZnJvbSBjbGllbnQgdG8gb3BlbnZpZHUtc2VydmVyXG4gICAgICAgIC8qaWYgKHRoaXMuc2Vzc2lvbi5vcGVudmlkdS53ZWJydGNTdGF0c0ludGVydmFsID4gMCkge1xuICAgICAgICAgICAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2F0aGVyU3RhdHNGb3JQZWVyKCkudGhlbihqc29uU3RhdHMgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBib2R5ID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkOiB0aGlzLnNlc3Npb24uc2Vzc2lvbklkLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGljaXBhbnRQcml2YXRlSWQ6IHRoaXMuY29ubmVjdGlvbi5ycGNTZXNzaW9uSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0czoganNvblN0YXRzXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgICAgICB4aHIub3BlbignUE9TVCcsIHRoaXMuc2Vzc2lvbi5vcGVudmlkdS5odHRwVXJpICsgJy9lbGFzdGljc2VhcmNoL3dlYnJ0Yy1zdGF0cycsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC1UeXBlJywgJ2FwcGxpY2F0aW9uL2pzb24nKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNlbmQoSlNPTi5zdHJpbmdpZnkoYm9keSkpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9LCB0aGlzLnNlc3Npb24ub3BlbnZpZHUud2VicnRjU3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuICAgICAgICB9Ki9cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0b3BXZWJSdGNTdGF0cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy53ZWJSdGNTdGF0cyAmJiB0aGlzLndlYlJ0Y1N0YXRzLmlzRW5hYmxlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLndlYlJ0Y1N0YXRzLnN0b3BXZWJSdGNTdGF0cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRJY2VTZXJ2ZXJzQ29uZigpOiBSVENJY2VTZXJ2ZXJbXSB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGxldCByZXR1cm5WYWx1ZTtcbiAgICAgICAgaWYgKCEhdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzKSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9XG4gICAgICAgICAgICAgICAgdGhpcy5zZXNzaW9uLm9wZW52aWR1LmFkdmFuY2VkQ29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzID09PSAnZnJlZWljZSdcbiAgICAgICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgOiB0aGlzLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnMpIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlID0gdGhpcy5zZXNzaW9uLm9wZW52aWR1LmljZVNlcnZlcnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnYXRoZXJTdGF0c0ZvclBlZXIoKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTG9jYWwoKSkge1xuICAgICAgICAgICAgICAgIC8vIFB1Ymxpc2hlciBzdHJlYW0gc3RhdHNcblxuICAgICAgICAgICAgICAgIHRoaXMuZ2V0UlRDUGVlckNvbm5lY3Rpb24oKVxuICAgICAgICAgICAgICAgICAgICAuZ2V0U2VuZGVycygpXG4gICAgICAgICAgICAgICAgICAgIC5mb3JFYWNoKChzZW5kZXIpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICBzZW5kZXIuZ2V0U3RhdHMoKS50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2goKHJlcG9ydCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc1JlcG9ydFdhbnRlZChyZXBvcnQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaW5hbFJlcG9ydCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndHlwZSddID0gcmVwb3J0LnR5cGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsndGltZXN0YW1wJ10gPSByZXBvcnQudGltZXN0YW1wO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2lkJ10gPSByZXBvcnQuaWQ7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbW1vbiB0byBDaHJvbWUsIEZpcmVmb3ggYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnb3V0Ym91bmQtcnRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wydzc3JjJ10gPSByZXBvcnQuc3NyYztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZmlyQ291bnQnXSA9IHJlcG9ydC5maXJDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGxpQ291bnQnXSA9IHJlcG9ydC5wbGlDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbmFja0NvdW50J10gPSByZXBvcnQubmFja0NvdW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydxcFN1bSddID0gcmVwb3J0LnFwU3VtO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2V0IG1lZGlhIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoISFyZXBvcnQua2luZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQua2luZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCEhcmVwb3J0Lm1lZGlhVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQubWVkaWFUeXBlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBkb2VzIG5vdCBoYXZlICdtZWRpYVR5cGUnIGRlZmluZWQgZm9yIGluYm91bmQtcnRwLiBNdXN0IGJlIGluZmVycmVkIGZyb20gJ2lkJyBmaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnbWVkaWFUeXBlJ10gPSByZXBvcnQuaWQuaW5kZXhPZignVmlkZW9TdHJlYW0nKSAhPT0gLTEgPyAndmlkZW8nIDogJ2F1ZGlvJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID09PSAndmlkZW8nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydmcmFtZXNFbmNvZGVkJ10gPSByZXBvcnQuZnJhbWVzRW5jb2RlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c1NlbnQnXSA9IHJlcG9ydC5wYWNrZXRzU2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnYnl0ZXNTZW50J10gPSByZXBvcnQuYnl0ZXNTZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBDaHJvbWUgYW5kIFNhZmFyaVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAnY2FuZGlkYXRlLXBhaXInICYmIHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGhlIGZpbmFsIHNlbGVjdGVkIGNhbmRpZGF0ZSBwYWlyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2YWlsYWJsZU91dGdvaW5nQml0cmF0ZSddID0gcmVwb3J0LmF2YWlsYWJsZU91dGdvaW5nQml0cmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncnR0J10gPSByZXBvcnQuY3VycmVudFJvdW5kVHJpcFRpbWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2F2ZXJhZ2VSdHQnXSA9IHJlcG9ydC50b3RhbFJvdW5kVHJpcFRpbWUgLyByZXBvcnQucmVzcG9uc2VzUmVjZWl2ZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9ubHkgZm9yIEZpcmVmb3ggPj0gNjYuMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydC50eXBlID09PSAncmVtb3RlLWluYm91bmQtcnRwJyB8fCByZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1vdXRib3VuZC1ydHAnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coZmluYWxSZXBvcnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBTdWJzY3JpYmVyIHN0cmVhbSBzdGF0c1xuXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRSVENQZWVyQ29ubmVjdGlvbigpXG4gICAgICAgICAgICAgICAgICAgIC5nZXRSZWNlaXZlcnMoKVxuICAgICAgICAgICAgICAgICAgICAuZm9yRWFjaCgocmVjZWl2ZXIpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlci5nZXRTdGF0cygpLnRoZW4oKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UuZm9yRWFjaCgocmVwb3J0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzUmVwb3J0V2FudGVkKHJlcG9ydCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsUmVwb3J0ID0ge307XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0eXBlJ10gPSByZXBvcnQudHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0Wyd0aW1lc3RhbXAnXSA9IHJlcG9ydC50aW1lc3RhbXA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaWQnXSA9IHJlcG9ydC5pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29tbW9uIHRvIENocm9tZSwgRmlyZWZveCBhbmQgU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LnR5cGUgPT09ICdpbmJvdW5kLXJ0cCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnc3NyYyddID0gcmVwb3J0LnNzcmM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ2ZpckNvdW50J10gPSByZXBvcnQuZmlyQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BsaUNvdW50J10gPSByZXBvcnQucGxpQ291bnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ25hY2tDb3VudCddID0gcmVwb3J0Lm5hY2tDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncXBTdW0nXSA9IHJlcG9ydC5xcFN1bTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNldCBtZWRpYSB0eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEhcmVwb3J0LmtpbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0LmtpbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghIXJlcG9ydC5tZWRpYVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0Lm1lZGlhVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgZG9lcyBub3QgaGF2ZSAnbWVkaWFUeXBlJyBkZWZpbmVkIGZvciBpbmJvdW5kLXJ0cC4gTXVzdCBiZSBpbmZlcnJlZCBmcm9tICdpZCcgZmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ21lZGlhVHlwZSddID0gcmVwb3J0LmlkLmluZGV4T2YoJ1ZpZGVvU3RyZWFtJykgIT09IC0xID8gJ3ZpZGVvJyA6ICdhdWRpbyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsUmVwb3J0WydtZWRpYVR5cGUnXSA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnZnJhbWVzRGVjb2RlZCddID0gcmVwb3J0LmZyYW1lc0RlY29kZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3BhY2tldHNSZWNlaXZlZCddID0gcmVwb3J0LnBhY2tldHNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsncGFja2V0c0xvc3QnXSA9IHJlcG9ydC5wYWNrZXRzTG9zdDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaW5hbFJlcG9ydFsnaml0dGVyJ10gPSByZXBvcnQuaml0dGVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydieXRlc1JlY2VpdmVkJ10gPSByZXBvcnQuYnl0ZXNSZWNlaXZlZDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gT25seSBmb3IgQ2hyb21lIGFuZCBTYWZhcmlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ2NhbmRpZGF0ZS1wYWlyJyAmJiByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBmaW5hbCBzZWxlY3RlZCBjYW5kaWRhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmFpbGFibGVJbmNvbWluZ0JpdHJhdGUnXSA9IHJlcG9ydC5hdmFpbGFibGVJbmNvbWluZ0JpdHJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxSZXBvcnRbJ3J0dCddID0gcmVwb3J0LmN1cnJlbnRSb3VuZFRyaXBUaW1lO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsUmVwb3J0WydhdmVyYWdlUnR0J10gPSByZXBvcnQudG90YWxSb3VuZFRyaXBUaW1lIC8gcmVwb3J0LnJlc3BvbnNlc1JlY2VpdmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZvciBGaXJlZm94ID49IDY2LjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXBvcnQudHlwZSA9PT0gJ3JlbW90ZS1pbmJvdW5kLXJ0cCcgfHwgcmVwb3J0LnR5cGUgPT09ICdyZW1vdGUtb3V0Ym91bmQtcnRwJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhmaW5hbFJlcG9ydCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNSZXBvcnRXYW50ZWQocmVwb3J0OiBhbnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIChyZXBvcnQudHlwZSA9PT0gJ2luYm91bmQtcnRwJyAmJiAhdGhpcy5pc0xvY2FsKCkpIHx8XG4gICAgICAgICAgICAocmVwb3J0LnR5cGUgPT09ICdvdXRib3VuZC1ydHAnICYmIHRoaXMuaXNMb2NhbCgpKSB8fFxuICAgICAgICAgICAgKHJlcG9ydC50eXBlID09PSAnY2FuZGlkYXRlLXBhaXInICYmIHJlcG9ydC5ub21pbmF0ZWQgJiYgcmVwb3J0LmJ5dGVzU2VudCA+IDApXG4gICAgICAgICk7XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IFN0cmVhbSB9IGZyb20gJy4vU3RyZWFtJztcbmltcG9ydCB7IFN1YnNjcmliZXIgfSBmcm9tICcuL1N1YnNjcmliZXInO1xuaW1wb3J0IHsgRXZlbnREaXNwYXRjaGVyIH0gZnJvbSAnLi9FdmVudERpc3BhdGNoZXInO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlclZpZGVvIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdHJlYW1NYW5hZ2VyVmlkZW8nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlckV2ZW50TWFwIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9FdmVudHMvRXZlbnRNYXAvU3RyZWFtTWFuYWdlckV2ZW50TWFwJztcbmltcG9ydCB7IFN0cmVhbU1hbmFnZXJFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1N0cmVhbU1hbmFnZXJFdmVudCc7XG5pbXBvcnQgeyBWaWRlb0VsZW1lbnRFdmVudCB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvRXZlbnRzL1ZpZGVvRWxlbWVudEV2ZW50JztcbmltcG9ydCB7IEV4Y2VwdGlvbkV2ZW50LCBFeGNlcHRpb25FdmVudE5hbWUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0V2ZW50cy9FeGNlcHRpb25FdmVudCc7XG5pbXBvcnQgeyBWaWRlb0luc2VydE1vZGUgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL0VudW1zL1ZpZGVvSW5zZXJ0TW9kZSc7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IFBsYXRmb3JtVXRpbHMgfSBmcm9tICcuLi9PcGVuVmlkdUludGVybmFsL1V0aWxzL1BsYXRmb3JtJztcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqIEBoaWRkZW5cbiAqL1xubGV0IHBsYXRmb3JtOiBQbGF0Zm9ybVV0aWxzO1xuXG4vKipcbiAqIEludGVyZmFjZSBpbiBjaGFyZ2Ugb2YgZGlzcGxheWluZyB0aGUgbWVkaWEgc3RyZWFtcyBpbiB0aGUgSFRNTCBET00uIFRoaXMgd3JhcHMgYW55IFtbUHVibGlzaGVyXV0gYW5kIFtbU3Vic2NyaWJlcl1dIG9iamVjdC5cbiAqIFlvdSBjYW4gaW5zZXJ0IGFzIG1hbnkgdmlkZW8gcGxheWVycyBmbyB0aGUgc2FtZSBTdHJlYW0gYXMgeW91IHdhbnQgYnkgY2FsbGluZyBbW1N0cmVhbU1hbmFnZXIuYWRkVmlkZW9FbGVtZW50XV0gb3JcbiAqIFtbU3RyZWFtTWFuYWdlci5jcmVhdGVWaWRlb0VsZW1lbnRdXS5cbiAqIFRoZSB1c2Ugb2YgU3RyZWFtTWFuYWdlciB3cmFwcGVyIGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiB5b3UgZG9uJ3QgbmVlZCB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gUHVibGlzaGVyIG9yIFN1YnNjcmliZXIgc3RyZWFtcyBvciBqdXN0XG4gKiB3YW50IHRvIGRpcmVjdGx5IG1hbmFnZSB5b3VyIG93biB2aWRlbyBlbGVtZW50cyAoZXZlbiBtb3JlIHRoYW4gb25lIHZpZGVvIGVsZW1lbnQgcGVyIFN0cmVhbSkuIFRoaXMgc2NlbmFyaW8gaXMgcHJldHR5IGNvbW1vbiBpblxuICogZGVjbGFyYXRpdmUsIE1WQyBmcm9udGVuZCBmcmFtZXdvcmtzIHN1Y2ggYXMgQW5ndWxhciwgUmVhY3Qgb3IgVnVlLmpzXG4gKlxuICogU2VlIGF2YWlsYWJsZSBldmVudCBsaXN0ZW5lcnMgYXQgW1tTdHJlYW1NYW5hZ2VyRXZlbnRNYXBdXS5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFN0cmVhbU1hbmFnZXIgZXh0ZW5kcyBFdmVudERpc3BhdGNoZXIge1xuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gcmVwcmVzZW50ZWQgaW4gdGhlIERPTSBieSB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXJcbiAgICAgKi9cbiAgICBzdHJlYW06IFN0cmVhbTtcblxuICAgIC8qKlxuICAgICAqIEFsbCB0aGUgdmlkZW9zIGRpc3BsYXlpbmcgdGhlIFN0cmVhbSBvZiB0aGlzIFB1Ymxpc2hlci9TdWJzY3JpYmVyXG4gICAgICovXG4gICAgdmlkZW9zOiBTdHJlYW1NYW5hZ2VyVmlkZW9bXSA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgU3RyZWFtIHJlcHJlc2VudGVkIGluIHRoZSBET00gaXMgbG9jYWwgb3IgcmVtb3RlXG4gICAgICogLSBgZmFsc2VgIGZvciBbW1B1Ymxpc2hlcl1dXG4gICAgICogLSBgdHJ1ZWAgZm9yIFtbU3Vic2NyaWJlcl1dXG4gICAgICovXG4gICAgcmVtb3RlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIERPTSBIVE1MRWxlbWVudCBhc3NpZ25lZCBhcyB0YXJnZXQgZWxlbWVudCB3aGVuIGNyZWF0aW5nIHRoZSB2aWRlbyBmb3IgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuXG4gICAgLyoqXG4gICAgICogYGlkYCBhdHRyaWJ1dGUgb2YgdGhlIERPTSB2aWRlbyBlbGVtZW50IGRpc3BsYXlpbmcgdGhlIFB1Ymxpc2hlci9TdWJzY3JpYmVyJ3Mgc3RyZWFtLiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgZGVmaW5lZCBpZjpcbiAgICAgKiAtIFtbUHVibGlzaGVyXV0gaGFzIGJlZW4gaW5pdGlhbGl6ZWQgYnkgY2FsbGluZyBtZXRob2QgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gd2l0aCBhIHZhbGlkIGB0YXJnZXRFbGVtZW50YCBwYXJhbWV0ZXJcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dIGhhcyBiZWVuIGluaXRpYWxpemVkIGJ5IGNhbGxpbmcgbWV0aG9kIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSB3aXRoIGEgdmFsaWQgYHRhcmdldEVsZW1lbnRgIHBhcmFtZXRlclxuICAgICAqL1xuICAgIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGZpcnN0VmlkZW9FbGVtZW50PzogU3RyZWFtTWFuYWdlclZpZGVvO1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgZWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjYW5QbGF5TGlzdGVuZXI6IEV2ZW50TGlzdGVuZXI7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHByaXZhdGUgc3RyZWFtUGxheWluZ0V2ZW50RXhjZXB0aW9uVGltZW91dD86IE5vZGVKUy5UaW1lb3V0O1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcml2YXRlIGxhenlMYXVuY2hWaWRlb0VsZW1lbnRDcmVhdGVkRXZlbnQgPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ2V0RWxlbWVudD86IEhUTUxFbGVtZW50IHwgc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHBsYXRmb3JtID0gUGxhdGZvcm1VdGlscy5nZXRJbnN0YW5jZSgpO1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5zdHJlYW0uc3RyZWFtTWFuYWdlciA9IHRoaXM7XG4gICAgICAgIHRoaXMucmVtb3RlID0gIXRoaXMuc3RyZWFtLmlzTG9jYWwoKTtcblxuICAgICAgICBpZiAoISF0YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRFbGVtZW50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRhcmdFbCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0YXJnRWwgPSB0YXJnZXRFbGVtZW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoISF0YXJnRWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpcnN0VmlkZW9FbGVtZW50ID0ge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRFbGVtZW50OiB0YXJnRWwsXG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpLFxuICAgICAgICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybS5pc1NhZmFyaUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgICAgICAocGxhdGZvcm0uaXNJUGhvbmVPcklQYWQoKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKHBsYXRmb3JtLmlzQ2hyb21lTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNFZGdlTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNPcGVyYU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzRmlyZWZveE1vYmlsZUJyb3dzZXIoKSkpXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmlyc3RWaWRlb0VsZW1lbnQudmlkZW8ucGxheXNJbmxpbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldEVsZW1lbnQgPSB0YXJnRWw7XG4gICAgICAgICAgICAgICAgdGhpcy5lbGVtZW50ID0gdGFyZ0VsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jYW5QbGF5TGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmRlYWN0aXZhdGVTdHJlYW1QbGF5aW5nRXZlbnRFeGNlcHRpb25UaW1lb3V0KCk7XG4gICAgICAgICAgICB0aGlzLmVlLmVtaXRFdmVudCgnc3RyZWFtUGxheWluZycsIFtuZXcgU3RyZWFtTWFuYWdlckV2ZW50KHRoaXMsICdzdHJlYW1QbGF5aW5nJywgdW5kZWZpbmVkKV0pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vbl1dXG4gICAgICovXG4gICAgb248SyBleHRlbmRzIGtleW9mIFN0cmVhbU1hbmFnZXJFdmVudE1hcD4odHlwZTogSywgaGFuZGxlcjogKGV2ZW50OiBTdHJlYW1NYW5hZ2VyRXZlbnRNYXBbS10pID0+IHZvaWQpOiB0aGlzIHtcbiAgICAgICAgc3VwZXIub25BdXgodHlwZSwgXCJFdmVudCAnXCIgKyB0eXBlICsgXCInIHRyaWdnZXJlZCBieSAnXCIgKyAodGhpcy5yZW1vdGUgPyAnU3Vic2NyaWJlcicgOiAnUHVibGlzaGVyJykgKyBcIidcIiwgaGFuZGxlcik7XG5cbiAgICAgICAgaWYgKHR5cGUgPT09ICd2aWRlb0VsZW1lbnRDcmVhdGVkJykge1xuICAgICAgICAgICAgaWYgKCEhdGhpcy5zdHJlYW0gJiYgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHRoaXMudmlkZW9zWzBdLnZpZGVvLCB0aGlzLCAndmlkZW9FbGVtZW50Q3JlYXRlZCcpXSk7XG4gICAgICAgICAgICAgICAgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50ID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdzdHJlYW1QbGF5aW5nJykge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8gJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5jdXJyZW50VGltZSA+IDAgJiZcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXS52aWRlby5wYXVzZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uZW5kZWQgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucmVhZHlTdGF0ZSA9PT0gNFxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3N0cmVhbVBsYXlpbmcnLCBbbmV3IFN0cmVhbU1hbmFnZXJFdmVudCh0aGlzLCAnc3RyZWFtUGxheWluZycsIHVuZGVmaW5lZCldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5zdHJlYW0uaGFzQXVkaW8pIHtcbiAgICAgICAgICAgIGlmICh0eXBlID09PSAncHVibGlzaGVyU3RhcnRTcGVha2luZycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVIYXJrU3BlYWtpbmdFdmVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZUhhcmtWb2x1bWVDaGFuZ2VFdmVudChmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlIFtbRXZlbnREaXNwYXRjaGVyLm9uY2VdXVxuICAgICAqL1xuICAgIG9uY2U8SyBleHRlbmRzIGtleW9mIFN0cmVhbU1hbmFnZXJFdmVudE1hcD4odHlwZTogSywgaGFuZGxlcjogKGV2ZW50OiBTdHJlYW1NYW5hZ2VyRXZlbnRNYXBbS10pID0+IHZvaWQpOiB0aGlzIHtcbiAgICAgICAgc3VwZXIub25jZUF1eCh0eXBlLCBcIkV2ZW50ICdcIiArIHR5cGUgKyBcIicgdHJpZ2dlcmVkIG9uY2UgYnkgJ1wiICsgKHRoaXMucmVtb3RlID8gJ1N1YnNjcmliZXInIDogJ1B1Ymxpc2hlcicpICsgXCInXCIsIGhhbmRsZXIpO1xuXG4gICAgICAgIGlmICh0eXBlID09PSAndmlkZW9FbGVtZW50Q3JlYXRlZCcpIHtcbiAgICAgICAgICAgIGlmICghIXRoaXMuc3RyZWFtICYmIHRoaXMubGF6eUxhdW5jaFZpZGVvRWxlbWVudENyZWF0ZWRFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCd2aWRlb0VsZW1lbnRDcmVhdGVkJywgW25ldyBWaWRlb0VsZW1lbnRFdmVudCh0aGlzLnZpZGVvc1swXS52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudENyZWF0ZWQnKV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlID09PSAnc3RyZWFtUGxheWluZycpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB0aGlzLnZpZGVvc1swXSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8uY3VycmVudFRpbWUgPiAwICYmXG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3NbMF0udmlkZW8ucGF1c2VkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmVuZGVkID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLnJlYWR5U3RhdGUgPT09IDRcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KCdzdHJlYW1QbGF5aW5nJywgW25ldyBTdHJlYW1NYW5hZ2VyRXZlbnQodGhpcywgJ3N0cmVhbVBsYXlpbmcnLCB1bmRlZmluZWQpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RyZWFtLmhhc0F1ZGlvKSB7XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZW5hYmxlT25jZUhhcmtTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ3B1Ymxpc2hlclN0b3BTcGVha2luZycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5lbmFibGVPbmNlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJykge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmVuYWJsZU9uY2VIYXJrVm9sdW1lQ2hhbmdlRXZlbnQoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZSBbW0V2ZW50RGlzcGF0Y2hlci5vZmZdXVxuICAgICAqL1xuICAgIG9mZjxLIGV4dGVuZHMga2V5b2YgU3RyZWFtTWFuYWdlckV2ZW50TWFwPih0eXBlOiBLLCBoYW5kbGVyPzogKGV2ZW50OiBTdHJlYW1NYW5hZ2VyRXZlbnRNYXBbS10pID0+IHZvaWQpOiB0aGlzIHtcbiAgICAgICAgc3VwZXIub2ZmQXV4KHR5cGUsIGhhbmRsZXIpO1xuXG4gICAgICAgIGlmICh0eXBlID09PSAncHVibGlzaGVyU3RhcnRTcGVha2luZycpIHtcbiAgICAgICAgICAgIC8vIEJvdGggU3RyZWFtTWFuYWdlciBhbmQgU2Vzc2lvbiBjYW4gaGF2ZSBcInB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdcIiBldmVudCBsaXN0ZW5lcnNcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpbmluZ1N0YXJ0U3BlYWtpbmdFdmVudExpc3RlbmVycyA9XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5nZXRMaXN0ZW5lcnModHlwZSkubGVuZ3RoICsgdGhpcy5zdHJlYW0uc2Vzc2lvbi5lZS5nZXRMaXN0ZW5lcnModHlwZSkubGVuZ3RoO1xuICAgICAgICAgICAgaWYgKHJlbWFpbmluZ1N0YXJ0U3BlYWtpbmdFdmVudExpc3RlbmVycyA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc2FibGVIYXJrU3BlYWtpbmdFdmVudChmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGUgPT09ICdwdWJsaXNoZXJTdG9wU3BlYWtpbmcnKSB7XG4gICAgICAgICAgICAvLyBCb3RoIFN0cmVhbU1hbmFnZXIgYW5kIFNlc3Npb24gY2FuIGhhdmUgXCJwdWJsaXNoZXJTdG9wU3BlYWtpbmdcIiBldmVudCBsaXN0ZW5lcnNcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpbmluZ1N0b3BTcGVha2luZ0V2ZW50TGlzdGVuZXJzID1cbiAgICAgICAgICAgICAgICB0aGlzLmVlLmdldExpc3RlbmVycyh0eXBlKS5sZW5ndGggKyB0aGlzLnN0cmVhbS5zZXNzaW9uLmVlLmdldExpc3RlbmVycyh0eXBlKS5sZW5ndGg7XG4gICAgICAgICAgICBpZiAocmVtYWluaW5nU3RvcFNwZWFraW5nRXZlbnRMaXN0ZW5lcnMgPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5kaXNhYmxlSGFya1N0b3BwZWRTcGVha2luZ0V2ZW50KGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZSA9PT0gJ3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlJykge1xuICAgICAgICAgICAgLy8gT25seSBTdHJlYW1NYW5hZ2VyIGNhbiBoYXZlIFwic3RyZWFtQXVkaW9Wb2x1bWVDaGFuZ2VcIiBldmVudCBsaXN0ZW5lcnNcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpbmluZ1ZvbHVtZUV2ZW50TGlzdGVuZXJzID0gdGhpcy5lZS5nZXRMaXN0ZW5lcnModHlwZSkubGVuZ3RoO1xuICAgICAgICAgICAgaWYgKHJlbWFpbmluZ1ZvbHVtZUV2ZW50TGlzdGVuZXJzID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzYWJsZUhhcmtWb2x1bWVDaGFuZ2VFdmVudChmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBgdmlkZW9gIGVsZW1lbnQgcGFyYW1ldGVyIGRpc3BsYXkgdGhpcyBbW3N0cmVhbV1dLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSBhcmVcbiAgICAgKiBbbWFuYWdpbmcgdGhlIHZpZGVvIGVsZW1lbnRzIG9uIHlvdXIgb3duXSgvZW4vc3RhYmxlL2NoZWF0c2hlZXQvbWFuYWdlLXZpZGVvcy8jeW91LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycylcbiAgICAgKlxuICAgICAqIENhbGxpbmcgdGhpcyBtZXRob2Qgd2l0aCBhIHZpZGVvIGFscmVhZHkgYWRkZWQgdG8gb3RoZXIgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBjYXVzZSB0aGUgdmlkZW8gZWxlbWVudCB0byBiZVxuICAgICAqIGRpc2Fzc29jaWF0ZWQgZnJvbSB0aGF0IHByZXZpb3VzIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCB0byBiZSBhc3NvY2lhdGVkIHRvIHRoaXMgb25lLlxuICAgICAqXG4gICAgICogQHJldHVybnMgMSBpZiB0aGUgdmlkZW8gd2Fzbid0IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyIFB1Ymxpc2hlci9TdWJzY3JpYmVyIGFuZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYWRkZWQgdG8gdGhpcyBvbmUuXG4gICAgICogMCBpZiB0aGUgdmlkZW8gd2FzIGFscmVhZHkgYWRkZWQgdG8gdGhpcyBQdWJsaXNoZXIvU3Vic2NyaWJlci4gLTEgaWYgdGhlIHZpZGVvIHdhcyBwcmV2aW91c2x5IGFzc29jaWF0ZWQgdG8gYW55IG90aGVyXG4gICAgICogUHVibGlzaGVyL1N1YnNjcmliZXIgYW5kIGhhcyBiZWVuIHN1Y2Nlc3NmdWxseSBkaXNhc3NvY2lhdGVkIGZyb20gdGhhdCBvbmUgYW5kIHByb3Blcmx5IGFkZGVkIHRvIHRoaXMgb25lLlxuICAgICAqL1xuICAgIGFkZFZpZGVvRWxlbWVudCh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IG51bWJlciB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZVZpZGVvUHJvcGVydGllcyh2aWRlbyk7XG5cbiAgICAgICAgaWYgKCF0aGlzLnJlbW90ZSAmJiB0aGlzLnN0cmVhbS5kaXNwbGF5TXlSZW1vdGUoKSkge1xuICAgICAgICAgICAgaWYgKHZpZGVvLnNyY09iamVjdCAhPT0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKSkge1xuICAgICAgICAgICAgICAgIHZpZGVvLnNyY09iamVjdCA9IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGUgdmlkZW8gZWxlbWVudCBpcyBhbHJlYWR5IHBhcnQgb2YgdGhpcyBTdHJlYW1NYW5hZ2VyIGRvIG5vdGhpbmdcbiAgICAgICAgZm9yIChjb25zdCB2IG9mIHRoaXMudmlkZW9zKSB7XG4gICAgICAgICAgICBpZiAodi52aWRlbyA9PT0gdmlkZW8pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxldCByZXR1cm5OdW1iZXIgPSAxO1xuXG4gICAgICAgIGZvciAoY29uc3Qgc3RyZWFtTWFuYWdlciBvZiB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzKSB7XG4gICAgICAgICAgICBpZiAoc3RyZWFtTWFuYWdlci5kaXNhc3NvY2lhdGVWaWRlbyh2aWRlbykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm5OdW1iZXIgPSAtMTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnMuZm9yRWFjaCgoc3RyZWFtTWFuYWdlcikgPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlci5kaXNhc3NvY2lhdGVWaWRlbyh2aWRlbyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyh7XG4gICAgICAgICAgICB2aWRlbyxcbiAgICAgICAgICAgIGlkOiB2aWRlby5pZCxcbiAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICB9KTtcblxuICAgICAgICBsb2dnZXIuaW5mbygnTmV3IHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byAnLCB0aGlzKTtcblxuICAgICAgICByZXR1cm4gcmV0dXJuTnVtYmVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgdmlkZW8gZWxlbWVudCBkaXNwbGF5aW5nIHRoaXMgW1tzdHJlYW1dXS4gVGhpcyBhbGxvd3MgeW91IHRvIGhhdmUgbXVsdGlwbGUgdmlkZW8gZWxlbWVudHMgZGlzcGxheWluZyB0aGUgc2FtZSBtZWRpYSBzdHJlYW0uXG4gICAgICpcbiAgICAgKiAjIyMjIEV2ZW50cyBkaXNwYXRjaGVkXG4gICAgICpcbiAgICAgKiBUaGUgUHVibGlzaGVyL1N1YnNjcmliZXIgb2JqZWN0IHdpbGwgZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50Q3JlYXRlZGAgZXZlbnQgb25jZSB0aGUgSFRNTCB2aWRlbyBlbGVtZW50IGhhcyBiZWVuIGFkZGVkIHRvIERPTS4gU2VlIFtbVmlkZW9FbGVtZW50RXZlbnRdXVxuICAgICAqXG4gICAgICogQHBhcmFtIHRhcmdldEVsZW1lbnQgSFRNTCBET00gZWxlbWVudCAob3IgaXRzIGBpZGAgYXR0cmlidXRlKSBpbiB3aGljaCB0aGUgdmlkZW8gZWxlbWVudCBvZiB0aGUgUHVibGlzaGVyL1N1YnNjcmliZXIgd2lsbCBiZSBpbnNlcnRlZFxuICAgICAqIEBwYXJhbSBpbnNlcnRNb2RlIEhvdyB0aGUgdmlkZW8gZWxlbWVudCB3aWxsIGJlIGluc2VydGVkIGFjY29yZGluZ2x5IHRvIGB0YXJnZXRFbGVtZXRgXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBIVE1MVmlkZW9FbGVtZW50XG4gICAgICovXG4gICAgY3JlYXRlVmlkZW9FbGVtZW50KHRhcmdldEVsZW1lbnQ/OiBzdHJpbmcgfCBIVE1MRWxlbWVudCwgaW5zZXJ0TW9kZT86IFZpZGVvSW5zZXJ0TW9kZSk6IEhUTUxWaWRlb0VsZW1lbnQge1xuICAgICAgICBsZXQgdGFyZ0VsO1xuICAgICAgICBpZiAodHlwZW9mIHRhcmdldEVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0YXJnRWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgICAgIGlmICghdGFyZ0VsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHByb3ZpZGVkICd0YXJnZXRFbGVtZW50JyBjb3VsZG4ndCBiZSByZXNvbHZlZCB0byBhbnkgSFRNTCBlbGVtZW50OiBcIiArIHRhcmdldEVsZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHRhcmdldEVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xuICAgICAgICAgICAgdGFyZ0VsID0gdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBwcm92aWRlZCAndGFyZ2V0RWxlbWVudCcgY291bGRuJ3QgYmUgcmVzb2x2ZWQgdG8gYW55IEhUTUwgZWxlbWVudDogXCIgKyB0YXJnZXRFbGVtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHZpZGVvID0gdGhpcy5jcmVhdGVWaWRlbygpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW8pO1xuXG4gICAgICAgIGxldCBpbnNNb2RlID0gISFpbnNlcnRNb2RlID8gaW5zZXJ0TW9kZSA6IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQ7XG4gICAgICAgIHN3aXRjaCAoaW5zTW9kZSkge1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuQUZURVI6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLnBhcmVudE5vZGUhIS5pbnNlcnRCZWZvcmUodmlkZW8sIHRhcmdFbC5uZXh0U2libGluZyk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQ6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLmFwcGVuZENoaWxkKHZpZGVvKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLkJFRk9SRTpcbiAgICAgICAgICAgICAgICB0YXJnRWwucGFyZW50Tm9kZSEhLmluc2VydEJlZm9yZSh2aWRlbywgdGFyZ0VsKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgVmlkZW9JbnNlcnRNb2RlLlBSRVBFTkQ6XG4gICAgICAgICAgICAgICAgdGFyZ0VsLmluc2VydEJlZm9yZSh2aWRlbywgdGFyZ0VsLmNoaWxkTm9kZXNbMF0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBWaWRlb0luc2VydE1vZGUuUkVQTEFDRTpcbiAgICAgICAgICAgICAgICB0YXJnRWwucGFyZW50Tm9kZSEhLnJlcGxhY2VDaGlsZCh2aWRlbywgdGFyZ0VsKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgaW5zTW9kZSA9IFZpZGVvSW5zZXJ0TW9kZS5BUFBFTkQ7XG4gICAgICAgICAgICAgICAgdGFyZ0VsLmFwcGVuZENoaWxkKHZpZGVvKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHY6IFN0cmVhbU1hbmFnZXJWaWRlbyA9IHtcbiAgICAgICAgICAgIHRhcmdldEVsZW1lbnQ6IHRhcmdFbCxcbiAgICAgICAgICAgIHZpZGVvLFxuICAgICAgICAgICAgaW5zZXJ0TW9kZTogaW5zTW9kZSxcbiAgICAgICAgICAgIGlkOiB2aWRlby5pZCxcbiAgICAgICAgICAgIGNhbnBsYXlMaXN0ZW5lckFkZGVkOiBmYWxzZVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnB1c2hOZXdTdHJlYW1NYW5hZ2VyVmlkZW8odik7XG5cbiAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudENyZWF0ZWQnLCBbbmV3IFZpZGVvRWxlbWVudEV2ZW50KHYudmlkZW8sIHRoaXMsICd2aWRlb0VsZW1lbnRDcmVhdGVkJyldKTtcbiAgICAgICAgdGhpcy5sYXp5TGF1bmNoVmlkZW9FbGVtZW50Q3JlYXRlZEV2ZW50ID0gISF0aGlzLmZpcnN0VmlkZW9FbGVtZW50O1xuXG4gICAgICAgIHJldHVybiB2aWRlbztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIHRoZSBjdXJyZW50IGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBbW1B1Ymxpc2hlclNwZWFraW5nRXZlbnRdXSBmZWF0dXJlIGFuZCB0aGUgW1N0cmVhbU1hbmFnZXJFdmVudC5zdHJlYW1BdWRpb1ZvbHVtZUNoYW5nZV0oL2VuL3N0YWJsZS9hcGkvb3BlbnZpZHUtYnJvd3Nlci9jbGFzc2VzL1N0cmVhbU1hbmFnZXJFdmVudC5odG1sKSBmZWF0dXJlIGZvciB0aGlzIHNwZWNpZmljXG4gICAgICogU3RyZWFtTWFuYWdlciBhdWRpbyBzdHJlYW0sIG92ZXJyaWRpbmcgdGhlIGdsb2JhbCBvcHRpb25zIHNldCB3aXRoIFtbT3BlblZpZHUuc2V0QWR2YW5jZWRDb25maWd1cmF0aW9uXV0uIFRoaXMgd2F5IHlvdSBjYW4gY3VzdG9taXplIHRoZSBhdWRpbyBldmVudHMgb3B0aW9uc1xuICAgICAqIGZvciBlYWNoIHNwZWNpZmljIFN0cmVhbU1hbmFnZXIgYW5kIGNoYW5nZSB0aGVtIGR5bmFtaWNhbGx5LlxuICAgICAqXG4gICAgICogQHBhcmFtIHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucyBOZXcgb3B0aW9ucyB0byBiZSBhcHBsaWVkIHRvIHRoaXMgU3RyZWFtTWFuYWdlcidzIGF1ZGlvIHN0cmVhbS4gSXQgaXMgYW4gb2JqZWN0IHdoaWNoIGluY2x1ZGVzIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgcHJvcGVydGllczpcbiAgICAgKiAtIGBpbnRlcnZhbGA6IChudW1iZXIpIGhvdyBmcmVxdWVudGx5IHRoZSBhbmFseXNlciBwb2xscyB0aGUgYXVkaW8gc3RyZWFtIHRvIGNoZWNrIGlmIHNwZWFraW5nIGhhcyBzdGFydGVkL3N0b3BwZWQgb3IgYXVkaW8gdm9sdW1lIGhhcyBjaGFuZ2VkLiBEZWZhdWx0ICoqMTAwKiogKG1zKVxuICAgICAqIC0gYHRocmVzaG9sZGA6IChudW1iZXIpIHRoZSB2b2x1bWUgYXQgd2hpY2ggX3B1Ymxpc2hlclN0YXJ0U3BlYWtpbmdfLCBfcHVibGlzaGVyU3RvcFNwZWFraW5nXyBldmVudHMgd2lsbCBiZSBmaXJlZC4gRGVmYXVsdCAqKi01MCoqIChkQilcbiAgICAgKi9cbiAgICB1cGRhdGVQdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMocHVibGlzaGVyU3BlYWtpbmdFdmVudHNPcHRpb25zOiB7IGludGVydmFsPzogbnVtYmVyOyB0aHJlc2hvbGQ/OiBudW1iZXIgfSk6IHZvaWQge1xuICAgICAgICBjb25zdCBjdXJyZW50SGFya09wdGlvbnMgPSAhIXRoaXMuc3RyZWFtLmhhcmtPcHRpb25zXG4gICAgICAgICAgICA/IHRoaXMuc3RyZWFtLmhhcmtPcHRpb25zXG4gICAgICAgICAgICA6IHRoaXMuc3RyZWFtLnNlc3Npb24ub3BlbnZpZHUuYWR2YW5jZWRDb25maWd1cmF0aW9uLnB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucyB8fCB7fTtcbiAgICAgICAgY29uc3QgbmV3SW50ZXJ2YWwgPVxuICAgICAgICAgICAgdHlwZW9mIHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucy5pbnRlcnZhbCA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICAgICA/IHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucy5pbnRlcnZhbFxuICAgICAgICAgICAgICAgIDogdHlwZW9mIGN1cnJlbnRIYXJrT3B0aW9ucy5pbnRlcnZhbCA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICAgICA/IGN1cnJlbnRIYXJrT3B0aW9ucy5pbnRlcnZhbFxuICAgICAgICAgICAgICAgIDogMTAwO1xuICAgICAgICBjb25zdCBuZXdUaHJlc2hvbGQgPVxuICAgICAgICAgICAgdHlwZW9mIHB1Ymxpc2hlclNwZWFraW5nRXZlbnRzT3B0aW9ucy50aHJlc2hvbGQgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgPyBwdWJsaXNoZXJTcGVha2luZ0V2ZW50c09wdGlvbnMudGhyZXNob2xkXG4gICAgICAgICAgICAgICAgOiB0eXBlb2YgY3VycmVudEhhcmtPcHRpb25zLnRocmVzaG9sZCA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICAgICA/IGN1cnJlbnRIYXJrT3B0aW9ucy50aHJlc2hvbGRcbiAgICAgICAgICAgICAgICA6IC01MDtcbiAgICAgICAgdGhpcy5zdHJlYW0uaGFya09wdGlvbnMgPSB7XG4gICAgICAgICAgICBpbnRlcnZhbDogbmV3SW50ZXJ2YWwsXG4gICAgICAgICAgICB0aHJlc2hvbGQ6IG5ld1RocmVzaG9sZFxuICAgICAgICB9O1xuICAgICAgICBpZiAoISF0aGlzLnN0cmVhbS5zcGVlY2hFdmVudCkge1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc3BlZWNoRXZlbnQuc2V0SW50ZXJ2YWwobmV3SW50ZXJ2YWwpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc3BlZWNoRXZlbnQuc2V0VGhyZXNob2xkKG5ld1RocmVzaG9sZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiBIaWRkZW4gbWV0aG9kcyAqL1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGluaXRpYWxpemVWaWRlb1Byb3BlcnRpZXModmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKCEoIXRoaXMucmVtb3RlICYmIHRoaXMuc3RyZWFtLmRpc3BsYXlNeVJlbW90ZSgpKSkge1xuICAgICAgICAgICAgLy8gQXZvaWQgc2V0dGluZyB0aGUgTWVkaWFTdHJlYW0gaW50byB0aGUgc3JjT2JqZWN0IGlmIHJlbW90ZSBzdWJzY3JpcHRpb24gYmVmb3JlIHB1Ymxpc2hpbmdcbiAgICAgICAgICAgIGlmICh2aWRlby5zcmNPYmplY3QgIT09IHRoaXMuc3RyZWFtLmdldE1lZGlhU3RyZWFtKCkpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBzcmNPYmplY3QgYWxyZWFkeSBzZXQgZG9uJ3QgZG8gaXQgYWdhaW5cbiAgICAgICAgICAgICAgICB2aWRlby5zcmNPYmplY3QgPSB0aGlzLnN0cmVhbS5nZXRNZWRpYVN0cmVhbSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZpZGVvLmF1dG9wbGF5ID0gdHJ1ZTtcbiAgICAgICAgdmlkZW8uY29udHJvbHMgPSBmYWxzZTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBwbGF0Zm9ybS5pc1NhZmFyaUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgKHBsYXRmb3JtLmlzSVBob25lT3JJUGFkKCkgJiZcbiAgICAgICAgICAgICAgICAocGxhdGZvcm0uaXNDaHJvbWVNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNFZGdlTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICAgICAgICAgIHBsYXRmb3JtLmlzT3BlcmFNb2JpbGVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgICAgICAgICAgcGxhdGZvcm0uaXNGaXJlZm94TW9iaWxlQnJvd3NlcigpKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgICB2aWRlby5wbGF5c0lubGluZSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXZpZGVvLmlkKSB7XG4gICAgICAgICAgICB2aWRlby5pZCA9ICh0aGlzLnJlbW90ZSA/ICdyZW1vdGUtJyA6ICdsb2NhbC0nKSArICd2aWRlby0nICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQ7XG4gICAgICAgICAgICAvLyBERVBSRUNBVEVEIHByb3BlcnR5OiBhc3NpZ24gb25jZSB0aGUgcHJvcGVydHkgaWQgaWYgdGhlIHVzZXIgcHJvdmlkZWQgYSB2YWxpZCB0YXJnZXRFbGVtZW50XG4gICAgICAgICAgICBpZiAoIXRoaXMuaWQgJiYgISF0aGlzLnRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlkID0gdmlkZW8uaWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5yZW1vdGUgJiYgdGhpcy5pc01pcnJvcmVkVmlkZW8odmlkZW8pKSB7XG4gICAgICAgICAgICAvLyBTdWJzY3JpYmVyIHZpZGVvIGFzc29jaWF0ZWQgdG8gYSBwcmV2aW91c2x5IG1pcnJvcmVkIHZpZGVvIGVsZW1lbnRcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlTWlycm9yVmlkZW8odmlkZW8pO1xuICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLnJlbW90ZSAmJiAhdGhpcy5zdHJlYW0uZGlzcGxheU15UmVtb3RlKCkpIHtcbiAgICAgICAgICAgIC8vIFB1Ymxpc2hlciB2aWRlb1xuICAgICAgICAgICAgdmlkZW8ubXV0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNNaXJyb3JlZFZpZGVvKHZpZGVvKSAmJiAhdGhpcy5zdHJlYW0ub3V0Ym91bmRTdHJlYW1PcHRzLnB1Ymxpc2hlclByb3BlcnRpZXMubWlycm9yKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIHZpZGVvIHdhcyBhbHJlYWR5IHJvdGF0ZWQgYW5kIG5vdyBpcyBzZXQgdG8gbm90IG1pcnJvclxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTWlycm9yVmlkZW8odmlkZW8pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnN0cmVhbS5vdXRib3VuZFN0cmVhbU9wdHMucHVibGlzaGVyUHJvcGVydGllcy5taXJyb3IgJiYgIXRoaXMuc3RyZWFtLmlzU2VuZFNjcmVlbigpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIHZpZGVvIGlzIG5vdyBzZXQgdG8gbWlycm9yIGFuZCBpcyBub3Qgc2NyZWVuIHNoYXJlXG4gICAgICAgICAgICAgICAgdGhpcy5taXJyb3JWaWRlbyh2aWRlbyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcmVtb3ZlQWxsVmlkZW9zKCk6IHZvaWQge1xuICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5zdHJlYW0uc2Vzc2lvbi5zdHJlYW1NYW5hZ2Vycy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnNlc3Npb24uc3RyZWFtTWFuYWdlcnNbaV0gPT09IHRoaXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudmlkZW9zLmZvckVhY2goKHN0cmVhbU1hbmFnZXJWaWRlbykgPT4ge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIG9uY2FucGxheSBldmVudCBsaXN0ZW5lciAob25seSBPcGVuVmlkdSBicm93c2VyIGxpc3RlbmVyLCBub3QgdGhlIHVzZXIgb25lcylcbiAgICAgICAgICAgIGlmICghIXN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyAmJiAhIXN0cmVhbU1hbmFnZXJWaWRlby52aWRlby5yZW1vdmVFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCB0aGlzLmNhblBsYXlMaXN0ZW5lcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8uY2FucGxheUxpc3RlbmVyQWRkZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICghIXN0cmVhbU1hbmFnZXJWaWRlby50YXJnZXRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gT25seSByZW1vdmUgZnJvbSBET00gdmlkZW9zIGNyZWF0ZWQgYnkgT3BlblZpZHUgQnJvd3NlciAodGhvc2UgZ2VuZXJhdGVkIGJ5IHBhc3NpbmcgYSB2YWxpZCB0YXJnZXRFbGVtZW50IGluIE9wZW5WaWR1LmluaXRQdWJsaXNoZXJcbiAgICAgICAgICAgICAgICAvLyBhbmQgU2Vzc2lvbi5zdWJzY3JpYmUgb3IgdGhvc2UgY3JlYXRlZCBieSBTdHJlYW1NYW5hZ2VyLmNyZWF0ZVZpZGVvRWxlbWVudCkuIEFsbCB0aGlzIHZpZGVvcyB0cmlnZ2VyZWQgYSB2aWRlb0VsZW1lbnRDcmVhdGVkIGV2ZW50XG4gICAgICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudE5vZGUhLnJlbW92ZUNoaWxkKHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbyk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZS5lbWl0RXZlbnQoJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcsIFtcbiAgICAgICAgICAgICAgICAgICAgbmV3IFZpZGVvRWxlbWVudEV2ZW50KHN0cmVhbU1hbmFnZXJWaWRlby52aWRlbywgdGhpcywgJ3ZpZGVvRWxlbWVudERlc3Ryb3llZCcpXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBSZW1vdmUgc3JjT2JqZWN0IGZyb20gdGhlIHZpZGVvXG4gICAgICAgICAgICB0aGlzLnJlbW92ZVNyY09iamVjdChzdHJlYW1NYW5hZ2VyVmlkZW8pO1xuICAgICAgICAgICAgLy8gUmVtb3ZlIGZyb20gY29sbGVjdGlvbiBvZiB2aWRlb3MgZXZlcnkgdmlkZW8gbWFuYWdlZCBieSBPcGVuVmlkdSBCcm93c2VyXG4gICAgICAgICAgICB0aGlzLnZpZGVvcy5maWx0ZXIoKHYpID0+ICF2LnRhcmdldEVsZW1lbnQpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGlzYXNzb2NpYXRlVmlkZW8odmlkZW86IEhUTUxWaWRlb0VsZW1lbnQpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IGRpc2Fzc29jaWF0ZWQgPSBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnZpZGVvcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHRoaXMudmlkZW9zW2ldLnZpZGVvID09PSB2aWRlbykge1xuICAgICAgICAgICAgICAgIHRoaXMudmlkZW9zW2ldLnZpZGVvLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCB0aGlzLmNhblBsYXlMaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgdGhpcy52aWRlb3Muc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgIGRpc2Fzc29jaWF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdWaWRlbyBlbGVtZW50IGRpc2Fzc29jaWF0ZWQgZnJvbSAnLCB0aGlzKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGlzYXNzb2NpYXRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCkge1xuICAgICAgICBpZiAoISF0aGlzLnZpZGVvc1swXSAmJiAhIXRoaXMudmlkZW9zWzBdLnZpZGVvICYmICF0aGlzLnZpZGVvc1swXS5jYW5wbGF5TGlzdGVuZXJBZGRlZCkge1xuICAgICAgICAgICAgdGhpcy5hY3RpdmF0ZVN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQoKTtcbiAgICAgICAgICAgIHRoaXMudmlkZW9zWzBdLnZpZGVvLmFkZEV2ZW50TGlzdGVuZXIoJ2NhbnBsYXknLCB0aGlzLmNhblBsYXlMaXN0ZW5lcik7XG4gICAgICAgICAgICB0aGlzLnZpZGVvc1swXS5jYW5wbGF5TGlzdGVuZXJBZGRlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgdXBkYXRlTWVkaWFTdHJlYW0obWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtKSB7XG4gICAgICAgIHRoaXMudmlkZW9zLmZvckVhY2goKHN0cmVhbU1hbmFnZXJWaWRlbykgPT4ge1xuICAgICAgICAgICAgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnNyY09iamVjdCA9IG1lZGlhU3RyZWFtO1xuICAgICAgICAgICAgaWYgKHBsYXRmb3JtLmlzSW9uaWNJb3MoKSkge1xuICAgICAgICAgICAgICAgIC8vIGlPUyBJb25pYy4gTElNSVRBVElPTjogbXVzdCByZWluc2VydCB0aGUgdmlkZW8gaW4gdGhlIERPTSBmb3JcbiAgICAgICAgICAgICAgICAvLyB0aGUgbWVkaWEgc3RyZWFtIHRvIGJlIHVwZGF0ZWRcbiAgICAgICAgICAgICAgICBjb25zdCB2UGFyZW50ID0gc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3VmlkZW8gPSBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW87XG4gICAgICAgICAgICAgICAgdlBhcmVudCEhLnJlcGxhY2VDaGlsZChuZXdWaWRlbywgc3RyZWFtTWFuYWdlclZpZGVvLnZpZGVvKTtcbiAgICAgICAgICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8gPSBuZXdWaWRlbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGVtaXRFdmVudCh0eXBlOiBzdHJpbmcsIGV2ZW50QXJyYXk6IGFueVtdKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZWUuZW1pdEV2ZW50KHR5cGUsIGV2ZW50QXJyYXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjcmVhdGVWaWRlbygpOiBIVE1MVmlkZW9FbGVtZW50IHtcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3ZpZGVvJyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHJlbW92ZVNyY09iamVjdChzdHJlYW1NYW5hZ2VyVmlkZW86IFN0cmVhbU1hbmFnZXJWaWRlbykge1xuICAgICAgICBzdHJlYW1NYW5hZ2VyVmlkZW8udmlkZW8uc3JjT2JqZWN0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5kZWFjdGl2YXRlU3RyZWFtUGxheWluZ0V2ZW50RXhjZXB0aW9uVGltZW91dCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBhYnN0cmFjdCByZXBsYWNlVHJhY2tJbk1lZGlhU3RyZWFtKHRyYWNrOiBNZWRpYVN0cmVhbVRyYWNrLCB1cGRhdGVMYXN0Q29uc3RyYWludHM6IGJvb2xlYW4pOiB2b2lkO1xuXG4gICAgLyogUHJpdmF0ZSBtZXRob2RzICovXG5cbiAgICBwcm90ZWN0ZWQgcHVzaE5ld1N0cmVhbU1hbmFnZXJWaWRlbyhzdHJlYW1NYW5hZ2VyVmlkZW86IFN0cmVhbU1hbmFnZXJWaWRlbykge1xuICAgICAgICB0aGlzLnZpZGVvcy5wdXNoKHN0cmVhbU1hbmFnZXJWaWRlbyk7XG4gICAgICAgIHRoaXMuYWRkUGxheUV2ZW50VG9GaXJzdFZpZGVvKCk7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLmluZGV4T2YodGhpcykgPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5zZXNzaW9uLnN0cmVhbU1hbmFnZXJzLnB1c2godGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG1pcnJvclZpZGVvKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogdm9pZCB7XG4gICAgICAgIGlmICghcGxhdGZvcm0uaXNJb25pY0lvcygpKSB7XG4gICAgICAgICAgICB2aWRlby5zdHlsZS50cmFuc2Zvcm0gPSAncm90YXRlWSgxODBkZWcpJztcbiAgICAgICAgICAgIHZpZGVvLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9ICdyb3RhdGVZKDE4MGRlZyknO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZW1vdmVNaXJyb3JWaWRlbyh2aWRlbzogSFRNTFZpZGVvRWxlbWVudCk6IHZvaWQge1xuICAgICAgICB2aWRlby5zdHlsZS50cmFuc2Zvcm0gPSAndW5zZXQnO1xuICAgICAgICB2aWRlby5zdHlsZS53ZWJraXRUcmFuc2Zvcm0gPSAndW5zZXQnO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNNaXJyb3JlZFZpZGVvKHZpZGVvOiBIVE1MVmlkZW9FbGVtZW50KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB2aWRlby5zdHlsZS50cmFuc2Zvcm0gPT09ICdyb3RhdGVZKDE4MGRlZyknIHx8IHZpZGVvLnN0eWxlLndlYmtpdFRyYW5zZm9ybSA9PT0gJ3JvdGF0ZVkoMTgwZGVnKSc7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhY3RpdmF0ZVN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQoKSB7XG4gICAgICAgIGlmICghdGhpcy5yZW1vdGUpIHtcbiAgICAgICAgICAgIC8vIEV4Y2VwdGlvbkV2ZW50IE5PX1NUUkVBTV9QTEFZSU5HX0VWRU5UIGlzIG9ubHkgZm9yIHN1YnNjcmliZXJzXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RyZWFtUGxheWluZ0V2ZW50RXhjZXB0aW9uVGltZW91dCAhPSBudWxsKSB7XG4gICAgICAgICAgICAvLyBUaGUgdGltZW91dCBpcyBhbHJlYWR5IGFjdGl2YXRlZFxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRyaWdnZXIgRXhjZXB0aW9uRXZlbnQgTk9fU1RSRUFNX1BMQVlJTkdfRVZFTlQgaWYgYWZ0ZXIgdGltZW91dCB0aGVyZSBpcyBubyAnY2FucGxheScgZXZlbnRcbiAgICAgICAgY29uc3QgbXNUaW1lb3V0ID0gdGhpcy5zdHJlYW0uc2Vzc2lvbi5vcGVudmlkdS5hZHZhbmNlZENvbmZpZ3VyYXRpb24ubm9TdHJlYW1QbGF5aW5nRXZlbnRFeGNlcHRpb25UaW1lb3V0IHx8IDQwMDA7XG4gICAgICAgIHRoaXMuc3RyZWFtUGxheWluZ0V2ZW50RXhjZXB0aW9uVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbXNnID1cbiAgICAgICAgICAgICAgICAnU3RyZWFtTWFuYWdlciBvZiBTdHJlYW0gJyArXG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uc3RyZWFtSWQgK1xuICAgICAgICAgICAgICAgICcgKCcgK1xuICAgICAgICAgICAgICAgICh0aGlzLnJlbW90ZSA/ICdTdWJzY3JpYmVyJyA6ICdQdWJsaXNoZXInKSArXG4gICAgICAgICAgICAgICAgJykgZGlkIG5vdCB0cmlnZ2VyIFwic3RyZWFtUGxheWluZ1wiIGV2ZW50IGluICcgK1xuICAgICAgICAgICAgICAgIG1zVGltZW91dCArXG4gICAgICAgICAgICAgICAgJyBtcyc7XG4gICAgICAgICAgICBsb2dnZXIud2Fybihtc2cpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5lbWl0RXZlbnQoJ2V4Y2VwdGlvbicsIFtcbiAgICAgICAgICAgICAgICBuZXcgRXhjZXB0aW9uRXZlbnQodGhpcy5zdHJlYW0uc2Vzc2lvbiwgRXhjZXB0aW9uRXZlbnROYW1lLk5PX1NUUkVBTV9QTEFZSU5HX0VWRU5ULCAoPGFueT50aGlzKSBhcyBTdWJzY3JpYmVyLCBtc2cpXG4gICAgICAgICAgICBdKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLnN0cmVhbVBsYXlpbmdFdmVudEV4Y2VwdGlvblRpbWVvdXQ7XG4gICAgICAgIH0sIG1zVGltZW91dCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBkZWFjdGl2YXRlU3RyZWFtUGxheWluZ0V2ZW50RXhjZXB0aW9uVGltZW91dCgpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuc3RyZWFtUGxheWluZ0V2ZW50RXhjZXB0aW9uVGltZW91dCBhcyBhbnkpO1xuICAgICAgICBkZWxldGUgdGhpcy5zdHJlYW1QbGF5aW5nRXZlbnRFeGNlcHRpb25UaW1lb3V0O1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuL1N0cmVhbSc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi9TdHJlYW1NYW5hZ2VyJztcbmltcG9ydCB7IFN1YnNjcmliZXJQcm9wZXJ0aWVzIH0gZnJvbSAnLi4vT3BlblZpZHVJbnRlcm5hbC9JbnRlcmZhY2VzL1B1YmxpYy9TdWJzY3JpYmVyUHJvcGVydGllcyc7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL09wZW5WaWR1SW50ZXJuYWwvTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqIFBhY2tzIHJlbW90ZSBtZWRpYSBzdHJlYW1zLiBQYXJ0aWNpcGFudHMgYXV0b21hdGljYWxseSByZWNlaXZlIHRoZW0gd2hlbiBvdGhlcnMgcHVibGlzaCB0aGVpciBzdHJlYW1zLiBJbml0aWFsaXplZCB3aXRoIFtbU2Vzc2lvbi5zdWJzY3JpYmVdXSBtZXRob2RcbiAqXG4gKiBTZWUgYXZhaWxhYmxlIGV2ZW50IGxpc3RlbmVycyBhdCBbW1N0cmVhbU1hbmFnZXJFdmVudE1hcF1dLlxuICovXG5leHBvcnQgY2xhc3MgU3Vic2NyaWJlciBleHRlbmRzIFN0cmVhbU1hbmFnZXIge1xuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwcm9wZXJ0aWVzOiBTdWJzY3JpYmVyUHJvcGVydGllcztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzdHJlYW06IFN0cmVhbSwgdGFyZ0VsOiBzdHJpbmcgfCBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZCwgcHJvcGVydGllczogU3Vic2NyaWJlclByb3BlcnRpZXMpIHtcbiAgICAgICAgc3VwZXIoc3RyZWFtLCB0YXJnRWwpO1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLnRhcmdldEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN1YnNjcmliZSBvciB1bnN1YnNjcmliZSBmcm9tIHRoZSBhdWRpbyBzdHJlYW0gKGlmIGF2YWlsYWJsZSkuIENhbGxpbmcgdGhpcyBtZXRob2QgdHdpY2UgaW4gYSByb3cgcGFzc2luZyBzYW1lIHZhbHVlIHdpbGwgaGF2ZSBubyBlZmZlY3RcbiAgICAgKiBAcGFyYW0gdmFsdWUgYHRydWVgIHRvIHN1YnNjcmliZSB0byB0aGUgYXVkaW8gc3RyZWFtLCBgZmFsc2VgIHRvIHVuc3Vic2NyaWJlIGZyb20gaXRcbiAgICAgKi9cbiAgICBzdWJzY3JpYmVUb0F1ZGlvKHZhbHVlOiBib29sZWFuKTogU3Vic2NyaWJlciB7XG4gICAgICAgIHRoaXMuc3RyZWFtXG4gICAgICAgICAgICAuZ2V0TWVkaWFTdHJlYW0oKVxuICAgICAgICAgICAgLmdldEF1ZGlvVHJhY2tzKClcbiAgICAgICAgICAgIC5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB0aGlzLnN0cmVhbS5hdWRpb0FjdGl2ZSA9IHZhbHVlO1xuICAgICAgICBsb2dnZXIuaW5mbyhcIidTdWJzY3JpYmVyJyBoYXMgXCIgKyAodmFsdWUgPyAnc3Vic2NyaWJlZCB0bycgOiAndW5zdWJzY3JpYmVkIGZyb20nKSArICcgaXRzIGF1ZGlvIHN0cmVhbScpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJzY3JpYmUgb3IgdW5zdWJzY3JpYmUgZnJvbSB0aGUgdmlkZW8gc3RyZWFtIChpZiBhdmFpbGFibGUpLiBDYWxsaW5nIHRoaXMgbWV0aG9kIHR3aWNlIGluIGEgcm93IHBhc3Npbmcgc2FtZSB2YWx1ZSB3aWxsIGhhdmUgbm8gZWZmZWN0XG4gICAgICogQHBhcmFtIHZhbHVlIGB0cnVlYCB0byBzdWJzY3JpYmUgdG8gdGhlIHZpZGVvIHN0cmVhbSwgYGZhbHNlYCB0byB1bnN1YnNjcmliZSBmcm9tIGl0XG4gICAgICovXG4gICAgc3Vic2NyaWJlVG9WaWRlbyh2YWx1ZTogYm9vbGVhbik6IFN1YnNjcmliZXIge1xuICAgICAgICB0aGlzLnN0cmVhbVxuICAgICAgICAgICAgLmdldE1lZGlhU3RyZWFtKClcbiAgICAgICAgICAgIC5nZXRWaWRlb1RyYWNrcygpXG4gICAgICAgICAgICAuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5lbmFibGVkID0gdmFsdWU7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zdHJlYW0udmlkZW9BY3RpdmUgPSB2YWx1ZTtcbiAgICAgICAgbG9nZ2VyLmluZm8oXCInU3Vic2NyaWJlcicgaGFzIFwiICsgKHZhbHVlID8gJ3N1YnNjcmliZWQgdG8nIDogJ3Vuc3Vic2NyaWJlZCBmcm9tJykgKyAnIGl0cyB2aWRlbyBzdHJlYW0nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyogSGlkZGVuIG1ldGhvZHMgKi9cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICByZXBsYWNlVHJhY2tJbk1lZGlhU3RyZWFtKHRyYWNrOiBNZWRpYVN0cmVhbVRyYWNrLCB1cGRhdGVMYXN0Q29uc3RyYWludHM6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbWVkaWFTdHJlYW06IE1lZGlhU3RyZWFtID0gdGhpcy5zdHJlYW0uZ2V0TWVkaWFTdHJlYW0oKTtcbiAgICAgICAgbGV0IHJlbW92ZWRUcmFjazogTWVkaWFTdHJlYW1UcmFjaztcbiAgICAgICAgaWYgKHRyYWNrLmtpbmQgPT09ICd2aWRlbycpIHtcbiAgICAgICAgICAgIHJlbW92ZWRUcmFjayA9IG1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF07XG4gICAgICAgICAgICBpZiAodXBkYXRlTGFzdENvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0ubGFzdFZpZGVvVHJhY2tDb25zdHJhaW50cyA9IHRyYWNrLmdldENvbnN0cmFpbnRzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZW1vdmVkVHJhY2sgPSBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpWzBdO1xuICAgICAgICB9XG4gICAgICAgIG1lZGlhU3RyZWFtLnJlbW92ZVRyYWNrKHJlbW92ZWRUcmFjayk7XG4gICAgICAgIHJlbW92ZWRUcmFjay5zdG9wKCk7XG4gICAgICAgIG1lZGlhU3RyZWFtLmFkZFRyYWNrKHRyYWNrKTtcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuZXhwb3J0IGVudW0gTG9jYWxSZWNvcmRlclN0YXRlIHtcbiAgICBSRUFEWSA9ICdSRUFEWScsXG4gICAgUkVDT1JESU5HID0gJ1JFQ09SRElORycsXG4gICAgUEFVU0VEID0gJ1BBVVNFRCcsXG4gICAgRklOSVNIRUQgPSAnRklOSVNIRUQnXG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLyoqXG4gKiBEZWZpbmVzIHByb3BlcnR5IFtbT3BlblZpZHVFcnJvci5uYW1lXV1cbiAqL1xuZXhwb3J0IGVudW0gT3BlblZpZHVFcnJvck5hbWUge1xuICAgIC8qKlxuICAgICAqIEJyb3dzZXIgaXMgbm90IHN1cHBvcnRlZCBieSBPcGVuVmlkdS5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW1Nlc3Npb24uY29ubmVjdF1dXG4gICAgICovXG4gICAgQlJPV1NFUl9OT1RfU1VQUE9SVEVEID0gJ0JST1dTRVJfTk9UX1NVUFBPUlRFRCcsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdXNlciBoYXNuJ3QgZ3JhbnRlZCBwZXJtaXNzaW9ucyB0byB0aGUgcmVxdWlyZWQgaW5wdXQgZGV2aWNlIHdoZW4gdGhlIGJyb3dzZXIgYXNrZWQgZm9yIHRoZW0uXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIERFVklDRV9BQ0NFU1NfREVOSUVEID0gJ0RFVklDRV9BQ0NFU1NfREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSByZXF1aXJlZCBpbnB1dCBkZXZpY2UgaXMgcHJvYmFibHkgYmVpbmcgdXNlZCBieSBvdGhlciBwcm9jZXNzIHdoZW4gdGhlIGJyb3dzZXIgYXNrZWQgZm9yIGl0LlxuICAgICAqIFRoaXMgZXJyb3IgY2FuIGFsc28gYmUgdHJpZ2dlcmVkIHdoZW4gdGhlIHVzZXIgZ3JhbnRlZCBwZXJtaXNzaW9uIHRvIHVzZSB0aGUgZGV2aWNlcyBidXQgYSBoYXJkd2FyZVxuICAgICAqIGVycm9yIG9jY3VycmVkIGF0IHRoZSBPUywgYnJvd3NlciBvciB3ZWIgcGFnZSBsZXZlbCwgd2hpY2ggcHJldmVudGVkIGFjY2VzcyB0byB0aGUgZGV2aWNlLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBERVZJQ0VfQUxSRUFEWV9JTl9VU0UgPSAnREVWSUNFX0FMUkVBRFlfSU5fVVNFJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSB1c2VyIGhhc24ndCBncmFudGVkIHBlcm1pc3Npb25zIHRvIGNhcHR1cmUgc29tZSBkZXNrdG9wIHNjcmVlbiB3aGVuIHRoZSBicm93c2VyIGFza2VkIGZvciB0aGVtLlxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBTQ1JFRU5fQ0FQVFVSRV9ERU5JRUQgPSAnU0NSRUVOX0NBUFRVUkVfREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIEJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBzY3JlZW4gc2hhcmluZy5cbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgU0NSRUVOX1NIQVJJTkdfTk9UX1NVUFBPUlRFRCA9ICdTQ1JFRU5fU0hBUklOR19OT1RfU1VQUE9SVEVEJyxcblxuICAgIC8qKlxuICAgICAqIE9ubHkgZm9yIENocm9tZSwgdGhlcmUncyBubyBzY3JlZW4gc2hhcmluZyBleHRlbnNpb24gaW5zdGFsbGVkXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIFNDUkVFTl9FWFRFTlNJT05fTk9UX0lOU1RBTExFRCA9ICdTQ1JFRU5fRVhURU5TSU9OX05PVF9JTlNUQUxMRUQnLFxuXG4gICAgLyoqXG4gICAgICogT25seSBmb3IgQ2hyb21lLCB0aGUgc2NyZWVuIHNoYXJpbmcgZXh0ZW5zaW9uIGlzIGluc3RhbGxlZCBidXQgaXMgZGlzYWJsZWRcbiAgICAgKiBSZXR1cm5lZCB1cG9uIHVuc3VjY2Vzc2Z1bCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBbW09wZW5WaWR1LmdldFVzZXJNZWRpYV1dXG4gICAgICovXG4gICAgU0NSRUVOX0VYVEVOU0lPTl9ESVNBQkxFRCA9ICdTQ1JFRU5fRVhURU5TSU9OX0RJU0FCTEVEJyxcblxuICAgIC8qKlxuICAgICAqIE5vIHZpZGVvIGlucHV0IGRldmljZSBmb3VuZCB3aXRoIHRoZSBwcm92aWRlZCBkZXZpY2VJZCAocHJvcGVydHkgW1tQdWJsaXNoZXJQcm9wZXJ0aWVzLnZpZGVvU291cmNlXV0pXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIElOUFVUX1ZJREVPX0RFVklDRV9OT1RfRk9VTkQgPSAnSU5QVVRfVklERU9fREVWSUNFX05PVF9GT1VORCcsXG5cbiAgICAvKipcbiAgICAgKiBObyBhdWRpbyBpbnB1dCBkZXZpY2UgZm91bmQgd2l0aCB0aGUgcHJvdmlkZWQgZGV2aWNlSWQgKHByb3BlcnR5IFtbUHVibGlzaGVyUHJvcGVydGllcy5hdWRpb1NvdXJjZV1dKVxuICAgICAqIFJldHVybmVkIHVwb24gdW5zdWNjZXNzZnVsIFtbT3BlblZpZHUuaW5pdFB1Ymxpc2hlcl1dIG9yIFtbT3BlblZpZHUuZ2V0VXNlck1lZGlhXV1cbiAgICAgKi9cbiAgICBJTlBVVF9BVURJT19ERVZJQ0VfTk9UX0ZPVU5EID0gJ0lOUFVUX0FVRElPX0RFVklDRV9OT1RfRk9VTkQnLFxuXG4gICAgLyoqXG4gICAgICogVGhlcmUgd2FzIGFuIHVua25vd24gZXJyb3Igd2hlbiB0cnlpbmcgdG8gYWNjZXNzIHRoZSBzcGVjaWZpZWQgYXVkaW8gZGV2aWNlXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIElOUFVUX0FVRElPX0RFVklDRV9HRU5FUklDX0VSUk9SID0gJ0lOUFVUX0FVRElPX0RFVklDRV9HRU5FUklDX0VSUk9SJyxcblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciAgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXSBoYXMgYmVlbiBjYWxsZWQgd2l0aCBwcm9wZXJ0aWVzIGB2aWRlb1NvdXJjZWAgYW5kIGBhdWRpb1NvdXJjZWAgb2ZcbiAgICAgKiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBwYXJhbWV0ZXIgYm90aCBzZXQgdG8gKmZhbHNlKiBvciAqbnVsbCpcbiAgICAgKi9cbiAgICBOT19JTlBVVF9TT1VSQ0VfU0VUID0gJ05PX0lOUFVUX1NPVVJDRV9TRVQnLFxuXG4gICAgLyoqXG4gICAgICogU29tZSBtZWRpYSBwcm9wZXJ0eSBvZiBbW1B1Ymxpc2hlclByb3BlcnRpZXNdXSBzdWNoIGFzIGBmcmFtZVJhdGVgIG9yIGByZXNvbHV0aW9uYCBpcyBub3Qgc3VwcG9ydGVkXG4gICAgICogYnkgdGhlIGlucHV0IGRldmljZXMgKHdoZW5ldmVyIGl0IGlzIHBvc3NpYmxlIHRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgYWRqdXN0ZWQgdG8gdGhlIG1vc3Qgc2ltaWxhciB2YWx1ZSkuXG4gICAgICogUmV0dXJuZWQgdXBvbiB1bnN1Y2Nlc3NmdWwgW1tPcGVuVmlkdS5pbml0UHVibGlzaGVyXV0gb3IgW1tPcGVuVmlkdS5nZXRVc2VyTWVkaWFdXVxuICAgICAqL1xuICAgIFBVQkxJU0hFUl9QUk9QRVJUSUVTX0VSUk9SID0gJ1BVQkxJU0hFUl9QUk9QRVJUSUVTX0VSUk9SJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdHJpZWQgdG8gY2FsbCBhIG1ldGhvZCB3aXRob3V0IHRoZSByZXF1aXJlZCBwZXJtaXNzaW9ucy4gVGhpcyBjYW4gb2NjdXIgZm9yIG1ldGhvZHMgW1tTZXNzaW9uLnB1Ymxpc2hdXSxcbiAgICAgKiBbW1Nlc3Npb24uZm9yY2VVbnB1Ymxpc2hdXSwgW1tTZXNzaW9uLmZvcmNlRGlzY29ubmVjdF1dLCBbW1N0cmVhbS5hcHBseUZpbHRlcl1dLCBbW1N0cmVhbS5yZW1vdmVGaWx0ZXJdXVxuICAgICAqL1xuICAgIE9QRU5WSURVX1BFUk1JU1NJT05fREVOSUVEID0gJ09QRU5WSURVX1BFUk1JU1NJT05fREVOSUVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZXJlIGlzIG5vIGNvbm5lY3Rpb24gdG8gdGhlIFNlc3Npb24uIFRoaXMgZXJyb3Igd2lsbCBiZSB0aHJvd24gd2hlbiBhbnkgbWV0aG9kIHJlcXVpcmluZyBhIGNvbm5lY3Rpb24gdG9cbiAgICAgKiBvcGVudmlkdS1zZXJ2ZXIgaXMgY2FsbGVkIGJlZm9yZSBzdWNjZXNzZnVsbHkgY2FsbGluZyBtZXRob2QgW1tTZXNzaW9uLmNvbm5lY3RdXVxuICAgICAqL1xuICAgIE9QRU5WSURVX05PVF9DT05ORUNURUQgPSAnT1BFTlZJRFVfTk9UX0NPTk5FQ1RFRCcsXG5cbiAgICAvKipcbiAgICAgKiBFcnJvciByZWxhdGVkIHRvIFtWaXJ0dWFsIEJhY2tncm91bmRdKC9lbi9zdGFibGUvYWR2YW5jZWQtZmVhdHVyZXMvdmlydHVhbC1iYWNrZ3JvdW5kLylcbiAgICAgKi9cbiAgICBWSVJUVUFMX0JBQ0tHUk9VTkRfRVJST1IgPSAnVklSVFVBTF9CQUNLR1JPVU5EX0VSUk9SJyxcblxuICAgIC8qKlxuICAgICAqIEdlbmVyaWMgZXJyb3JcbiAgICAgKi9cbiAgICBHRU5FUklDX0VSUk9SID0gJ0dFTkVSSUNfRVJST1InXG59XG5cbi8qKlxuICogU2ltcGxlIG9iamVjdCB0byBpZGVudGlmeSBydW50aW1lIGVycm9ycyBvbiB0aGUgY2xpZW50IHNpZGVcbiAqL1xuZXhwb3J0IGNsYXNzIE9wZW5WaWR1RXJyb3Ige1xuICAgIC8qKlxuICAgICAqIFVuaXF1ZWx5IGlkZW50aWZ5aW5nIG5hbWUgb2YgdGhlIGVycm9yXG4gICAgICovXG4gICAgbmFtZTogT3BlblZpZHVFcnJvck5hbWU7XG5cbiAgICAvKipcbiAgICAgKiBGdWxsIGRlc2NyaXB0aW9uIG9mIHRoZSBlcnJvclxuICAgICAqL1xuICAgIG1lc3NhZ2U6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihuYW1lOiBPcGVuVmlkdUVycm9yTmFtZSwgbWVzc2FnZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMubWVzc2FnZSA9IG1lc3NhZ2U7XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmV4cG9ydCBlbnVtIFR5cGVPZlZpZGVvIHtcbiAgICBDQU1FUkEgPSAnQ0FNRVJBJyxcbiAgICBTQ1JFRU4gPSAnU0NSRUVOJyxcbiAgICBDVVNUT00gPSAnQ1VTVE9NJyxcbiAgICBJUENBTSA9ICdJUENBTSdcbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIEhvdyB0aGUgdmlkZW8gd2lsbCBiZSBpbnNlcnRlZCBpbiB0aGUgRE9NIGZvciBQdWJsaXNoZXJzIGFuZCBTdWJzY3JpYmVycy4gU2VlIFtbUHVibGlzaGVyUHJvcGVydGllcy5pbnNlcnRNb2RlXV0gYW5kIFtbU3Vic2NyaWJlclByb3BlcnRpZXMuaW5zZXJ0TW9kZV1dXG4gKi9cbmV4cG9ydCBlbnVtIFZpZGVvSW5zZXJ0TW9kZSB7XG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYWZ0ZXIgdGhlIHRhcmdldCBlbGVtZW50IChhcyBuZXh0IHNpYmxpbmcpXG4gICAgICovXG4gICAgQUZURVIgPSAnQUZURVInLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIGluc2VydGVkIGFzIGxhc3QgY2hpbGQgb2YgdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgQVBQRU5EID0gJ0FQUEVORCcsXG4gICAgLyoqXG4gICAgICogVmlkZW8gaW5zZXJ0ZWQgYmVmb3JlIHRoZSB0YXJnZXQgZWxlbWVudCAoYXMgcHJldmlvdXMgc2libGluZylcbiAgICAgKi9cbiAgICBCRUZPUkUgPSAnQkVGT1JFJyxcbiAgICAvKipcbiAgICAgKiBWaWRlbyBpbnNlcnRlZCBhcyBmaXJzdCBjaGlsZCBvZiB0aGUgdGFyZ2V0IGVsZW1lbnRcbiAgICAgKi9cbiAgICBQUkVQRU5EID0gJ1BSRVBFTkQnLFxuICAgIC8qKlxuICAgICAqIFZpZGVvIHJlcGxhY2VzIHRhcmdldCBlbGVtZW50XG4gICAgICovXG4gICAgUkVQTEFDRSA9ICdSRVBMQUNFJ1xufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBDb25uZWN0aW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvQ29ubmVjdGlvbic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnRSZWFzb24gfSBmcm9tICcuL1R5cGVzL1R5cGVzJztcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnk6XG4gKiAtIFtbY29ubmVjdGlvbkNyZWF0ZWRdXVxuICogLSBbW2Nvbm5lY3Rpb25EZXN0cm95ZWRdXVxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvbkV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIENvbm5lY3Rpb24gb2JqZWN0IHRoYXQgd2FzIGNyZWF0ZWQgb3IgZGVzdHJveWVkXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEZvciBgY29ubmVjdGlvbkRlc3Ryb3llZGAgZXZlbnQ6XG4gICAgICogLSBcImRpc2Nvbm5lY3RcIjogdGhlIHJlbW90ZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZGlzY29ubmVjdCgpYFxuICAgICAqIC0gXCJmb3JjZURpc2Nvbm5lY3RCeVVzZXJcIjogdGhlIHJlbW90ZSB1c2VyIGhhcyBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSBvdGhlciB1c2VyIGNhbGxpbmcgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHRoZSByZW1vdGUgdXNlciBoYXMgYmVlbiBldmljdGVkIGZyb20gdGhlIFNlc3Npb24gYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcInNlc3Npb25DbG9zZWRCeVNlcnZlclwiOiB0aGUgU2Vzc2lvbiBoYXMgYmVlbiBjbG9zZWQgYnkgdGhlIGFwcGxpY2F0aW9uXG4gICAgICogLSBcIm5ldHdvcmtEaXNjb25uZWN0XCI6IHRoZSByZW1vdGUgdXNlciBuZXR3b3JrIGNvbm5lY3Rpb24gaGFzIGRyb3BwZWRcbiAgICAgKiAtIFwibm9kZUNyYXNoZWRcIjogYSBub2RlIGhhcyBjcmFzaGVkIGluIHRoZSBzZXJ2ZXIgc2lkZVxuICAgICAqXG4gICAgICogRm9yIGBjb25uZWN0aW9uQ3JlYXRlZGAgZXZlbnQgYW4gZW1wdHkgc3RyaW5nXG4gICAgICovXG4gICAgcmVhc29uOiBDb25uZWN0aW9uRXZlbnRSZWFzb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uLCB0eXBlOiBzdHJpbmcsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHJlYXNvbjogQ29ubmVjdGlvbkV2ZW50UmVhc29uKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuY29ubmVjdGlvbiA9IGNvbm5lY3Rpb247XG4gICAgICAgIHRoaXMucmVhc29uID0gcmVhc29uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcblxuLyoqXG4gKiAqKlRoaXMgZmVhdHVyZSBpcyBwYXJ0IG9mIE9wZW5WaWR1XG4gKiA8YSBocmVmPVwiaHR0cHM6Ly9kb2NzLm9wZW52aWR1LmlvL2VuL3N0YWJsZS9vcGVudmlkdS1wcm8vXCIgc3R5bGU9XCJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IGJhY2tncm91bmQtY29sb3I6IHJnYigwLCAxMzYsIDE3MCk7IGNvbG9yOiB3aGl0ZTsgZm9udC13ZWlnaHQ6IGJvbGQ7IHBhZGRpbmc6IDBweCA1cHg7IG1hcmdpbjogMCAycHggMCAycHg7IGJvcmRlci1yYWRpdXM6IDNweDsgZm9udC1zaXplOiAxM3B4OyBsaW5lLWhlaWdodDoyMXB4OyB0ZXh0LWRlY29yYXRpb246IG5vbmU7IGZvbnQtZmFtaWx5OiBNb250c2VycmF0LCBzYW5zLXNlcmlmXCI+UFJPPC9hPlxuICogYW5kXG4gKiA8YSBocmVmPVwiaHR0cHM6Ly9kb2NzLm9wZW52aWR1LmlvL2VuL3N0YWJsZS9vcGVudmlkdS1lbnRlcnByaXNlL1wiIHN0eWxlPVwiZGlzcGxheTogaW5saW5lLWJsb2NrOyBiYWNrZ3JvdW5kLWNvbG9yOiByZ2IoMTU2LCAzOSwgMTc2KTsgY29sb3I6IHdoaXRlOyBmb250LXdlaWdodDogYm9sZDsgcGFkZGluZzogMHB4IDVweDsgbWFyZ2luOiAwIDJweCAwIDJweDsgYm9yZGVyLXJhZGl1czogM3B4OyBmb250LXNpemU6IDEzcHg7IGxpbmUtaGVpZ2h0OjIxcHg7IHRleHQtZGVjb3JhdGlvbjogbm9uZTsgZm9udC1mYW1pbHk6IE1vbnRzZXJyYXQsIHNhbnMtc2VyaWZcIj5FTlRFUlBSSVNFPC9hPlxuICogZWRpdGlvbnMqKlxuICpcbiAqIFRyaWdnZXJlZCBieSBbW2Nvbm5lY3Rpb25Qcm9wZXJ0eUNoYW5nZWRdXVxuICovXG5leHBvcnQgY2xhc3MgQ29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIFRoZSBDb25uZWN0aW9uIHdob3NlIHByb3BlcnR5IGhhcyBjaGFuZ2VkXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBwcm9wZXJ0eSBvZiB0aGUgc3RyZWFtIHRoYXQgY2hhbmdlZC4gVGhpcyB2YWx1ZSBpcyBlaXRoZXIgYFwicm9sZVwiYCBvciBgXCJyZWNvcmRcImBcbiAgICAgKi9cbiAgICBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIE5ldyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGFmdGVyIGNoYW5nZSwgY3VycmVudCB2YWx1ZSlcbiAgICAgKi9cbiAgICBuZXdWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogUHJldmlvdXMgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChiZWZvcmUgY2hhbmdlKVxuICAgICAqL1xuICAgIG9sZFZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCBjb25uZWN0aW9uOiBDb25uZWN0aW9uLCBjaGFuZ2VkUHJvcGVydHk6IHN0cmluZywgbmV3VmFsdWU6IE9iamVjdCwgb2xkVmFsdWU6IE9iamVjdCkge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCAnY29ubmVjdGlvblByb3BlcnR5Q2hhbmdlZCcpO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgICAgICB0aGlzLmNoYW5nZWRQcm9wZXJ0eSA9IGNoYW5nZWRQcm9wZXJ0eTtcbiAgICAgICAgdGhpcy5uZXdWYWx1ZSA9IG5ld1ZhbHVlO1xuICAgICAgICB0aGlzLm9sZFZhbHVlID0gb2xkVmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7fVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEZpbHRlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0ZpbHRlcic7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgZXZlbnQgaGFzIGEgZGVmYXVsdCBiZWhhdmlvciB0aGF0IG1heSBiZSBwcmV2ZW50ZWQgYnkgY2FsbGluZyBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV1cbiAgICAgKi9cbiAgICBjYW5jZWxhYmxlOiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9iamVjdCB0aGF0IGRpc3BhdGNoZWQgdGhlIGV2ZW50XG4gICAgICovXG4gICAgdGFyZ2V0OiBTZXNzaW9uIHwgU3RyZWFtTWFuYWdlciB8IEZpbHRlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIGV2ZW50LiBUaGlzIGlzIHRoZSBzYW1lIHN0cmluZyB5b3UgcGFzcyBhcyBmaXJzdCBwYXJhbWV0ZXIgd2hlbiBjYWxsaW5nIG1ldGhvZCBgb24oKWAgb2YgYW55IG9iamVjdCBpbXBsZW1lbnRpbmcgW1tFdmVudERpc3BhdGNoZXJdXSBpbnRlcmZhY2VcbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaGFzQmVlblByZXZlbnRlZCA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbGFibGU6IGJvb2xlYW4sIHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIgfCBGaWx0ZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICB0aGlzLmNhbmNlbGFibGUgPSBjYW5jZWxhYmxlO1xuICAgICAgICB0aGlzLnRhcmdldCA9IHRhcmdldDtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBkZWZhdWx0IGJlYWhpdm91ciBvZiB0aGUgZXZlbnQgaGFzIGJlZW4gcHJldmVudGVkIG9yIG5vdC4gQ2FsbCBbW0V2ZW50LnByZXZlbnREZWZhdWx0XV0gdG8gcHJldmVudCBpdFxuICAgICAqL1xuICAgIGlzRGVmYXVsdFByZXZlbnRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzQmVlblByZXZlbnRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcmV2ZW50cyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgZXZlbnQuIFRoZSBmb2xsb3dpbmcgZXZlbnRzIGhhdmUgYSBkZWZhdWx0IGJlaGF2aW9yOlxuICAgICAqXG4gICAgICogLSBgc2Vzc2lvbkRpc2Nvbm5lY3RlZGA6IGRpc3BhdGNoZWQgYnkgW1tTZXNzaW9uXV0gb2JqZWN0LCBhdXRvbWF0aWNhbGx5IHVuc3Vic2NyaWJlcyB0aGUgbGVhdmluZyBwYXJ0aWNpcGFudCBmcm9tIGV2ZXJ5IFN1YnNjcmliZXIgb2JqZWN0IG9mIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIGVhY2ggU3Vic2NyaWJlciAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YCBpbiBtZXRob2QgW1tTZXNzaW9uLnN1YnNjcmliZV1dIG9yXG4gICAgICogYnkgY2FsbGluZyBbW1N1YnNjcmliZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0pLiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgZWFjaCBTdWJzY3JpYmVyIG9iamVjdCB3aWxsIGFsc28gZGlzcGF0Y2ggYSBgdmlkZW9FbGVtZW50RGVzdHJveWVkYCBldmVudC5cbiAgICAgKlxuICAgICAqIC0gYHN0cmVhbURlc3Ryb3llZGA6XG4gICAgICogICAtIElmIGRpc3BhdGNoZWQgYnkgYSBbW1B1Ymxpc2hlcl1dICgqeW91KiBoYXZlIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSBzdG9wcyBhbGwgbWVkaWEgdHJhY2tzIGFuZCBkZWxldGVzIGFueSBIVE1MIHZpZGVvIGVsZW1lbnQgYXNzb2NpYXRlZCB0byBpdCAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YFxuICAgICAqIGluIG1ldGhvZCBbW09wZW5WaWR1LmluaXRQdWJsaXNoZXJdXSBvciBieSBjYWxsaW5nIFtbUHVibGlzaGVyLmNyZWF0ZVZpZGVvRWxlbWVudF1dKS4gRm9yIGV2ZXJ5IHZpZGVvIHJlbW92ZWQsIHRoZSBQdWJsaXNoZXIgb2JqZWN0IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqICAgLSBJZiBkaXNwYXRjaGVkIGJ5IFtbU2Vzc2lvbl1dICgqb3RoZXIgdXNlciogaGFzIHVucHVibGlzaGVkKTogYXV0b21hdGljYWxseSB1bnN1YnNjcmliZXMgdGhlIHByb3BlciBTdWJzY3JpYmVyIG9iamVjdCBmcm9tIHRoZSBzZXNzaW9uICh0aGlzIGluY2x1ZGVzIGNsb3NpbmcgdGhlIFJUQ1BlZXJDb25uZWN0aW9uIGFuZCBkaXNwb3NpbmcgYWxsIE1lZGlhU3RyZWFtVHJhY2tzKVxuICAgICAqIGFuZCBhbHNvIGRlbGV0ZXMgYW55IEhUTUwgdmlkZW8gZWxlbWVudCBhc3NvY2lhdGVkIHRvIHRoYXQgU3Vic2NyaWJlciAob25seSB0aG9zZSBjcmVhdGVkIGJ5IE9wZW5WaWR1IEJyb3dzZXIsIGVpdGhlciBieSBwYXNzaW5nIGEgdmFsaWQgcGFyYW1ldGVyIGFzIGB0YXJnZXRFbGVtZW50YCBpbiBtZXRob2QgW1tTZXNzaW9uLnN1YnNjcmliZV1dIG9yXG4gICAgICogYnkgY2FsbGluZyBbW1N1YnNjcmliZXIuY3JlYXRlVmlkZW9FbGVtZW50XV0pLiBGb3IgZXZlcnkgdmlkZW8gcmVtb3ZlZCwgdGhlIFN1YnNjcmliZXIgb2JqZWN0IHdpbGwgYWxzbyBkaXNwYXRjaCBhIGB2aWRlb0VsZW1lbnREZXN0cm95ZWRgIGV2ZW50LlxuICAgICAqL1xuICAgIHByZXZlbnREZWZhdWx0KCkge1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICAgICAgdGhpcy5jYWxsRGVmYXVsdEJlaGF2aW9yID0gKCkgPT4ge307XG4gICAgICAgIHRoaXMuaGFzQmVlblByZXZlbnRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFic3RyYWN0IGNhbGxEZWZhdWx0QmVoYXZpb3IoKTtcbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgU3Vic2NyaWJlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N1YnNjcmliZXInO1xuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcblxuLyoqXG4gKiBEZWZpbmVzIHByb3BlcnR5IFtbRXhjZXB0aW9uRXZlbnQubmFtZV1dXG4gKi9cbmV4cG9ydCBlbnVtIEV4Y2VwdGlvbkV2ZW50TmFtZSB7XG4gICAgLyoqXG4gICAgICogVGhlcmUgd2FzIGFuIHVuZXhwZWN0ZWQgZXJyb3Igb24gdGhlIHNlcnZlci1zaWRlIHByb2Nlc3NpbmcgYW4gSUNFIGNhbmRpZGF0ZSBnZW5lcmF0ZWQgYW5kIHNlbnQgYnkgdGhlIGNsaWVudC1zaWRlLlxuICAgICAqXG4gICAgICogW1tFeGNlcHRpb25FdmVudF1dIG9iamVjdHMgd2l0aCB0aGlzIFtbRXhjZXB0aW9uRXZlbnQubmFtZV1dIHdpbGwgaGF2ZSBhcyBbW0V4Y2VwdGlvbkV2ZW50Lm9yaWdpbl1dIHByb3BlcnR5IGEgW1tTZXNzaW9uXV0gb2JqZWN0LlxuICAgICAqL1xuICAgIElDRV9DQU5ESURBVEVfRVJST1IgPSAnSUNFX0NBTkRJREFURV9FUlJPUicsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgW0lDRSBjb25uZWN0aW9uIHN0YXRlXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUlRDUGVlckNvbm5lY3Rpb24vaWNlQ29ubmVjdGlvblN0YXRlKVxuICAgICAqIG9mIGFuIFtSVENQZWVyQ29ubmVjdGlvbl0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1JUQ1BlZXJDb25uZWN0aW9uKSByZWFjaGVkIGBmYWlsZWRgIHN0YXR1cy5cbiAgICAgKlxuICAgICAqIFRoaXMgaXMgYSB0ZXJtaW5hbCBlcnJvciB0aGF0IHdvbid0IGhhdmUgYW55IGtpbmQgb2YgcG9zc2libGUgcmVjb3ZlcnkuIElmIHRoZSBjbGllbnQgaXMgc3RpbGwgY29ubmVjdGVkIHRvIE9wZW5WaWR1IFNlcnZlcixcbiAgICAgKiB0aGVuIGFuIGF1dG9tYXRpYyByZWNvbm5lY3Rpb24gcHJvY2VzcyBvZiB0aGUgbWVkaWEgc3RyZWFtIGlzIGltbWVkaWF0ZWx5IHBlcmZvcm1lZC4gSWYgdGhlIElDRSBjb25uZWN0aW9uIGhhcyBicm9rZW4gZHVlIHRvXG4gICAgICogYSB0b3RhbCBuZXR3b3JrIGRyb3AsIHRoZW4gbm8gYXV0b21hdGljIHJlY29ubmVjdGlvbiBwcm9jZXNzIHdpbGwgYmUgcG9zc2libGUuXG4gICAgICpcbiAgICAgKiBbW0V4Y2VwdGlvbkV2ZW50XV0gb2JqZWN0cyB3aXRoIHRoaXMgW1tFeGNlcHRpb25FdmVudC5uYW1lXV0gd2lsbCBoYXZlIGFzIFtbRXhjZXB0aW9uRXZlbnQub3JpZ2luXV0gcHJvcGVydHkgYSBbW1N0cmVhbV1dIG9iamVjdC5cbiAgICAgKi9cbiAgICBJQ0VfQ09OTkVDVElPTl9GQUlMRUQgPSAnSUNFX0NPTk5FQ1RJT05fRkFJTEVEJyxcblxuICAgIC8qKlxuICAgICAqIFRoZSBbSUNFIGNvbm5lY3Rpb24gc3RhdGVdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9SVENQZWVyQ29ubmVjdGlvbi9pY2VDb25uZWN0aW9uU3RhdGUpXG4gICAgICogb2YgYW4gW1JUQ1BlZXJDb25uZWN0aW9uXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUlRDUGVlckNvbm5lY3Rpb24pIHJlYWNoZWQgYGRpc2Nvbm5lY3RlZGAgc3RhdHVzLlxuICAgICAqXG4gICAgICogVGhpcyBpcyBub3QgYSB0ZXJtaW5hbCBlcnJvciwgYW5kIGl0IGlzIHBvc3NpYmxlIGZvciB0aGUgSUNFIGNvbm5lY3Rpb24gdG8gYmUgcmVjb25uZWN0ZWQuIElmIHRoZSBjbGllbnQgaXMgc3RpbGwgY29ubmVjdGVkIHRvXG4gICAgICogT3BlblZpZHUgU2VydmVyIGFuZCBhZnRlciBjZXJ0YWluIHRpbWVvdXQgdGhlIElDRSBjb25uZWN0aW9uIGhhcyBub3QgcmVhY2hlZCBhIHN1Y2Nlc3Mgb3IgdGVybWluYWwgc3RhdHVzLCB0aGVuIGFuIGF1dG9tYXRpY1xuICAgICAqIHJlY29ubmVjdGlvbiBwcm9jZXNzIG9mIHRoZSBtZWRpYSBzdHJlYW0gaXMgcGVyZm9ybWVkLiBJZiB0aGUgSUNFIGNvbm5lY3Rpb24gaGFzIGJyb2tlbiBkdWUgdG8gYSB0b3RhbCBuZXR3b3JrIGRyb3AsIHRoZW4gbm9cbiAgICAgKiBhdXRvbWF0aWMgcmVjb25uZWN0aW9uIHByb2Nlc3Mgd2lsbCBiZSBwb3NzaWJsZS5cbiAgICAgKlxuICAgICAqIFlvdSBjYW4gY3VzdG9taXplIHRoZSB0aW1lb3V0IGZvciB0aGUgcmVjb25uZWN0aW9uIGF0dGVtcHQgd2l0aCBwcm9wZXJ0eSBbW09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uLmljZUNvbm5lY3Rpb25EaXNjb25uZWN0ZWRFeGNlcHRpb25UaW1lb3V0XV0sXG4gICAgICogd2hpY2ggYnkgZGVmYXVsdCBpcyA0MDAwIG1pbGxpc2Vjb25kcy5cbiAgICAgKlxuICAgICAqIFtbRXhjZXB0aW9uRXZlbnRdXSBvYmplY3RzIHdpdGggdGhpcyBbW0V4Y2VwdGlvbkV2ZW50Lm5hbWVdXSB3aWxsIGhhdmUgYXMgW1tFeGNlcHRpb25FdmVudC5vcmlnaW5dXSBwcm9wZXJ0eSBhIFtbU3RyZWFtXV0gb2JqZWN0LlxuICAgICAqL1xuICAgIElDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRCA9ICdJQ0VfQ09OTkVDVElPTl9ESVNDT05ORUNURUQnLFxuXG4gICAgLyoqXG4gICAgICogQSBbW1N1YnNjcmliZXJdXSBvYmplY3QgaGFzIG5vdCBmaXJlZCBldmVudCBgc3RyZWFtUGxheWluZ2AgYWZ0ZXIgY2VydGFpbiB0aW1lb3V0LiBgc3RyZWFtUGxheWluZ2AgZXZlbnQgYmVsb25ncyB0byBbW1N0cmVhbU1hbmFnZXJFdmVudF1dXG4gICAgICogY2F0ZWdvcnkuIEl0IHdyYXBzIFdlYiBBUEkgbmF0aXZlIGV2ZW50IFtjYW5wbGF5XShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvSFRNTE1lZGlhRWxlbWVudC9jYW5wbGF5X2V2ZW50KS5cbiAgICAgKlxuICAgICAqIE9wZW5WaWR1IEJyb3dzZXIgY2FuIHRha2UgY2FyZSBvZiB0aGUgdmlkZW8gcGxheWVycyAoc2VlIFtoZXJlXSgvZW4vc3RhYmxlL2NoZWF0c2hlZXQvbWFuYWdlLXZpZGVvcy8jbGV0LW9wZW52aWR1LXRha2UtY2FyZS1vZi10aGUtdmlkZW8tcGxheWVycykpLFxuICAgICAqIG9yIHlvdSBjYW4gdGFrZSBjYXJlIG9mIHZpZGVvIHBsYXllcnMgb24geW91ciBvd24gKHNlZSBbaGVyZV0oL2VuL3N0YWJsZS9jaGVhdHNoZWV0L21hbmFnZS12aWRlb3MvI3lvdS10YWtlLWNhcmUtb2YtdGhlLXZpZGVvLXBsYXllcnMpKS5cbiAgICAgKiBFaXRoZXIgd2F5LCB3aGVuZXZlciBhIFtbU3Vic2NyaWJlcl1dIG9iamVjdCBpcyBjb21tYW5kZWQgdG8gYXR0YWNoIGl0cyBbW1N0cmVhbV1dIHRvIGEgdmlkZW8gZWxlbWVudCwgaXQgaXMgc3VwcG9zZWQgdG8gZmlyZSBgc3RyZWFtUGxheWluZ2BcbiAgICAgKiBldmVudCBzaG9ydGx5IGFmdGVyLiBJZiBpdCBkb2VzIG5vdCwgdGhlbiB3ZSBjYW4gc2FmZWx5IGFzc3VtZSB0aGF0IHNvbWV0aGluZyB3cm9uZyBoYXMgaGFwcGVuZWQgd2hpbGUgcGxheWluZyB0aGUgcmVtb3RlIHZpZGVvIGFuZCB0aGVcbiAgICAgKiBhcHBsaWNhdGlvbiBtYXkgYmUgbm90aWZpZWQgdGhyb3VnaCB0aGlzIHNwZWNpZmljIEV4Y2VwdGlvbkV2ZW50LlxuICAgICAqXG4gICAgICogVGhlIHRpbWVvdXQgY2FuIGJlIGNvbmZpZ3VyZWQgd2l0aCBwcm9wZXJ0eSBbW09wZW5WaWR1QWR2YW5jZWRDb25maWd1cmF0aW9uLm5vU3RyZWFtUGxheWluZ0V2ZW50RXhjZXB0aW9uVGltZW91dF1dLiBCeSBkZWZhdWx0IGl0IGlzIDQwMDAgbWlsbGlzZWNvbmRzLlxuICAgICAqXG4gICAgICogVGhpcyBpcyBqdXN0IGFuIGluZm9ybWF0aXZlIGV4Y2VwdGlvbi4gSXQgb25seSBtZWFucyB0aGF0IGEgcmVtb3RlIFN0cmVhbSB0aGF0IGlzIHN1cHBvc2VkIHRvIGJlIHBsYXlpbmcgYnkgYSB2aWRlbyBwbGF5ZXIgaGFzIG5vdCBkb25lIHNvXG4gICAgICogaW4gYSByZWFzb25hYmxlIHRpbWUuIEJ1dCB0aGUgbGFjayBvZiB0aGUgZXZlbnQgY2FuIGJlIGNhdXNlZCBieSBtdWx0aXBsZSByZWFzb25zLiBJZiBhIFN1YnNjcmliZXIgaXMgbm90IHBsYXlpbmcgaXRzIFN0cmVhbSwgdGhlIG9yaWdpblxuICAgICAqIG9mIHRoZSBwcm9ibGVtIGNvdWxkIGJlIGxvY2F0ZWQgYXQgdGhlIFB1Ymxpc2hlciBzaWRlLiBPciBtYXkgYmUgY2F1c2VkIGJ5IGEgdHJhbnNpZW50IG5ldHdvcmsgcHJvYmxlbS4gQnV0IGl0IGFsc28gY291bGQgYmUgYSBwcm9ibGVtIHdpdGhcbiAgICAgKiBhdXRvcGxheSBwZXJtaXNzaW9ucy4gQm90dG9tIGxpbmUsIHRoZSBjYXVzZSBjYW4gYmUgdmVyeSB2YXJpZWQsIGFuZCBkZXBlbmRpbmcgb24gdGhlIGFwcGxpY2F0aW9uIHRoZSBsYWNrIG9mIHRoZSBldmVudCBjb3VsZCBldmVuIGJlIGV4cGVjdGVkLlxuICAgICAqXG4gICAgICogW1tFeGNlcHRpb25FdmVudF1dIG9iamVjdHMgd2l0aCB0aGlzIFtbRXhjZXB0aW9uRXZlbnQubmFtZV1dIHdpbGwgaGF2ZSBhcyBbW0V4Y2VwdGlvbkV2ZW50Lm9yaWdpbl1dIHByb3BlcnR5IGEgW1tTdWJzY3JpYmVyXV0gb2JqZWN0LlxuICAgICAqL1xuICAgIE5PX1NUUkVBTV9QTEFZSU5HX0VWRU5UID0gJ05PX1NUUkVBTV9QTEFZSU5HX0VWRU5UJyxcblxuICAgIC8qKlxuICAgICAqIFRoZXJlIGhhcyBiZWVuIGEgc2VydmVyLXNpZGUgZGlzY29ubmVjdGlvbiBvZiB0aGUgU3BlZWNoIFRvIFRleHQgbW9kdWxlLiBGcm9tIHRoZSBtb21lbnQgdGhpcyBleGNlcHRpb24gaXMgZmlyZWQgdG8gdGhlIG1vbWVudCBtZXRob2RcbiAgICAgKiBbW1Nlc3Npb24uc3Vic2NyaWJlVG9TcGVlY2hUb1RleHRdXSBpcyBjYWxsZWQgYWdhaW4sIHRoZSB0cmFuc2NyaXB0aW9uIG9mIHRoZSBhdWRpbyBzdHJlYW0gd2lsbCBub3QgYmUgYXZhaWxhYmxlIGFuZCBubyBbW1NwZWVjaFRvVGV4dEV2ZW50XV1cbiAgICAgKiB3aWxsIGJlIGZpcmVkLlxuICAgICAqXG4gICAgICogW1tFeGNlcHRpb25FdmVudF1dIG9iamVjdHMgd2l0aCB0aGlzIFtbRXhjZXB0aW9uRXZlbnQubmFtZV1dIHdpbGwgaGF2ZSBhcyBbW0V4Y2VwdGlvbkV2ZW50Lm9yaWdpbl1dIHByb3BlcnR5IGEgW1tTZXNzaW9uXV0gb2JqZWN0LlxuICAgICAqL1xuICAgIFNQRUVDSF9UT19URVhUX0RJU0NPTk5FQ1RFRCA9ICdTUEVFQ0hfVE9fVEVYVF9ESVNDT05ORUNURUQnLFxufVxuXG4vKipcbiAqIFRyaWdnZXJlZCBieSBbW1Nlc3Npb25FdmVudE1hcC5leGNlcHRpb25dXVxuICovXG5leHBvcnQgY2xhc3MgRXhjZXB0aW9uRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogTmFtZSBvZiB0aGUgZXhjZXB0aW9uXG4gICAgICovXG4gICAgbmFtZTogRXhjZXB0aW9uRXZlbnROYW1lO1xuXG4gICAgLyoqXG4gICAgICogT2JqZWN0IGFmZmVjdGVkIGJ5IHRoZSBleGNlcHRpb24uIERlcGVuZGluZyBvbiB0aGUgW1tFeGNlcHRpb25FdmVudC5uYW1lXV0gcHJvcGVydHk6XG4gICAgICogLSBbW1Nlc3Npb25dXTogYElDRV9DQU5ESURBVEVfRVJST1JgXG4gICAgICogLSBbW1N0cmVhbV1dOiBgSUNFX0NPTk5FQ1RJT05fRkFJTEVEYCwgYElDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRGBcbiAgICAgKiAtIFtbU3Vic2NyaWJlcl1dOiBgTk9fU1RSRUFNX1BMQVlJTkdfRVZFTlRgXG4gICAgICovXG4gICAgb3JpZ2luOiBTZXNzaW9uIHwgU3RyZWFtIHwgU3Vic2NyaWJlcjtcblxuICAgIC8qKlxuICAgICAqIEluZm9ybWF0aXZlIGRlc2NyaXB0aW9uIG9mIHRoZSBleGNlcHRpb25cbiAgICAgKi9cbiAgICBtZXNzYWdlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBBbnkgZXh0cmEgaW5mb3JtYXRpb24gYXNzb2NpYXRlZCB0byB0aGUgZXhjZXB0aW9uXG4gICAgICovXG4gICAgZGF0YT86IGFueTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzZXNzaW9uOiBTZXNzaW9uLCBuYW1lOiBFeGNlcHRpb25FdmVudE5hbWUsIG9yaWdpbjogU2Vzc2lvbiB8IFN0cmVhbSB8IFN1YnNjcmliZXIsIG1lc3NhZ2U6IHN0cmluZywgZGF0YT86IGFueSkge1xuICAgICAgICBzdXBlcihmYWxzZSwgc2Vzc2lvbiwgJ2V4Y2VwdGlvbicpO1xuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB0aGlzLm9yaWdpbiA9IG9yaWdpbjtcbiAgICAgICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9GaWx0ZXInO1xuXG4vKipcbiAqIERlZmluZXMgZXZlcnkgZXZlbnQgZGlzcGF0Y2hlZCBieSBhdWRpby92aWRlbyBzdHJlYW0gZmlsdGVycy4gWW91IGNhbiBzdWJzY3JpYmUgdG8gZmlsdGVyIGV2ZW50cyBieSBjYWxsaW5nIFtbRmlsdGVyLmFkZEV2ZW50TGlzdGVuZXJdXVxuICovXG5leHBvcnQgY2xhc3MgRmlsdGVyRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogRGF0YSBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICBkYXRhOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBGaWx0ZXIsIGV2ZW50VHlwZTogc3RyaW5nLCBkYXRhOiBPYmplY3QpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgZXZlbnRUeXBlKTtcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHt9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnkgW1tuZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZF1dXG4gKi9cbmV4cG9ydCBjbGFzcyBOZXR3b3JrUXVhbGl0eUxldmVsQ2hhbmdlZEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIE5ldyB2YWx1ZSBvZiB0aGUgbmV0d29yayBxdWFsaXR5IGxldmVsXG4gICAgICovXG4gICAgbmV3VmFsdWU6IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIE9sZCB2YWx1ZSBvZiB0aGUgbmV0d29yayBxdWFsaXR5IGxldmVsXG4gICAgICovXG4gICAgb2xkVmFsdWU6IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIENvbm5lY3Rpb24gZm9yIHdob20gdGhlIG5ldHdvcmsgcXVhbGl0eSBsZXZlbCBjaGFuZ2VkXG4gICAgICovXG4gICAgY29ubmVjdGlvbjogQ29ubmVjdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIG5ld1ZhbHVlOiBudW1iZXIsIG9sZFZhbHVlOiBudW1iZXIsIGNvbm5lY3Rpb246IENvbm5lY3Rpb24pIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgJ25ldHdvcmtRdWFsaXR5TGV2ZWxDaGFuZ2VkJyk7XG4gICAgICAgIHRoaXMubmV3VmFsdWUgPSBuZXdWYWx1ZTtcbiAgICAgICAgdGhpcy5vbGRWYWx1ZSA9IG9sZFZhbHVlO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge31cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuXG4vKipcbiAqIFRyaWdnZXJlZCBieTpcbiAqIC0gYHB1Ymxpc2hlclN0YXJ0U3BlYWtpbmdgIChhdmFpbGFibGUgZm9yIFtTZXNzaW9uXSgvZW4vc3RhYmxlL2FwaS9vcGVudmlkdS1icm93c2VyL2ludGVyZmFjZXMvU2Vzc2lvbkV2ZW50TWFwLmh0bWwjcHVibGlzaGVyU3RhcnRTcGVha2luZykgYW5kIFtTdHJlYW1NYW5hZ2VyXSgvZW4vc3RhYmxlL2FwaS9vcGVudmlkdS1icm93c2VyL2ludGVyZmFjZXMvU3RyZWFtTWFuYWdlckV2ZW50TWFwLmh0bWwjcHVibGlzaGVyU3RhcnRTcGVha2luZykgb2JqZWN0cylcbiAqIC0gYHB1Ymxpc2hlclN0b3BTcGVha2luZ2AgKGF2YWlsYWJsZSBmb3IgW1Nlc3Npb25dKC9lbi9zdGFibGUvYXBpL29wZW52aWR1LWJyb3dzZXIvaW50ZXJmYWNlcy9TZXNzaW9uRXZlbnRNYXAuaHRtbCNwdWJsaXNoZXJTdG9wU3BlYWtpbmcpIGFuZCBbU3RyZWFtTWFuYWdlcl0oL2VuL3N0YWJsZS9hcGkvb3BlbnZpZHUtYnJvd3Nlci9pbnRlcmZhY2VzL1N0cmVhbU1hbmFnZXJFdmVudE1hcC5odG1sI3B1Ymxpc2hlclN0b3BTcGVha2luZykgb2JqZWN0cylcbiAqL1xuZXhwb3J0IGNsYXNzIFB1Ymxpc2hlclNwZWFraW5nRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogVGhlIGNsaWVudCB0aGF0IHN0YXJ0ZWQgb3Igc3RvcHBlZCBzcGVha2luZ1xuICAgICAqL1xuICAgIGNvbm5lY3Rpb246IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBUaGUgc3RyZWFtSWQgb2YgdGhlIFN0cmVhbSBhZmZlY3RlZCBieSB0aGUgc3BlYWtpbmcgZXZlbnRcbiAgICAgKi9cbiAgICBzdHJlYW1JZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZywgY29ubmVjdGlvbjogQ29ubmVjdGlvbiwgc3RyZWFtSWQ6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy5zdHJlYW1JZCA9IHN0cmVhbUlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkge31cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuaW1wb3J0IHsgUmVjb3JkaW5nRXZlbnRSZWFzb24gfSBmcm9tICcuL1R5cGVzL1R5cGVzJztcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnk6XG4gKiAtIFtbcmVjb3JkaW5nU3RhcnRlZF1dXG4gKiAtIFtbcmVjb3JkaW5nU3RvcHBlZF1dXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWNvcmRpbmdFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBUaGUgcmVjb3JkaW5nIElEIGdlbmVyYXRlZCBpbiBvcGVudmlkdS1zZXJ2ZXJcbiAgICAgKi9cbiAgICBpZDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlY29yZGluZyBuYW1lIHlvdSBzdXBwbGllZCB0byBvcGVudmlkdS1zZXJ2ZXIuIEZvciBleGFtcGxlLCB0byBuYW1lIHlvdXIgcmVjb3JkaW5nIGZpbGUgTVlfUkVDT1JESU5HOlxuICAgICAqIC0gV2l0aCAqKkFQSSBSRVNUKio6IFBPU1QgdG8gYC9hcGkvcmVjb3JkaW5ncy9zdGFydGAgcGFzc2luZyBKU09OIGJvZHkgYHtcInNlc3Npb25cIjpcInNlc3Npb25JZFwiLFwibmFtZVwiOlwiTVlfUkVDT1JESU5HXCJ9YFxuICAgICAqIC0gV2l0aCAqKm9wZW52aWR1LWphdmEtY2xpZW50Kio6IGBPcGVuVmlkdS5zdGFydFJlY29yZGluZyhzZXNzaW9uSWQsIFwiTVlfUkVDT1JESU5HXCIpYCBvciBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBuZXcgUmVjb3JkaW5nUHJvcGVydGllcy5CdWlsZGVyKCkubmFtZShcIk1ZX1JFQ09SRElOR1wiKS5idWlsZCgpKWBcbiAgICAgKiAtIFdpdGggKipvcGVudmlkdS1ub2RlLWNsaWVudCoqOiBgT3BlblZpZHUuc3RhcnRSZWNvcmRpbmcoc2Vzc2lvbklkLCBcIk1ZX1JFQ09SRElOR1wiKWAgb3IgYE9wZW5WaWR1LnN0YXJ0UmVjb3JkaW5nKHNlc3Npb25JZCwge25hbWU6IFwiTVlfUkVDT1JESU5HXCJ9KWBcbiAgICAgKlxuICAgICAqIElmIG5vIG5hbWUgaXMgc3VwcGxpZWQsIHRoaXMgcHJvcGVydHkgd2lsbCBiZSB1bmRlZmluZWQgYW5kIHRoZSByZWNvcmRlZCBmaWxlIHdpbGwgYmUgbmFtZWQgYWZ0ZXIgcHJvcGVydHkgW1tpZF1dXG4gICAgICovXG4gICAgbmFtZT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEZvciAncmVjb3JkaW5nU3RvcHBlZCcgZXZlbnQ6XG4gICAgICogLSBcInJlY29yZGluZ1N0b3BwZWRCeVNlcnZlclwiOiB0aGUgcmVjb3JkaW5nIGhhcyBiZWVuIGdyYWNlZnVsbHkgc3RvcHBlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwic2Vzc2lvbkNsb3NlZEJ5U2VydmVyXCI6IHRoZSBTZXNzaW9uIGhhcyBiZWVuIGNsb3NlZCBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiYXV0b21hdGljU3RvcFwiOiBzZWUgW0F1dG9tYXRpYyBzdG9wIG9mIHJlY29yZGluZ3NdKC9lbi9zdGFibGUvYWR2YW5jZWQtZmVhdHVyZXMvcmVjb3JkaW5nLyNhdXRvbWF0aWMtc3RvcC1vZi1yZWNvcmRpbmdzKVxuICAgICAqIC0gXCJub2RlQ3Jhc2hlZFwiOiBhIG5vZGUgaGFzIGNyYXNoZWQgaW4gdGhlIHNlcnZlciBzaWRlXG4gICAgICpcbiAgICAgKiBGb3IgJ3JlY29yZGluZ1N0YXJ0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbj86IFJlY29yZGluZ0V2ZW50UmVhc29uO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU2Vzc2lvbiwgdHlwZTogc3RyaW5nLCBpZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIHJlYXNvbj86IFJlY29yZGluZ0V2ZW50UmVhc29uKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLmlkID0gaWQ7XG4gICAgICAgIGlmIChuYW1lICE9PSBpZCkge1xuICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBPcGVuVmlkdUxvZ2dlciB9IGZyb20gJy4uL0xvZ2dlci9PcGVuVmlkdUxvZ2dlcic7XG5pbXBvcnQgeyBDb25uZWN0aW9uRXZlbnRSZWFzb24gfSBmcm9tICcuL1R5cGVzL1R5cGVzJztcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqIFRyaWdnZXJlZCBieSBbW3Nlc3Npb25EaXNjb25uZWN0ZWRdXVxuICovXG5leHBvcnQgY2xhc3MgU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIC0gXCJkaXNjb25uZWN0XCI6IHlvdSBoYXZlIGNhbGxlZCBgU2Vzc2lvbi5kaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiB5b3UgaGF2ZSBiZWVuIGV2aWN0ZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSBvdGhlciB1c2VyIGNhbGxpbmcgYFNlc3Npb24uZm9yY2VEaXNjb25uZWN0KClgXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5U2VydmVyXCI6IHlvdSBoYXZlIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB5b3VyIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZC4gQmVmb3JlIGEgU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50IHdpdGggdGhpcyByZWFzb24gaXMgdHJpZ2dlcmVkLFxuICAgICAqICAgICAgU2Vzc2lvbiBvYmplY3Qgd2lsbCBhbHdheXMgaGF2ZSBwcmV2aW91c2x5IGRpc3BhdGNoZWQgYSBgcmVjb25uZWN0aW5nYCBldmVudC4gSWYgdGhlIHJlY29ubmVjdGlvbiBwcm9jZXNzIHN1Y2NlZWRzLFxuICAgICAqICAgICAgU2Vzc2lvbiBvYmplY3Qgd2lsbCBkaXNwYXRjaCBhIGByZWNvbm5lY3RlZGAgZXZlbnQuIElmIGl0IGZhaWxzLCBTZXNzaW9uIG9iamVjdCB3aWxsIGRpc3BhdGNoIGEgU2Vzc2lvbkRpc2Nvbm5lY3RlZEV2ZW50XG4gICAgICogICAgICB3aXRoIHJlYXNvbiBcIm5ldHdvcmtEaXNjb25uZWN0XCJcbiAgICAgKiAtIFwibm9kZUNyYXNoZWRcIjogYSBub2RlIGhhcyBjcmFzaGVkIGluIHRoZSBzZXJ2ZXIgc2lkZS4gWW91IGNhbiB1c2UgdGhpcyByZWFzb24gdG8gYXNrIHlvdXIgYXBwbGljYXRpb24ncyBiYWNrZW5kIHRvIHJlY29ubmVjdFxuICAgICAqIHRvIGEgbmV3IHNlc3Npb24gdG8gcmVwbGFjZSB0aGUgY3Jhc2hlZCBvbmVcbiAgICAgKi9cbiAgICByZWFzb246IENvbm5lY3Rpb25FdmVudFJlYXNvbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0YXJnZXQ6IFNlc3Npb24sIHJlYXNvbjogQ29ubmVjdGlvbkV2ZW50UmVhc29uKSB7XG4gICAgICAgIHN1cGVyKHRydWUsIHRhcmdldCwgJ3Nlc3Npb25EaXNjb25uZWN0ZWQnKTtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKFwiQ2FsbGluZyBkZWZhdWx0IGJlaGF2aW9yIHVwb24gJ1wiICsgdGhpcy50eXBlICsgXCInIGV2ZW50IGRpc3BhdGNoZWQgYnkgJ1Nlc3Npb24nXCIpO1xuXG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSA8U2Vzc2lvbj50aGlzLnRhcmdldDtcblxuICAgICAgICAvLyBEaXNwb3NlIGFuZCBkZWxldGUgYWxsIHJlbW90ZSBDb25uZWN0aW9uc1xuICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zLmZvckVhY2goKHJlbW90ZUNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb25JZCA9IHJlbW90ZUNvbm5lY3Rpb24uY29ubmVjdGlvbklkO1xuICAgICAgICAgICAgaWYgKCEhc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9ucy5nZXQoY29ubmVjdGlvbklkKT8uc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9ucy5nZXQoY29ubmVjdGlvbklkKT8uc3RyZWFtIS5kaXNwb3NlV2ViUnRjUGVlcigpO1xuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMuZ2V0KGNvbm5lY3Rpb25JZCk/LnN0cmVhbSEuZGlzcG9zZU1lZGlhU3RyZWFtKCk7XG4gICAgICAgICAgICAgICAgaWYgKHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMuZ2V0KGNvbm5lY3Rpb25JZCk/LnN0cmVhbSEuc3RyZWFtTWFuYWdlcikge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZUNvbm5lY3Rpb25zLmdldChjb25uZWN0aW9uSWQpPy5zdHJlYW0hLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbUlkID0gc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9ucy5nZXQoY29ubmVjdGlvbklkKT8uc3RyZWFtPy5zdHJlYW1JZDtcbiAgICAgICAgICAgICAgICBpZiAoISFzdHJlYW1JZCkge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkLmRlbGV0ZShzdHJlYW1JZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMuZ2V0KGNvbm5lY3Rpb25JZCk/LmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlc3Npb24ucmVtb3RlQ29ubmVjdGlvbnMuZGVsZXRlKGNvbm5lY3Rpb25JZCk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTctMjAyMiBPcGVuVmlkdSAoaHR0cHM6Ly9vcGVudmlkdS5pbylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQgeyBFdmVudCB9IGZyb20gJy4vRXZlbnQnO1xuaW1wb3J0IHsgQ29ubmVjdGlvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L0Nvbm5lY3Rpb24nO1xuaW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1Nlc3Npb24nO1xuXG4vKipcbiAqIFRyaWdnZXJlZCBieSBbW1Nlc3Npb25FdmVudE1hcC5zaWduYWxdXVxuICovXG5leHBvcnQgY2xhc3MgU2lnbmFsRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2Ygc2lnbmFsLiBJdCBpcyBzdHJpbmcgYFwic2lnbmFsXCJgIGZvciB0aG9zZSBzaWduYWxzIHNlbnQgd2l0aCBubyBbW1NpZ25hbE9wdGlvbnMudHlwZV1dIHByb3BlcnR5LCBhbmQgYFwic2lnbmFsOnR5cGVcImAgaWYgd2FzIHNlbnQgd2l0aCBhXG4gICAgICogdmFsaWQgW1tTaWduYWxPcHRpb25zLnR5cGVdXSBwcm9wZXJ0eS5cbiAgICAgKlxuICAgICAqIFRoZSBjbGllbnQgbXVzdCBiZSBzcGVjaWZpY2FsbHkgc3Vic2NyaWJlZCB0byBgU2Vzc2lvbi5vbignc2lnbmFsOnR5cGUnLCBmdW5jdGlvbihzaWduYWxFdmVudCkgey4uLn0pYCB0byB0cmlnZ2VyIHRoYXQgdHlwZSBvZiBzaWduYWwuXG4gICAgICpcbiAgICAgKiBTdWJzY3JpYmluZyB0byBgU2Vzc2lvbi5vbignc2lnbmFsJywgZnVuY3Rpb24oc2lnbmFsRXZlbnQpIHsuLi59KWAgd2lsbCB0cmlnZ2VyIGFsbCBzaWduYWxzLCBubyBtYXR0ZXIgdGhlaXIgdHlwZS5cbiAgICAgKi9cbiAgICB0eXBlOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgbWVzc2FnZSBvZiB0aGUgc2lnbmFsIChjYW4gYmUgZW1wdHkpXG4gICAgICovXG4gICAgZGF0YT86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFRoZSBjbGllbnQgdGhhdCBzZW50IHRoZSBzaWduYWwuIFRoaXMgcHJvcGVydHkgaXMgdW5kZWZpbmVkIGlmIHRoZSBzaWduYWxcbiAgICAgKiB3YXMgZGlyZWN0bHkgZ2VuZXJhdGVkIGJ5IHRoZSBhcHBsaWNhdGlvbiBzZXJ2ZXIgKG5vdCBieSBvdGhlciBjbGllbnQpXG4gICAgICovXG4gICAgZnJvbT86IENvbm5lY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCB0eXBlPzogc3RyaW5nLCBkYXRhPzogc3RyaW5nLCBmcm9tPzogQ29ubmVjdGlvbikge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCAnc2lnbmFsJyk7XG4gICAgICAgIGlmICghIXR5cGUpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9ICdzaWduYWw6JyArIHR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHt9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IENvbm5lY3Rpb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9Db25uZWN0aW9uJztcbmltcG9ydCB7IFNlc3Npb24gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TZXNzaW9uJztcbmltcG9ydCB7IFNwZWVjaFRvVGV4dEV2ZW50UmVhc29uIH0gZnJvbSAnLi9UeXBlcy9UeXBlcyc7XG5cbi8qKlxuICogVHJpZ2dlcmVkIGJ5IFtbU2Vzc2lvbkV2ZW50TWFwLnNwZWVjaFRvVGV4dE1lc3NhZ2VdXVxuICovXG5leHBvcnQgY2xhc3MgU3BlZWNoVG9UZXh0RXZlbnQgZXh0ZW5kcyBFdmVudCB7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgW1tDb25uZWN0aW9uXV0gb3duaW5nIHRoZSBTdHJlYW0gdGhhdCBwcm9kdWNlZCB0aGUgc3BlZWNoLXRvLXRleHQgZXZlbnQuXG4gICAgICogSW4gb3RoZXIgd29yZHMsIHRoaXMgaXMgdGhlIHBhcnRpY2lwYW50IHRoYXQgc3Bva2UgYW5kIHByb2R1Y2VkIHRoaXMgdHJhbnNjcmlwdGlvbiBldmVudC5cbiAgICAgKi9cbiAgICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHRleHQgb2YgdGhlIGV2ZW50LiBUaGlzIGlzIHRoZSB0cmFuc2NyaXB0aW9uIGZvciB0aGlzIHNwZWNpZmljIHBpZWNlIG9mIGF1ZGlvIHN0cmVhbVxuICAgICAqL1xuICAgIHRleHQ6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEFsbCBzcGVlY2gtdG8tdGV4dCBldmVudHMgYXJlIGdlbmVyYXRlZCBcbiAgICAgKi9cbiAgICByZWFzb246IFNwZWVjaFRvVGV4dEV2ZW50UmVhc29uO1xuXG4gICAgLyoqXG4gICAgICogVGhlIG9yaWdpbmFsIGV2ZW50IGZyb20gdGhlIHNwZWVjaCB0byB0ZXh0IGVuZ2luZS4gVGhpcyBjYW4gdmFyeSBkZXBlbmRpbmcgb24gdGhlIGVuZ2luZVxuICAgICAqL1xuICAgIHJhdzogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogW0JDUC00N10oaHR0cHM6Ly90b29scy5pZXRmLm9yZy9odG1sL2JjcDQ3KSBsYW5ndWFnZSB0YWcgKGxpa2UgXCJlbi1VU1wiIG9yIFwiZXMtRVNcIikgb2YgdGhlIHJlY29nbml6ZWQgdGV4dC4gVGhpcyB3aWxsIGJlIHRoZSBzYW1lIGFzIHRoZSBsYW5ndWFnZSBwcm92aWRlZFxuICAgICAqIGluIG1ldGhvZCBbW1Nlc3Npb24uc3Vic2NyaWJlVG9TcGVlY2hUb1RleHRdXSBtZXRob2RcbiAgICAgKi9cbiAgICBsYW5nOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodGFyZ2V0OiBTZXNzaW9uLCBjb25uZWN0aW9uOiBDb25uZWN0aW9uLCB0ZXh0OiBzdHJpbmcsIHJlYXNvbjogU3BlZWNoVG9UZXh0RXZlbnRSZWFzb24sIHJhdzogc3RyaW5nLCBsYW5nOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgJ3NwZWVjaFRvVGV4dE1lc3NhZ2UnKTtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgICAgICAgdGhpcy50ZXh0ID0gdGV4dDtcbiAgICAgICAgdGhpcy5yZWFzb24gPSByZWFzb247XG4gICAgICAgIHRoaXMucmF3ID0gcmF3O1xuICAgICAgICB0aGlzLmxhbmcgPSBsYW5nO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tZW1wdHlcbiAgICBjYWxsRGVmYXVsdEJlaGF2aW9yKCkgeyB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHsgRXZlbnQgfSBmcm9tICcuL0V2ZW50JztcbmltcG9ydCB7IFB1Ymxpc2hlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1B1Ymxpc2hlcic7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgT3BlblZpZHVMb2dnZXIgfSBmcm9tICcuLi9Mb2dnZXIvT3BlblZpZHVMb2dnZXInO1xuaW1wb3J0IHsgU3RyZWFtRXZlbnRSZWFzb24gfSBmcm9tICcuL1R5cGVzL1R5cGVzJztcblxuLyoqXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IGxvZ2dlcjogT3BlblZpZHVMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqIFRyaWdnZXJlZCBieTpcbiAqIC0gYHN0cmVhbUNyZWF0ZWRgIChhdmFpbGFibGUgZm9yIFtTZXNzaW9uXSgvZW4vc3RhYmxlL2FwaS9vcGVudmlkdS1icm93c2VyL2ludGVyZmFjZXMvU2Vzc2lvbkV2ZW50TWFwLmh0bWwjc3RyZWFtQ3JlYXRlZCkgYW5kIFtQdWJsaXNoZXJdKC9lbi9zdGFibGUvYXBpL29wZW52aWR1LWJyb3dzZXIvaW50ZXJmYWNlcy9QdWJsaXNoZXJFdmVudE1hcC5odG1sI3N0cmVhbUNyZWF0ZWQpIG9iamVjdHMpXG4gKiAtIGBzdHJlYW1EZXN0cm95ZWRgIChhdmFpbGFibGUgZm9yIFtTZXNzaW9uXSgvZW4vc3RhYmxlL2FwaS9vcGVudmlkdS1icm93c2VyL2ludGVyZmFjZXMvU2Vzc2lvbkV2ZW50TWFwLmh0bWwjc3RyZWFtRGVzdHJveWVkKSBhbmQgW1B1Ymxpc2hlcl0oL2VuL3N0YWJsZS9hcGkvb3BlbnZpZHUtYnJvd3Nlci9pbnRlcmZhY2VzL1B1Ymxpc2hlckV2ZW50TWFwLmh0bWwjc3RyZWFtRGVzdHJveWVkKSBvYmplY3RzKVxuICovXG5leHBvcnQgY2xhc3MgU3RyZWFtRXZlbnQgZXh0ZW5kcyBFdmVudCB7XG4gICAgLyoqXG4gICAgICogU3RyZWFtIG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIG9yIGRlc3Ryb3llZFxuICAgICAqL1xuICAgIHN0cmVhbTogU3RyZWFtO1xuXG4gICAgLyoqXG4gICAgICogRm9yICdzdHJlYW1EZXN0cm95ZWQnIGV2ZW50OlxuICAgICAqIC0gXCJ1bnB1Ymxpc2hcIjogbWV0aG9kIGBTZXNzaW9uLnVucHVibGlzaCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZGlzY29ubmVjdFwiOiBtZXRob2QgYFNlc3Npb24uZGlzY29ubmVjdCgpYCBoYXMgYmVlbiBjYWxsZWRcbiAgICAgKiAtIFwiZm9yY2VVbnB1Ymxpc2hCeVVzZXJcIjogc29tZSB1c2VyIGhhcyBjYWxsZWQgYFNlc3Npb24uZm9yY2VVbnB1Ymxpc2goKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlRGlzY29ubmVjdEJ5VXNlclwiOiBzb21lIHVzZXIgaGFzIGNhbGxlZCBgU2Vzc2lvbi5mb3JjZURpc2Nvbm5lY3QoKWAgb3ZlciB0aGUgU3RyZWFtXG4gICAgICogLSBcImZvcmNlVW5wdWJsaXNoQnlTZXJ2ZXJcIjogdGhlIHVzZXIncyBzdHJlYW0gaGFzIGJlZW4gdW5wdWJsaXNoZWQgZnJvbSB0aGUgU2Vzc2lvbiBieSB0aGUgYXBwbGljYXRpb25cbiAgICAgKiAtIFwiZm9yY2VEaXNjb25uZWN0QnlTZXJ2ZXJcIjogdGhlIHVzZXIgaGFzIGJlZW4gZXZpY3RlZCBmcm9tIHRoZSBTZXNzaW9uIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJzZXNzaW9uQ2xvc2VkQnlTZXJ2ZXJcIjogdGhlIFNlc3Npb24gaGFzIGJlZW4gY2xvc2VkIGJ5IHRoZSBhcHBsaWNhdGlvblxuICAgICAqIC0gXCJuZXR3b3JrRGlzY29ubmVjdFwiOiB0aGUgdXNlcidzIG5ldHdvcmsgY29ubmVjdGlvbiBoYXMgZHJvcHBlZFxuICAgICAqIC0gXCJub2RlQ3Jhc2hlZFwiOiBhIG5vZGUgaGFzIGNyYXNoZWQgaW4gdGhlIHNlcnZlciBzaWRlXG4gICAgICpcbiAgICAgKiBGb3IgJ3N0cmVhbUNyZWF0ZWQnIGVtcHR5IHN0cmluZ1xuICAgICAqL1xuICAgIHJlYXNvbjogU3RyZWFtRXZlbnRSZWFzb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY2FuY2VsYWJsZTogYm9vbGVhbiwgdGFyZ2V0OiBTZXNzaW9uIHwgUHVibGlzaGVyLCB0eXBlOiBzdHJpbmcsIHN0cmVhbTogU3RyZWFtLCByZWFzb246IFN0cmVhbUV2ZW50UmVhc29uKSB7XG4gICAgICAgIHN1cGVyKGNhbmNlbGFibGUsIHRhcmdldCwgdHlwZSk7XG4gICAgICAgIHRoaXMuc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ3N0cmVhbURlc3Ryb3llZCcpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRhcmdldCBpbnN0YW5jZW9mIFNlc3Npb24pIHtcbiAgICAgICAgICAgICAgICAvLyBSZW1vdGUgU3RyZWFtXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oXCJDYWxsaW5nIGRlZmF1bHQgYmVoYXZpb3IgdXBvbiAnXCIgKyB0aGlzLnR5cGUgKyBcIicgZXZlbnQgZGlzcGF0Y2hlZCBieSAnU2Vzc2lvbidcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uZGlzcG9zZVdlYlJ0Y1BlZXIoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy50YXJnZXQgaW5zdGFuY2VvZiBQdWJsaXNoZXIpIHtcbiAgICAgICAgICAgICAgICAvLyBMb2NhbCBTdHJlYW1cbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhcIkNhbGxpbmcgZGVmYXVsdCBiZWhhdmlvciB1cG9uICdcIiArIHRoaXMudHlwZSArIFwiJyBldmVudCBkaXNwYXRjaGVkIGJ5ICdQdWJsaXNoZXInXCIpO1xuICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLnNjcmVlblNoYXJlUmVzaXplSW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLmlzTG9jYWxTdHJlYW1SZWFkeVRvUHVibGlzaCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgLy8gRGVsZXRlIFB1Ymxpc2hlciBvYmplY3QgZnJvbSBPcGVuVmlkdSBwdWJsaXNoZXJzIGFycmF5XG4gICAgICAgICAgICAgICAgY29uc3Qgb3BlbnZpZHVQdWJsaXNoZXJzID0gKDxQdWJsaXNoZXI+dGhpcy50YXJnZXQpLm9wZW52aWR1LnB1Ymxpc2hlcnM7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcGVudmlkdVB1Ymxpc2hlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW52aWR1UHVibGlzaGVyc1tpXSA9PT0gPFB1Ymxpc2hlcj50aGlzLnRhcmdldCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3BlbnZpZHVQdWJsaXNoZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBEaXNwb3NlIHRoZSBNZWRpYVN0cmVhbSBsb2NhbCBvYmplY3RcbiAgICAgICAgICAgIHRoaXMuc3RyZWFtLmRpc3Bvc2VNZWRpYVN0cmVhbSgpO1xuXG4gICAgICAgICAgICAvLyBSZW1vdmUgZnJvbSBET00gYWxsIHZpZGVvIGVsZW1lbnRzIGFzc29jaWF0ZWQgdG8gdGhpcyBTdHJlYW0sIGlmIHRoZXJlJ3MgYSBTdHJlYW1NYW5hZ2VyIGRlZmluZWRcbiAgICAgICAgICAgIC8vIChtZXRob2QgU2Vzc2lvbi5zdWJzY3JpYmUgbXVzdCBoYXZlIGJlZW4gY2FsbGVkKVxuICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIpIHRoaXMuc3RyZWFtLnN0cmVhbU1hbmFnZXIucmVtb3ZlQWxsVmlkZW9zKCk7XG5cbiAgICAgICAgICAgIC8vIERlbGV0ZSBzdHJlYW0gZnJvbSBTZXNzaW9uLnJlbW90ZVN0cmVhbXNDcmVhdGVkIG1hcFxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVTdHJlYW1zQ3JlYXRlZC5kZWxldGUodGhpcy5zdHJlYW0uc3RyZWFtSWQpO1xuXG4gICAgICAgICAgICAvLyBEZWxldGUgU3RyZWFtT3B0aW9uc1NlcnZlciBmcm9tIHJlbW90ZSBDb25uZWN0aW9uXG4gICAgICAgICAgICBjb25zdCByZW1vdGVDb25uZWN0aW9uID0gdGhpcy5zdHJlYW0uc2Vzc2lvbi5yZW1vdGVDb25uZWN0aW9ucy5nZXQodGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWQpO1xuICAgICAgICAgICAgaWYgKCEhcmVtb3RlQ29ubmVjdGlvbiAmJiAhIXJlbW90ZUNvbm5lY3Rpb24ucmVtb3RlT3B0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0cmVhbU9wdGlvbnNTZXJ2ZXIgPSByZW1vdGVDb25uZWN0aW9uLnJlbW90ZU9wdGlvbnMuc3RyZWFtcztcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gc3RyZWFtT3B0aW9uc1NlcnZlci5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RyZWFtT3B0aW9uc1NlcnZlcltpXS5pZCA9PT0gdGhpcy5zdHJlYW0uc3RyZWFtSWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmVhbU9wdGlvbnNTZXJ2ZXIuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cbi8qKlxuICogVHJpZ2dlcmVkIGJ5OlxuICogLSBbW3N0cmVhbVBsYXlpbmddXVxuICogLSBbW3N0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlXV1cbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbU1hbmFnZXJFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBGb3IgYHN0cmVhbUF1ZGlvVm9sdW1lQ2hhbmdlYCBldmVudDpcbiAgICAgKiAtIGB7bmV3VmFsdWU6IG51bWJlciwgb2xkVmFsdWU6IG51bWJlcn1gOiBuZXcgYW5kIG9sZCBhdWRpbyB2b2x1bWUgdmFsdWVzLiBUaGVzZSB2YWx1ZXMgYXJlIGJldHdlZW4gLTEwMCAoc2lsZW5jZSkgYW5kIDAgKGxvdWRlc3QgcG9zc2libGUgdm9sdW1lKS5cbiAgICAgKiBUaGV5IGFyZSBub3QgZXhhY3QgYW5kIGRlcGVuZCBvbiBob3cgdGhlIGJyb3dzZXIgaXMgbWFuYWdpbmcgdGhlIGF1ZGlvIHRyYWNrLCBidXQgLTEwMCBhbmQgMCBjYW4gYmUgdGFrZW4gYXMgbGltaXQgdmFsdWVzLlxuICAgICAqXG4gICAgICogRm9yIGBzdHJlYW1QbGF5aW5nYCBldmVudCB1bmRlZmluZWRcbiAgICAgKi9cbiAgICB2YWx1ZTogT2JqZWN0IHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRhcmdldDogU3RyZWFtTWFuYWdlciwgdHlwZTogc3RyaW5nLCB2YWx1ZTogT2JqZWN0IHwgdW5kZWZpbmVkKSB7XG4gICAgICAgIHN1cGVyKGZhbHNlLCB0YXJnZXQsIHR5cGUpO1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1lbXB0eVxuICAgIGNhbGxEZWZhdWx0QmVoYXZpb3IoKSB7fVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU2Vzc2lvbic7XG5pbXBvcnQgeyBTdHJlYW0gfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9TdHJlYW0nO1xuaW1wb3J0IHsgU3RyZWFtTWFuYWdlciB9IGZyb20gJy4uLy4uL09wZW5WaWR1L1N0cmVhbU1hbmFnZXInO1xuaW1wb3J0IHsgU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRSZWFzb24sIENoYW5nZWRQcm9wZXJ0eVR5cGUgfSBmcm9tICcuL1R5cGVzL1R5cGVzJztcblxuLyoqXG4gKiBUcmlnZ2VyZWQgYnkgYHN0cmVhbVByb3BlcnR5Q2hhbmdlZGAgKGF2YWlsYWJsZSBmb3IgW1Nlc3Npb25dKC9lbi9zdGFibGUvYXBpL29wZW52aWR1LWJyb3dzZXIvaW50ZXJmYWNlcy9TZXNzaW9uRXZlbnRNYXAuaHRtbCNzdHJlYW1Qcm9wZXJ0eUNoYW5nZWQpIGFuZCBbU3RyZWFtTWFuYWdlcl0oL2VuL3N0YWJsZS9hcGkvb3BlbnZpZHUtYnJvd3Nlci9pbnRlcmZhY2VzL1N0cmVhbU1hbmFnZXJFdmVudE1hcC5odG1sI3N0cmVhbVByb3BlcnR5Q2hhbmdlZCkgb2JqZWN0cylcbiAqL1xuZXhwb3J0IGNsYXNzIFN0cmVhbVByb3BlcnR5Q2hhbmdlZEV2ZW50IGV4dGVuZHMgRXZlbnQge1xuICAgIC8qKlxuICAgICAqIFRoZSBTdHJlYW0gd2hvc2UgcHJvcGVydHkgaGFzIGNoYW5nZWQuIFlvdSBjYW4gYWx3YXlzIGlkZW50aWZ5IHRoZSB1c2VyIHB1Ymxpc2hpbmcgdGhlIGNoYW5nZWQgc3RyZWFtIGJ5IGNvbnN1bHRpbmcgcHJvcGVydHkgW1tTdHJlYW0uY29ubmVjdGlvbl1dXG4gICAgICovXG4gICAgc3RyZWFtOiBTdHJlYW07XG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvcGVydHkgb2YgdGhlIHN0cmVhbSB0aGF0IGNoYW5nZWQuIFRoaXMgdmFsdWUgaXMgZWl0aGVyIGBcInZpZGVvQWN0aXZlXCJgLCBgXCJhdWRpb0FjdGl2ZVwiYCwgYFwidmlkZW9UcmFja1wiYCwgYFwiYXVkaW9UcmFja1wiYCwgYFwidmlkZW9EaW1lbnNpb25zXCJgIG9yIGBcImZpbHRlclwiYFxuICAgICAqL1xuICAgIGNoYW5nZWRQcm9wZXJ0eTogQ2hhbmdlZFByb3BlcnR5VHlwZTtcblxuICAgIC8qKlxuICAgICAqIENhdXNlIG9mIHRoZSBjaGFuZ2Ugb24gdGhlIHN0cmVhbSdzIHByb3BlcnR5OlxuICAgICAqIC0gRm9yIGB2aWRlb0FjdGl2ZWA6IGBcInB1Ymxpc2hWaWRlb1wiYFxuICAgICAqIC0gRm9yIGBhdWRpb0FjdGl2ZWA6IGBcInB1Ymxpc2hBdWRpb1wiYFxuICAgICAqIC0gRm9yIGB2aWRlb1RyYWNrYDogYFwidHJhY2tSZXBsYWNlZFwiYFxuICAgICAqIC0gRm9yIGBhdWRpb1RyYWNrYDogYFwidHJhY2tSZXBsYWNlZFwiYFxuICAgICAqIC0gRm9yIGB2aWRlb0RpbWVuc2lvbnNgOiBgXCJkZXZpY2VSb3RhdGVkXCJgLCBgXCJzY3JlZW5SZXNpemVkXCJgIG9yIGBcInRyYWNrUmVwbGFjZWRcImBcbiAgICAgKiAtIEZvciBgZmlsdGVyYDogYFwiYXBwbHlGaWx0ZXJcImAsIGBcImV4ZWNGaWx0ZXJNZXRob2RcImAgb3IgYFwicmVtb3ZlRmlsdGVyXCJgXG4gICAgICovXG4gICAgcmVhc29uOiBTdHJlYW1Qcm9wZXJ0eUNoYW5nZWRFdmVudFJlYXNvbjtcblxuICAgIC8qKlxuICAgICAqIE5ldyB2YWx1ZSBvZiB0aGUgcHJvcGVydHkgKGFmdGVyIGNoYW5nZSwgY3VycmVudCB2YWx1ZSlcbiAgICAgKi9cbiAgICBuZXdWYWx1ZTogT2JqZWN0O1xuXG4gICAgLyoqXG4gICAgICogUHJldmlvdXMgdmFsdWUgb2YgdGhlIHByb3BlcnR5IChiZWZvcmUgY2hhbmdlKVxuICAgICAqL1xuICAgIG9sZFZhbHVlOiBPYmplY3Q7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHRhcmdldDogU2Vzc2lvbiB8IFN0cmVhbU1hbmFnZXIsXG4gICAgICAgIHN0cmVhbTogU3RyZWFtLFxuICAgICAgICBjaGFuZ2VkUHJvcGVydHk6IENoYW5nZWRQcm9wZXJ0eVR5cGUsXG4gICAgICAgIG5ld1ZhbHVlOiBPYmplY3QsXG4gICAgICAgIG9sZFZhbHVlOiBPYmplY3QsXG4gICAgICAgIHJlYXNvbjogU3RyZWFtUHJvcGVydHlDaGFuZ2VkRXZlbnRSZWFzb25cbiAgICApIHtcbiAgICAgICAgc3VwZXIoZmFsc2UsIHRhcmdldCwgJ3N0cmVhbVByb3BlcnR5Q2hhbmdlZCcpO1xuICAgICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgdGhpcy5jaGFuZ2VkUHJvcGVydHkgPSBjaGFuZ2VkUHJvcGVydHk7XG4gICAgICAgIHRoaXMubmV3VmFsdWUgPSBuZXdWYWx1ZTtcbiAgICAgICAgdGhpcy5vbGRWYWx1ZSA9IG9sZFZhbHVlO1xuICAgICAgICB0aGlzLnJlYXNvbiA9IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHsgfVxufVxuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNy0yMDIyIE9wZW5WaWR1IChodHRwczovL29wZW52aWR1LmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7IEV2ZW50IH0gZnJvbSAnLi9FdmVudCc7XG5pbXBvcnQgeyBTdHJlYW1NYW5hZ2VyIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtTWFuYWdlcic7XG5cbi8qKlxuICogVHJpZ2dlcmVkIGJ5OlxuICogLSBbW3ZpZGVvRWxlbWVudENyZWF0ZWRdXVxuICogLSBbW3ZpZGVvRWxlbWVudERlc3Ryb3llZF1dXG4gKi9cbmV4cG9ydCBjbGFzcyBWaWRlb0VsZW1lbnRFdmVudCBleHRlbmRzIEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBWaWRlbyBlbGVtZW50IHRoYXQgd2FzIGNyZWF0ZWQgb3IgZGVzdHJveWVkXG4gICAgICovXG4gICAgZWxlbWVudDogSFRNTFZpZGVvRWxlbWVudDtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50OiBIVE1MVmlkZW9FbGVtZW50LCB0YXJnZXQ6IFN0cmVhbU1hbmFnZXIsIHR5cGU6IHN0cmluZykge1xuICAgICAgICBzdXBlcihmYWxzZSwgdGFyZ2V0LCB0eXBlKTtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWVtcHR5XG4gICAgY2FsbERlZmF1bHRCZWhhdmlvcigpIHt9XG59XG4iLCJmdW5jdGlvbiBNYXBwZXIoKSB7XG4gICAgdmFyIHNvdXJjZXMgPSB7fTtcblxuICAgIHRoaXMuZm9yRWFjaCA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gc291cmNlcykge1xuICAgICAgICAgICAgdmFyIHNvdXJjZSA9IHNvdXJjZXNba2V5XTtcblxuICAgICAgICAgICAgZm9yICh2YXIga2V5MiBpbiBzb3VyY2UpIGNhbGxiYWNrKHNvdXJjZVtrZXkyXSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgdGhpcy5nZXQgPSBmdW5jdGlvbiAoaWQsIHNvdXJjZSkge1xuICAgICAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgICAgICBpZiAoaWRzID09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgICAgICByZXR1cm4gaWRzW2lkXTtcbiAgICB9O1xuXG4gICAgdGhpcy5yZW1vdmUgPSBmdW5jdGlvbiAoaWQsIHNvdXJjZSkge1xuICAgICAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgICAgICBpZiAoaWRzID09IHVuZGVmaW5lZCkgcmV0dXJuO1xuXG4gICAgICAgIGRlbGV0ZSBpZHNbaWRdO1xuXG4gICAgICAgIC8vIENoZWNrIGl0J3MgZW1wdHlcbiAgICAgICAgZm9yICh2YXIgaSBpbiBpZHMpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlbGV0ZSBzb3VyY2VzW3NvdXJjZV07XG4gICAgfTtcblxuICAgIHRoaXMuc2V0ID0gZnVuY3Rpb24gKHZhbHVlLCBpZCwgc291cmNlKSB7XG4gICAgICAgIGlmICh2YWx1ZSA9PSB1bmRlZmluZWQpIHJldHVybiB0aGlzLnJlbW92ZShpZCwgc291cmNlKTtcblxuICAgICAgICB2YXIgaWRzID0gc291cmNlc1tzb3VyY2VdO1xuICAgICAgICBpZiAoaWRzID09IHVuZGVmaW5lZCkgc291cmNlc1tzb3VyY2VdID0gaWRzID0ge307XG5cbiAgICAgICAgaWRzW2lkXSA9IHZhbHVlO1xuICAgIH07XG59XG5cbk1hcHBlci5wcm90b3R5cGUucG9wID0gZnVuY3Rpb24gKGlkLCBzb3VyY2UpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLmdldChpZCwgc291cmNlKTtcbiAgICBpZiAodmFsdWUgPT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgdGhpcy5yZW1vdmUoaWQsIHNvdXJjZSk7XG5cbiAgICByZXR1cm4gdmFsdWU7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hcHBlcjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgSnNvblJwY0NsaWVudCA9IHJlcXVpcmUoJy4vanNvbnJwY2NsaWVudCcpO1xuXG5leHBvcnRzLkpzb25ScGNDbGllbnQgPSBKc29uUnBjQ2xpZW50O1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxNCBLdXJlbnRvIChodHRwOi8va3VyZW50by5vcmcvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbnZhciBScGNCdWlsZGVyID0gcmVxdWlyZSgnLi4vJyk7XG52YXIgV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiA9IHJlcXVpcmUoJy4vdHJhbnNwb3J0cy93ZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uJyk7XG52YXIgT3BlblZpZHVMb2dnZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9Mb2dnZXIvT3BlblZpZHVMb2dnZXInKS5PcGVuVmlkdUxvZ2dlcjtcblxuRGF0ZS5ub3cgPVxuICAgIERhdGUubm93IHx8XG4gICAgZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gK25ldyBEYXRlKCk7XG4gICAgfTtcblxudmFyIFBJTkdfSU5URVJWQUwgPSA1MDAwO1xuXG52YXIgUkVDT05ORUNUSU5HID0gJ1JFQ09OTkVDVElORyc7XG52YXIgQ09OTkVDVEVEID0gJ0NPTk5FQ1RFRCc7XG52YXIgRElTQ09OTkVDVEVEID0gJ0RJU0NPTk5FQ1RFRCc7XG5cbnZhciBMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG4vKipcbiAqXG4gKiBoZWFydGJlYXQ6IGludGVydmFsIGluIG1zIGZvciBlYWNoIGhlYXJ0YmVhdCBtZXNzYWdlLFxuICogPHByZT5cbiAqIHdzIDoge1xuICogXHR1cmkgOiBVUkkgdG8gY29ubnRlY3QgdG8sXG4gKiBcdG9uY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIGNvbm5lY3Rpb24gaXMgc3VjY2Vzc2Z1bCxcbiAqIFx0b25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QgKG1heCByZXRyaWVzIGZvciByZWNvbm5lY3RpbmcgcmVhY2hlZCksXG4gKiBcdG9ucmVjb25uZWN0aW5nIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgaXMgcmVjb25uZWN0aW5nLFxuICogXHRvbnJlY29ubmVjdGVkIDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjbGllbnQgc3VjY2Vzc2Z1bGx5IHJlY29ubmVjdHMsXG4gKiBcdG9uZXJyb3IgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlcmUgaXMgYW4gZXJyb3JcbiAqIH0sXG4gKiBycGMgOiB7XG4gKiBcdHJlcXVlc3RUaW1lb3V0IDogdGltZW91dCBmb3IgYSByZXF1ZXN0LFxuICogXHRzZXNzaW9uU3RhdHVzQ2hhbmdlZDogY2FsbGJhY2sgbWV0aG9kIGZvciBjaGFuZ2VzIGluIHNlc3Npb24gc3RhdHVzLFxuICogXHRtZWRpYVJlbmVnb3RpYXRpb246IG1lZGlhUmVuZWdvdGlhdGlvblxuICogfVxuICogPC9wcmU+XG4gKi9cbmZ1bmN0aW9uIEpzb25ScGNDbGllbnQoY29uZmlndXJhdGlvbikge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciB3c0NvbmZpZyA9IGNvbmZpZ3VyYXRpb24ud3M7XG5cbiAgICB2YXIgbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbiA9IC0xO1xuXG4gICAgdmFyIHBpbmdOZXh0TnVtID0gMDtcbiAgICB2YXIgZW5hYmxlZFBpbmdzID0gdHJ1ZTtcbiAgICB2YXIgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgdmFyIHBpbmdJbnRlcnZhbDtcblxuICAgIHZhciBzdGF0dXMgPSBESVNDT05ORUNURUQ7XG5cbiAgICB2YXIgb25yZWNvbm5lY3RpbmcgPSB3c0NvbmZpZy5vbnJlY29ubmVjdGluZztcbiAgICB2YXIgb25yZWNvbm5lY3RlZCA9IHdzQ29uZmlnLm9ucmVjb25uZWN0ZWQ7XG4gICAgdmFyIG9uY29ubmVjdGVkID0gd3NDb25maWcub25jb25uZWN0ZWQ7XG4gICAgdmFyIG9uZXJyb3IgPSB3c0NvbmZpZy5vbmVycm9yO1xuXG4gICAgY29uZmlndXJhdGlvbi5ycGMucHVsbCA9IGZ1bmN0aW9uIChwYXJhbXMsIHJlcXVlc3QpIHtcbiAgICAgICAgcmVxdWVzdC5yZXBseShudWxsLCAncHVzaCcpO1xuICAgIH07XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCctLS0tLS0tLS0gT05SRUNPTk5FQ1RJTkcgLS0tLS0tLS0tLS0nKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gUkVDT05ORUNUSU5HKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoJ1dlYnNvY2tldCBhbHJlYWR5IGluIFJFQ09OTkVDVElORyBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTlJFQ09OTkVDVElORyBtZXNzYWdlLiBJZ25vcmluZyBpdCcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RvcFBpbmcoKTtcblxuICAgICAgICBzdGF0dXMgPSBSRUNPTk5FQ1RJTkc7XG4gICAgICAgIGlmIChvbnJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgb25yZWNvbm5lY3RpbmcoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3c0NvbmZpZy5vbnJlY29ubmVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoJy0tLS0tLS0tLSBPTlJFQ09OTkVDVEVEIC0tLS0tLS0tLS0tJyk7XG4gICAgICAgIGlmIChzdGF0dXMgPT09IENPTk5FQ1RFRCkge1xuICAgICAgICAgICAgTG9nZ2VyLmVycm9yKCdXZWJzb2NrZXQgYWxyZWFkeSBpbiBDT05ORUNURUQgc3RhdGUgd2hlbiByZWNlaXZpbmcgYSBuZXcgT05SRUNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdCcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN0YXR1cyA9IENPTk5FQ1RFRDtcblxuICAgICAgICB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCk7XG5cbiAgICAgICAgaWYgKG9ucmVjb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIG9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3c0NvbmZpZy5vbmNvbm5lY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCctLS0tLS0tLS0gT05DT05ORUNURUQgLS0tLS0tLS0tLS0nKTtcbiAgICAgICAgaWYgKHN0YXR1cyA9PT0gQ09OTkVDVEVEKSB7XG4gICAgICAgICAgICBMb2dnZXIuZXJyb3IoJ1dlYnNvY2tldCBhbHJlYWR5IGluIENPTk5FQ1RFRCBzdGF0ZSB3aGVuIHJlY2VpdmluZyBhIG5ldyBPTkNPTk5FQ1RFRCBtZXNzYWdlLiBJZ25vcmluZyBpdCcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHN0YXR1cyA9IENPTk5FQ1RFRDtcblxuICAgICAgICBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgICAgICB1c2VQaW5nKCk7XG5cbiAgICAgICAgaWYgKG9uY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBvbmNvbm5lY3RlZCgpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHdzQ29uZmlnLm9uZXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCctLS0tLS0tLS0gT05FUlJPUiAtLS0tLS0tLS0tLScpO1xuXG4gICAgICAgIHN0YXR1cyA9IERJU0NPTk5FQ1RFRDtcblxuICAgICAgICBzdG9wUGluZygpO1xuXG4gICAgICAgIGlmIChvbmVycm9yKSB7XG4gICAgICAgICAgICBvbmVycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgd3MgPSBuZXcgV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbih3c0NvbmZpZyk7XG5cbiAgICBMb2dnZXIuZGVidWcoJ0Nvbm5lY3Rpbmcgd2Vic29ja2V0IHRvIFVSSTogJyArIHdzQ29uZmlnLnVyaSk7XG5cbiAgICB2YXIgcnBjQnVpbGRlck9wdGlvbnMgPSB7XG4gICAgICAgIHJlcXVlc3RfdGltZW91dDogY29uZmlndXJhdGlvbi5ycGMucmVxdWVzdFRpbWVvdXQsXG4gICAgICAgIHBpbmdfcmVxdWVzdF90aW1lb3V0OiBjb25maWd1cmF0aW9uLnJwYy5oZWFydGJlYXRSZXF1ZXN0VGltZW91dFxuICAgIH07XG5cbiAgICB2YXIgcnBjID0gbmV3IFJwY0J1aWxkZXIoUnBjQnVpbGRlci5wYWNrZXJzLkpzb25SUEMsIHJwY0J1aWxkZXJPcHRpb25zLCB3cywgZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCdSZWNlaXZlZCByZXF1ZXN0OiAnICsgSlNPTi5zdHJpbmdpZnkocmVxdWVzdCkpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YXIgZnVuYyA9IGNvbmZpZ3VyYXRpb24ucnBjW3JlcXVlc3QubWV0aG9kXTtcblxuICAgICAgICAgICAgaWYgKGZ1bmMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignTWV0aG9kICcgKyByZXF1ZXN0Lm1ldGhvZCArICcgbm90IHJlZ2lzdGVyZWQgaW4gY2xpZW50Jyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZ1bmMocmVxdWVzdC5wYXJhbXMsIHJlcXVlc3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcignRXhjZXB0aW9uIHByb2Nlc3NpbmcgcmVxdWVzdDogJyArIEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpKTtcbiAgICAgICAgICAgIExvZ2dlci5lcnJvcihlcnIpO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICB0aGlzLnNlbmQgPSBmdW5jdGlvbiAobWV0aG9kLCBwYXJhbXMsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciByZXF1ZXN0VGltZSA9IERhdGUubm93KCk7XG5cbiAgICAgICAgcnBjLmVuY29kZShtZXRob2QsIHBhcmFtcywgZnVuY3Rpb24gKGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICdFUlJPUjonICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnIGluIFJlcXVlc3Q6IG1ldGhvZDonICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgcGFyYW1zOicgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHBhcmFtcykgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgcmVxdWVzdDonICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvci5yZXF1ZXN0XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvci5kYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZXJyb3IoJ0VSUk9SIERBVEE6JyArIEpTT04uc3RyaW5naWZ5KGVycm9yLmRhdGEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgICAgZXJyb3IucmVxdWVzdFRpbWUgPSByZXF1ZXN0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT0gdW5kZWZpbmVkICYmIHJlc3VsdC52YWx1ZSAhPT0gJ3BvbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUmVzcG9uc2U6ICcgKyBKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiB1cGRhdGVOb3RSZWNvbm5lY3RJZkxlc3NUaGFuKCkge1xuICAgICAgICBMb2dnZXIuZGVidWcoJ25vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gPSAnICsgcGluZ05leHROdW0gKyAnIChvbGQ9JyArIG5vdFJlY29ubmVjdElmTnVtTGVzc1RoYW4gKyAnKScpO1xuICAgICAgICBub3RSZWNvbm5lY3RJZk51bUxlc3NUaGFuID0gcGluZ05leHROdW07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2VuZFBpbmcoKSB7XG4gICAgICAgIGlmIChlbmFibGVkUGluZ3MpIHtcbiAgICAgICAgICAgIHZhciBwYXJhbXMgPSBudWxsO1xuICAgICAgICAgICAgaWYgKHBpbmdOZXh0TnVtID09IDAgfHwgcGluZ05leHROdW0gPT0gbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbikge1xuICAgICAgICAgICAgICAgIHBhcmFtcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWw6IGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0IHx8IFBJTkdfSU5URVJWQUxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcGluZ05leHROdW0rKztcblxuICAgICAgICAgICAgc2VsZi5zZW5kKFxuICAgICAgICAgICAgICAgICdwaW5nJyxcbiAgICAgICAgICAgICAgICBwYXJhbXMsXG4gICAgICAgICAgICAgICAgKGZ1bmN0aW9uIChwaW5nTnVtKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdFcnJvciBpbiBwaW5nIHJlcXVlc3QgIycgKyBwaW5nTnVtICsgJyAoJyArIGVycm9yLm1lc3NhZ2UgKyAnKScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwaW5nTnVtID4gbm90UmVjb25uZWN0SWZOdW1MZXNzVGhhbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlTm90UmVjb25uZWN0SWZMZXNzVGhhbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1NlcnZlciBkaWQgbm90IHJlc3BvbmQgdG8gcGluZyBtZXNzYWdlICMnICsgcGluZ051bSArICcuIFJlY29ubmVjdGluZy4uLiAnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3MucmVjb25uZWN0V3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkocGluZ05leHROdW0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdUcnlpbmcgdG8gc2VuZCBwaW5nLCBidXQgcGluZyBpcyBub3QgZW5hYmxlZCcpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLypcbiAgICAgKiBJZiBjb25maWd1cmF0aW9uLmhlYXJiZWF0IGhhcyBhbnkgdmFsdWUsIHRoZSBwaW5nLXBvbmcgd2lsbCB3b3JrIHdpdGggdGhlIGludGVydmFsXG4gICAgICogb2YgY29uZmlndXJhdGlvbi5oZWFyYmVhdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHVzZVBpbmcoKSB7XG4gICAgICAgIGlmICghcGluZ1BvbmdTdGFydGVkKSB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1N0YXJ0aW5nIHBpbmcgKGlmIGNvbmZpZ3VyZWQpJyk7XG4gICAgICAgICAgICBwaW5nUG9uZ1N0YXJ0ZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoY29uZmlndXJhdGlvbi5oZWFydGJlYXQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcGluZ0ludGVydmFsID0gc2V0SW50ZXJ2YWwoc2VuZFBpbmcsIGNvbmZpZ3VyYXRpb24uaGVhcnRiZWF0KTtcbiAgICAgICAgICAgICAgICBzZW5kUGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RvcFBpbmcoKSB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwocGluZ0ludGVydmFsKTtcbiAgICAgICAgcGluZ1BvbmdTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIGVuYWJsZWRQaW5ncyA9IGZhbHNlO1xuICAgICAgICBwaW5nTmV4dE51bSA9IC0xO1xuICAgICAgICBycGMuY2FuY2VsKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSA9IGZ1bmN0aW9uIChjb2RlLCByZWFzb24pIHtcbiAgICAgICAgTG9nZ2VyLmRlYnVnKCdDbG9zaW5nICB3aXRoIGNvZGU6ICcgKyBjb2RlICsgJyBiZWNhdXNlOiAnICsgcmVhc29uKTtcbiAgICAgICAgaWYgKHBpbmdJbnRlcnZhbCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnQ2xlYXJpbmcgcGluZyBpbnRlcnZhbCcpO1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbChwaW5nSW50ZXJ2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHBpbmdQb25nU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBlbmFibGVkUGluZ3MgPSBmYWxzZTtcbiAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICB9O1xuXG4gICAgdGhpcy5yZWNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdzLnJlY29ubmVjdFdzKCk7XG4gICAgfTtcblxuICAgIHRoaXMucmVzZXRQaW5nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBlbmFibGVkUGluZ3MgPSB0cnVlO1xuICAgICAgICBwaW5nTmV4dE51bSA9IDA7XG4gICAgICAgIHVzZVBpbmcoKTtcbiAgICB9O1xuXG4gICAgdGhpcy5nZXRSZWFkeVN0YXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gd3MuZ2V0UmVhZHlTdGF0ZSgpO1xuICAgIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gSnNvblJwY0NsaWVudDtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbiA9IHJlcXVpcmUoJy4vd2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbicpO1xuXG5leHBvcnRzLldlYlNvY2tldFdpdGhSZWNvbm5lY3Rpb24gPSBXZWJTb2NrZXRXaXRoUmVjb25uZWN0aW9uO1xuIiwiLypcbiAqIChDKSBDb3B5cmlnaHQgMjAxMy0yMDE1IEt1cmVudG8gKGh0dHA6Ly9rdXJlbnRvLm9yZy8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG52YXIgT3BlblZpZHVMb2dnZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9Mb2dnZXIvT3BlblZpZHVMb2dnZXInKS5PcGVuVmlkdUxvZ2dlcjtcbnZhciBMb2dnZXIgPSBPcGVuVmlkdUxvZ2dlci5nZXRJbnN0YW5jZSgpO1xuXG52YXIgTUFYX1JFVFJJRVMgPSAyMDAwOyAvLyBGb3JldmVyLi4uXG52YXIgUkVUUllfVElNRV9NUyA9IDMwMDA7IC8vIEZJWE1FOiBJbXBsZW1lbnQgZXhwb25lbnRpYWwgd2FpdCB0aW1lcy4uLlxuXG52YXIgQ09OTkVDVElORyA9IDA7XG52YXIgT1BFTiA9IDE7XG52YXIgQ0xPU0lORyA9IDI7XG52YXIgQ0xPU0VEID0gMztcblxuLypcbmNvbmZpZyA9IHtcbnVyaSA6IHdzVXJpLFxub25jb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gY29ubmVjdGlvbiBpcyBzdWNjZXNzZnVsLFxub25kaXNjb25uZWN0IDogY2FsbGJhY2sgbWV0aG9kIHRvIGludm9rZSB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGxvc3QgKG1heCByZXRyaWVzIGZvciByZWNvbm5lY3RpbmcgcmVhY2hlZCksXG5vbnJlY29ubmVjdGluZyA6IGNhbGxiYWNrIG1ldGhvZCB0byBpbnZva2Ugd2hlbiB0aGUgY2xpZW50IGlzIHJlY29ubmVjdGluZyxcbm9ucmVjb25uZWN0ZWQgOiBjYWxsYmFjayBtZXRob2QgdG8gaW52b2tlIHdoZW4gdGhlIGNsaWVudCBzdWNjZXNzZnVsbHkgcmVjb25uZWN0cyxcbn07XG4qL1xuZnVuY3Rpb24gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbihjb25maWcpIHtcbiAgICB2YXIgY2xvc2luZyA9IGZhbHNlO1xuICAgIHZhciByZWdpc3Rlck1lc3NhZ2VIYW5kbGVyO1xuICAgIHZhciB3c1VyaSA9IGNvbmZpZy51cmk7XG4gICAgdmFyIHJlY29ubmVjdGluZyA9IGZhbHNlO1xuXG4gICAgdmFyIHdzID0gbmV3IFdlYlNvY2tldCh3c1VyaSk7XG5cbiAgICB3cy5vbm9wZW4gPSAoKSA9PiB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZygnV2ViU29ja2V0IGNvbm5lY3RlZCB0byAnICsgd3NVcmkpO1xuICAgICAgICBpZiAoY29uZmlnLm9uY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBjb25maWcub25jb25uZWN0ZWQoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB3cy5vbmVycm9yID0gKGVycm9yKSA9PiB7XG4gICAgICAgIExvZ2dlci5lcnJvcignQ291bGQgbm90IGNvbm5lY3QgdG8gJyArIHdzVXJpICsgJyAoaW52b2tpbmcgb25lcnJvciBpZiBkZWZpbmVkKScsIGVycm9yKTtcbiAgICAgICAgaWYgKGNvbmZpZy5vbmVycm9yKSB7XG4gICAgICAgICAgICBjb25maWcub25lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgdmFyIHJlY29ubmVjdGlvbk9uQ2xvc2UgPSAoKSA9PiB7XG4gICAgICAgIGlmICh3cy5yZWFkeVN0YXRlID09PSBDTE9TRUQpIHtcbiAgICAgICAgICAgIGlmIChjbG9zaW5nKSB7XG4gICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdDb25uZWN0aW9uIGNsb3NlZCBieSB1c2VyJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChjb25maWcuaXNtYXN0ZXJub2RlY3Jhc2hlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIExvZ2dlci5lcnJvcignTWFzdGVyIE5vZGUgaGFzIGNyYXNoZWQuIFN0b3BwaW5nIHJlY29ubmVjdGlvbiBwcm9jZXNzJyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdDb25uZWN0aW9uIGNsb3NlZCB1bmV4cGVjdGVkbHkuIFJlY29ubmVjdGluZy4uLicpO1xuICAgICAgICAgICAgICAgICAgICByZWNvbm5lY3QoTUFYX1JFVFJJRVMsIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnQ2xvc2UgY2FsbGJhY2sgZnJvbSBwcmV2aW91cyB3ZWJzb2NrZXQuIElnbm9yaW5nIGl0Jyk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgd3Mub25jbG9zZSA9IHJlY29ubmVjdGlvbk9uQ2xvc2U7XG5cbiAgICBmdW5jdGlvbiByZWNvbm5lY3QobWF4UmV0cmllcywgbnVtUmV0cmllcykge1xuICAgICAgICBMb2dnZXIuZGVidWcoJ3JlY29ubmVjdCAoYXR0ZW1wdCAjJyArIG51bVJldHJpZXMgKyAnLCBtYXg9JyArIG1heFJldHJpZXMgKyAnKScpO1xuICAgICAgICBpZiAobnVtUmV0cmllcyA9PT0gMSkge1xuICAgICAgICAgICAgaWYgKHJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIExvZ2dlci53YXJuKCdUcnlpbmcgdG8gcmVjb25uZWN0IHdoZW4gYWxyZWFkeSByZWNvbm5lY3RpbmcuLi4gSWdub3JpbmcgdGhpcyByZWNvbm5lY3Rpb24uJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWNvbm5lY3RpbmcgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvbmZpZy5vbnJlY29ubmVjdGluZykge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5vbnJlY29ubmVjdGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJlY29ubmVjdEF1eChtYXhSZXRyaWVzLCBudW1SZXRyaWVzKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRSZWNvbm5lY3Rpb25RdWVyeVBhcmFtc0lmTWlzc2luZyh1cmlTdHJpbmcpIHtcbiAgICAgICAgdmFyIHNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMobmV3IFVSTCh1cmlTdHJpbmcpLnNlYXJjaCk7XG4gICAgICAgIGlmICghc2VhcmNoUGFyYW1zLmhhcygncmVjb25uZWN0JykpIHtcbiAgICAgICAgICAgIHVyaVN0cmluZyA9IEFycmF5LmZyb20oc2VhcmNoUGFyYW1zKS5sZW5ndGggPiAwID8gdXJpU3RyaW5nICsgJyZyZWNvbm5lY3Q9dHJ1ZScgOiB1cmlTdHJpbmcgKyAnP3JlY29ubmVjdD10cnVlJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXJpU3RyaW5nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlY29ubmVjdEF1eChtYXhSZXRyaWVzLCBudW1SZXRyaWVzKSB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZygnUmVjb25uZWN0aW9uIGF0dGVtcHQgIycgKyBudW1SZXRyaWVzKTtcbiAgICAgICAgd3MuY2xvc2UoNDEwNCwgJ0Nvbm5lY3Rpb24gY2xvc2VkIGZvciByZWNvbm5lY3Rpb24nKTtcblxuICAgICAgICB3c1VyaSA9IGFkZFJlY29ubmVjdGlvblF1ZXJ5UGFyYW1zSWZNaXNzaW5nKHdzVXJpKTtcbiAgICAgICAgd3MgPSBuZXcgV2ViU29ja2V0KHdzVXJpKTtcblxuICAgICAgICB3cy5vbm9wZW4gPSAoKSA9PiB7XG4gICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JlY29ubmVjdGVkIHRvICcgKyB3c1VyaSArICcgYWZ0ZXIgJyArIG51bVJldHJpZXMgKyAnIGF0dGVtcHRzLi4uJyk7XG4gICAgICAgICAgICByZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIoKTtcbiAgICAgICAgICAgIGlmIChjb25maWcub25yZWNvbm5lY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLm9ucmVjb25uZWN0ZWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHdzLm9uY2xvc2UgPSByZWNvbm5lY3Rpb25PbkNsb3NlO1xuICAgICAgICB9O1xuXG4gICAgICAgIHdzLm9uZXJyb3IgPSAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgIExvZ2dlci53YXJuKCdSZWNvbm5lY3Rpb24gZXJyb3I6ICcsIGVycm9yKTtcbiAgICAgICAgICAgIGlmIChudW1SZXRyaWVzID09PSBtYXhSZXRyaWVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbmZpZy5vbmRpc2Nvbm5lY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLm9uZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlY29ubmVjdChtYXhSZXRyaWVzLCBudW1SZXRyaWVzICsgMSk7XG4gICAgICAgICAgICAgICAgfSwgUkVUUllfVElNRV9NUyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5jbG9zZSA9IChjb2RlLCByZWFzb24pID0+IHtcbiAgICAgICAgY2xvc2luZyA9IHRydWU7XG4gICAgICAgIHdzLmNsb3NlKGNvZGUsIHJlYXNvbik7XG4gICAgfTtcblxuICAgIHRoaXMucmVjb25uZWN0V3MgPSAoKSA9PiB7XG4gICAgICAgIExvZ2dlci5kZWJ1ZygncmVjb25uZWN0V3MnKTtcbiAgICAgICAgcmVjb25uZWN0KE1BWF9SRVRSSUVTLCAxKTtcbiAgICB9O1xuXG4gICAgdGhpcy5zZW5kID0gKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgd3Muc2VuZChtZXNzYWdlKTtcbiAgICB9O1xuXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyID0gKHR5cGUsIGNhbGxiYWNrKSA9PiB7XG4gICAgICAgIHJlZ2lzdGVyTWVzc2FnZUhhbmRsZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICB3cy5hZGRFdmVudExpc3RlbmVyKHR5cGUsIGNhbGxiYWNrKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmVnaXN0ZXJNZXNzYWdlSGFuZGxlcigpO1xuICAgIH07XG5cbiAgICB0aGlzLmdldFJlYWR5U3RhdGUgPSAoKSA9PiB7XG4gICAgICAgIHJldHVybiB3cy5yZWFkeVN0YXRlO1xuICAgIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gV2ViU29ja2V0V2l0aFJlY29ubmVjdGlvbjtcbiIsIi8qXG4gKiAoQykgQ29weXJpZ2h0IDIwMTQgS3VyZW50byAoaHR0cDovL2t1cmVudG8ub3JnLylcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG52YXIgZGVmaW5lUHJvcGVydHlfSUU4ID0gZmFsc2U7XG5pZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7XG4gICAgdHJ5IHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHt9LCAneCcsIHt9KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGRlZmluZVByb3BlcnR5X0lFOCA9IHRydWU7XG4gICAgfVxufVxuXG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9GdW5jdGlvbi9iaW5kXG5pZiAoIUZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kKSB7XG4gICAgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbiAob1RoaXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAvLyBjbG9zZXN0IHRoaW5nIHBvc3NpYmxlIHRvIHRoZSBFQ01BU2NyaXB0IDVcbiAgICAgICAgICAgIC8vIGludGVybmFsIElzQ2FsbGFibGUgZnVuY3Rpb25cbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kIC0gd2hhdCBpcyB0cnlpbmcgdG8gYmUgYm91bmQgaXMgbm90IGNhbGxhYmxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgYUFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxuICAgICAgICAgICAgZlRvQmluZCA9IHRoaXMsXG4gICAgICAgICAgICBmTk9QID0gZnVuY3Rpb24gKCkge30sXG4gICAgICAgICAgICBmQm91bmQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZUb0JpbmQuYXBwbHkodGhpcyBpbnN0YW5jZW9mIGZOT1AgJiYgb1RoaXMgPyB0aGlzIDogb1RoaXMsIGFBcmdzLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgIGZOT1AucHJvdG90eXBlID0gdGhpcy5wcm90b3R5cGU7XG4gICAgICAgIGZCb3VuZC5wcm90b3R5cGUgPSBuZXcgZk5PUCgpO1xuXG4gICAgICAgIHJldHVybiBmQm91bmQ7XG4gICAgfTtcbn1cblxudmFyIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcblxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcblxudmFyIHBhY2tlcnMgPSByZXF1aXJlKCcuL3BhY2tlcnMnKTtcbnZhciBNYXBwZXIgPSByZXF1aXJlKCcuL01hcHBlcicpO1xuXG52YXIgQkFTRV9USU1FT1VUID0gNTAwMDtcblxuZnVuY3Rpb24gdW5pZnlSZXNwb25zZU1ldGhvZHMocmVzcG9uc2VNZXRob2RzKSB7XG4gICAgaWYgKCFyZXNwb25zZU1ldGhvZHMpIHJldHVybiB7fTtcblxuICAgIGZvciAodmFyIGtleSBpbiByZXNwb25zZU1ldGhvZHMpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gcmVzcG9uc2VNZXRob2RzW2tleV07XG5cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJylcbiAgICAgICAgICAgIHJlc3BvbnNlTWV0aG9kc1trZXldID0ge1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlOiB2YWx1ZVxuICAgICAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzcG9uc2VNZXRob2RzO1xufVxuXG5mdW5jdGlvbiB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpIHtcbiAgICBpZiAoIXRyYW5zcG9ydCkgcmV0dXJuO1xuXG4gICAgLy8gVHJhbnNwb3J0IGFzIGEgZnVuY3Rpb25cbiAgICBpZiAodHJhbnNwb3J0IGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZW5kOiB0cmFuc3BvcnRcbiAgICAgICAgfTtcblxuICAgIC8vIFdlYlNvY2tldCAmIERhdGFDaGFubmVsXG4gICAgaWYgKHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pIHJldHVybiB0cmFuc3BvcnQ7XG5cbiAgICAvLyBNZXNzYWdlIEFQSSAoSW50ZXItd2luZG93ICYgV2ViV29ya2VyKVxuICAgIGlmICh0cmFuc3BvcnQucG9zdE1lc3NhZ2UgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICB0cmFuc3BvcnQuc2VuZCA9IHRyYW5zcG9ydC5wb3N0TWVzc2FnZTtcbiAgICAgICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgICB9XG5cbiAgICAvLyBTdHJlYW0gQVBJXG4gICAgaWYgKHRyYW5zcG9ydC53cml0ZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgIHRyYW5zcG9ydC5zZW5kID0gdHJhbnNwb3J0LndyaXRlO1xuICAgICAgICByZXR1cm4gdHJhbnNwb3J0O1xuICAgIH1cblxuICAgIC8vIFRyYW5zcG9ydHMgdGhhdCBvbmx5IGNhbiByZWNlaXZlIG1lc3NhZ2VzLCBidXQgbm90IHNlbmRcbiAgICBpZiAodHJhbnNwb3J0Lm9ubWVzc2FnZSAhPT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgaWYgKHRyYW5zcG9ydC5wYXVzZSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSByZXR1cm47XG5cbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1RyYW5zcG9ydCBpcyBub3QgYSBmdW5jdGlvbiBub3IgYSB2YWxpZCBvYmplY3QnKTtcbn1cblxuLyoqXG4gKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyBub3RpZmljYXRpb25cbiAqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIC1tZXRob2Qgb2YgdGhlIG5vdGlmaWNhdGlvblxuICogQHBhcmFtIHBhcmFtcyAtIHBhcmFtZXRlcnMgb2YgdGhlIG5vdGlmaWNhdGlvblxuICovXG5mdW5jdGlvbiBScGNOb3RpZmljYXRpb24obWV0aG9kLCBwYXJhbXMpIHtcbiAgICBpZiAoZGVmaW5lUHJvcGVydHlfSUU4KSB7XG4gICAgICAgIHRoaXMubWV0aG9kID0gbWV0aG9kO1xuICAgICAgICB0aGlzLnBhcmFtcyA9IHBhcmFtcztcbiAgICB9IGVsc2Uge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ21ldGhvZCcsIHtcbiAgICAgICAgICAgIHZhbHVlOiBtZXRob2QsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BhcmFtcycsIHtcbiAgICAgICAgICAgIHZhbHVlOiBwYXJhbXMsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuLyoqXG4gKiBAY2xhc3NcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge29iamVjdH0gcGFja2VyXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBbdHJhbnNwb3J0XVxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtvblJlcXVlc3RdXG4gKi9cbmZ1bmN0aW9uIFJwY0J1aWxkZXIocGFja2VyLCBvcHRpb25zLCB0cmFuc3BvcnQsIG9uUmVxdWVzdCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIGlmICghcGFja2VyKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoJ1BhY2tlciBpcyBub3QgZGVmaW5lZCcpO1xuXG4gICAgaWYgKCFwYWNrZXIucGFjayB8fCAhcGFja2VyLnVucGFjaykgdGhyb3cgbmV3IFN5bnRheEVycm9yKCdQYWNrZXIgaXMgaW52YWxpZCcpO1xuXG4gICAgdmFyIHJlc3BvbnNlTWV0aG9kcyA9IHVuaWZ5UmVzcG9uc2VNZXRob2RzKHBhY2tlci5yZXNwb25zZU1ldGhvZHMpO1xuXG4gICAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICBpZiAodHJhbnNwb3J0ICE9IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBvblJlcXVlc3RcIik7XG5cbiAgICAgICAgb25SZXF1ZXN0ID0gb3B0aW9ucztcbiAgICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgICBvcHRpb25zID0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuc2VuZCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgIGlmICh0cmFuc3BvcnQgJiYgISh0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHRocm93IG5ldyBTeW50YXhFcnJvcignT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnQnKTtcblxuICAgICAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgICAgIHRyYW5zcG9ydCA9IG9wdGlvbnM7XG4gICAgICAgIG9wdGlvbnMgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKHRyYW5zcG9ydCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgIGlmIChvblJlcXVlc3QgIT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIG9uUmVxdWVzdFwiKTtcblxuICAgICAgICBvblJlcXVlc3QgPSB0cmFuc3BvcnQ7XG4gICAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAodHJhbnNwb3J0ICYmIHRyYW5zcG9ydC5zZW5kIGluc3RhbmNlb2YgRnVuY3Rpb24pXG4gICAgICAgIGlmIChvblJlcXVlc3QgJiYgIShvblJlcXVlc3QgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHRocm93IG5ldyBTeW50YXhFcnJvcignT25seSBhIGZ1bmN0aW9uIGNhbiBiZSBhZnRlciB0cmFuc3BvcnQnKTtcblxuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gICAgRXZlbnRFbWl0dGVyLmNhbGwodGhpcyk7XG5cbiAgICBpZiAob25SZXF1ZXN0KSB0aGlzLm9uKCdyZXF1ZXN0Jywgb25SZXF1ZXN0KTtcblxuICAgIGlmIChkZWZpbmVQcm9wZXJ0eV9JRTgpIHRoaXMucGVlcklEID0gb3B0aW9ucy5wZWVySUQ7XG4gICAgZWxzZVxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3BlZXJJRCcsIHtcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnBlZXJJRFxuICAgICAgICB9KTtcblxuICAgIHZhciBtYXhfcmV0cmllcyA9IG9wdGlvbnMubWF4X3JldHJpZXMgfHwgMDtcblxuICAgIGZ1bmN0aW9uIHRyYW5zcG9ydE1lc3NhZ2UoZXZlbnQpIHtcbiAgICAgICAgc2VsZi5kZWNvZGUoZXZlbnQuZGF0YSB8fCBldmVudCk7XG4gICAgfVxuXG4gICAgdGhpcy5nZXRUcmFuc3BvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgfTtcbiAgICB0aGlzLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAvLyBSZW1vdmUgbGlzdGVuZXIgZnJvbSBvbGQgdHJhbnNwb3J0XG4gICAgICAgIGlmICh0cmFuc3BvcnQpIHtcbiAgICAgICAgICAgIC8vIFczQyB0cmFuc3BvcnRzXG4gICAgICAgICAgICBpZiAodHJhbnNwb3J0LnJlbW92ZUV2ZW50TGlzdGVuZXIpIHRyYW5zcG9ydC5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdHJhbnNwb3J0TWVzc2FnZSk7XG4gICAgICAgICAgICAvLyBOb2RlLmpzIFN0cmVhbXMgQVBJXG4gICAgICAgICAgICBlbHNlIGlmICh0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIpIHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGxpc3RlbmVyIG9uIG5ldyB0cmFuc3BvcnRcbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBXM0MgdHJhbnNwb3J0c1xuICAgICAgICAgICAgaWYgKHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIpIHZhbHVlLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0cmFuc3BvcnRNZXNzYWdlKTtcbiAgICAgICAgICAgIC8vIE5vZGUuanMgU3RyZWFtcyBBUElcbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlLmFkZExpc3RlbmVyKSB2YWx1ZS5hZGRMaXN0ZW5lcignZGF0YScsIHRyYW5zcG9ydE1lc3NhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodmFsdWUpO1xuICAgIH07XG5cbiAgICBpZiAoIWRlZmluZVByb3BlcnR5X0lFOClcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd0cmFuc3BvcnQnLCB7XG4gICAgICAgICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICAgICAgICBzZXQ6IHRoaXMuc2V0VHJhbnNwb3J0LmJpbmQodGhpcylcbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLnNldFRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgdmFyIHJlcXVlc3RfdGltZW91dCA9IG9wdGlvbnMucmVxdWVzdF90aW1lb3V0IHx8IEJBU0VfVElNRU9VVDtcbiAgICB2YXIgcGluZ19yZXF1ZXN0X3RpbWVvdXQgPSBvcHRpb25zLnBpbmdfcmVxdWVzdF90aW1lb3V0IHx8IHJlcXVlc3RfdGltZW91dDtcbiAgICB2YXIgcmVzcG9uc2VfdGltZW91dCA9IG9wdGlvbnMucmVzcG9uc2VfdGltZW91dCB8fCBCQVNFX1RJTUVPVVQ7XG4gICAgdmFyIGR1cGxpY2F0ZXNfdGltZW91dCA9IG9wdGlvbnMuZHVwbGljYXRlc190aW1lb3V0IHx8IEJBU0VfVElNRU9VVDtcblxuICAgIHZhciByZXF1ZXN0SUQgPSAwO1xuXG4gICAgdmFyIHJlcXVlc3RzID0gbmV3IE1hcHBlcigpO1xuICAgIHZhciByZXNwb25zZXMgPSBuZXcgTWFwcGVyKCk7XG4gICAgdmFyIHByb2Nlc3NlZFJlc3BvbnNlcyA9IG5ldyBNYXBwZXIoKTtcblxuICAgIHZhciBtZXNzYWdlMktleSA9IHt9O1xuXG4gICAgLyoqXG4gICAgICogU3RvcmUgdGhlIHJlc3BvbnNlIHRvIHByZXZlbnQgdG8gcHJvY2VzcyBkdXBsaWNhdGUgcmVxdWVzdCBsYXRlclxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHN0b3JlUmVzcG9uc2UobWVzc2FnZSwgaWQsIGRlc3QpIHtcbiAgICAgICAgdmFyIHJlc3BvbnNlID0ge1xuICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgICAgIC8qKiBUaW1lb3V0IHRvIGF1dG8tY2xlYW4gb2xkIHJlc3BvbnNlcyAqL1xuICAgICAgICAgICAgdGltZW91dDogc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2VzLnJlbW92ZShpZCwgZGVzdCk7XG4gICAgICAgICAgICB9LCByZXNwb25zZV90aW1lb3V0KVxuICAgICAgICB9O1xuXG4gICAgICAgIHJlc3BvbnNlcy5zZXQocmVzcG9uc2UsIGlkLCBkZXN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gaWdub3JlIGR1cGxpY2F0ZWQgbWVzc2FnZXMgbGF0ZXJcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzdG9yZVByb2Nlc3NlZFJlc3BvbnNlKGFjaywgZnJvbSkge1xuICAgICAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcHJvY2Vzc2VkUmVzcG9uc2VzLnJlbW92ZShhY2ssIGZyb20pO1xuICAgICAgICB9LCBkdXBsaWNhdGVzX3RpbWVvdXQpO1xuXG4gICAgICAgIHByb2Nlc3NlZFJlc3BvbnNlcy5zZXQodGltZW91dCwgYWNrLCBmcm9tKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXByZXNlbnRhdGlvbiBvZiBhIFJQQyByZXF1ZXN0XG4gICAgICpcbiAgICAgKiBAY2xhc3NcbiAgICAgKiBAZXh0ZW5kcyBScGNOb3RpZmljYXRpb25cbiAgICAgKlxuICAgICAqIEBjb25zdHJ1Y3RvclxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICAgKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAgICogQHBhcmFtIHtJbnRlZ2VyfSBpZCAtIGlkZW50aWZpZXIgb2YgdGhlIHJlcXVlc3RcbiAgICAgKiBAcGFyYW0gW2Zyb21dIC0gc291cmNlIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICAgKi9cbiAgICBmdW5jdGlvbiBScGNSZXF1ZXN0KG1ldGhvZCwgcGFyYW1zLCBpZCwgZnJvbSwgdHJhbnNwb3J0KSB7XG4gICAgICAgIFJwY05vdGlmaWNhdGlvbi5jYWxsKHRoaXMsIG1ldGhvZCwgcGFyYW1zKTtcblxuICAgICAgICB0aGlzLmdldFRyYW5zcG9ydCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0cmFuc3BvcnQ7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh2YWx1ZSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKCFkZWZpbmVQcm9wZXJ0eV9JRTgpXG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RyYW5zcG9ydCcsIHtcbiAgICAgICAgICAgICAgICBnZXQ6IHRoaXMuZ2V0VHJhbnNwb3J0LmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgc2V0OiB0aGlzLnNldFRyYW5zcG9ydC5iaW5kKHRoaXMpXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB2YXIgcmVzcG9uc2UgPSByZXNwb25zZXMuZ2V0KGlkLCBmcm9tKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQGNvbnN0YW50IHtCb29sZWFufSBkdXBsaWNhdGVkXG4gICAgICAgICAqL1xuICAgICAgICBpZiAoISh0cmFuc3BvcnQgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKSkpIHtcbiAgICAgICAgICAgIGlmIChkZWZpbmVQcm9wZXJ0eV9JRTgpIHRoaXMuZHVwbGljYXRlZCA9IEJvb2xlYW4ocmVzcG9uc2UpO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnZHVwbGljYXRlZCcsIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IEJvb2xlYW4ocmVzcG9uc2UpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVzcG9uc2VNZXRob2QgPSByZXNwb25zZU1ldGhvZHNbbWV0aG9kXTtcblxuICAgICAgICB0aGlzLnBhY2sgPSBwYWNrZXIucGFjay5iaW5kKHBhY2tlciwgdGhpcywgaWQpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZW5lcmF0ZSBhIHJlc3BvbnNlIHRvIHRoaXMgcmVxdWVzdFxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge0Vycm9yfSBbZXJyb3JdXG4gICAgICAgICAqIEBwYXJhbSB7Kn0gW3Jlc3VsdF1cbiAgICAgICAgICpcbiAgICAgICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVwbHkgPSBmdW5jdGlvbiAoZXJyb3IsIHJlc3VsdCwgdHJhbnNwb3J0KSB7XG4gICAgICAgICAgICAvLyBGaXggb3B0aW9uYWwgcGFyYW1ldGVyc1xuICAgICAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRnVuY3Rpb24gfHwgKGVycm9yICYmIGVycm9yLnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICAgICAgICAgIHRyYW5zcG9ydCA9IGVycm9yO1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IG51bGw7XG4gICAgICAgICAgICAgICAgZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEZ1bmN0aW9uIHx8IChyZXN1bHQgJiYgcmVzdWx0LnNlbmQgaW5zdGFuY2VvZiBGdW5jdGlvbikpIHtcbiAgICAgICAgICAgICAgICBpZiAodHJhbnNwb3J0ICE9IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICAgICAgICAgIHRyYW5zcG9ydCA9IHJlc3VsdDtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgICAgICAgICAvLyBEdXBsaWNhdGVkIHJlcXVlc3QsIHJlbW92ZSBvbGQgcmVzcG9uc2UgdGltZW91dFxuICAgICAgICAgICAgaWYgKHJlc3BvbnNlKSBjbGVhclRpbWVvdXQocmVzcG9uc2UudGltZW91dCk7XG5cbiAgICAgICAgICAgIGlmIChmcm9tICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGlmIChlcnJvcikgZXJyb3IuZGVzdCA9IGZyb207XG5cbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0KSByZXN1bHQuZGVzdCA9IGZyb207XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBtZXNzYWdlO1xuXG4gICAgICAgICAgICAvLyBOZXcgcmVxdWVzdCBvciBvdmVycmlkZW4gb25lLCBjcmVhdGUgbmV3IHJlc3BvbnNlIHdpdGggcHJvdmlkZWQgZGF0YVxuICAgICAgICAgICAgaWYgKGVycm9yIHx8IHJlc3VsdCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvcikgZXJyb3IuZnJvbSA9IHNlbGYucGVlcklEO1xuICAgICAgICAgICAgICAgICAgICBlbHNlIHJlc3VsdC5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gUHJvdG9jb2wgaW5kaWNhdGVzIHRoYXQgcmVzcG9uc2VzIGhhcyBvd24gcmVxdWVzdCBtZXRob2RzXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlTWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZU1ldGhvZC5lcnJvciA9PSB1bmRlZmluZWQgJiYgZXJyb3IpXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvclxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgbWV0aG9kID0gZXJyb3IgPyByZXNwb25zZU1ldGhvZC5lcnJvciA6IHJlc3BvbnNlTWV0aG9kLnJlc3BvbnNlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtczogZXJyb3IgfHwgcmVzdWx0XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ6IHJlc3VsdFxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRHVwbGljYXRlICYgbm90LW92ZXJyaWRlbiByZXF1ZXN0LCByZS1zZW5kIG9sZCByZXNwb25zZVxuICAgICAgICAgICAgZWxzZSBpZiAocmVzcG9uc2UpIG1lc3NhZ2UgPSByZXNwb25zZS5tZXNzYWdlO1xuICAgICAgICAgICAgLy8gTmV3IGVtcHR5IHJlcGx5LCByZXNwb25zZSBudWxsIHZhbHVlXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQ6IG51bGxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgaWRcbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyBTdG9yZSB0aGUgcmVzcG9uc2UgdG8gcHJldmVudCB0byBwcm9jZXNzIGEgZHVwbGljYXRlZCByZXF1ZXN0IGxhdGVyXG4gICAgICAgICAgICBzdG9yZVJlc3BvbnNlKG1lc3NhZ2UsIGlkLCBmcm9tKTtcblxuICAgICAgICAgICAgLy8gUmV0dXJuIHRoZSBzdG9yZWQgcmVzcG9uc2Ugc28gaXQgY2FuIGJlIGRpcmVjdGx5IHNlbmQgYmFja1xuICAgICAgICAgICAgdHJhbnNwb3J0ID0gdHJhbnNwb3J0IHx8IHRoaXMuZ2V0VHJhbnNwb3J0KCkgfHwgc2VsZi5nZXRUcmFuc3BvcnQoKTtcblxuICAgICAgICAgICAgaWYgKHRyYW5zcG9ydCkgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKG1lc3NhZ2UpO1xuXG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaW5oZXJpdHMoUnBjUmVxdWVzdCwgUnBjTm90aWZpY2F0aW9uKTtcblxuICAgIGZ1bmN0aW9uIGNhbmNlbChtZXNzYWdlKSB7XG4gICAgICAgIHZhciBrZXkgPSBtZXNzYWdlMktleVttZXNzYWdlXTtcbiAgICAgICAgaWYgKCFrZXkpIHJldHVybjtcblxuICAgICAgICBkZWxldGUgbWVzc2FnZTJLZXlbbWVzc2FnZV07XG5cbiAgICAgICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5wb3Aoa2V5LmlkLCBrZXkuZGVzdCk7XG4gICAgICAgIGlmICghcmVxdWVzdCkgcmV0dXJuO1xuXG4gICAgICAgIGNsZWFyVGltZW91dChyZXF1ZXN0LnRpbWVvdXQpO1xuXG4gICAgICAgIC8vIFN0YXJ0IGR1cGxpY2F0ZWQgcmVzcG9uc2VzIHRpbWVvdXRcbiAgICAgICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShrZXkuaWQsIGtleS5kZXN0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBbGxvdyB0byBjYW5jZWwgYSByZXF1ZXN0IGFuZCBkb24ndCB3YWl0IGZvciBhIHJlc3BvbnNlXG4gICAgICpcbiAgICAgKiBJZiBgbWVzc2FnZWAgaXMgbm90IGdpdmVuLCBjYW5jZWwgYWxsIHRoZSByZXF1ZXN0XG4gICAgICovXG4gICAgdGhpcy5jYW5jZWwgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICBpZiAobWVzc2FnZSkgcmV0dXJuIGNhbmNlbChtZXNzYWdlKTtcblxuICAgICAgICBmb3IgKHZhciBtZXNzYWdlIGluIG1lc3NhZ2UyS2V5KSBjYW5jZWwobWVzc2FnZSk7XG4gICAgfTtcblxuICAgIHRoaXMuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFByZXZlbnQgdG8gcmVjZWl2ZSBuZXcgbWVzc2FnZXNcbiAgICAgICAgdmFyIHRyYW5zcG9ydCA9IHRoaXMuZ2V0VHJhbnNwb3J0KCk7XG4gICAgICAgIGlmICh0cmFuc3BvcnQgJiYgdHJhbnNwb3J0LmNsb3NlKSB0cmFuc3BvcnQuY2xvc2UoNDAwMywgJ0NhbmNlbCByZXF1ZXN0Jyk7XG5cbiAgICAgICAgLy8gUmVxdWVzdCAmIHByb2Nlc3NlZCByZXNwb25zZXNcbiAgICAgICAgdGhpcy5jYW5jZWwoKTtcblxuICAgICAgICBwcm9jZXNzZWRSZXNwb25zZXMuZm9yRWFjaChjbGVhclRpbWVvdXQpO1xuXG4gICAgICAgIC8vIFJlc3BvbnNlc1xuICAgICAgICByZXNwb25zZXMuZm9yRWFjaChmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dChyZXNwb25zZS50aW1lb3V0KTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlcyBhbmQgZW5jb2RlIGEgSnNvblJQQyAyLjAgbWVzc2FnZVxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCAtbWV0aG9kIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICAgKiBAcGFyYW0gcGFyYW1zIC0gcGFyYW1ldGVycyBvZiB0aGUgbm90aWZpY2F0aW9uXG4gICAgICogQHBhcmFtIFtkZXN0XSAtIGRlc3RpbmF0aW9uIG9mIHRoZSBub3RpZmljYXRpb25cbiAgICAgKiBAcGFyYW0ge29iamVjdH0gW3RyYW5zcG9ydF0gLSB0cmFuc3BvcnQgd2hlcmUgdG8gc2VuZCB0aGUgbWVzc2FnZVxuICAgICAqIEBwYXJhbSBbY2FsbGJhY2tdIC0gZnVuY3Rpb24gY2FsbGVkIHdoZW4gYSByZXNwb25zZSB0byB0aGlzIHJlcXVlc3QgaXNcbiAgICAgKiAgIHJlY2VpdmVkLiBJZiBub3QgZGVmaW5lZCwgYSBub3RpZmljYXRpb24gd2lsbCBiZSBzZW5kIGluc3RlYWRcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEEgcmF3IEpzb25SUEMgMi4wIHJlcXVlc3Qgb3Igbm90aWZpY2F0aW9uIHN0cmluZ1xuICAgICAqL1xuICAgIHRoaXMuZW5jb2RlID0gZnVuY3Rpb24gKG1ldGhvZCwgcGFyYW1zLCBkZXN0LCB0cmFuc3BvcnQsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIEZpeCBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgICAgIGlmIChwYXJhbXMgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICAgICAgaWYgKGRlc3QgIT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJUaGVyZSBjYW4ndCBiZSBwYXJhbWV0ZXJzIGFmdGVyIGNhbGxiYWNrXCIpO1xuXG4gICAgICAgICAgICBjYWxsYmFjayA9IHBhcmFtcztcbiAgICAgICAgICAgIHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGRlc3QgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBwYXJhbXMgPSB1bmRlZmluZWQ7XG4gICAgICAgIH0gZWxzZSBpZiAoZGVzdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG4gICAgICAgICAgICBpZiAodHJhbnNwb3J0ICE9IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICAgICAgY2FsbGJhY2sgPSBkZXN0O1xuICAgICAgICAgICAgdHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgZGVzdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfSBlbHNlIGlmICh0cmFuc3BvcnQgaW5zdGFuY2VvZiBGdW5jdGlvbikge1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrICE9IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFN5bnRheEVycm9yKFwiVGhlcmUgY2FuJ3QgYmUgcGFyYW1ldGVycyBhZnRlciBjYWxsYmFja1wiKTtcblxuICAgICAgICAgICAgY2FsbGJhY2sgPSB0cmFuc3BvcnQ7XG4gICAgICAgICAgICB0cmFuc3BvcnQgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2VsZi5wZWVySUQgIT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG5cbiAgICAgICAgICAgIHBhcmFtcy5mcm9tID0gc2VsZi5wZWVySUQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGVzdCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7fTtcblxuICAgICAgICAgICAgcGFyYW1zLmRlc3QgPSBkZXN0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRW5jb2RlIG1lc3NhZ2VcbiAgICAgICAgdmFyIG1lc3NhZ2UgPSB7XG4gICAgICAgICAgICBtZXRob2Q6IG1ldGhvZCxcbiAgICAgICAgICAgIHBhcmFtczogcGFyYW1zXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICB2YXIgaWQgPSByZXF1ZXN0SUQrKztcbiAgICAgICAgICAgIHZhciByZXRyaWVkID0gMDtcblxuICAgICAgICAgICAgbWVzc2FnZSA9IHBhY2tlci5wYWNrKG1lc3NhZ2UsIGlkKTtcblxuICAgICAgICAgICAgZnVuY3Rpb24gZGlzcGF0Y2hDYWxsYmFjayhlcnJvciwgcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgc2VsZi5jYW5jZWwobWVzc2FnZSk7XG5cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHJlcXVlc3QgPSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogZGlzcGF0Y2hDYWxsYmFjayxcbiAgICAgICAgICAgICAgICByZXNwb25zZU1ldGhvZHM6IHJlc3BvbnNlTWV0aG9kc1ttZXRob2RdIHx8IHt9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB2YXIgZW5jb2RlX3RyYW5zcG9ydCA9IHVuaWZ5VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCkge1xuICAgICAgICAgICAgICAgIHZhciBydCA9IG1ldGhvZCA9PT0gJ3BpbmcnID8gcGluZ19yZXF1ZXN0X3RpbWVvdXQgOiByZXF1ZXN0X3RpbWVvdXQ7XG4gICAgICAgICAgICAgICAgcmVxdWVzdC50aW1lb3V0ID0gc2V0VGltZW91dCh0aW1lb3V0LCBydCAqIE1hdGgucG93KDIsIHJldHJpZWQrKykpO1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UyS2V5W21lc3NhZ2VdID0ge1xuICAgICAgICAgICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICAgICAgICAgIGRlc3Q6IGRlc3RcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlcXVlc3RzLnNldChyZXF1ZXN0LCBpZCwgZGVzdCk7XG5cbiAgICAgICAgICAgICAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgZW5jb2RlX3RyYW5zcG9ydCB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgICAgICAgICAgIGlmICh0cmFuc3BvcnQpIHJldHVybiB0cmFuc3BvcnQuc2VuZChtZXNzYWdlKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiByZXRyeSh0cmFuc3BvcnQpIHtcbiAgICAgICAgICAgICAgICB0cmFuc3BvcnQgPSB1bmlmeVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKHJldHJpZWQgKyAnIHJldHJ5IGZvciByZXF1ZXN0IG1lc3NhZ2U6JywgbWVzc2FnZSk7XG5cbiAgICAgICAgICAgICAgICB2YXIgdGltZW91dCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5wb3AoaWQsIGRlc3QpO1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBzZW5kUmVxdWVzdCh0cmFuc3BvcnQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiB0aW1lb3V0KCkge1xuICAgICAgICAgICAgICAgIGlmIChyZXRyaWVkIDwgbWF4X3JldHJpZXMpIHJldHVybiByZXRyeSh0cmFuc3BvcnQpO1xuXG4gICAgICAgICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdSZXF1ZXN0IGhhcyB0aW1lZCBvdXQnKTtcbiAgICAgICAgICAgICAgICBlcnJvci5yZXF1ZXN0ID0gbWVzc2FnZTtcblxuICAgICAgICAgICAgICAgIGVycm9yLnJldHJ5ID0gcmV0cnk7XG5cbiAgICAgICAgICAgICAgICBkaXNwYXRjaENhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHNlbmRSZXF1ZXN0KHRyYW5zcG9ydCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZXR1cm4gdGhlIHBhY2tlZCBtZXNzYWdlXG4gICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIucGFjayhtZXNzYWdlKTtcblxuICAgICAgICB0cmFuc3BvcnQgPSB0cmFuc3BvcnQgfHwgdGhpcy5nZXRUcmFuc3BvcnQoKTtcbiAgICAgICAgaWYgKHRyYW5zcG9ydCkgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKG1lc3NhZ2UpO1xuXG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBEZWNvZGUgYW5kIHByb2Nlc3MgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIHN0cmluZyB3aXRoIHRoZSBjb250ZW50IG9mIHRoZSBtZXNzYWdlXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7UnBjTm90aWZpY2F0aW9ufFJwY1JlcXVlc3R8dW5kZWZpbmVkfSAtIHRoZSByZXByZXNlbnRhdGlvbiBvZiB0aGVcbiAgICAgKiAgIG5vdGlmaWNhdGlvbiBvciB0aGUgcmVxdWVzdC4gSWYgYSByZXNwb25zZSB3YXMgcHJvY2Vzc2VkLCBpdCB3aWxsIHJldHVyblxuICAgICAqICAgYHVuZGVmaW5lZGAgdG8gbm90aWZ5IHRoYXQgaXQgd2FzIHByb2Nlc3NlZFxuICAgICAqXG4gICAgICogQHRocm93cyB7VHlwZUVycm9yfSAtIE1lc3NhZ2UgaXMgbm90IGRlZmluZWRcbiAgICAgKi9cbiAgICB0aGlzLmRlY29kZSA9IGZ1bmN0aW9uIChtZXNzYWdlLCB0cmFuc3BvcnQpIHtcbiAgICAgICAgaWYgKCFtZXNzYWdlKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdNZXNzYWdlIGlzIG5vdCBkZWZpbmVkJyk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBwYWNrZXIudW5wYWNrKG1lc3NhZ2UpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgaW52YWxpZCBtZXNzYWdlc1xuICAgICAgICAgICAgcmV0dXJuIGNvbnNvbGUuZGVidWcoZSwgbWVzc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaWQgPSBtZXNzYWdlLmlkO1xuICAgICAgICB2YXIgYWNrID0gbWVzc2FnZS5hY2s7XG4gICAgICAgIHZhciBtZXRob2QgPSBtZXNzYWdlLm1ldGhvZDtcbiAgICAgICAgdmFyIHBhcmFtcyA9IG1lc3NhZ2UucGFyYW1zIHx8IHt9O1xuXG4gICAgICAgIHZhciBmcm9tID0gcGFyYW1zLmZyb207XG4gICAgICAgIHZhciBkZXN0ID0gcGFyYW1zLmRlc3Q7XG5cbiAgICAgICAgLy8gSWdub3JlIG1lc3NhZ2VzIHNlbmQgYnkgdXNcbiAgICAgICAgaWYgKHNlbGYucGVlcklEICE9IHVuZGVmaW5lZCAmJiBmcm9tID09IHNlbGYucGVlcklEKSByZXR1cm47XG5cbiAgICAgICAgLy8gTm90aWZpY2F0aW9uXG4gICAgICAgIGlmIChpZCA9PSB1bmRlZmluZWQgJiYgYWNrID09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdmFyIG5vdGlmaWNhdGlvbiA9IG5ldyBScGNOb3RpZmljYXRpb24obWV0aG9kLCBwYXJhbXMpO1xuXG4gICAgICAgICAgICBpZiAoc2VsZi5lbWl0KCdyZXF1ZXN0Jywgbm90aWZpY2F0aW9uKSkgcmV0dXJuO1xuICAgICAgICAgICAgcmV0dXJuIG5vdGlmaWNhdGlvbjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NSZXF1ZXN0KCkge1xuICAgICAgICAgICAgLy8gSWYgd2UgaGF2ZSBhIHRyYW5zcG9ydCBhbmQgaXQncyBhIGR1cGxpY2F0ZWQgcmVxdWVzdCwgcmVwbHkgaW5tZWRpYXRseVxuICAgICAgICAgICAgdHJhbnNwb3J0ID0gdW5pZnlUcmFuc3BvcnQodHJhbnNwb3J0KSB8fCBzZWxmLmdldFRyYW5zcG9ydCgpO1xuICAgICAgICAgICAgaWYgKHRyYW5zcG9ydCkge1xuICAgICAgICAgICAgICAgIHZhciByZXNwb25zZSA9IHJlc3BvbnNlcy5nZXQoaWQsIGZyb20pO1xuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZSkgcmV0dXJuIHRyYW5zcG9ydC5zZW5kKHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgaWRBY2sgPSBpZCAhPSB1bmRlZmluZWQgPyBpZCA6IGFjaztcbiAgICAgICAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFJwY1JlcXVlc3QobWV0aG9kLCBwYXJhbXMsIGlkQWNrLCBmcm9tLCB0cmFuc3BvcnQpO1xuXG4gICAgICAgICAgICBpZiAoc2VsZi5lbWl0KCdyZXF1ZXN0JywgcmVxdWVzdCkpIHJldHVybjtcbiAgICAgICAgICAgIHJldHVybiByZXF1ZXN0O1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1Jlc3BvbnNlKHJlcXVlc3QsIGVycm9yLCByZXN1bHQpIHtcbiAgICAgICAgICAgIHJlcXVlc3QuY2FsbGJhY2soZXJyb3IsIHJlc3VsdCk7XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBkdXBsaWNhdGVkUmVzcG9uc2UodGltZW91dCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdSZXNwb25zZSBhbHJlYWR5IHByb2Nlc3NlZCcsIG1lc3NhZ2UpO1xuXG4gICAgICAgICAgICAvLyBVcGRhdGUgZHVwbGljYXRlZCByZXNwb25zZXMgdGltZW91dFxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICAgICAgc3RvcmVQcm9jZXNzZWRSZXNwb25zZShhY2ssIGZyb20pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVxdWVzdCwgb3IgcmVzcG9uc2Ugd2l0aCBvd24gbWV0aG9kXG4gICAgICAgIGlmIChtZXRob2QpIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGl0J3MgYSByZXNwb25zZSB3aXRoIG93biBtZXRob2RcbiAgICAgICAgICAgIGlmIChkZXN0ID09IHVuZGVmaW5lZCB8fCBkZXN0ID09IHNlbGYucGVlcklEKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0cy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgICAgICAgICBpZiAocmVxdWVzdCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzcG9uc2VNZXRob2RzID0gcmVxdWVzdC5yZXNwb25zZU1ldGhvZHM7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKG1ldGhvZCA9PSByZXNwb25zZU1ldGhvZHMuZXJyb3IpIHJldHVybiBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgcGFyYW1zKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAobWV0aG9kID09IHJlc3BvbnNlTWV0aG9kcy5yZXNwb25zZSkgcmV0dXJuIHByb2Nlc3NSZXNwb25zZShyZXF1ZXN0LCBudWxsLCBwYXJhbXMpO1xuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9jZXNzUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhciBwcm9jZXNzZWQgPSBwcm9jZXNzZWRSZXNwb25zZXMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NlZCkgcmV0dXJuIGR1cGxpY2F0ZWRSZXNwb25zZShwcm9jZXNzZWQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZXF1ZXN0XG4gICAgICAgICAgICByZXR1cm4gcHJvY2Vzc1JlcXVlc3QoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBlcnJvciA9IG1lc3NhZ2UuZXJyb3I7XG4gICAgICAgIHZhciByZXN1bHQgPSBtZXNzYWdlLnJlc3VsdDtcblxuICAgICAgICAvLyBJZ25vcmUgcmVzcG9uc2VzIG5vdCBzZW5kIHRvIHVzXG4gICAgICAgIGlmIChlcnJvciAmJiBlcnJvci5kZXN0ICYmIGVycm9yLmRlc3QgIT0gc2VsZi5wZWVySUQpIHJldHVybjtcbiAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQuZGVzdCAmJiByZXN1bHQuZGVzdCAhPSBzZWxmLnBlZXJJRCkgcmV0dXJuO1xuXG4gICAgICAgIC8vIFJlc3BvbnNlXG4gICAgICAgIHZhciByZXF1ZXN0ID0gcmVxdWVzdHMuZ2V0KGFjaywgZnJvbSk7XG4gICAgICAgIGlmICghcmVxdWVzdCkge1xuICAgICAgICAgICAgdmFyIHByb2Nlc3NlZCA9IHByb2Nlc3NlZFJlc3BvbnNlcy5nZXQoYWNrLCBmcm9tKTtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzZWQpIHJldHVybiBkdXBsaWNhdGVkUmVzcG9uc2UocHJvY2Vzc2VkKTtcblxuICAgICAgICAgICAgcmV0dXJuIGNvbnNvbGUud2FybignTm8gY2FsbGJhY2sgd2FzIGRlZmluZWQgZm9yIHRoaXMgbWVzc2FnZScsIG1lc3NhZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJvY2VzcyByZXNwb25zZVxuICAgICAgICBwcm9jZXNzUmVzcG9uc2UocmVxdWVzdCwgZXJyb3IsIHJlc3VsdCk7XG4gICAgfTtcbn1cbmluaGVyaXRzKFJwY0J1aWxkZXIsIEV2ZW50RW1pdHRlcik7XG5cblJwY0J1aWxkZXIuUnBjTm90aWZpY2F0aW9uID0gUnBjTm90aWZpY2F0aW9uO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFJwY0J1aWxkZXI7XG5cbnZhciBjbGllbnRzID0gcmVxdWlyZSgnLi9jbGllbnRzJyk7XG52YXIgdHJhbnNwb3J0cyA9IHJlcXVpcmUoJy4vY2xpZW50cy90cmFuc3BvcnRzJyk7XG5cblJwY0J1aWxkZXIuY2xpZW50cyA9IGNsaWVudHM7XG5ScGNCdWlsZGVyLmNsaWVudHMudHJhbnNwb3J0cyA9IHRyYW5zcG9ydHM7XG5ScGNCdWlsZGVyLnBhY2tlcnMgPSBwYWNrZXJzO1xuIiwiLyoqXG4gKiBKc29uUlBDIDIuMCBwYWNrZXJcbiAqL1xuXG4vKipcbiAqIFBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG1lc3NhZ2UgLSBvYmplY3QgdG8gYmUgcGFja2FnZWQuIEl0IHJlcXVpcmVzIHRvIGhhdmUgYWxsIHRoZVxuICogICBmaWVsZHMgbmVlZGVkIGJ5IHRoZSBKc29uUlBDIDIuMCBtZXNzYWdlIHRoYXQgaXQncyBnb2luZyB0byBiZSBnZW5lcmF0ZWRcbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IC0gdGhlIHN0cmluZ2lmaWVkIEpzb25SUEMgMi4wIG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gcGFjayhtZXNzYWdlLCBpZCkge1xuICAgIHZhciByZXN1bHQgPSB7XG4gICAgICAgIGpzb25ycGM6ICcyLjAnXG4gICAgfTtcblxuICAgIC8vIFJlcXVlc3RcbiAgICBpZiAobWVzc2FnZS5tZXRob2QpIHtcbiAgICAgICAgcmVzdWx0Lm1ldGhvZCA9IG1lc3NhZ2UubWV0aG9kO1xuXG4gICAgICAgIGlmIChtZXNzYWdlLnBhcmFtcykgcmVzdWx0LnBhcmFtcyA9IG1lc3NhZ2UucGFyYW1zO1xuXG4gICAgICAgIC8vIFJlcXVlc3QgaXMgYSBub3RpZmljYXRpb25cbiAgICAgICAgaWYgKGlkICE9IHVuZGVmaW5lZCkgcmVzdWx0LmlkID0gaWQ7XG4gICAgfVxuXG4gICAgLy8gUmVzcG9uc2VcbiAgICBlbHNlIGlmIChpZCAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKG1lc3NhZ2UuZXJyb3IpIHtcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdCb3RoIHJlc3VsdCBhbmQgZXJyb3IgYXJlIGRlZmluZWQnKTtcblxuICAgICAgICAgICAgcmVzdWx0LmVycm9yID0gbWVzc2FnZS5lcnJvcjtcbiAgICAgICAgfSBlbHNlIGlmIChtZXNzYWdlLnJlc3VsdCAhPT0gdW5kZWZpbmVkKSByZXN1bHQucmVzdWx0ID0gbWVzc2FnZS5yZXN1bHQ7XG4gICAgICAgIGVsc2UgdGhyb3cgbmV3IFR5cGVFcnJvcignTm8gcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWQnKTtcblxuICAgICAgICByZXN1bHQuaWQgPSBpZDtcbiAgICB9XG5cbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocmVzdWx0KTtcbn1cblxuLyoqXG4gKiBVbnBhY2sgYSBKc29uUlBDIDIuMCBtZXNzYWdlXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgLSBzdHJpbmcgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgSnNvblJQQyAyLjAgbWVzc2FnZVxuICpcbiAqIEB0aHJvd3Mge1R5cGVFcnJvcn0gLSBJbnZhbGlkIEpzb25SUEMgdmVyc2lvblxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gLSBvYmplY3QgZmlsbGVkIHdpdGggdGhlIEpzb25SUEMgMi4wIG1lc3NhZ2UgY29udGVudFxuICovXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSkge1xuICAgIHZhciByZXN1bHQgPSBtZXNzYWdlO1xuXG4gICAgaWYgKHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJyB8fCBtZXNzYWdlIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgICAgIHJlc3VsdCA9IEpTT04ucGFyc2UobWVzc2FnZSk7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgaXQncyBhIHZhbGlkIG1lc3NhZ2VcblxuICAgIHZhciB2ZXJzaW9uID0gcmVzdWx0Lmpzb25ycGM7XG4gICAgaWYgKHZlcnNpb24gIT09ICcyLjAnKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBKc29uUlBDIHZlcnNpb24gJ1wiICsgdmVyc2lvbiArIFwiJzogXCIgKyBtZXNzYWdlKTtcblxuICAgIC8vIFJlc3BvbnNlXG4gICAgaWYgKHJlc3VsdC5tZXRob2QgPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChyZXN1bHQuaWQgPT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG1lc3NhZ2U6ICcgKyBtZXNzYWdlKTtcblxuICAgICAgICB2YXIgcmVzdWx0X2RlZmluZWQgPSByZXN1bHQucmVzdWx0ICE9PSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciBlcnJvcl9kZWZpbmVkID0gcmVzdWx0LmVycm9yICE9PSB1bmRlZmluZWQ7XG5cbiAgICAgICAgLy8gQ2hlY2sgb25seSByZXN1bHQgb3IgZXJyb3IgaXMgZGVmaW5lZCwgbm90IGJvdGggb3Igbm9uZVxuICAgICAgICBpZiAocmVzdWx0X2RlZmluZWQgJiYgZXJyb3JfZGVmaW5lZCkgdGhyb3cgbmV3IFR5cGVFcnJvcignQm90aCByZXN1bHQgYW5kIGVycm9yIGFyZSBkZWZpbmVkOiAnICsgbWVzc2FnZSk7XG5cbiAgICAgICAgaWYgKCFyZXN1bHRfZGVmaW5lZCAmJiAhZXJyb3JfZGVmaW5lZCkgdGhyb3cgbmV3IFR5cGVFcnJvcignTm8gcmVzdWx0IG9yIGVycm9yIGlzIGRlZmluZWQ6ICcgKyBtZXNzYWdlKTtcblxuICAgICAgICByZXN1bHQuYWNrID0gcmVzdWx0LmlkO1xuICAgICAgICBkZWxldGUgcmVzdWx0LmlkO1xuICAgIH1cblxuICAgIC8vIFJldHVybiB1bnBhY2tlZCBtZXNzYWdlXG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0cy5wYWNrID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwiZnVuY3Rpb24gcGFjayhtZXNzYWdlKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignTm90IHlldCBpbXBsZW1lbnRlZCcpO1xufVxuXG5mdW5jdGlvbiB1bnBhY2sobWVzc2FnZSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ05vdCB5ZXQgaW1wbGVtZW50ZWQnKTtcbn1cblxuZXhwb3J0cy5wYWNrID0gcGFjaztcbmV4cG9ydHMudW5wYWNrID0gdW5wYWNrO1xuIiwidmFyIEpzb25SUEMgPSByZXF1aXJlKCcuL0pzb25SUEMnKTtcbnZhciBYbWxSUEMgPSByZXF1aXJlKCcuL1htbFJQQycpO1xuXG5leHBvcnRzLkpzb25SUEMgPSBKc29uUlBDO1xuZXhwb3J0cy5YbWxSUEMgPSBYbWxSUEM7XG4iLCJ0eXBlIENvbnNvbGVGdW5jdGlvbiA9ICguLi5kYXRhOiBhbnkpID0+IHZvaWQ7XG5leHBvcnQgY2xhc3MgQ29uc29sZUxvZ2dlciB7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxvZ2dlcjogQ29uc29sZTtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBsb2c6IENvbnNvbGVGdW5jdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBpbmZvOiBDb25zb2xlRnVuY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGVidWc6IENvbnNvbGVGdW5jdGlvbjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICB3YXJuOiBDb25zb2xlRnVuY3Rpb247XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZXJyb3I6IENvbnNvbGVGdW5jdGlvbjtcblxuICAgIGNvbnN0cnVjdG9yKGNvbnNvbGU6IENvbnNvbGUpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIgPSBjb25zb2xlO1xuICAgICAgICAodGhpcy5sb2cgPSBjb25zb2xlLmxvZyksXG4gICAgICAgICAgICAodGhpcy5pbmZvID0gY29uc29sZS5pbmZvKSxcbiAgICAgICAgICAgICh0aGlzLmRlYnVnID0gY29uc29sZS5kZWJ1ZyksXG4gICAgICAgICAgICAodGhpcy53YXJuID0gY29uc29sZS53YXJuKSxcbiAgICAgICAgICAgICh0aGlzLmVycm9yID0gY29uc29sZS5lcnJvcik7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgSkwgfSBmcm9tICdqc25sb2cnO1xuaW1wb3J0IHsgT3BlblZpZHUgfSBmcm9tICcuLi8uLi9PcGVuVmlkdS9PcGVuVmlkdSc7XG5pbXBvcnQgeyBDb25zb2xlTG9nZ2VyIH0gZnJvbSAnLi9Db25zb2xlTG9nZ2VyJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbiB9IGZyb20gJy4vT3BlblZpZHVMb2dnZXJDb25maWd1cmF0aW9uJztcblxuZXhwb3J0IGNsYXNzIE9wZW5WaWR1TG9nZ2VyIHtcbiAgICBwcml2YXRlIHN0YXRpYyBpbnN0YW5jZTogT3BlblZpZHVMb2dnZXI7XG5cbiAgICBwcml2YXRlIEpTTkxPR19VUkw6IHN0cmluZyA9ICcvb3BlbnZpZHUvZWxrL29wZW52aWR1LWJyb3dzZXItbG9ncyc7XG4gICAgcHJpdmF0ZSBNQVhfSlNOTE9HX0JBVENIX0xPR19NRVNTQUdFUzogbnVtYmVyID0gMTAwO1xuICAgIHByaXZhdGUgTUFYX01TRUNPTkRTX0JBVENIX01FU1NBR0VTOiBudW1iZXIgPSA1MDAwO1xuICAgIHByaXZhdGUgTUFYX0xFTkdUSF9TVFJJTkdfSlNPTjogbnVtYmVyID0gMTAwMDtcblxuICAgIHByaXZhdGUgZGVmYXVsdENvbnNvbGVMb2dnZXI6IENvbnNvbGVMb2dnZXIgPSBuZXcgQ29uc29sZUxvZ2dlcihnbG9iYWxUaGlzLmNvbnNvbGUpO1xuXG4gICAgcHJpdmF0ZSBjdXJyZW50QXBwZW5kZXI6IGFueTtcblxuICAgIHByaXZhdGUgaXNQcm9kTW9kZSA9IGZhbHNlO1xuICAgIHByaXZhdGUgaXNKU05Mb2dTZXR1cCA9IGZhbHNlO1xuXG4gICAgLy8gVGhpcyB0d28gdmFyaWFibGVzIGFyZSB1c2VkIHRvIHJlc3RhcnQgSlNOTG9nXG4gICAgLy8gb24gZGlmZmVyZW50IHNlc3Npb25zIGFuZCBkaWZmZXJlbnQgdXNlcklkc1xuICAgIHByaXZhdGUgbG9nZ2luZ1Nlc3Npb25JZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN0YXRpYyBjb25maWd1cmVKU05Mb2cob3BlblZpZHU6IE9wZW5WaWR1LCB0b2tlbjogc3RyaW5nKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBJZiBkZXYgbW9kZSBvci4uLlxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIGdsb2JhbFRoaXNbJ0xPR19KU05MT0dfUkVTVUxUUyddIHx8XG4gICAgICAgICAgICAgICAgLy8gSWYgaW5zdGFuY2UgaXMgY3JlYXRlZCBhbmQgaXQgaXMgT3BlblZpZHUgUHJvXG4gICAgICAgICAgICAgICAgKHRoaXMuaW5zdGFuY2UgJiZcbiAgICAgICAgICAgICAgICAgICAgb3BlblZpZHUuaXNBdExlYXN0UHJvICYmXG4gICAgICAgICAgICAgICAgICAgIC8vIElmIGxvZ3MgYXJlIGVuYWJsZWRcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5pc09wZW5WaWR1QnJvd3NlckxvZ3NEZWJ1Z0FjdGl2ZShvcGVuVmlkdSkgJiZcbiAgICAgICAgICAgICAgICAgICAgLy8gT25seSByZWNvbmZpZ3VyZSBpdCBpZiBzZXNzaW9uIG9yIGZpbmFsVXNlcklkIGhhcyBjaGFuZ2VkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuY2FuQ29uZmlndXJlSlNOTG9nKG9wZW5WaWR1LCB0aGlzLmluc3RhbmNlKSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGFwcCBsb2dzIGNhbiBiZSBzZW50XG4gICAgICAgICAgICAgICAgLy8gYW5kIHJlcGxhY2UgY29uc29sZS5sb2cgZnVuY3Rpb24gdG8gc2VuZFxuICAgICAgICAgICAgICAgIC8vIGxvZ3Mgb2YgdGhlIGFwcGxpY2F0aW9uXG4gICAgICAgICAgICAgICAgaWYgKG9wZW5WaWR1LnNlbmRCcm93c2VyTG9ncyA9PT0gT3BlblZpZHVMb2dnZXJDb25maWd1cmF0aW9uLmRlYnVnX2FwcCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluc3RhbmNlLnJlcGxhY2VXaW5kb3dDb25zb2xlKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gaXNKU05Mb2dTZXR1cCB3aWxsIG5vdCBiZSB0cnVlIHVudGlsIGNvbXBsZXRlZCBzZXR1cFxuICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuaXNKU05Mb2dTZXR1cCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuaW5mbygnQ29uZmlndXJpbmcgSlNOTG9ncy4nKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGZpbmFsVXNlcklkID0gb3BlblZpZHUuZmluYWxVc2VySWQ7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gb3BlblZpZHUuc2Vzc2lvbi5zZXNzaW9uSWQ7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBiZWZvcmVTZW5kQ2FsbGJhY2sgPSAoeGhyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElmIDQwMSBvciA0MDMgb3IgNDA0IG1vZGlmeSByZWFkeSBhbmQgc3RhdHVzIHNvIEpTTkxvZyBkb24ndCByZXRyeSB0byBzZW5kIGxvZ3NcbiAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21wZXJkZWNrL2pzbmxvZy5qcy9ibG9iL3YyLjMwLjAvanNubG9nLnRzI0w4MDUtTDgxOFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnRSZWFkeVN0YXRlRnVuY3Rpb24gPSB4aHIub25yZWFkeXN0YXRlY2hhbmdlO1xuICAgICAgICAgICAgICAgICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNJbnZhbGlkUmVzcG9uc2UoeGhyKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh4aHIsICdyZWFkeVN0YXRlJywgeyB2YWx1ZTogNCB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoeGhyLCAnc3RhdHVzJywgeyB2YWx1ZTogMjAwIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERpc2FibGUgSlNOTG9nIHRvbyB0byBub3Qgc2VuZCBwZXJpb2RpY2FsbHkgZXJyb3JzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5kaXNhYmxlTG9nZ2VyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRSZWFkeVN0YXRlRnVuY3Rpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBIZWFkZXJzIHRvIGlkZW50aWZ5IGFuZCBhdXRoZW50aWNhdGUgbG9nc1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQXV0aG9yaXphdGlvbicsICdCYXNpYyAnICsgYnRvYShgJHtmaW5hbFVzZXJJZH0lLyUke3Nlc3Npb25JZH1gICsgJzonICsgdG9rZW4pKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ1gtUmVxdWVzdGVkLVdpdGgnLCAnWE1MSHR0cFJlcXVlc3QnKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBoZWFkZXJzIGZvciBPcGVuVmlkdVxuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignT1YtRmluYWwtVXNlci1JZCcsIGZpbmFsVXNlcklkKTtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ09WLVNlc3Npb24tSWQnLCBzZXNzaW9uSWQpO1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignT1YtVG9rZW4nLCB0b2tlbik7XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIC8vIENyZWF0aW9uIG9mIHRoZSBhcHBlbmRlci5cbiAgICAgICAgICAgICAgICB0aGlzLmluc3RhbmNlLmN1cnJlbnRBcHBlbmRlciA9IEpMLmNyZWF0ZUFqYXhBcHBlbmRlcihgYXBwZW5kZXItJHtmaW5hbFVzZXJJZH0tJHtzZXNzaW9uSWR9YCk7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5jdXJyZW50QXBwZW5kZXIuc2V0T3B0aW9ucyh7XG4gICAgICAgICAgICAgICAgICAgIGJlZm9yZVNlbmQ6IGJlZm9yZVNlbmRDYWxsYmFjayxcbiAgICAgICAgICAgICAgICAgICAgbWF4QmF0Y2hTaXplOiAxMDAwLFxuICAgICAgICAgICAgICAgICAgICBiYXRjaFNpemU6IHRoaXMuaW5zdGFuY2UuTUFYX0pTTkxPR19CQVRDSF9MT0dfTUVTU0FHRVMsXG4gICAgICAgICAgICAgICAgICAgIGJhdGNoVGltZW91dDogdGhpcy5pbnN0YW5jZS5NQVhfTVNFQ09ORFNfQkFUQ0hfTUVTU0FHRVNcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIC8vIEF2b2lkIGNpcmN1bGFyIGRlcGVuZGVuY2llc1xuICAgICAgICAgICAgICAgIGNvbnN0IGxvZ1NlcmlhbGl6ZXIgPSAob2JqKTogc3RyaW5nID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2V0Q2lyY3VsYXJSZXBsYWNlciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHNlZW4gPSBuZXcgV2Vha1NldCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChrZXksIHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2Vlbi5oYXModmFsdWUpIHx8IChnbG9iYWxUaGlzLkhUTUxFbGVtZW50ICYmIHZhbHVlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vlbi5hZGQodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIEN1dCBsb25nIG1lc3NhZ2VzXG4gICAgICAgICAgICAgICAgICAgIGxldCBzdHJpbmdpZnlKc29uID0gSlNPTi5zdHJpbmdpZnkob2JqLCBnZXRDaXJjdWxhclJlcGxhY2VyKCkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RyaW5naWZ5SnNvbi5sZW5ndGggPiB0aGlzLmluc3RhbmNlLk1BWF9MRU5HVEhfU1RSSU5HX0pTT04pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ2lmeUpzb24gPSBgJHtzdHJpbmdpZnlKc29uLnN1YnN0cmluZygwLCB0aGlzLmluc3RhbmNlLk1BWF9MRU5HVEhfU1RSSU5HX0pTT04pfS4uLmA7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoZ2xvYmFsVGhpc1snTE9HX0pTTkxPR19SRVNVTFRTJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHN0cmluZ2lmeUpzb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0cmluZ2lmeUpzb247XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgSkwgdG8gc2VuZCBsb2dzXG4gICAgICAgICAgICAgICAgSkwuc2V0T3B0aW9ucyh7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRBamF4VXJsOiBvcGVuVmlkdS5odHRwVXJpICsgdGhpcy5pbnN0YW5jZS5KU05MT0dfVVJMLFxuICAgICAgICAgICAgICAgICAgICBzZXJpYWxpemU6IGxvZ1NlcmlhbGl6ZXIsXG4gICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBKTCgpLnNldE9wdGlvbnMoe1xuICAgICAgICAgICAgICAgICAgICBhcHBlbmRlcnM6IFt0aGlzLmluc3RhbmNlLmN1cnJlbnRBcHBlbmRlcl1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuaXNKU05Mb2dTZXR1cCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnN0YW5jZS5sb2dnaW5nU2Vzc2lvbklkID0gc2Vzc2lvbklkO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuaW5mbygnSlNOTG9nIGNvbmZpZ3VyZWQuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIFByaW50IGVycm9yXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBjb25maWd1cmluZyBKU05Mb2c6ICcpO1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICAgIC8vIFJlc3RvcmUgZGVmYXVsdHMgdmFsdWVzIGp1c3QgaW4gY2FzZSBhbnkgZXhjZXB0aW9uIGhhcHBlbi1cbiAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UuZGlzYWJsZUxvZ2dlcigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRJbnN0YW5jZSgpOiBPcGVuVmlkdUxvZ2dlciB7XG4gICAgICAgIGlmICghT3BlblZpZHVMb2dnZXIuaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIE9wZW5WaWR1TG9nZ2VyLmluc3RhbmNlID0gbmV3IE9wZW5WaWR1TG9nZ2VyKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIE9wZW5WaWR1TG9nZ2VyLmluc3RhbmNlO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGlzSW52YWxpZFJlc3BvbnNlKHhocjogWE1MSHR0cFJlcXVlc3QpIHtcbiAgICAgICAgcmV0dXJuIHhoci5zdGF0dXMgPT0gNDAxIHx8IHhoci5zdGF0dXMgPT0gNDAzIHx8IHhoci5zdGF0dXMgPT0gNDA0IHx8IHhoci5zdGF0dXMgPT0gMDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNhbkNvbmZpZ3VyZUpTTkxvZyhvcGVuVmlkdTogT3BlblZpZHUsIGxvZ2dlcjogT3BlblZpZHVMb2dnZXIpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIG9wZW5WaWR1LnNlc3Npb24uc2Vzc2lvbklkICE9IGxvZ2dlci5sb2dnaW5nU2Vzc2lvbklkO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNPcGVuVmlkdUJyb3dzZXJMb2dzRGVidWdBY3RpdmUob3BlblZpZHU6IE9wZW5WaWR1KSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBvcGVuVmlkdS5zZW5kQnJvd3NlckxvZ3MgPT09IE9wZW5WaWR1TG9nZ2VyQ29uZmlndXJhdGlvbi5kZWJ1ZyB8fFxuICAgICAgICAgICAgb3BlblZpZHUuc2VuZEJyb3dzZXJMb2dzID09PSBPcGVuVmlkdUxvZ2dlckNvbmZpZ3VyYXRpb24uZGVidWdfYXBwXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIGNvbnNvbGUgZnVuY3Rpb25zIHdpdGgganNubG9nIGludGVncmF0aW9uXG4gICAgcHJpdmF0ZSBnZXRDb25zb2xlV2l0aEpTTkxvZygpIHtcbiAgICAgICAgcmV0dXJuIChmdW5jdGlvbiAob3BlblZpZHVMb2dnZXI6IE9wZW5WaWR1TG9nZ2VyKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGxvZzogZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlblZpZHVMb2dnZXIuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nLmFwcGx5KG9wZW5WaWR1TG9nZ2VyLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmxvZ2dlciwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW5WaWR1TG9nZ2VyLmlzSlNOTG9nU2V0dXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEpMKCkuaW5mbyhhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBpbmZvOiBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgICAgICAgICAgICAgICAgICBvcGVuVmlkdUxvZ2dlci5kZWZhdWx0Q29uc29sZUxvZ2dlci5pbmZvLmFwcGx5KG9wZW5WaWR1TG9nZ2VyLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmxvZ2dlciwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW5WaWR1TG9nZ2VyLmlzSlNOTG9nU2V0dXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEpMKCkuaW5mbyhhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBkZWJ1ZzogZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlblZpZHVMb2dnZXIuZGVmYXVsdENvbnNvbGVMb2dnZXIuZGVidWcuYXBwbHkob3BlblZpZHVMb2dnZXIuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgd2FybjogZnVuY3Rpb24gKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlblZpZHVMb2dnZXIuZGVmYXVsdENvbnNvbGVMb2dnZXIud2Fybi5hcHBseShvcGVuVmlkdUxvZ2dlci5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2dnZXIsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcGVuVmlkdUxvZ2dlci5pc0pTTkxvZ1NldHVwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBKTCgpLndhcm4oYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgICAgIG9wZW5WaWR1TG9nZ2VyLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmVycm9yLmFwcGx5KG9wZW5WaWR1TG9nZ2VyLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmxvZ2dlciwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW5WaWR1TG9nZ2VyLmlzSlNOTG9nU2V0dXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEpMKCkuZXJyb3IoYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKHRoaXMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVwbGFjZVdpbmRvd0NvbnNvbGUoKSB7XG4gICAgICAgIGdsb2JhbFRoaXMuY29uc29sZSA9IHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUubG9nID0gdGhpcy5nZXRDb25zb2xlV2l0aEpTTkxvZygpLmxvZztcbiAgICAgICAgZ2xvYmFsVGhpcy5jb25zb2xlLmluZm8gPSB0aGlzLmdldENvbnNvbGVXaXRoSlNOTG9nKCkuaW5mbztcbiAgICAgICAgZ2xvYmFsVGhpcy5jb25zb2xlLmRlYnVnID0gdGhpcy5nZXRDb25zb2xlV2l0aEpTTkxvZygpLmRlYnVnO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUud2FybiA9IHRoaXMuZ2V0Q29uc29sZVdpdGhKU05Mb2coKS53YXJuO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUuZXJyb3IgPSB0aGlzLmdldENvbnNvbGVXaXRoSlNOTG9nKCkuZXJyb3I7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBkaXNhYmxlTG9nZ2VyKCkge1xuICAgICAgICBKTC5zZXRPcHRpb25zKHsgZW5hYmxlZDogZmFsc2UgfSk7XG4gICAgICAgIHRoaXMuaXNKU05Mb2dTZXR1cCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmxvZ2dpbmdTZXNzaW9uSWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuY3VycmVudEFwcGVuZGVyID0gdW5kZWZpbmVkO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUgPSB0aGlzLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmxvZ2dlcjtcbiAgICAgICAgZ2xvYmFsVGhpcy5jb25zb2xlLmxvZyA9IHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nO1xuICAgICAgICBnbG9iYWxUaGlzLmNvbnNvbGUuaW5mbyA9IHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIuaW5mbztcbiAgICAgICAgZ2xvYmFsVGhpcy5jb25zb2xlLmRlYnVnID0gdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5kZWJ1ZztcbiAgICAgICAgZ2xvYmFsVGhpcy5jb25zb2xlLndhcm4gPSB0aGlzLmRlZmF1bHRDb25zb2xlTG9nZ2VyLndhcm47XG4gICAgICAgIGdsb2JhbFRoaXMuY29uc29sZS5lcnJvciA9IHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIuZXJyb3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGxvZyguLi5hcmdzOiBhbnlbXSkge1xuICAgICAgICBpZiAoIXRoaXMuaXNQcm9kTW9kZSkge1xuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2cuYXBwbHkodGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2dnZXIsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaXNKU05Mb2dTZXR1cCkge1xuICAgICAgICAgICAgSkwoKS5pbmZvKGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZGVidWcoLi4uYXJnczogYW55W10pIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzUHJvZE1vZGUpIHtcbiAgICAgICAgICAgIHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIuZGVidWcuYXBwbHkodGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5sb2dnZXIsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgaW5mbyguLi5hcmdzOiBhbnlbXSkge1xuICAgICAgICBpZiAoIXRoaXMuaXNQcm9kTW9kZSkge1xuICAgICAgICAgICAgdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci5pbmZvLmFwcGx5KHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmlzSlNOTG9nU2V0dXApIHtcbiAgICAgICAgICAgIEpMKCkuaW5mbyhhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHdhcm4oLi4uYXJnczogYW55W10pIHtcbiAgICAgICAgdGhpcy5kZWZhdWx0Q29uc29sZUxvZ2dlci53YXJuLmFwcGx5KHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyLCBhcmd1bWVudHMpO1xuICAgICAgICBpZiAodGhpcy5pc0pTTkxvZ1NldHVwKSB7XG4gICAgICAgICAgICBKTCgpLndhcm4oYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBlcnJvciguLi5hcmdzOiBhbnlbXSkge1xuICAgICAgICB0aGlzLmRlZmF1bHRDb25zb2xlTG9nZ2VyLmVycm9yLmFwcGx5KHRoaXMuZGVmYXVsdENvbnNvbGVMb2dnZXIubG9nZ2VyLCBhcmd1bWVudHMpO1xuICAgICAgICBpZiAodGhpcy5pc0pTTkxvZ1NldHVwKSB7XG4gICAgICAgICAgICBKTCgpLmVycm9yKGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgZmx1c2goKSB7XG4gICAgICAgIGlmICh0aGlzLmlzSlNOTG9nU2V0dXAgJiYgdGhpcy5jdXJyZW50QXBwZW5kZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50QXBwZW5kZXIuc2VuZEJhdGNoKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBlbmFibGVQcm9kTW9kZSgpIHtcbiAgICAgICAgdGhpcy5pc1Byb2RNb2RlID0gdHJ1ZTtcbiAgICB9XG59XG4iLCJleHBvcnQgZW51bSBPcGVuVmlkdUxvZ2dlckNvbmZpZ3VyYXRpb24ge1xuICAgIGRpc2FibGVkID0gJ2Rpc2FibGVkJyxcbiAgICBkZWJ1ZyA9ICdkZWJ1ZycsXG4gICAgZGVidWdfYXBwID0gJ2RlYnVnX2FwcCdcbn1cbiIsIi8vIExhc3QgdGltZSB1cGRhdGVkIG9uIEp1bmUgMDgsIDIwMThcblxuLy8gTGF0ZXN0IGZpbGUgY2FuIGJlIGZvdW5kIGhlcmU6IGh0dHBzOi8vY2RuLndlYnJ0Yy1leHBlcmltZW50LmNvbS9nZXRTY3JlZW5JZC5qc1xuXG4vLyBNdWF6IEtoYW4gICAgICAgICAtIHd3dy5NdWF6S2hhbi5jb21cbi8vIE1JVCBMaWNlbnNlICAgICAgIC0gd3d3LldlYlJUQy1FeHBlcmltZW50LmNvbS9saWNlbmNlXG4vLyBEb2N1bWVudGF0aW9uICAgICAtIGh0dHBzOi8vZ2l0aHViLmNvbS9tdWF6LWtoYW4vZ2V0U2NyZWVuSWQuXG5cbi8vIF9fX19fX19fX19fX19fXG4vLyBnZXRTY3JlZW5JZC5qc1xuXG4vKlxuZ2V0U2NyZWVuSWQoZnVuY3Rpb24gKGVycm9yLCBzb3VyY2VJZCwgc2NyZWVuX2NvbnN0cmFpbnRzKSB7XG4gICAgLy8gZXJyb3IgICAgPT0gbnVsbCB8fCAncGVybWlzc2lvbi1kZW5pZWQnIHx8ICdub3QtaW5zdGFsbGVkJyB8fCAnaW5zdGFsbGVkLWRpc2FibGVkJyB8fCAnbm90LWNocm9tZSdcbiAgICAvLyBzb3VyY2VJZCA9PSBudWxsIHx8ICdzdHJpbmcnIHx8ICdmaXJlZm94J1xuXG4gICAgaWYobWljcm9zb2Z0RWRnZSkge1xuICAgICAgICBuYXZpZ2F0b3IuZ2V0RGlzcGxheU1lZGlhKHNjcmVlbl9jb25zdHJhaW50cykudGhlbihvblN1Y2Nlc3MsIG9uRmFpbHVyZSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzKWNhdGNoKG9uRmFpbHVyZSk7XG4gICAgfVxufSwgJ3Bhc3Mgc2Vjb25kIHBhcmFtZXRlciBvbmx5IGlmIHlvdSB3YW50IHN5c3RlbSBhdWRpbycpO1xuKi9cblxuZ2xvYmFsVGhpcy5nZXRTY3JlZW5JZCA9IGZ1bmN0aW9uIChmaXJlZm94U3RyaW5nLCBjYWxsYmFjaywgY3VzdG9tX3BhcmFtZXRlcikge1xuICAgIGlmIChuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0VkZ2UnKSAhPT0gLTEgJiYgKCEhbmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IgfHwgISFuYXZpZ2F0b3IubXNTYXZlQmxvYikpIHtcbiAgICAgICAgLy8gbWljcm9zb2Z0IGVkZ2UgPT4gbmF2aWdhdG9yLmdldERpc3BsYXlNZWRpYShzY3JlZW5fY29uc3RyYWludHMpLnRoZW4ob25TdWNjZXNzLCBvbkZhaWx1cmUpO1xuICAgICAgICBjYWxsYmFjayh7XG4gICAgICAgICAgICB2aWRlbzogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGZvciBGaXJlZm94OlxuICAgIC8vIHNvdXJjZUlkID09ICdmaXJlZm94J1xuICAgIC8vIHNjcmVlbl9jb25zdHJhaW50cyA9IHsuLi59XG4gICAgaWYgKCEhbmF2aWdhdG9yLm1vekdldFVzZXJNZWRpYSkge1xuICAgICAgICBjYWxsYmFjayhudWxsLCAnZmlyZWZveCcsIHtcbiAgICAgICAgICAgIHZpZGVvOiB7XG4gICAgICAgICAgICAgICAgbW96TWVkaWFTb3VyY2U6IGZpcmVmb3hTdHJpbmcsXG4gICAgICAgICAgICAgICAgbWVkaWFTb3VyY2U6IGZpcmVmb3hTdHJpbmdcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBnbG9iYWxUaGlzLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbklGcmFtZUNhbGxiYWNrKTtcblxuICAgIGZ1bmN0aW9uIG9uSUZyYW1lQ2FsbGJhY2soZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudC5kYXRhKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCA9PT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygncGVybWlzc2lvbi1kZW5pZWQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmRhdGEuY2hyb21lTWVkaWFTb3VyY2VJZCxcbiAgICAgICAgICAgICAgICAgICAgZ2V0U2NyZWVuQ29uc3RyYWludHMobnVsbCwgZXZlbnQuZGF0YS5jaHJvbWVNZWRpYVNvdXJjZUlkLCBldmVudC5kYXRhLmNhblJlcXVlc3RBdWRpb1RyYWNrKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRoaXMgZXZlbnQgbGlzdGVuZXIgaXMgbm8gbW9yZSBuZWVkZWRcbiAgICAgICAgICAgIGdsb2JhbFRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhldmVudC5kYXRhLmNocm9tZUV4dGVuc2lvblN0YXR1cywgbnVsbCwgZ2V0U2NyZWVuQ29uc3RyYWludHMoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpKTtcblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgZ2xvYmFsVGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICAgICAgc2V0VGltZW91dChwb3N0R2V0U291cmNlSWRNZXNzYWdlLCAxMDApO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcG9zdEdldFNvdXJjZUlkTWVzc2FnZShjdXN0b21fcGFyYW1ldGVyKTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICB9XG59O1xuXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50cyhlcnJvciwgc291cmNlSWQsIGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgdmFyIHNjcmVlbl9jb25zdHJhaW50cyA9IHtcbiAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICB2aWRlbzoge1xuICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGVycm9yID8gJ3NjcmVlbicgOiAnZGVza3RvcCcsXG4gICAgICAgICAgICAgICAgbWF4V2lkdGg6IGdsb2JhbFRoaXMuc2NyZWVuLndpZHRoID4gMTkyMCA/IGdsb2JhbFRoaXMuc2NyZWVuLndpZHRoIDogMTkyMCxcbiAgICAgICAgICAgICAgICBtYXhIZWlnaHQ6IGdsb2JhbFRoaXMuc2NyZWVuLmhlaWdodCA+IDEwODAgPyBnbG9iYWxUaGlzLnNjcmVlbi5oZWlnaHQgOiAxMDgwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKCEhY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvID0ge1xuICAgICAgICAgICAgbWFuZGF0b3J5OiB7XG4gICAgICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGVycm9yID8gJ3NjcmVlbicgOiAnZGVza3RvcCdcbiAgICAgICAgICAgICAgICAvLyBlY2hvQ2FuY2VsbGF0aW9uOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uYWw6IFtdXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHNvdXJjZUlkKSB7XG4gICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy52aWRlby5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuXG4gICAgICAgIGlmIChzY3JlZW5fY29uc3RyYWludHMuYXVkaW8gJiYgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeSkge1xuICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmF1ZGlvLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc2NyZWVuX2NvbnN0cmFpbnRzO1xufVxuXG5mdW5jdGlvbiBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpIHtcbiAgICBpZiAoIWlmcmFtZSkge1xuICAgICAgICBsb2FkSUZyYW1lKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHBvc3RHZXRTb3VyY2VJZE1lc3NhZ2UoY3VzdG9tX3BhcmFtZXRlcik7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFpZnJhbWUuaXNMb2FkZWQpIHtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBwb3N0R2V0U291cmNlSWRNZXNzYWdlKGN1c3RvbV9wYXJhbWV0ZXIpO1xuICAgICAgICB9LCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjdXN0b21fcGFyYW1ldGVyKSB7XG4gICAgICAgIGlmcmFtZS5jb250ZW50V2luZG93LnBvc3RNZXNzYWdlKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNhcHR1cmVTb3VyY2VJZDogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICcqJ1xuICAgICAgICApO1xuICAgIH0gZWxzZSBpZiAoISFjdXN0b21fcGFyYW1ldGVyLmZvckVhY2gpIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY2FwdHVyZUN1c3RvbVNvdXJjZUlkOiBjdXN0b21fcGFyYW1ldGVyXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJyonXG4gICAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvOiB0cnVlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJyonXG4gICAgICAgICk7XG4gICAgfVxufVxuXG52YXIgaWZyYW1lO1xuXG4vLyB0aGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gUlRDTXVsdGlDb25uZWN0aW9uIHYzXG5nbG9iYWxUaGlzLmdldFNjcmVlbkNvbnN0cmFpbnRzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgbG9hZElGcmFtZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGdldFNjcmVlbklkKGZ1bmN0aW9uIChlcnJvciwgc291cmNlSWQsIHNjcmVlbl9jb25zdHJhaW50cykge1xuICAgICAgICAgICAgaWYgKCFzY3JlZW5fY29uc3RyYWludHMpIHtcbiAgICAgICAgICAgICAgICBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZGVvOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2FsbGJhY2soZXJyb3IsIHNjcmVlbl9jb25zdHJhaW50cy52aWRlbyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufTtcblxuZnVuY3Rpb24gbG9hZElGcmFtZShsb2FkQ2FsbGJhY2spIHtcbiAgICBpZiAoaWZyYW1lKSB7XG4gICAgICAgIGxvYWRDYWxsYmFjaygpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgaWZyYW1lLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWZyYW1lLmlzTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgbG9hZENhbGxiYWNrKCk7XG4gICAgfTtcbiAgICBpZnJhbWUuc3JjID0gJ2h0dHBzOi8vb3BlbnZpZHUuZ2l0aHViLmlvL29wZW52aWR1LXNjcmVlbi1zaGFyaW5nLWNocm9tZS1leHRlbnNpb24vJztcbiAgICBpZnJhbWUuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAoZG9jdW1lbnQuYm9keSB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmFwcGVuZENoaWxkKGlmcmFtZSk7XG59XG5cbmdsb2JhbFRoaXMuZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgLy8gZm9yIEZpcmVmb3g6XG4gICAgaWYgKCEhbmF2aWdhdG9yLm1vekdldFVzZXJNZWRpYSkge1xuICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWVuYWJsZWQnKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGdsb2JhbFRoaXMuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uSUZyYW1lQ2FsbGJhY2spO1xuXG4gICAgZnVuY3Rpb24gb25JRnJhbWVDYWxsYmFjayhldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LmRhdGEpIHJldHVybjtcblxuICAgICAgICBpZiAoZXZlbnQuZGF0YS5jaHJvbWVFeHRlbnNpb25TdGF0dXMpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50LmRhdGEuY2hyb21lRXh0ZW5zaW9uU3RhdHVzKTtcblxuICAgICAgICAgICAgLy8gdGhpcyBldmVudCBsaXN0ZW5lciBpcyBubyBtb3JlIG5lZWRlZFxuICAgICAgICAgICAgZ2xvYmFsVGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25JRnJhbWVDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xufTtcblxuZnVuY3Rpb24gcG9zdEdldENocm9tZUV4dGVuc2lvblN0YXR1c01lc3NhZ2UoKSB7XG4gICAgaWYgKCFpZnJhbWUpIHtcbiAgICAgICAgbG9hZElGcmFtZShwb3N0R2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzTWVzc2FnZSk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWlmcmFtZS5pc0xvYWRlZCkge1xuICAgICAgICBzZXRUaW1lb3V0KHBvc3RHZXRDaHJvbWVFeHRlbnNpb25TdGF0dXNNZXNzYWdlLCAxMDApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWZyYW1lLmNvbnRlbnRXaW5kb3cucG9zdE1lc3NhZ2UoXG4gICAgICAgIHtcbiAgICAgICAgICAgIGdldENocm9tZUV4dGVuc2lvblN0YXR1czogdHJ1ZVxuICAgICAgICB9LFxuICAgICAgICAnKidcbiAgICApO1xufVxuXG5leHBvcnRzLmdldFNjcmVlbklkID0gZ2xvYmFsVGhpcy5nZXRTY3JlZW5JZDtcbiIsIi8vIGdsb2JhbCB2YXJpYWJsZXNcbnZhciBjaHJvbWVNZWRpYVNvdXJjZSA9ICdzY3JlZW4nO1xudmFyIHNvdXJjZUlkO1xudmFyIHNjcmVlbkNhbGxiYWNrO1xuXG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG5hdmlnYXRvci51c2VyQWdlbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdmFyIGlzRmlyZWZveCA9IHR5cGVvZiB3aW5kb3cuSW5zdGFsbFRyaWdnZXIgIT09ICd1bmRlZmluZWQnO1xuICAgIHZhciBpc09wZXJhID0gISF3aW5kb3cub3BlcmEgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCcgT1BSLycpID49IDA7XG4gICAgdmFyIGlzQ2hyb21lID0gISF3aW5kb3cuY2hyb21lICYmICFpc09wZXJhO1xuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50Lm9yaWdpbiAhPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgb25NZXNzYWdlQ2FsbGJhY2soZXZlbnQuZGF0YSk7XG4gICAgfSk7XG59XG5cbi8vIGFuZCB0aGUgZnVuY3Rpb24gdGhhdCBoYW5kbGVzIHJlY2VpdmVkIG1lc3NhZ2VzXG5mdW5jdGlvbiBvbk1lc3NhZ2VDYWxsYmFjayhkYXRhKSB7XG4gICAgLy8gXCJjYW5jZWxcIiBidXR0b24gaXMgY2xpY2tlZFxuICAgIGlmIChkYXRhID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKSB7XG4gICAgICAgIGlmIChzY3JlZW5DYWxsYmFjaykgcmV0dXJuIHNjcmVlbkNhbGxiYWNrKCdQZXJtaXNzaW9uRGVuaWVkRXJyb3InKTtcbiAgICAgICAgZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicpO1xuICAgIH1cbiAgICAvLyBleHRlbnNpb24gbm90aWZpZWQgaGlzIHByZXNlbmNlXG4gICAgaWYgKGRhdGEgPT0gJ3J0Y211bHRpY29ubmVjdGlvbi1leHRlbnNpb24tbG9hZGVkJykge1xuICAgICAgICBjaHJvbWVNZWRpYVNvdXJjZSA9ICdkZXNrdG9wJztcbiAgICB9XG4gICAgLy8gZXh0ZW5zaW9uIHNoYXJlZCB0ZW1wIHNvdXJjZUlkXG4gICAgaWYgKGRhdGEuc291cmNlSWQgJiYgc2NyZWVuQ2FsbGJhY2spIHtcbiAgICAgICAgc2NyZWVuQ2FsbGJhY2soKHNvdXJjZUlkID0gZGF0YS5zb3VyY2VJZCksIGRhdGEuY2FuUmVxdWVzdEF1ZGlvVHJhY2sgPT09IHRydWUpO1xuICAgIH1cbn1cblxuLy8gdGhpcyBtZXRob2QgY2FuIGJlIHVzZWQgdG8gY2hlY2sgaWYgY2hyb21lIGV4dGVuc2lvbiBpcyBpbnN0YWxsZWQgJiBlbmFibGVkLlxuZnVuY3Rpb24gaXNDaHJvbWVFeHRlbnNpb25BdmFpbGFibGUoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSByZXR1cm47XG4gICAgaWYgKGNocm9tZU1lZGlhU291cmNlID09ICdkZXNrdG9wJykgcmV0dXJuIGNhbGxiYWNrKHRydWUpO1xuXG4gICAgLy8gYXNrIGV4dGVuc2lvbiBpZiBpdCBpcyBhdmFpbGFibGVcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2FyZS15b3UtdGhlcmUnLCAnKicpO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIGNhbGxiYWNrKHRydWUpO1xuICAgIH0sIDIwMDApO1xufVxuXG4vLyB0aGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIGdldCBcInNvdXJjZS1pZFwiIGZyb20gdGhlIGV4dGVuc2lvblxuZnVuY3Rpb24gZ2V0U291cmNlSWQoY2FsbGJhY2spIHtcbiAgICBpZiAoIWNhbGxiYWNrKSB0aHJvdyAnXCJjYWxsYmFja1wiIHBhcmFtZXRlciBpcyBtYW5kYXRvcnkuJztcbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2dldC1zb3VyY2VJZCcsICcqJyk7XG59XG5cbi8vIHRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gZ2V0IFwic291cmNlLWlkXCIgZnJvbSB0aGUgZXh0ZW5zaW9uXG5mdW5jdGlvbiBnZXRDdXN0b21Tb3VyY2VJZChhcnIsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCFhcnIgfHwgIWFyci5mb3JFYWNoKSB0aHJvdyAnXCJhcnJcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5IGFuZCBpdCBtdXN0IGJlIGFuIGFycmF5Lic7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG5cbiAgICBpZiAoc291cmNlSWQpIHJldHVybiBjYWxsYmFjayhzb3VyY2VJZCk7XG5cbiAgICBzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgIHdpbmRvdy5wb3N0TWVzc2FnZShcbiAgICAgICAge1xuICAgICAgICAgICAgJ2dldC1jdXN0b20tc291cmNlSWQnOiBhcnJcbiAgICAgICAgfSxcbiAgICAgICAgJyonXG4gICAgKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZXQgXCJzb3VyY2UtaWRcIiBmcm9tIHRoZSBleHRlbnNpb25cbmZ1bmN0aW9uIGdldFNvdXJjZUlkV2l0aEF1ZGlvKGNhbGxiYWNrKSB7XG4gICAgaWYgKCFjYWxsYmFjaykgdGhyb3cgJ1wiY2FsbGJhY2tcIiBwYXJhbWV0ZXIgaXMgbWFuZGF0b3J5Lic7XG4gICAgaWYgKHNvdXJjZUlkKSByZXR1cm4gY2FsbGJhY2soc291cmNlSWQpO1xuXG4gICAgc2NyZWVuQ2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2F1ZGlvLXBsdXMtdGFiJywgJyonKTtcbn1cblxuZnVuY3Rpb24gZ2V0Q2hyb21lRXh0ZW5zaW9uU3RhdHVzKGV4dGVuc2lvbmlkLCBjYWxsYmFjaykge1xuICAgIGlmIChpc0ZpcmVmb3gpIHJldHVybiBjYWxsYmFjaygnbm90LWNocm9tZScpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoICE9IDIpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBleHRlbnNpb25pZDtcbiAgICAgICAgZXh0ZW5zaW9uaWQgPSAnbGZjZ2ZlcGFmbm9iZGxvZWNjaG5mYWNsaWJlbmpvbGQnOyAvLyBkZWZhdWx0IGV4dGVuc2lvbi1pZFxuICAgIH1cbiAgICB2YXIgaW1hZ2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICBpbWFnZS5zcmMgPSAnY2hyb21lLWV4dGVuc2lvbjovLycgKyBleHRlbnNpb25pZCArICcvaWNvbi5wbmcnO1xuICAgIGltYWdlLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2hyb21lTWVkaWFTb3VyY2UgPSAnc2NyZWVuJztcbiAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKCdhcmUteW91LXRoZXJlJywgJyonKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ3NjcmVlbicpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygnaW5zdGFsbGVkLWRpc2FibGVkJyk7XG4gICAgICAgICAgICB9IGVsc2UgY2FsbGJhY2soJ2luc3RhbGxlZC1lbmFibGVkJyk7XG4gICAgICAgIH0sIDIwMDApO1xuICAgIH07XG4gICAgaW1hZ2Uub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY2FsbGJhY2soJ25vdC1pbnN0YWxsZWQnKTtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBnZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbyhjYWxsYmFjaykge1xuICAgIGdldFNjcmVlbkNvbnN0cmFpbnRzKGNhbGxiYWNrLCB0cnVlKTtcbn1cblxuLy8gdGhpcyBmdW5jdGlvbiBleHBsYWlucyBob3cgdG8gdXNlIGFib3ZlIG1ldGhvZHMvb2JqZWN0c1xuZnVuY3Rpb24gZ2V0U2NyZWVuQ29uc3RyYWludHMoY2FsbGJhY2ssIGNhcHR1cmVTb3VyY2VJZFdpdGhBdWRpbykge1xuICAgIHNvdXJjZUlkID0gJyc7XG4gICAgdmFyIGZpcmVmb3hTY3JlZW5Db25zdHJhaW50cyA9IHtcbiAgICAgICAgbW96TWVkaWFTb3VyY2U6ICd3aW5kb3cnLFxuICAgICAgICBtZWRpYVNvdXJjZTogJ3dpbmRvdydcbiAgICB9O1xuICAgIGlmIChpc0ZpcmVmb3gpIHJldHVybiBjYWxsYmFjayhudWxsLCBmaXJlZm94U2NyZWVuQ29uc3RyYWludHMpO1xuICAgIC8vIHRoaXMgc3RhdGVtZW50IGRlZmluZXMgZ2V0VXNlck1lZGlhIGNvbnN0cmFpbnRzXG4gICAgLy8gdGhhdCB3aWxsIGJlIHVzZWQgdG8gY2FwdHVyZSBjb250ZW50IG9mIHNjcmVlblxuICAgIHZhciBzY3JlZW5fY29uc3RyYWludHMgPSB7XG4gICAgICAgIG1hbmRhdG9yeToge1xuICAgICAgICAgICAgY2hyb21lTWVkaWFTb3VyY2U6IGNocm9tZU1lZGlhU291cmNlLFxuICAgICAgICAgICAgbWF4V2lkdGg6IHNjcmVlbi53aWR0aCA+IDE5MjAgPyBzY3JlZW4ud2lkdGggOiAxOTIwLFxuICAgICAgICAgICAgbWF4SGVpZ2h0OiBzY3JlZW4uaGVpZ2h0ID4gMTA4MCA/IHNjcmVlbi5oZWlnaHQgOiAxMDgwXG4gICAgICAgIH0sXG4gICAgICAgIG9wdGlvbmFsOiBbXVxuICAgIH07XG4gICAgLy8gdGhpcyBzdGF0ZW1lbnQgdmVyaWZpZXMgY2hyb21lIGV4dGVuc2lvbiBhdmFpbGFiaWxpdHlcbiAgICAvLyBpZiBpbnN0YWxsZWQgYW5kIGF2YWlsYWJsZSB0aGVuIGl0IHdpbGwgaW52b2tlIGV4dGVuc2lvbiBBUElcbiAgICAvLyBvdGhlcndpc2UgaXQgd2lsbCBmYWxsYmFjayB0byBjb21tYW5kLWxpbmUgYmFzZWQgc2NyZWVuIGNhcHR1cmluZyBBUElcbiAgICBpZiAoY2hyb21lTWVkaWFTb3VyY2UgPT0gJ2Rlc2t0b3AnICYmICFzb3VyY2VJZCkge1xuICAgICAgICBpZiAoY2FwdHVyZVNvdXJjZUlkV2l0aEF1ZGlvKSB7XG4gICAgICAgICAgICBnZXRTb3VyY2VJZFdpdGhBdWRpbyhmdW5jdGlvbiAoc291cmNlSWQsIGNhblJlcXVlc3RBdWRpb1RyYWNrKSB7XG4gICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoY2FuUmVxdWVzdEF1ZGlvVHJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLmNhblJlcXVlc3RBdWRpb1RyYWNrID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soc291cmNlSWQgPT0gJ1Blcm1pc3Npb25EZW5pZWRFcnJvcicgPyBzb3VyY2VJZCA6IG51bGwsIHNjcmVlbl9jb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdldFNvdXJjZUlkKGZ1bmN0aW9uIChzb3VyY2VJZCkge1xuICAgICAgICAgICAgICAgIHNjcmVlbl9jb25zdHJhaW50cy5tYW5kYXRvcnkuY2hyb21lTWVkaWFTb3VyY2VJZCA9IHNvdXJjZUlkO1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKHNvdXJjZUlkID09ICdQZXJtaXNzaW9uRGVuaWVkRXJyb3InID8gc291cmNlSWQgOiBudWxsLCBzY3JlZW5fY29uc3RyYWludHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHRoaXMgc3RhdGVtZW50IHNldHMgZ2V0cyAnc291cmNlSWRcIiBhbmQgc2V0cyBcImNocm9tZU1lZGlhU291cmNlSWRcIlxuICAgIGlmIChjaHJvbWVNZWRpYVNvdXJjZSA9PSAnZGVza3RvcCcpIHtcbiAgICAgICAgc2NyZWVuX2NvbnN0cmFpbnRzLm1hbmRhdG9yeS5jaHJvbWVNZWRpYVNvdXJjZUlkID0gc291cmNlSWQ7XG4gICAgfVxuXG4gICAgLy8gbm93IGludm9raW5nIG5hdGl2ZSBnZXRVc2VyTWVkaWEgQVBJXG4gICAgY2FsbGJhY2sobnVsbCwgc2NyZWVuX2NvbnN0cmFpbnRzKTtcbn1cblxuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50cyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzO1xuZXhwb3J0cy5nZXRTY3JlZW5Db25zdHJhaW50c1dpdGhBdWRpbyA9IGdldFNjcmVlbkNvbnN0cmFpbnRzV2l0aEF1ZGlvO1xuZXhwb3J0cy5pc0Nocm9tZUV4dGVuc2lvbkF2YWlsYWJsZSA9IGlzQ2hyb21lRXh0ZW5zaW9uQXZhaWxhYmxlO1xuZXhwb3J0cy5nZXRDaHJvbWVFeHRlbnNpb25TdGF0dXMgPSBnZXRDaHJvbWVFeHRlbnNpb25TdGF0dXM7XG5leHBvcnRzLmdldFNvdXJjZUlkID0gZ2V0U291cmNlSWQ7XG4iLCJpbXBvcnQgcGxhdGZvcm0gPSByZXF1aXJlKCdwbGF0Zm9ybScpO1xuXG5leHBvcnQgY2xhc3MgUGxhdGZvcm1VdGlscyB7XG4gICAgcHJvdGVjdGVkIHN0YXRpYyBpbnN0YW5jZTogUGxhdGZvcm1VdGlscztcbiAgICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgICBzdGF0aWMgZ2V0SW5zdGFuY2UoKTogUGxhdGZvcm1VdGlscyB7XG4gICAgICAgIGlmICghdGhpcy5pbnN0YW5jZSkge1xuICAgICAgICAgICAgdGhpcy5pbnN0YW5jZSA9IG5ldyBQbGF0Zm9ybVV0aWxzKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFBsYXRmb3JtVXRpbHMuaW5zdGFuY2U7XG4gICAgfVxuXG4gICAgcHVibGljIGlzQ2hyb21lQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgPT09ICdDaHJvbWUnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNTYWZhcmlCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ1NhZmFyaSc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0Nocm9tZU1vYmlsZUJyb3dzZXIoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5uYW1lID09PSAnQ2hyb21lIE1vYmlsZSc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0ZpcmVmb3hCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ0ZpcmVmb3gnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNGaXJlZm94TW9iaWxlQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgPT09ICdGaXJlZm94IE1vYmlsZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ0ZpcmVmb3ggZm9yIGlPUyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc09wZXJhQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgPT09ICdPcGVyYSc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc09wZXJhTW9iaWxlQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgPT09ICdPcGVyYSBNb2JpbGUnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNFZGdlQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdmVyc2lvbiA9IHBsYXRmb3JtPy52ZXJzaW9uID8gcGFyc2VGbG9hdChwbGF0Zm9ybS52ZXJzaW9uKSA6IC0xO1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ01pY3Jvc29mdCBFZGdlJyAmJiB2ZXJzaW9uID49IDgwO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNFZGdlTW9iaWxlQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdmVyc2lvbiA9IHBsYXRmb3JtPy52ZXJzaW9uID8gcGFyc2VGbG9hdChwbGF0Zm9ybS52ZXJzaW9uKSA6IC0xO1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ01pY3Jvc29mdCBFZGdlJyAmJiAocGxhdGZvcm0ub3M/LmZhbWlseSA9PT0gJ0FuZHJvaWQnIHx8IHBsYXRmb3JtLm9zPy5mYW1pbHkgPT09ICdpT1MnKSAmJiB2ZXJzaW9uID4gNDU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0FuZHJvaWRCcm93c2VyKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ0FuZHJvaWQgQnJvd3Nlcic7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBpc0VsZWN0cm9uKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ0VsZWN0cm9uJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzTm9kZUpzKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ubmFtZSA9PT0gJ05vZGUuanMnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNTYW1zdW5nQnJvd3NlcigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgPT09ICdTYW1zdW5nIEludGVybmV0IE1vYmlsZScgfHwgcGxhdGZvcm0ubmFtZSA9PT0gJ1NhbXN1bmcgSW50ZXJuZXQnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNJUGhvbmVPcklQYWQoKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHVzZXJBZ2VudCA9ICEhcGxhdGZvcm0udWEgPyBwbGF0Zm9ybS51YSA6IG5hdmlnYXRvci51c2VyQWdlbnQ7XG4gICAgICAgIGNvbnN0IGlzVG91Y2hhYmxlID0gJ29udG91Y2hlbmQnIGluIGRvY3VtZW50O1xuICAgICAgICBjb25zdCBpc0lQYWQgPSAvXFxiKFxcdypNYWNpbnRvc2hcXHcqKVxcYi8udGVzdCh1c2VyQWdlbnQpICYmIGlzVG91Y2hhYmxlO1xuICAgICAgICBjb25zdCBpc0lQaG9uZSA9IC9cXGIoXFx3KmlQaG9uZVxcdyopXFxiLy50ZXN0KHVzZXJBZ2VudCkgJiYgL1xcYihcXHcqTW9iaWxlXFx3KilcXGIvLnRlc3QodXNlckFnZW50KSAmJiBpc1RvdWNoYWJsZTtcbiAgICAgICAgcmV0dXJuIGlzSVBhZCB8fCBpc0lQaG9uZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzSU9TV2l0aFNhZmFyaSgpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdXNlckFnZW50ID0gISFwbGF0Zm9ybS51YSA/IHBsYXRmb3JtLnVhIDogbmF2aWdhdG9yLnVzZXJBZ2VudDtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHRoaXMuaXNJUGhvbmVPcklQYWQoKSAmJlxuICAgICAgICAgICAgL1xcYihcXHcqQXBwbGVcXHcqKVxcYi8udGVzdChuYXZpZ2F0b3IudmVuZG9yKSAmJlxuICAgICAgICAgICAgL1xcYihcXHcqU2FmYXJpXFx3KilcXGIvLnRlc3QodXNlckFnZW50KSAmJlxuICAgICAgICAgICAgIS9cXGIoXFx3KkNyaU9TXFx3KilcXGIvLnRlc3QodXNlckFnZW50KSAmJlxuICAgICAgICAgICAgIS9cXGIoXFx3KkZ4aU9TXFx3KilcXGIvLnRlc3QodXNlckFnZW50KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNJb25pY0lvcygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNJUGhvbmVPcklQYWQoKSAmJiBwbGF0Zm9ybS51YSEhLmluZGV4T2YoJ1NhZmFyaScpID09PSAtMTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzSW9uaWNBbmRyb2lkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gcGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdBbmRyb2lkJyAmJiBwbGF0Zm9ybS5uYW1lID09ICdBbmRyb2lkIEJyb3dzZXInO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgaXNNb2JpbGVEZXZpY2UoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5vcyEhLmZhbWlseSA9PT0gJ2lPUycgfHwgcGxhdGZvcm0ub3MhIS5mYW1pbHkgPT09ICdBbmRyb2lkJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzUmVhY3ROYXRpdmUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGlzQ2hyb21pdW0oKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLmlzQ2hyb21lQnJvd3NlcigpIHx8XG4gICAgICAgICAgICB0aGlzLmlzQ2hyb21lTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICB0aGlzLmlzT3BlcmFCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNPcGVyYU1vYmlsZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgdGhpcy5pc0VkZ2VCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNFZGdlTW9iaWxlQnJvd3NlcigpIHx8XG4gICAgICAgICAgICB0aGlzLmlzU2Ftc3VuZ0Jyb3dzZXIoKSB8fFxuICAgICAgICAgICAgdGhpcy5pc0lvbmljQW5kcm9pZCgpIHx8XG4gICAgICAgICAgICB0aGlzLmlzSW9uaWNJb3MoKSB8fFxuICAgICAgICAgICAgdGhpcy5pc0VsZWN0cm9uKClcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGNhblNjcmVlblNoYXJlKCk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCB2ZXJzaW9uID0gcGxhdGZvcm0/LnZlcnNpb24gPyBwYXJzZUZsb2F0KHBsYXRmb3JtLnZlcnNpb24pIDogLTE7XG4gICAgICAgIC8vIFJlamVjdCBtb2JpbGUgZGV2aWNlc1xuICAgICAgICBpZiAodGhpcy5pc01vYmlsZURldmljZSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHRoaXMuaXNDaHJvbWVCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNGaXJlZm94QnJvd3NlcigpIHx8XG4gICAgICAgICAgICB0aGlzLmlzT3BlcmFCcm93c2VyKCkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNFbGVjdHJvbigpIHx8XG4gICAgICAgICAgICB0aGlzLmlzRWRnZUJyb3dzZXIoKSB8fFxuICAgICAgICAgICAgKHRoaXMuaXNTYWZhcmlCcm93c2VyKCkgJiYgdmVyc2lvbiA+PSAxMylcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGdldE5hbWUoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHBsYXRmb3JtLm5hbWUgfHwgJyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRWZXJzaW9uKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS52ZXJzaW9uIHx8ICcnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0RmFtaWx5KCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5vcyEhLmZhbWlseSB8fCAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGdldERlc2NyaXB0aW9uKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBwbGF0Zm9ybS5kZXNjcmlwdGlvbiB8fCAnJztcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IGZyZWVpY2UgPSByZXF1aXJlKCdmcmVlaWNlJyk7XG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tICd1dWlkJztcbmltcG9ydCB7IFR5cGVPZlZpZGVvIH0gZnJvbSAnLi4vRW51bXMvVHlwZU9mVmlkZW8nO1xuaW1wb3J0IHsgRXhjZXB0aW9uRXZlbnROYW1lIH0gZnJvbSAnLi4vRXZlbnRzL0V4Y2VwdGlvbkV2ZW50JztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyIH0gZnJvbSAnLi4vTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IFBsYXRmb3JtVXRpbHMgfSBmcm9tICcuLi9VdGlscy9QbGF0Zm9ybSc7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5jb25zdCBsb2dnZXI6IE9wZW5WaWR1TG9nZ2VyID0gT3BlblZpZHVMb2dnZXIuZ2V0SW5zdGFuY2UoKTtcbi8qKlxuICogQGhpZGRlblxuICovXG5sZXQgcGxhdGZvcm06IFBsYXRmb3JtVXRpbHM7XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24ge1xuICAgIG1lZGlhQ29uc3RyYWludHM6IHtcbiAgICAgICAgYXVkaW86IGJvb2xlYW47XG4gICAgICAgIHZpZGVvOiBib29sZWFuO1xuICAgIH07XG4gICAgc2ltdWxjYXN0OiBib29sZWFuO1xuICAgIG1lZGlhU2VydmVyOiBzdHJpbmc7XG4gICAgb25JY2VDYW5kaWRhdGU6IChldmVudDogUlRDSWNlQ2FuZGlkYXRlKSA9PiB2b2lkO1xuICAgIG9uSWNlQ29ubmVjdGlvblN0YXRlRXhjZXB0aW9uOiAoZXhjZXB0aW9uTmFtZTogRXhjZXB0aW9uRXZlbnROYW1lLCBtZXNzYWdlOiBzdHJpbmcsIGRhdGE/OiBhbnkpID0+IHZvaWQ7XG4gICAgaWNlU2VydmVycz86IFJUQ0ljZVNlcnZlcltdO1xuICAgIG1lZGlhU3RyZWFtPzogTWVkaWFTdHJlYW0gfCBudWxsO1xuICAgIG1vZGU/OiAnc2VuZG9ubHknIHwgJ3JlY3Zvbmx5JyB8ICdzZW5kcmVjdic7XG4gICAgaWQ/OiBzdHJpbmc7XG4gICAgdHlwZU9mVmlkZW86IFR5cGVPZlZpZGVvIHwgdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjUGVlciB7XG4gICAgcGM6IFJUQ1BlZXJDb25uZWN0aW9uO1xuICAgIHJlbW90ZUNhbmRpZGF0ZXNRdWV1ZTogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcbiAgICBsb2NhbENhbmRpZGF0ZXNRdWV1ZTogUlRDSWNlQ2FuZGlkYXRlW10gPSBbXTtcblxuICAgIC8vIFNhbWUgYXMgV2ViUnRjUGVlckNvbmZpZ3VyYXRpb24gYnV0IHdpdGhvdXQgb3B0aW9uYWwgZmllbGRzLlxuICAgIHByb3RlY3RlZCBjb25maWd1cmF0aW9uOiBSZXF1aXJlZDxXZWJSdGNQZWVyQ29uZmlndXJhdGlvbj47XG5cbiAgICBwcml2YXRlIGljZUNhbmRpZGF0ZUxpc3Q6IFJUQ0ljZUNhbmRpZGF0ZVtdID0gW107XG4gICAgcHJpdmF0ZSBjYW5kaWRhdGVnYXRoZXJpbmdkb25lID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBwbGF0Zm9ybSA9IFBsYXRmb3JtVXRpbHMuZ2V0SW5zdGFuY2UoKTtcblxuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSB7XG4gICAgICAgICAgICAuLi5jb25maWd1cmF0aW9uLFxuICAgICAgICAgICAgaWNlU2VydmVyczogISFjb25maWd1cmF0aW9uLmljZVNlcnZlcnMgJiYgY29uZmlndXJhdGlvbi5pY2VTZXJ2ZXJzLmxlbmd0aCA+IDAgPyBjb25maWd1cmF0aW9uLmljZVNlcnZlcnMgOiBmcmVlaWNlKCksXG4gICAgICAgICAgICBtZWRpYVN0cmVhbTogY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSAhPT0gdW5kZWZpbmVkID8gY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbSA6IG51bGwsXG4gICAgICAgICAgICBtb2RlOiAhIWNvbmZpZ3VyYXRpb24ubW9kZSA/IGNvbmZpZ3VyYXRpb24ubW9kZSA6ICdzZW5kcmVjdicsXG4gICAgICAgICAgICBpZDogISFjb25maWd1cmF0aW9uLmlkID8gY29uZmlndXJhdGlvbi5pZCA6IHRoaXMuZ2VuZXJhdGVVbmlxdWVJZCgpXG4gICAgICAgIH07XG4gICAgICAgIC8vIHByZXR0aWVyLWlnbm9yZVxuICAgICAgICBsb2dnZXIuZGVidWcoYFtXZWJSdGNQZWVyXSBjb25maWd1cmF0aW9uOlxcbiR7SlNPTi5zdHJpbmdpZnkodGhpcy5jb25maWd1cmF0aW9uLCBudWxsLCAyKX1gKTtcblxuICAgICAgICB0aGlzLnBjID0gbmV3IFJUQ1BlZXJDb25uZWN0aW9uKHsgaWNlU2VydmVyczogdGhpcy5jb25maWd1cmF0aW9uLmljZVNlcnZlcnMgfSk7XG5cbiAgICAgICAgdGhpcy5wYy5hZGRFdmVudExpc3RlbmVyKCdpY2VjYW5kaWRhdGUnLCAoZXZlbnQ6IFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudC5jYW5kaWRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAvLyBgUlRDUGVlckNvbm5lY3Rpb25JY2VFdmVudC5jYW5kaWRhdGVgIGlzIHN1cHBvc2VkIHRvIGJlIGFuIFJUQ0ljZUNhbmRpZGF0ZTpcbiAgICAgICAgICAgICAgICAvLyBodHRwczovL3czYy5naXRodWIuaW8vd2VicnRjLXBjLyNkb20tcnRjcGVlcmNvbm5lY3Rpb25pY2VldmVudC1jYW5kaWRhdGVcbiAgICAgICAgICAgICAgICAvL1xuICAgICAgICAgICAgICAgIC8vIEJ1dCBpbiBwcmFjdGljZSwgaXQgaXMgYWN0dWFsbHkgYW4gUlRDSWNlQ2FuZGlkYXRlSW5pdCB0aGF0IGNhbiBiZSB1c2VkIHRvXG4gICAgICAgICAgICAgICAgLy8gb2J0YWluIGEgcHJvcGVyIGNhbmRpZGF0ZSwgdXNpbmcgdGhlIFJUQ0ljZUNhbmRpZGF0ZSBjb25zdHJ1Y3RvcjpcbiAgICAgICAgICAgICAgICAvLyBodHRwczovL3czYy5naXRodWIuaW8vd2VicnRjLXBjLyNkb20tcnRjaWNlY2FuZGlkYXRlLWNvbnN0cnVjdG9yXG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlSW5pdDogUlRDSWNlQ2FuZGlkYXRlSW5pdCA9IGV2ZW50LmNhbmRpZGF0ZSBhcyBSVENJY2VDYW5kaWRhdGVJbml0O1xuICAgICAgICAgICAgICAgIGNvbnN0IGljZUNhbmRpZGF0ZSA9IG5ldyBSVENJY2VDYW5kaWRhdGUoY2FuZGlkYXRlSW5pdCk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ub25JY2VDYW5kaWRhdGUoaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICBpZiAoaWNlQ2FuZGlkYXRlLmNhbmRpZGF0ZSAhPT0gJycpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2NhbENhbmRpZGF0ZXNRdWV1ZS5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnBjLmFkZEV2ZW50TGlzdGVuZXIoJ3NpZ25hbGluZ3N0YXRlY2hhbmdlJywgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdzdGFibGUnKSB7XG4gICAgICAgICAgICAgICAgLy8gU0RQIE9mZmVyL0Fuc3dlciBmaW5pc2hlZC4gQWRkIHN0b3JlZCByZW1vdGUgY2FuZGlkYXRlcy5cbiAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5pY2VDYW5kaWRhdGVMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNhbmRpZGF0ZSA9IHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZEljZUNhbmRpZGF0ZSg8UlRDSWNlQ2FuZGlkYXRlPmNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBnZXRJZCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWd1cmF0aW9uLmlkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIGZyZWVzIHRoZSByZXNvdXJjZXMgdXNlZCBieSBXZWJSdGNQZWVyXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdEaXNwb3NpbmcgV2ViUnRjUGVlcicpO1xuICAgICAgICBpZiAodGhpcy5wYykge1xuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5wYy5jbG9zZSgpO1xuICAgICAgICAgICAgdGhpcy5yZW1vdGVDYW5kaWRhdGVzUXVldWUgPSBbXTtcbiAgICAgICAgICAgIHRoaXMubG9jYWxDYW5kaWRhdGVzUXVldWUgPSBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIERFUFJFQ0FURUQgTEVHQUNZIE1FVEhPRDogT2xkIFdlYlJUQyB2ZXJzaW9ucyBkb24ndCBpbXBsZW1lbnRcbiAgICAvLyBUcmFuc2NlaXZlcnMsIGFuZCBpbnN0ZWFkIGRlcGVuZCBvbiB0aGUgZGVwcmVjYXRlZFxuICAgIC8vIFwib2ZmZXJUb1JlY2VpdmVBdWRpb1wiIGFuZCBcIm9mZmVyVG9SZWNlaXZlVmlkZW9cIi5cbiAgICBwcml2YXRlIGNyZWF0ZU9mZmVyTGVnYWN5KCk6IFByb21pc2U8UlRDU2Vzc2lvbkRlc2NyaXB0aW9uSW5pdD4ge1xuICAgICAgICBpZiAoISF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIHRoaXMuZGVwcmVjYXRlZFBlZXJDb25uZWN0aW9uVHJhY2tBcGkoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGhhc0F1ZGlvID0gdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMuYXVkaW87XG4gICAgICAgIGNvbnN0IGhhc1ZpZGVvID0gdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhQ29uc3RyYWludHMudmlkZW87XG5cbiAgICAgICAgY29uc3Qgb3B0aW9uczogUlRDT2ZmZXJPcHRpb25zID0ge1xuICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVBdWRpbzogdGhpcy5jb25maWd1cmF0aW9uLm1vZGUgIT09ICdzZW5kb25seScgJiYgaGFzQXVkaW8sXG4gICAgICAgICAgICBvZmZlclRvUmVjZWl2ZVZpZGVvOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSAhPT0gJ3NlbmRvbmx5JyAmJiBoYXNWaWRlb1xuICAgICAgICB9O1xuXG4gICAgICAgIGxvZ2dlci5kZWJ1ZygnW2NyZWF0ZU9mZmVyTGVnYWN5XSBSVENQZWVyQ29ubmVjdGlvbi5jcmVhdGVPZmZlcigpIG9wdGlvbnM6JywgSlNPTi5zdHJpbmdpZnkob3B0aW9ucykpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnBjLmNyZWF0ZU9mZmVyKG9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gU0RQIG9mZmVyIGZyb20gdGhlIGxvY2FsIFJUQ1BlZXJDb25uZWN0aW9uIHRvIHNlbmQgdG8gdGhlIG90aGVyIHBlZXIuXG4gICAgICogT25seSBpZiB0aGUgbmVnb3RpYXRpb24gd2FzIGluaXRpYXRlZCBieSB0aGlzIHBlZXIuXG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlT2ZmZXIoKTogUHJvbWlzZTxSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0PiB7XG4gICAgICAgIC8vIFRPRE86IERlbGV0ZSB0aGlzIGNvbmRpdGlvbmFsIHdoZW4gYWxsIHN1cHBvcnRlZCBicm93c2VycyBhcmVcbiAgICAgICAgLy8gbW9kZXJuIGVub3VnaCB0byBpbXBsZW1lbnQgdGhlIFRyYW5zY2VpdmVyIG1ldGhvZHMuXG4gICAgICAgIGlmICghKCdhZGRUcmFuc2NlaXZlcicgaW4gdGhpcy5wYykpIHtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgICAgICAgICdbY3JlYXRlT2ZmZXJdIE1ldGhvZCBSVENQZWVyQ29ubmVjdGlvbi5hZGRUcmFuc2NlaXZlcigpIGlzIE5PVCBhdmFpbGFibGU7IHVzaW5nIExFR0FDWSBvZmZlclRvUmVjZWl2ZXtBdWRpbyxWaWRlb30nXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlT2ZmZXJMZWdhY3koKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnW2NyZWF0ZU9mZmVyXSBNZXRob2QgUlRDUGVlckNvbm5lY3Rpb24uYWRkVHJhbnNjZWl2ZXIoKSBpcyBhdmFpbGFibGU7IHVzaW5nIGl0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTcGVjIGRvYzogaHR0cHM6Ly93M2MuZ2l0aHViLmlvL3dlYnJ0Yy1wYy8jZG9tLXJ0Y3BlZXJjb25uZWN0aW9uLWFkZHRyYW5zY2VpdmVyXG5cbiAgICAgICAgaWYgKHRoaXMuY29uZmlndXJhdGlvbi5tb2RlICE9PSAncmVjdm9ubHknKSB7XG4gICAgICAgICAgICAvLyBUbyBzZW5kIG1lZGlhLCBhc3N1bWUgdGhhdCBhbGwgZGVzaXJlZCBtZWRpYSB0cmFja3MgaGF2ZSBiZWVuXG4gICAgICAgICAgICAvLyBhbHJlYWR5IGFkZGVkIGJ5IGhpZ2hlciBsZXZlbCBjb2RlIHRvIG91ciBNZWRpYVN0cmVhbS5cblxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIGBbV2ViUnRjUGVlci5jcmVhdGVPZmZlcl0gRGlyZWN0aW9uIGlzICcke3RoaXMuY29uZmlndXJhdGlvbi5tb2RlfScsIGJ1dCBubyBzdHJlYW0gd2FzIGNvbmZpZ3VyZWQgdG8gYmUgc2VudGBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRyYWNrIG9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbS5nZXRUcmFja3MoKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRjSW5pdDogUlRDUnRwVHJhbnNjZWl2ZXJJbml0ID0ge1xuICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMuY29uZmlndXJhdGlvbi5tb2RlLFxuICAgICAgICAgICAgICAgICAgICBzdHJlYW1zOiBbdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtXVxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBpZiAodHJhY2sua2luZCA9PT0gJ3ZpZGVvJyAmJiB0aGlzLmNvbmZpZ3VyYXRpb24uc2ltdWxjYXN0KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSByZXF1ZXN0ZWQgc2l6ZSBpcyBlbm91Z2ggdG8gYXNrIGZvciAzIGxheWVycy5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhY2tTZXR0aW5ncyA9IHRyYWNrLmdldFNldHRpbmdzKCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRyYWNrQ29uc3RzID0gdHJhY2suZ2V0Q29uc3RyYWludHMoKTtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0cmFja1dpZHRoOiBudW1iZXIgPVxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2tTZXR0aW5ncy53aWR0aCA/PyAodHJhY2tDb25zdHMud2lkdGggYXMgQ29uc3RyYWluVUxvbmdSYW5nZSkuaWRlYWwgPz8gKHRyYWNrQ29uc3RzLndpZHRoIGFzIG51bWJlcikgPz8gMDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhY2tIZWlnaHQ6IG51bWJlciA9XG4gICAgICAgICAgICAgICAgICAgICAgICB0cmFja1NldHRpbmdzLmhlaWdodCA/PyAodHJhY2tDb25zdHMuaGVpZ2h0IGFzIENvbnN0cmFpblVMb25nUmFuZ2UpLmlkZWFsID8/ICh0cmFja0NvbnN0cy5oZWlnaHQgYXMgbnVtYmVyKSA/PyAwO1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhgW2NyZWF0ZU9mZmVyXSBWaWRlbyB0cmFjayBkaW1lbnNpb25zOiAke3RyYWNrV2lkdGh9eCR7dHJhY2tIZWlnaHR9YCk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJhY2tQaXhlbHMgPSB0cmFja1dpZHRoICogdHJhY2tIZWlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIGxldCBtYXhMYXllcnMgPSAwO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHJhY2tQaXhlbHMgPj0gOTYwICogNTQwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXhMYXllcnMgPSAzO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRyYWNrUGl4ZWxzID49IDQ4MCAqIDI3MCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWF4TGF5ZXJzID0gMjtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heExheWVycyA9IDE7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICB0Y0luaXQuc2VuZEVuY29kaW5ncyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBsID0gMDsgbCA8IG1heExheWVyczsgbCsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsYXllckRpdiA9IDIgKiogKG1heExheWVycyAtIGwgLSAxKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5jb2Rpbmc6IFJUQ1J0cEVuY29kaW5nUGFyYW1ldGVycyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByaWQ6ICdyZGl2JyArIGxheWVyRGl2LnRvU3RyaW5nKCksXG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlIC0tIFByb3BlcnR5IG1pc3NpbmcgZnJvbSBET00gdHlwZXMuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGFiaWxpdHlNb2RlOiAnTDFUMSdcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChbJ2RldGFpbCcsICd0ZXh0J10uaW5jbHVkZXModHJhY2suY29udGVudEhpbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUHJpb3JpdGl6ZSBiZXN0IHJlc29sdXRpb24sIGZvciBtYXhpbXVtIHBpY3R1cmUgZGV0YWlsLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kaW5nLnNjYWxlUmVzb2x1dGlvbkRvd25CeSA9IDEuMDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmUgLS0gUHJvcGVydHkgbWlzc2luZyBmcm9tIERPTSB0eXBlcy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZy5tYXhGcmFtZXJhdGUgPSBNYXRoLmZsb29yKDMwIC8gbGF5ZXJEaXYpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZy5zY2FsZVJlc29sdXRpb25Eb3duQnkgPSBsYXllckRpdjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGNJbml0LnNlbmRFbmNvZGluZ3MucHVzaChlbmNvZGluZyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCB0YyA9IHRoaXMucGMuYWRkVHJhbnNjZWl2ZXIodHJhY2ssIHRjSW5pdCk7XG5cbiAgICAgICAgICAgICAgICBpZiAodHJhY2sua2luZCA9PT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgc2VuZFBhcmFtcyA9IHRjLnNlbmRlci5nZXRQYXJhbWV0ZXJzKCk7XG4gICAgICAgICAgICAgICAgICAgIGxldCBuZWVkU2V0UGFyYW1zID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzZW5kUGFyYW1zLmRlZ3JhZGF0aW9uUHJlZmVyZW5jZT8ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWdyYWRhdGlvblByZWZlcmVuY2UgZm9yIHZpZGVvOiBcImJhbGFuY2VkXCIsIFwibWFpbnRhaW4tZnJhbWVyYXRlXCIsIFwibWFpbnRhaW4tcmVzb2x1dGlvblwiLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMTgvQ1Itd2VicnRjLTIwMTgwOTI3LyNkb20tcnRjZGVncmFkYXRpb25wcmVmZXJlbmNlXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoWydkZXRhaWwnLCAndGV4dCddLmluY2x1ZGVzKHRyYWNrLmNvbnRlbnRIaW50KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbmRQYXJhbXMuZGVncmFkYXRpb25QcmVmZXJlbmNlID0gJ21haW50YWluLXJlc29sdXRpb24nO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUGFyYW1zLmRlZ3JhZGF0aW9uUHJlZmVyZW5jZSA9ICdiYWxhbmNlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGBbY3JlYXRlT2ZmZXJdIFZpZGVvIHNlbmRlciBEZWdyYWRhdGlvbiBQcmVmZXJlbmNlIHNldDogJHtzZW5kUGFyYW1zLmRlZ3JhZGF0aW9uUHJlZmVyZW5jZX1gKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRklYTUU6IEZpcmVmb3ggaW1wbGVtZW50cyBkZWdyYWRhdGlvblByZWZlcmVuY2Ugb24gZWFjaCBpbmRpdmlkdWFsIGVuY29kaW5nIVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gKHNldCBpdCBvbiBldmVyeSBlbGVtZW50IG9mIHRoZSBzZW5kUGFyYW1zLmVuY29kaW5ncyBhcnJheSlcblxuICAgICAgICAgICAgICAgICAgICAgICAgbmVlZFNldFBhcmFtcyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBGSVhNRTogQ2hlY2sgdGhhdCB0aGUgc2ltdWxjYXN0IGVuY29kaW5ncyB3ZXJlIGFwcGxpZWQuXG4gICAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggZG9lc24ndCBpbXBsZW1lbnQgYFJUQ1J0cFRyYW5zY2VpdmVySW5pdC5zZW5kRW5jb2RpbmdzYFxuICAgICAgICAgICAgICAgICAgICAvLyBzbyB0aGUgb25seSB3YXkgdG8gZW5hYmxlIHNpbXVsY2FzdCBpcyB3aXRoIGBSVENSdHBTZW5kZXIuc2V0UGFyYW1ldGVycygpYC5cbiAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBuZXh0IGJsb2NrIGNhbiBiZSBkZWxldGVkIHdoZW4gRmlyZWZveCBmaXhlcyBidWcgIzEzOTY5MTg6XG4gICAgICAgICAgICAgICAgICAgIC8vIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTEzOTY5MThcbiAgICAgICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAgICAgLy8gTk9URTogVGhpcyBpcyBkb25lIGluIGEgd2F5IHRoYXQgaXMgY29tcGF0aWJsZSB3aXRoIGFsbCBicm93c2VycywgdG8gc2F2ZSBvblxuICAgICAgICAgICAgICAgICAgICAvLyBicm93c2VyLWNvbmRpdGlvbmFsIGNvZGUuIFRoZSBpZGVhIGNvbWVzIGZyb20gV2ViUlRDIEFkYXB0ZXIuanM6XG4gICAgICAgICAgICAgICAgICAgIC8vICogaHR0cHM6Ly9naXRodWIuY29tL3dlYnJ0Y0hhY2tzL2FkYXB0ZXIvaXNzdWVzLzk5OFxuICAgICAgICAgICAgICAgICAgICAvLyAqIGh0dHBzOi8vZ2l0aHViLmNvbS93ZWJydGNIYWNrcy9hZGFwdGVyL2Jsb2IvdjcuNy4wL3NyYy9qcy9maXJlZm94L2ZpcmVmb3hfc2hpbS5qcyNMMjMxLUwyNTVcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlndXJhdGlvbi5zaW11bGNhc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZW5kUGFyYW1zLmVuY29kaW5ncz8ubGVuZ3RoICE9PSB0Y0luaXQuc2VuZEVuY29kaW5ncyEubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFBhcmFtcy5lbmNvZGluZ3MgPSB0Y0luaXQuc2VuZEVuY29kaW5ncyE7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWVkU2V0UGFyYW1zID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChuZWVkU2V0UGFyYW1zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYFtjcmVhdGVPZmZlcl0gU2V0dGluZyBuZXcgUlRDUnRwU2VuZFBhcmFtZXRlcnMgdG8gdmlkZW8gc2VuZGVyYCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRjLnNlbmRlci5zZXRQYXJhbWV0ZXJzKHNlbmRQYXJhbXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbWVzc2FnZSA9IGBbV2ViUnRjUGVlci5jcmVhdGVPZmZlcl0gQ2Fubm90IHNldCBSVENSdHBTZW5kUGFyYW1ldGVycyB0byB2aWRlbyBzZW5kZXJgO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgKz0gYDogJHtlcnJvci5tZXNzYWdlfWA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIERFQlVHOiBVbmNvbW1lbnQgZm9yIGRldGFpbHMuXG4gICAgICAgICAgICAgICAgLy8gaWYgKHRyYWNrLmtpbmQgPT09IFwidmlkZW9cIiAmJiB0aGlzLmNvbmZpZ3VyYXRpb24uc2ltdWxjYXN0KSB7XG4gICAgICAgICAgICAgICAgLy8gICAgIC8vIFByaW50IGJyb3dzZXIgY2FwYWJpbGl0aWVzLlxuICAgICAgICAgICAgICAgIC8vICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgICAgICAgICAvLyAgICAgbG9nZ2VyLmRlYnVnKGBbY3JlYXRlT2ZmZXJdIFRyYW5zY2VpdmVyIHNlbmQgY2FwYWJpbGl0aWVzIChzdGF0aWMpOlxcbiR7SlNPTi5zdHJpbmdpZnkoUlRDUnRwU2VuZGVyLmdldENhcGFiaWxpdGllcz8uKFwidmlkZW9cIiksIG51bGwsIDIpfWApO1xuICAgICAgICAgICAgICAgIC8vICAgICAvLyBwcmV0dGllci1pZ25vcmVcbiAgICAgICAgICAgICAgICAvLyAgICAgbG9nZ2VyLmRlYnVnKGBbY3JlYXRlT2ZmZXJdIFRyYW5zY2VpdmVyIHJlY3YgY2FwYWJpbGl0aWVzIChzdGF0aWMpOlxcbiR7SlNPTi5zdHJpbmdpZnkoUlRDUnRwUmVjZWl2ZXIuZ2V0Q2FwYWJpbGl0aWVzPy4oXCJ2aWRlb1wiKSwgbnVsbCwgMil9YCk7XG5cbiAgICAgICAgICAgICAgICAvLyAgICAgLy8gUHJpbnQgcmVxdWVzdGVkIFRyYW5zY2VpdmVyIGVuY29kaW5ncyBhbmQgcGFyYW1ldGVycy5cbiAgICAgICAgICAgICAgICAvLyAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgICAgICAgICAgLy8gICAgIGxvZ2dlci5kZWJ1ZyhgW2NyZWF0ZU9mZmVyXSBUcmFuc2NlaXZlciBzZW5kIGVuY29kaW5ncyAocmVxdWVzdGVkKTpcXG4ke0pTT04uc3RyaW5naWZ5KHRjSW5pdC5zZW5kRW5jb2RpbmdzLCBudWxsLCAyKX1gKTtcbiAgICAgICAgICAgICAgICAvLyAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgICAgICAgICAgLy8gICAgIGxvZ2dlci5kZWJ1ZyhgW2NyZWF0ZU9mZmVyXSBUcmFuc2NlaXZlciBzZW5kIHBhcmFtZXRlcnMgKGFjY2VwdGVkKTpcXG4ke0pTT04uc3RyaW5naWZ5KHRjLnNlbmRlci5nZXRQYXJhbWV0ZXJzKCksIG51bGwsIDIpfWApO1xuICAgICAgICAgICAgICAgIC8vIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFRvIGp1c3QgcmVjZWl2ZSBtZWRpYSwgY3JlYXRlIG5ldyByZWN2b25seSB0cmFuc2NlaXZlcnMuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtpbmQgb2YgWydhdWRpbycsICd2aWRlbyddKSB7XG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG1lZGlhIGtpbmQgc2hvdWxkIGJlIHVzZWQuXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50c1traW5kXSkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFTdHJlYW0gPSBuZXcgTWVkaWFTdHJlYW0oKTtcbiAgICAgICAgICAgICAgICB0aGlzLnBjLmFkZFRyYW5zY2VpdmVyKGtpbmQsIHtcbiAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZSxcbiAgICAgICAgICAgICAgICAgICAgc3RyZWFtczogW3RoaXMuY29uZmlndXJhdGlvbi5tZWRpYVN0cmVhbV1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBzZHBPZmZlcjogUlRDU2Vzc2lvbkRlc2NyaXB0aW9uSW5pdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHNkcE9mZmVyID0gYXdhaXQgdGhpcy5wYy5jcmVhdGVPZmZlcigpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbGV0IG1lc3NhZ2UgPSBgW1dlYlJ0Y1BlZXIuY3JlYXRlT2ZmZXJdIEJyb3dzZXIgZmFpbGVkIGNyZWF0aW5nIGFuIFNEUCBPZmZlcmA7XG4gICAgICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgKz0gYDogJHtlcnJvci5tZXNzYWdlfWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc2RwT2ZmZXI7XG4gICAgfVxuXG4gICAgZGVwcmVjYXRlZFBlZXJDb25uZWN0aW9uVHJhY2tBcGkoKSB7XG4gICAgICAgIGZvciAoY29uc3QgdHJhY2sgb2YgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtIS5nZXRUcmFja3MoKSkge1xuICAgICAgICAgICAgdGhpcy5wYy5hZGRUcmFjayh0cmFjaywgdGhpcy5jb25maWd1cmF0aW9uLm1lZGlhU3RyZWFtISk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGFuIFNEUCBhbnN3ZXIgZnJvbSB0aGUgbG9jYWwgUlRDUGVlckNvbm5lY3Rpb24gdG8gc2VuZCB0byB0aGUgb3RoZXIgcGVlclxuICAgICAqIE9ubHkgaWYgdGhlIG5lZ290aWF0aW9uIHdhcyBpbml0aWF0ZWQgYnkgdGhlIG90aGVyIHBlZXJcbiAgICAgKi9cbiAgICBjcmVhdGVBbnN3ZXIoKTogUHJvbWlzZTxSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAvLyBUT0RPOiBEZWxldGUgdGhpcyBjb25kaXRpb25hbCB3aGVuIGFsbCBzdXBwb3J0ZWQgYnJvd3NlcnMgYXJlXG4gICAgICAgICAgICAvLyBtb2Rlcm4gZW5vdWdoIHRvIGltcGxlbWVudCB0aGUgVHJhbnNjZWl2ZXIgbWV0aG9kcy5cbiAgICAgICAgICAgIGlmICgnZ2V0VHJhbnNjZWl2ZXJzJyBpbiB0aGlzLnBjKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdbY3JlYXRlQW5zd2VyXSBNZXRob2QgUlRDUGVlckNvbm5lY3Rpb24uZ2V0VHJhbnNjZWl2ZXJzKCkgaXMgYXZhaWxhYmxlOyB1c2luZyBpdCcpO1xuXG4gICAgICAgICAgICAgICAgLy8gRW5zdXJlIHRoYXQgdGhlIFBlZXJDb25uZWN0aW9uIGFscmVhZHkgY29udGFpbnMgb25lIFRyYW5zY2VpdmVyXG4gICAgICAgICAgICAgICAgLy8gZm9yIGVhY2gga2luZCBvZiBtZWRpYS5cbiAgICAgICAgICAgICAgICAvLyBUaGUgVHJhbnNjZWl2ZXJzIHNob3VsZCBoYXZlIGJlZW4gYWxyZWFkeSBjcmVhdGVkIGludGVybmFsbHkgYnlcbiAgICAgICAgICAgICAgICAvLyB0aGUgUEMgaXRzZWxmLCB3aGVuIGBwYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihzZHBPZmZlcilgIHdhcyBjYWxsZWQuXG5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGtpbmQgb2YgWydhdWRpbycsICd2aWRlbyddKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBtZWRpYSBraW5kIHNob3VsZCBiZSB1c2VkLlxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzW2tpbmRdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGxldCB0YyA9IHRoaXMucGMuZ2V0VHJhbnNjZWl2ZXJzKCkuZmluZCgodGMpID0+IHRjLnJlY2VpdmVyLnRyYWNrLmtpbmQgPT09IGtpbmQpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0Yykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRW5mb3JjZSBvdXIgZGVzaXJlZCBkaXJlY3Rpb24uXG4gICAgICAgICAgICAgICAgICAgICAgICB0Yy5kaXJlY3Rpb24gPSB0aGlzLmNvbmZpZ3VyYXRpb24ubW9kZTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKGAke2tpbmR9IHJlcXVlc3RlZCwgYnV0IG5vIHRyYW5zY2VpdmVyIHdhcyBjcmVhdGVkIGZyb20gcmVtb3RlIGRlc2NyaXB0aW9uYCkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5wY1xuICAgICAgICAgICAgICAgICAgICAuY3JlYXRlQW5zd2VyKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKHNkcEFuc3dlcikgPT4gcmVzb2x2ZShzZHBBbnN3ZXIpKVxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gVE9ETzogRGVsZXRlIGVsc2UgYnJhbmNoIHdoZW4gYWxsIHN1cHBvcnRlZCBicm93c2VycyBhcmVcbiAgICAgICAgICAgICAgICAvLyBtb2Rlcm4gZW5vdWdoIHRvIGltcGxlbWVudCB0aGUgVHJhbnNjZWl2ZXIgbWV0aG9kc1xuXG4gICAgICAgICAgICAgICAgbGV0IG9mZmVyQXVkaW8sXG4gICAgICAgICAgICAgICAgICAgIG9mZmVyVmlkZW8gPSB0cnVlO1xuICAgICAgICAgICAgICAgIGlmICghIXRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgIG9mZmVyQXVkaW8gPVxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLmF1ZGlvID09PSAnYm9vbGVhbicgPyB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy5hdWRpbyA6IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIG9mZmVyVmlkZW8gPVxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHRoaXMuY29uZmlndXJhdGlvbi5tZWRpYUNvbnN0cmFpbnRzLnZpZGVvID09PSAnYm9vbGVhbicgPyB0aGlzLmNvbmZpZ3VyYXRpb24ubWVkaWFDb25zdHJhaW50cy52aWRlbyA6IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0cmFpbnRzOiBSVENPZmZlck9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZlclRvUmVjZWl2ZUF1ZGlvOiBvZmZlckF1ZGlvLFxuICAgICAgICAgICAgICAgICAgICAgICAgb2ZmZXJUb1JlY2VpdmVWaWRlbzogb2ZmZXJWaWRlb1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBjIS5jcmVhdGVBbnN3ZXIoY29uc3RyYWludHMpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoc2RwQW5zd2VyKSA9PiByZXNvbHZlKHNkcEFuc3dlcikpXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGVsc2UsIHRoZXJlIGlzIG5vdGhpbmcgdG8gZG87IHRoZSBsZWdhY3kgY3JlYXRlQW5zd2VyKCkgb3B0aW9ucyBkb1xuICAgICAgICAgICAgLy8gbm90IG9mZmVyIGFueSBjb250cm9sIG92ZXIgd2hpY2ggdHJhY2tzIGFyZSBpbmNsdWRlZCBpbiB0aGUgYW5zd2VyLlxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIHBlZXIgaW5pdGlhdGVkIG5lZ290aWF0aW9uLiBTdGVwIDEvNCBvZiBTRFAgb2ZmZXItYW5zd2VyIHByb3RvY29sXG4gICAgICovXG4gICAgcHJvY2Vzc0xvY2FsT2ZmZXIob2ZmZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMucGNcbiAgICAgICAgICAgICAgICAuc2V0TG9jYWxEZXNjcmlwdGlvbihvZmZlcilcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvY2FsRGVzY3JpcHRpb24gPSB0aGlzLnBjLmxvY2FsRGVzY3JpcHRpb247XG4gICAgICAgICAgICAgICAgICAgIGlmICghIWxvY2FsRGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnTG9jYWwgZGVzY3JpcHRpb24gc2V0JywgbG9jYWxEZXNjcmlwdGlvbi5zZHApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoJ0xvY2FsIGRlc2NyaXB0aW9uIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHJlamVjdChlcnJvcikpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPdGhlciBwZWVyIGluaXRpYXRlZCBuZWdvdGlhdGlvbi4gU3RlcCAyLzQgb2YgU0RQIG9mZmVyLWFuc3dlciBwcm90b2NvbFxuICAgICAqL1xuICAgIHByb2Nlc3NSZW1vdGVPZmZlcihzZHBPZmZlcjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBvZmZlcjogUlRDU2Vzc2lvbkRlc2NyaXB0aW9uSW5pdCA9IHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnb2ZmZXInLFxuICAgICAgICAgICAgICAgIHNkcDogc2RwT2ZmZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1NEUCBvZmZlciByZWNlaXZlZCwgc2V0dGluZyByZW1vdGUgZGVzY3JpcHRpb24nLCBvZmZlcik7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoJ1JUQ1BlZXJDb25uZWN0aW9uIGlzIGNsb3NlZCB3aGVuIHRyeWluZyB0byBzZXQgcmVtb3RlIGRlc2NyaXB0aW9uJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldFJlbW90ZURlc2NyaXB0aW9uKG9mZmVyKVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHJlc29sdmUoKSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3RoZXIgcGVlciBpbml0aWF0ZWQgbmVnb3RpYXRpb24uIFN0ZXAgMy80IG9mIFNEUCBvZmZlci1hbnN3ZXIgcHJvdG9jb2xcbiAgICAgKi9cbiAgICBwcm9jZXNzTG9jYWxBbnN3ZXIoYW5zd2VyOiBSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1NEUCBhbnN3ZXIgY3JlYXRlZCwgc2V0dGluZyBsb2NhbCBkZXNjcmlwdGlvbicpO1xuICAgICAgICAgICAgaWYgKHRoaXMucGMuc2lnbmFsaW5nU3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlamVjdCgnUlRDUGVlckNvbm5lY3Rpb24gaXMgY2xvc2VkIHdoZW4gdHJ5aW5nIHRvIHNldCBsb2NhbCBkZXNjcmlwdGlvbicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5wY1xuICAgICAgICAgICAgICAgIC5zZXRMb2NhbERlc2NyaXB0aW9uKGFuc3dlcilcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiByZXNvbHZlKCkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRoaXMgcGVlciBpbml0aWF0ZWQgbmVnb3RpYXRpb24uIFN0ZXAgNC80IG9mIFNEUCBvZmZlci1hbnN3ZXIgcHJvdG9jb2xcbiAgICAgKi9cbiAgICBwcm9jZXNzUmVtb3RlQW5zd2VyKHNkcEFuc3dlcjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbnN3ZXI6IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbkluaXQgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2Fuc3dlcicsXG4gICAgICAgICAgICAgICAgc2RwOiBzZHBBbnN3ZXJcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1NEUCBhbnN3ZXIgcmVjZWl2ZWQsIHNldHRpbmcgcmVtb3RlIGRlc2NyaXB0aW9uJyk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnBjLnNpZ25hbGluZ1N0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoJ1JUQ1BlZXJDb25uZWN0aW9uIGlzIGNsb3NlZCB3aGVuIHRyeWluZyB0byBzZXQgcmVtb3RlIGRlc2NyaXB0aW9uJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldFJlbW90ZURlc2NyaXB0aW9uKGFuc3dlcilcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIERFQlVHOiBVbmNvbW1lbnQgZm9yIGRldGFpbHMuXG4gICAgICAgICAgICAgICAgICAgIC8vIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgIGNvbnN0IHRjID0gdGhpcy5wYy5nZXRUcmFuc2NlaXZlcnMoKS5maW5kKCh0YykgPT4gdGMuc2VuZGVyLnRyYWNrPy5raW5kID09PSBcInZpZGVvXCIpO1xuICAgICAgICAgICAgICAgICAgICAvLyAgICAgLy8gcHJldHRpZXItaWdub3JlXG4gICAgICAgICAgICAgICAgICAgIC8vICAgICBsb2dnZXIuZGVidWcoYFtwcm9jZXNzUmVtb3RlQW5zd2VyXSBUcmFuc2NlaXZlciBzZW5kIHBhcmFtZXRlcnMgKGVmZmVjdGl2ZSk6XFxuJHtKU09OLnN0cmluZ2lmeSh0Yz8uc2VuZGVyLmdldFBhcmFtZXRlcnMoKSwgbnVsbCwgMil9YCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIH1cblxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiByZWplY3QoZXJyb3IpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGFzeW5jIHNldFJlbW90ZURlc2NyaXB0aW9uKHNkcDogUlRDU2Vzc2lvbkRlc2NyaXB0aW9uSW5pdCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gdGhpcy5wYy5zZXRSZW1vdGVEZXNjcmlwdGlvbihzZHApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIGZ1bmN0aW9uIGludm9rZWQgd2hlbiBhbiBJQ0UgY2FuZGlkYXRlIGlzIHJlY2VpdmVkXG4gICAgICovXG4gICAgYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZTogUlRDSWNlQ2FuZGlkYXRlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1JlbW90ZSBJQ0UgY2FuZGlkYXRlIHJlY2VpdmVkJywgaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHRoaXMucmVtb3RlQ2FuZGlkYXRlc1F1ZXVlLnB1c2goaWNlQ2FuZGlkYXRlKTtcbiAgICAgICAgICAgIHN3aXRjaCAodGhpcy5wYy5zaWduYWxpbmdTdGF0ZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2Nsb3NlZCc6XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1BlZXJDb25uZWN0aW9uIG9iamVjdCBpcyBjbG9zZWQnKSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3N0YWJsZSc6XG4gICAgICAgICAgICAgICAgICAgIGlmICghIXRoaXMucGMucmVtb3RlRGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkSWNlQ2FuZGlkYXRlKGljZUNhbmRpZGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiByZXNvbHZlKCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gcmVqZWN0KGVycm9yKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmljZUNhbmRpZGF0ZUxpc3QucHVzaChpY2VDYW5kaWRhdGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaWNlQ2FuZGlkYXRlTGlzdC5wdXNoKGljZUNhbmRpZGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYWRkSWNlQ29ubmVjdGlvblN0YXRlQ2hhbmdlTGlzdGVuZXIob3RoZXJJZDogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMucGMuYWRkRXZlbnRMaXN0ZW5lcignaWNlY29ubmVjdGlvbnN0YXRlY2hhbmdlJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaWNlQ29ubmVjdGlvblN0YXRlOiBSVENJY2VDb25uZWN0aW9uU3RhdGUgPSB0aGlzLnBjLmljZUNvbm5lY3Rpb25TdGF0ZTtcbiAgICAgICAgICAgIHN3aXRjaCAoaWNlQ29ubmVjdGlvblN0YXRlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnZGlzY29ubmVjdGVkJzpcbiAgICAgICAgICAgICAgICAgICAgLy8gUG9zc2libGUgbmV0d29yayBkaXNjb25uZWN0aW9uXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1zZzEgPVxuICAgICAgICAgICAgICAgICAgICAgICAgJ0ljZUNvbm5lY3Rpb25TdGF0ZSBvZiBSVENQZWVyQ29ubmVjdGlvbiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5pZCArXG4gICAgICAgICAgICAgICAgICAgICAgICAnICgnICtcbiAgICAgICAgICAgICAgICAgICAgICAgIG90aGVySWQgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJykgY2hhbmdlIHRvIFwiZGlzY29ubmVjdGVkXCIuIFBvc3NpYmxlIG5ldHdvcmsgZGlzY29ubmVjdGlvbic7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci53YXJuKG1zZzEpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24ub25JY2VDb25uZWN0aW9uU3RhdGVFeGNlcHRpb24oRXhjZXB0aW9uRXZlbnROYW1lLklDRV9DT05ORUNUSU9OX0RJU0NPTk5FQ1RFRCwgbXNnMSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2ZhaWxlZCc6XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1zZzIgPSAnSWNlQ29ubmVjdGlvblN0YXRlIG9mIFJUQ1BlZXJDb25uZWN0aW9uICcgKyB0aGlzLmNvbmZpZ3VyYXRpb24uaWQgKyAnICgnICsgb3RoZXJJZCArICcpIHRvIFwiZmFpbGVkXCInO1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IobXNnMik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5vbkljZUNvbm5lY3Rpb25TdGF0ZUV4Y2VwdGlvbihFeGNlcHRpb25FdmVudE5hbWUuSUNFX0NPTk5FQ1RJT05fRkFJTEVELCBtc2cyKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnY2xvc2VkJzpcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmxvZyhcbiAgICAgICAgICAgICAgICAgICAgICAgICdJY2VDb25uZWN0aW9uU3RhdGUgb2YgUlRDUGVlckNvbm5lY3Rpb24gJyArIHRoaXMuY29uZmlndXJhdGlvbi5pZCArICcgKCcgKyBvdGhlcklkICsgJykgY2hhbmdlIHRvIFwiY2xvc2VkXCInXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ25ldyc6XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coJ0ljZUNvbm5lY3Rpb25TdGF0ZSBvZiBSVENQZWVyQ29ubmVjdGlvbiAnICsgdGhpcy5jb25maWd1cmF0aW9uLmlkICsgJyAoJyArIG90aGVySWQgKyAnKSBjaGFuZ2UgdG8gXCJuZXdcIicpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdjaGVja2luZyc6XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICAnSWNlQ29ubmVjdGlvblN0YXRlIG9mIFJUQ1BlZXJDb25uZWN0aW9uICcgKyB0aGlzLmNvbmZpZ3VyYXRpb24uaWQgKyAnICgnICsgb3RoZXJJZCArICcpIGNoYW5nZSB0byBcImNoZWNraW5nXCInXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ2Nvbm5lY3RlZCc6XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5sb2coXG4gICAgICAgICAgICAgICAgICAgICAgICAnSWNlQ29ubmVjdGlvblN0YXRlIG9mIFJUQ1BlZXJDb25uZWN0aW9uICcgKyB0aGlzLmNvbmZpZ3VyYXRpb24uaWQgKyAnICgnICsgb3RoZXJJZCArICcpIGNoYW5nZSB0byBcImNvbm5lY3RlZFwiJ1xuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdjb21wbGV0ZWQnOlxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIubG9nKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ0ljZUNvbm5lY3Rpb25TdGF0ZSBvZiBSVENQZWVyQ29ubmVjdGlvbiAnICsgdGhpcy5jb25maWd1cmF0aW9uLmlkICsgJyAoJyArIG90aGVySWQgKyAnKSBjaGFuZ2UgdG8gXCJjb21wbGV0ZWRcIidcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBnZW5lcmF0ZVVuaXF1ZUlkKCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB1dWlkdjQoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyUmVjdm9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAncmVjdm9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZG9ubHkgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZG9ubHknO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJSdGNQZWVyU2VuZHJlY3YgZXh0ZW5kcyBXZWJSdGNQZWVyIHtcbiAgICBjb25zdHJ1Y3Rvcihjb25maWd1cmF0aW9uOiBXZWJSdGNQZWVyQ29uZmlndXJhdGlvbikge1xuICAgICAgICBjb25maWd1cmF0aW9uLm1vZGUgPSAnc2VuZHJlY3YnO1xuICAgICAgICBzdXBlcihjb25maWd1cmF0aW9uKTtcbiAgICB9XG59XG4iLCIvKlxuICogKEMpIENvcHlyaWdodCAyMDE3LTIwMjIgT3BlblZpZHUgKGh0dHBzOi8vb3BlbnZpZHUuaW8pXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuLy8gdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWxcblxuaW1wb3J0IHsgU3RyZWFtIH0gZnJvbSAnLi4vLi4vT3BlblZpZHUvU3RyZWFtJztcbmltcG9ydCB7IE9wZW5WaWR1TG9nZ2VyIH0gZnJvbSAnLi4vTG9nZ2VyL09wZW5WaWR1TG9nZ2VyJztcbmltcG9ydCB7IFBsYXRmb3JtVXRpbHMgfSBmcm9tICcuLi9VdGlscy9QbGF0Zm9ybSc7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xuY29uc3QgbG9nZ2VyOiBPcGVuVmlkdUxvZ2dlciA9IE9wZW5WaWR1TG9nZ2VyLmdldEluc3RhbmNlKCk7XG4vKipcbiAqIEBoaWRkZW5cbiAqL1xubGV0IHBsYXRmb3JtOiBQbGF0Zm9ybVV0aWxzO1xuXG5pbnRlcmZhY2UgV2VicnRjU3RhdHNDb25maWcge1xuICAgIGludGVydmFsOiBudW1iZXI7XG4gICAgaHR0cEVuZHBvaW50OiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBKU09OU3RhdHNSZXNwb25zZSB7XG4gICAgJ0B0aW1lc3RhbXAnOiBzdHJpbmc7XG4gICAgcGFydGljaXBhbnRfaWQ6IHN0cmluZztcbiAgICBzZXNzaW9uX2lkOiBzdHJpbmc7XG4gICAgcGxhdGZvcm06IHN0cmluZztcbiAgICBwbGF0Zm9ybV9kZXNjcmlwdGlvbjogc3RyaW5nO1xuICAgIHN0cmVhbTogc3RyaW5nO1xuICAgIHdlYnJ0Y19zdGF0czogSVdlYnJ0Y1N0YXRzO1xufVxuXG4vKipcbiAqIENvbW1vbiBXZWJSdGNTVGF0cyBmb3IgbGF0ZXN0IENocm9taXVtIGFuZCBGaXJlZm94IHZlcnNpb25zXG4gKi9cbmludGVyZmFjZSBJV2VicnRjU3RhdHMge1xuICAgIGluYm91bmQ/OiB7XG4gICAgICAgIGF1ZGlvOlxuICAgICAgICAgICAgfCB7XG4gICAgICAgICAgICAgICAgICBieXRlc1JlY2VpdmVkOiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBwYWNrZXRzUmVjZWl2ZWQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIHBhY2tldHNMb3N0OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBqaXR0ZXI6IG51bWJlcjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfCB7fTtcbiAgICAgICAgdmlkZW86XG4gICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICAgIGJ5dGVzUmVjZWl2ZWQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIHBhY2tldHNSZWNlaXZlZDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgcGFja2V0c0xvc3Q6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIGppdHRlcj86IG51bWJlcjsgLy8gRmlyZWZveFxuICAgICAgICAgICAgICAgICAgaml0dGVyQnVmZmVyRGVsYXk/OiBudW1iZXI7IC8vIENocm9tZVxuICAgICAgICAgICAgICAgICAgZnJhbWVzRGVjb2RlZDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgZmlyQ291bnQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIG5hY2tDb3VudDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgcGxpQ291bnQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIGZyYW1lSGVpZ2h0PzogbnVtYmVyOyAvLyBDaHJvbWVcbiAgICAgICAgICAgICAgICAgIGZyYW1lV2lkdGg/OiBudW1iZXI7IC8vIENocm9tZVxuICAgICAgICAgICAgICAgICAgZnJhbWVzRHJvcHBlZD86IG51bWJlcjsgLy8gQ2hyb21lXG4gICAgICAgICAgICAgICAgICBmcmFtZXNSZWNlaXZlZD86IG51bWJlcjsgLy8gQ2hyb21lXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHwge307XG4gICAgfTtcbiAgICBvdXRib3VuZD86IHtcbiAgICAgICAgYXVkaW86XG4gICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfCB7fTtcbiAgICAgICAgdmlkZW86XG4gICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICAgIGJ5dGVzU2VudDogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgcGFja2V0c1NlbnQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIGZpckNvdW50OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBmcmFtZXNFbmNvZGVkOiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBuYWNrQ291bnQ6IG51bWJlcjtcbiAgICAgICAgICAgICAgICAgIHBsaUNvdW50OiBudW1iZXI7XG4gICAgICAgICAgICAgICAgICBxcFN1bTogbnVtYmVyO1xuICAgICAgICAgICAgICAgICAgZnJhbWVIZWlnaHQ/OiBudW1iZXI7IC8vIENocm9tZVxuICAgICAgICAgICAgICAgICAgZnJhbWVXaWR0aD86IG51bWJlcjsgLy8gQ2hyb21lXG4gICAgICAgICAgICAgICAgICBmcmFtZXNTZW50PzogbnVtYmVyOyAvLyBDaHJvbWVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfCB7fTtcbiAgICB9O1xuICAgIGNhbmRpZGF0ZXBhaXI/OiB7XG4gICAgICAgIGN1cnJlbnRSb3VuZFRyaXBUaW1lPzogbnVtYmVyOyAvLyBDaHJvbWVcbiAgICAgICAgYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlPzogbnVtYmVyOyAvL0Nocm9tZVxuICAgICAgICAvLyBhdmFpbGFibGVJbmNvbWluZ0JpdHJhdGU/OiBudW1iZXIgLy8gTm8gc3VwcG9ydCBmb3IgYW55IGJyb3dzZXJzIChodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvUlRDSWNlQ2FuZGlkYXRlUGFpclN0YXRzL2F2YWlsYWJsZUluY29taW5nQml0cmF0ZSlcbiAgICB9O1xufVxuXG5leHBvcnQgY2xhc3MgV2ViUnRjU3RhdHMge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgU1RBVFNfSVRFTV9OQU1FID0gJ3dlYnJ0Yy1zdGF0cy1jb25maWcnO1xuXG4gICAgcHJpdmF0ZSB3ZWJSdGNTdGF0c0VuYWJsZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIHdlYlJ0Y1N0YXRzSW50ZXJ2YWxJZDogTm9kZUpTLlRpbWVyO1xuICAgIHByaXZhdGUgc3RhdHNJbnRlcnZhbCA9IDE7XG4gICAgcHJpdmF0ZSBQT1NUX1VSTDogc3RyaW5nO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBzdHJlYW06IFN0cmVhbSkge1xuICAgICAgICBwbGF0Zm9ybSA9IFBsYXRmb3JtVXRpbHMuZ2V0SW5zdGFuY2UoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNFbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQ7XG4gICAgfVxuXG4gICAgcHVibGljIGluaXRXZWJSdGNTdGF0cygpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgd2VicnRjT2JqID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5TVEFUU19JVEVNX05BTUUpO1xuXG4gICAgICAgIGlmICghIXdlYnJ0Y09iaikge1xuICAgICAgICAgICAgdGhpcy53ZWJSdGNTdGF0c0VuYWJsZWQgPSB0cnVlO1xuICAgICAgICAgICAgY29uc3Qgd2VicnRjU3RhdHNDb25maWc6IFdlYnJ0Y1N0YXRzQ29uZmlnID0gSlNPTi5wYXJzZSh3ZWJydGNPYmopO1xuICAgICAgICAgICAgLy8gd2VicnRjIG9iamVjdCBmb3VuZCBpbiBsb2NhbCBzdG9yYWdlXG4gICAgICAgICAgICBsb2dnZXIud2FybihcbiAgICAgICAgICAgICAgICAnV2ViUnRjIHN0YXRzIGVuYWJsZWQgZm9yIHN0cmVhbSAnICsgdGhpcy5zdHJlYW0uc3RyZWFtSWQgKyAnIG9mIGNvbm5lY3Rpb24gJyArIHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uY29ubmVjdGlvbklkXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ2xvY2FsU3RvcmFnZSBpdGVtOiAnICsgSlNPTi5zdHJpbmdpZnkod2VicnRjU3RhdHNDb25maWcpKTtcblxuICAgICAgICAgICAgdGhpcy5QT1NUX1VSTCA9IHdlYnJ0Y1N0YXRzQ29uZmlnLmh0dHBFbmRwb2ludDtcbiAgICAgICAgICAgIHRoaXMuc3RhdHNJbnRlcnZhbCA9IHdlYnJ0Y1N0YXRzQ29uZmlnLmludGVydmFsOyAvLyBJbnRlcnZhbCBpbiBzZWNvbmRzXG5cbiAgICAgICAgICAgIHRoaXMud2ViUnRjU3RhdHNJbnRlcnZhbElkID0gc2V0SW50ZXJ2YWwoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuc2VuZFN0YXRzVG9IdHRwRW5kcG9pbnQoKTtcbiAgICAgICAgICAgIH0sIHRoaXMuc3RhdHNJbnRlcnZhbCAqIDEwMDApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdXZWJSdGMgc3RhdHMgbm90IGVuYWJsZWQnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIHtcbiAgICAvLyBcImxvY2FsQ2FuZGlkYXRlXCI6IHtcbiAgICAvLyAgICAgXCJpZFwiOiBcIlJUQ0ljZUNhbmRpZGF0ZV8vcjRQMXkyUVwiLFxuICAgIC8vICAgICBcInRpbWVzdGFtcFwiOiAxNjE2MDgwMTU1NjE3LFxuICAgIC8vICAgICBcInR5cGVcIjogXCJsb2NhbC1jYW5kaWRhdGVcIixcbiAgICAvLyAgICAgXCJ0cmFuc3BvcnRJZFwiOiBcIlJUQ1RyYW5zcG9ydF8wXzFcIixcbiAgICAvLyAgICAgXCJpc1JlbW90ZVwiOiBmYWxzZSxcbiAgICAvLyAgICAgXCJuZXR3b3JrVHlwZVwiOiBcIndpZmlcIixcbiAgICAvLyAgICAgXCJpcFwiOiBcIjEyMy40NS42Ny44OVwiLFxuICAgIC8vICAgICBcInBvcnRcIjogNjMzNDAsXG4gICAgLy8gICAgIFwicHJvdG9jb2xcIjogXCJ1ZHBcIixcbiAgICAvLyAgICAgXCJjYW5kaWRhdGVUeXBlXCI6IFwic3JmbHhcIixcbiAgICAvLyAgICAgXCJwcmlvcml0eVwiOiAxNjg2MDUyNjA3LFxuICAgIC8vICAgICBcImRlbGV0ZWRcIjogZmFsc2UsXG4gICAgLy8gICAgIFwicmF3XCI6IFtcbiAgICAvLyAgICAgXCJjYW5kaWRhdGU6MzM0NTQxMjkyMSAxIHVkcCAxNjg2MDUyNjA3IDEyMy40NS42Ny44OSA2MzM0MCB0eXAgc3JmbHggcmFkZHIgMTkyLjE2OC4xLjMxIHJwb3J0IDYzMzQwIGdlbmVyYXRpb24gMCB1ZnJhZyAwWnRUIG5ldHdvcmstaWQgMSBuZXR3b3JrLWNvc3QgMTBcIixcbiAgICAvLyAgICAgXCJjYW5kaWRhdGU6NTgwOTQ0ODIgMSB1ZHAgNDE4ODU2OTUgOTguNzYuNTQuMzIgNDQ0MzEgdHlwIHJlbGF5IHJhZGRyIDEyMy40NS42Ny44OSBycG9ydCA2MzM0MCBnZW5lcmF0aW9uIDAgdWZyYWcgMFp0VCBuZXR3b3JrLWlkIDEgbmV0d29yay1jb3N0IDEwXCJcbiAgICAvLyAgICAgXVxuICAgIC8vIH0sXG4gICAgLy8gXCJyZW1vdGVDYW5kaWRhdGVcIjoge1xuICAgIC8vICAgICBcImlkXCI6IFwiUlRDSWNlQ2FuZGlkYXRlXzFZTzE4Z3BoXCIsXG4gICAgLy8gICAgIFwidGltZXN0YW1wXCI6IDE2MTYwODAxNTU2MTcsXG4gICAgLy8gICAgIFwidHlwZVwiOiBcInJlbW90ZS1jYW5kaWRhdGVcIixcbiAgICAvLyAgICAgXCJ0cmFuc3BvcnRJZFwiOiBcIlJUQ1RyYW5zcG9ydF8wXzFcIixcbiAgICAvLyAgICAgXCJpc1JlbW90ZVwiOiB0cnVlLFxuICAgIC8vICAgICBcImlwXCI6IFwiMTIuMzQuNTYuNzhcIixcbiAgICAvLyAgICAgXCJwb3J0XCI6IDY0OTg5LFxuICAgIC8vICAgICBcInByb3RvY29sXCI6IFwidWRwXCIsXG4gICAgLy8gICAgIFwiY2FuZGlkYXRlVHlwZVwiOiBcInNyZmx4XCIsXG4gICAgLy8gICAgIFwicHJpb3JpdHlcIjogMTY3OTgxOTI2MyxcbiAgICAvLyAgICAgXCJkZWxldGVkXCI6IGZhbHNlLFxuICAgIC8vICAgICBcInJhd1wiOiBbXG4gICAgLy8gICAgIFwiY2FuZGlkYXRlOjE2IDEgVURQIDE2Nzk4MTkyNjMgMTIuMzQuNTYuNzggNjQ5ODkgdHlwIHNyZmx4IHJhZGRyIDE3Mi4xOS4wLjEgcnBvcnQgNjQ5ODlcIixcbiAgICAvLyAgICAgXCJjYW5kaWRhdGU6MTYgMSBVRFAgMTY3OTgxOTI2MyAxMi4zNC41Ni43OCA2NDk4OSB0eXAgc3JmbHggcmFkZHIgMTcyLjE5LjAuMSBycG9ydCA2NDk4OVwiXG4gICAgLy8gICAgIF1cbiAgICAvLyB9XG4gICAgLy8gfVxuICAgIC8vIEhhdmUgYmVlbiB0ZXN0ZWQgaW46XG4gICAgLy8gICAtIExpbnV4IERlc2t0b3A6XG4gICAgLy8gICAgICAgLSBDaHJvbWUgODkuMC40Mzg5LjkwXG4gICAgLy8gICAgICAgLSBPcGVyYSA3NC4wLjM5MTEuMjE4XG4gICAgLy8gICAgICAgLSBGaXJlZm94IDg2XG4gICAgLy8gICAgICAgLSBNaWNyb3NvZnQgRWRnZSA5MS4wLjgyNS4wXG4gICAgLy8gICAgICAgLSBFbGVjdHJvbiAxMS4zLjAgKENocm9taXVtIDg3LjAuNDI4MC4xNDEpXG4gICAgLy8gICAtIFdpbmRvd3MgRGVza3RvcDpcbiAgICAvLyAgICAgICAtIENocm9tZSA4OS4wLjQzODkuOTBcbiAgICAvLyAgICAgICAtIE9wZXJhIDc0LjAuMzkxMS4yMzJcbiAgICAvLyAgICAgICAtIEZpcmVmb3ggODYuMC4xXG4gICAgLy8gICAgICAgLSBNaWNyb3NvZnQgRWRnZSA4OS4wLjc3NC41NFxuICAgIC8vICAgICAgIC0gRWxlY3Ryb24gMTEuMy4wIChDaHJvbWl1bSA4Ny4wLjQyODAuMTQxKVxuICAgIC8vICAgLSBNYWNPUyBEZXNrdG9wOlxuICAgIC8vICAgICAgIC0gQ2hyb21lIDg5LjAuNDM4OS45MFxuICAgIC8vICAgICAgIC0gRmlyZWZveCA4Ny4wXG4gICAgLy8gICAgICAgLSBPcGVyYSA3NS4wLjM5NjkuOTNcbiAgICAvLyAgICAgICAtIE1pY3Jvc29mdCBFZGdlIDg5LjAuNzc0LjU3XG4gICAgLy8gICAgICAgLSBTYWZhcmkgMTQuMCAoMTQ2MTAuMS4yOC4xLjkpXG4gICAgLy8gICAgICAgLSBFbGVjdHJvbiAxMS4zLjAgKENocm9taXVtIDg3LjAuNDI4MC4xNDEpXG4gICAgLy8gICAtIEFuZHJvaWQ6XG4gICAgLy8gICAgICAgLSBDaHJvbWUgTW9iaWxlIDg5LjAuNDM4OS45MFxuICAgIC8vICAgICAgIC0gT3BlcmEgNjIuMy4zMTQ2LjU3NzYzXG4gICAgLy8gICAgICAgLSBGaXJlZm94IE1vYmlsZSA4Ni42LjFcbiAgICAvLyAgICAgICAtIE1pY3Jvc29mdCBFZGdlIE1vYmlsZSA0Ni4wMi40LjUxNDdcbiAgICAvLyAgICAgICAtIElvbmljIDVcbiAgICAvLyAgICAgICAtIFJlYWN0IE5hdGl2ZSAwLjY0XG4gICAgLy8gICAtIGlPUzpcbiAgICAvLyAgICAgICAtIFNhZmFyaSBNb2JpbGVcbiAgICAvLyAgICAgICAtIMK/SW9uaWM/XG4gICAgLy8gICAgICAgLSDCv1JlYWN0IE5hdGl2ZT9cbiAgICBwdWJsaWMgZ2V0U2VsZWN0ZWRJY2VDYW5kaWRhdGVJbmZvKCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdGF0c1JlcG9ydDogYW55ID0gYXdhaXQgdGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKS5nZXRTdGF0cygpO1xuICAgICAgICAgICAgbGV0IHRyYW5zcG9ydFN0YXQ7XG4gICAgICAgICAgICBjb25zdCBjYW5kaWRhdGVQYWlyczogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGNvbnN0IGxvY2FsQ2FuZGlkYXRlczogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNhbmRpZGF0ZXM6IE1hcDxzdHJpbmcsIGFueT4gPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBzdGF0c1JlcG9ydC5mb3JFYWNoKChzdGF0OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoc3RhdC50eXBlID09PSAndHJhbnNwb3J0JyAmJiAocGxhdGZvcm0uaXNDaHJvbWl1bSgpIHx8IHBsYXRmb3JtLmlzU2FmYXJpQnJvd3NlcigpIHx8IHBsYXRmb3JtLmlzUmVhY3ROYXRpdmUoKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNwb3J0U3RhdCA9IHN0YXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN3aXRjaCAoc3RhdC50eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2NhbmRpZGF0ZS1wYWlyJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbmRpZGF0ZVBhaXJzLnNldChzdGF0LmlkLCBzdGF0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdsb2NhbC1jYW5kaWRhdGUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxDYW5kaWRhdGVzLnNldChzdGF0LmlkLCBzdGF0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdyZW1vdGUtY2FuZGlkYXRlJzpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW90ZUNhbmRpZGF0ZXMuc2V0KHN0YXQuaWQsIHN0YXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBsZXQgc2VsZWN0ZWRDYW5kaWRhdGVQYWlyO1xuICAgICAgICAgICAgaWYgKHRyYW5zcG9ydFN0YXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkQ2FuZGlkYXRlUGFpcklkID0gdHJhbnNwb3J0U3RhdC5zZWxlY3RlZENhbmRpZGF0ZVBhaXJJZDtcbiAgICAgICAgICAgICAgICBzZWxlY3RlZENhbmRpZGF0ZVBhaXIgPSBjYW5kaWRhdGVQYWlycy5nZXQoc2VsZWN0ZWRDYW5kaWRhdGVQYWlySWQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGJhc2ljYWxseSBGaXJlZm94XG4gICAgICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gY2FuZGlkYXRlUGFpcnMuc2l6ZTtcbiAgICAgICAgICAgICAgICBjb25zdCBpdGVyYXRvciA9IGNhbmRpZGF0ZVBhaXJzLnZhbHVlcygpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FuZGlkYXRlUGFpciA9IGl0ZXJhdG9yLm5leHQoKS52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNhbmRpZGF0ZVBhaXJbJ3NlbGVjdGVkJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkQ2FuZGlkYXRlUGFpciA9IGNhbmRpZGF0ZVBhaXI7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGxvY2FsQ2FuZGlkYXRlSWQgPSBzZWxlY3RlZENhbmRpZGF0ZVBhaXIubG9jYWxDYW5kaWRhdGVJZDtcbiAgICAgICAgICAgIGNvbnN0IHJlbW90ZUNhbmRpZGF0ZUlkID0gc2VsZWN0ZWRDYW5kaWRhdGVQYWlyLnJlbW90ZUNhbmRpZGF0ZUlkO1xuICAgICAgICAgICAgbGV0IGZpbmFsTG9jYWxDYW5kaWRhdGUgPSBsb2NhbENhbmRpZGF0ZXMuZ2V0KGxvY2FsQ2FuZGlkYXRlSWQpO1xuICAgICAgICAgICAgaWYgKCEhZmluYWxMb2NhbENhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRMaXN0ID0gdGhpcy5zdHJlYW0uZ2V0TG9jYWxJY2VDYW5kaWRhdGVMaXN0KCk7XG4gICAgICAgICAgICAgICAgY29uc3QgY2FuZCA9IGNhbmRMaXN0LmZpbHRlcigoYzogUlRDSWNlQ2FuZGlkYXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAhIWMuY2FuZGlkYXRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLmlwKSA+PSAwIHx8IGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxMb2NhbENhbmRpZGF0ZS5hZGRyZXNzKSA+PSAwKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbExvY2FsQ2FuZGlkYXRlLnBvcnQpID49IDBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlLnJhdyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGMgb2YgY2FuZCkge1xuICAgICAgICAgICAgICAgICAgICBmaW5hbExvY2FsQ2FuZGlkYXRlLnJhdy5wdXNoKGMuY2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZpbmFsTG9jYWxDYW5kaWRhdGUgPSAnRVJST1I6IE5vIGFjdGl2ZSBsb2NhbCBJQ0UgY2FuZGlkYXRlLiBQcm9iYWJseSBJQ0UtVENQIGlzIGJlaW5nIHVzZWQnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgZmluYWxSZW1vdGVDYW5kaWRhdGUgPSByZW1vdGVDYW5kaWRhdGVzLmdldChyZW1vdGVDYW5kaWRhdGVJZCk7XG4gICAgICAgICAgICBpZiAoISFmaW5hbFJlbW90ZUNhbmRpZGF0ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRMaXN0ID0gdGhpcy5zdHJlYW0uZ2V0UmVtb3RlSWNlQ2FuZGlkYXRlTGlzdCgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbmQgPSBjYW5kTGlzdC5maWx0ZXIoKGM6IFJUQ0ljZUNhbmRpZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAgICAgISFjLmNhbmRpZGF0ZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKGMuY2FuZGlkYXRlLmluZGV4T2YoZmluYWxSZW1vdGVDYW5kaWRhdGUuaXApID49IDAgfHwgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5hZGRyZXNzKSA+PSAwKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgYy5jYW5kaWRhdGUuaW5kZXhPZihmaW5hbFJlbW90ZUNhbmRpZGF0ZS5wb3J0KSA+PSAwXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgZmluYWxSZW1vdGVDYW5kaWRhdGUucmF3ID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgYyBvZiBjYW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpbmFsUmVtb3RlQ2FuZGlkYXRlLnJhdy5wdXNoKGMuY2FuZGlkYXRlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZpbmFsUmVtb3RlQ2FuZGlkYXRlID0gJ0VSUk9SOiBObyBhY3RpdmUgcmVtb3RlIElDRSBjYW5kaWRhdGUuIFByb2JhYmx5IElDRS1UQ1AgaXMgYmVpbmcgdXNlZCc7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICBsb2NhbENhbmRpZGF0ZTogZmluYWxMb2NhbENhbmRpZGF0ZSxcbiAgICAgICAgICAgICAgICByZW1vdGVDYW5kaWRhdGU6IGZpbmFsUmVtb3RlQ2FuZGlkYXRlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHN0b3BXZWJSdGNTdGF0cygpIHtcbiAgICAgICAgaWYgKHRoaXMud2ViUnRjU3RhdHNFbmFibGVkKSB7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHRoaXMud2ViUnRjU3RhdHNJbnRlcnZhbElkKTtcbiAgICAgICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgICAgICAgICdXZWJSdGMgc3RhdHMgc3RvcHBlZCBmb3IgZGlzcG9zZWQgc3RyZWFtICcgKyB0aGlzLnN0cmVhbS5zdHJlYW1JZCArICcgb2YgY29ubmVjdGlvbiAnICsgdGhpcy5zdHJlYW0uY29ubmVjdGlvbi5jb25uZWN0aW9uSWRcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHNlbmRTdGF0cyh1cmw6IHN0cmluZywgcmVzcG9uc2U6IEpTT05TdGF0c1Jlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBjb25maWd1cmF0aW9uOiBSZXF1ZXN0SW5pdCA9IHtcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgICAgICdDb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbidcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlKSxcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdQT1NUJ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGF3YWl0IGZldGNoKHVybCwgY29uZmlndXJhdGlvbik7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYHNlbmRTdGF0cyBlcnJvcjogJHtKU09OLnN0cmluZ2lmeShlcnJvcil9YCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHNlbmRTdGF0c1RvSHR0cEVuZHBvaW50KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgd2VicnRjU3RhdHM6IElXZWJydGNTdGF0cyA9IGF3YWl0IHRoaXMuZ2V0Q29tbW9uU3RhdHMoKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gdGhpcy5nZW5lcmF0ZUpTT05TdGF0c1Jlc3BvbnNlKHdlYnJ0Y1N0YXRzKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2VuZFN0YXRzKHRoaXMuUE9TVF9VUkwsIHJlc3BvbnNlKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5sb2coZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gSGF2ZSBiZWVuIHRlc3RlZCBpbjpcbiAgICAvLyAgIC0gTGludXggRGVza3RvcDpcbiAgICAvLyAgICAgICAtIENocm9tZSA4OS4wLjQzODkuOTBcbiAgICAvLyAgICAgICAtIE9wZXJhIDc0LjAuMzkxMS4yMThcbiAgICAvLyAgICAgICAtIEZpcmVmb3ggODZcbiAgICAvLyAgICAgICAtIE1pY3Jvc29mdCBFZGdlIDkxLjAuODI1LjBcbiAgICAvLyAgICAgICAtIEVsZWN0cm9uIDExLjMuMCAoQ2hyb21pdW0gODcuMC40MjgwLjE0MSlcbiAgICAvLyAgIC0gV2luZG93cyBEZXNrdG9wOlxuICAgIC8vICAgICAgIC0gQ2hyb21lIDg5LjAuNDM4OS45MFxuICAgIC8vICAgICAgIC0gT3BlcmEgNzQuMC4zOTExLjIzMlxuICAgIC8vICAgICAgIC0gRmlyZWZveCA4Ni4wLjFcbiAgICAvLyAgICAgICAtIE1pY3Jvc29mdCBFZGdlIDg5LjAuNzc0LjU0XG4gICAgLy8gICAgICAgLSBFbGVjdHJvbiAxMS4zLjAgKENocm9taXVtIDg3LjAuNDI4MC4xNDEpXG4gICAgLy8gICAtIE1hY09TIERlc2t0b3A6XG4gICAgLy8gICAgICAgLSBDaHJvbWUgODkuMC40Mzg5LjkwXG4gICAgLy8gICAgICAgLSBPcGVyYSA3NS4wLjM5NjkuOTNcbiAgICAvLyAgICAgICAtIEZpcmVmb3ggODcuMFxuICAgIC8vICAgICAgIC0gTWljcm9zb2Z0IEVkZ2UgODkuMC43NzQuNTdcbiAgICAvLyAgICAgICAtIFNhZmFyaSAxNC4wICgxNDYxMC4xLjI4LjEuOSlcbiAgICAvLyAgICAgICAtIEVsZWN0cm9uIDExLjMuMCAoQ2hyb21pdW0gODcuMC40MjgwLjE0MSlcbiAgICAvLyAgIC0gQW5kcm9pZDpcbiAgICAvLyAgICAgICAtIENocm9tZSBNb2JpbGUgODkuMC40Mzg5LjkwXG4gICAgLy8gICAgICAgLSBPcGVyYSA2Mi4zLjMxNDYuNTc3NjNcbiAgICAvLyAgICAgICAtIEZpcmVmb3ggTW9iaWxlIDg2LjYuMVxuICAgIC8vICAgICAgIC0gTWljcm9zb2Z0IEVkZ2UgTW9iaWxlIDQ2LjAyLjQuNTE0N1xuICAgIC8vICAgICAgIC0gSW9uaWMgNVxuICAgIC8vICAgICAgIC0gUmVhY3QgTmF0aXZlIDAuNjRcbiAgICAvLyAgIC0gaU9TOlxuICAgIC8vICAgICAgIC0gU2FmYXJpIE1vYmlsZVxuICAgIC8vICAgICAgIC0gwr9Jb25pYz9cbiAgICAvLyAgICAgICAtIMK/UmVhY3QgTmF0aXZlP1xuICAgIHB1YmxpYyBhc3luYyBnZXRDb21tb25TdGF0cygpOiBQcm9taXNlPElXZWJydGNTdGF0cz4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdGF0c1JlcG9ydDogYW55ID0gYXdhaXQgdGhpcy5zdHJlYW0uZ2V0UlRDUGVlckNvbm5lY3Rpb24oKS5nZXRTdGF0cygpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlOiBJV2VicnRjU3RhdHMgPSB0aGlzLmdldFdlYlJ0Y1N0YXRzUmVzcG9uc2VPdXRsaW5lKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgdmlkZW9UcmFja1N0YXRzID0gWydmcmFtZXNSZWNlaXZlZCcsICdmcmFtZXNEcm9wcGVkJywgJ2ZyYW1lc1NlbnQnLCAnZnJhbWVIZWlnaHQnLCAnZnJhbWVXaWR0aCddO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNhbmRpZGF0ZVBhaXJTdGF0cyA9IFsnYXZhaWxhYmxlT3V0Z29pbmdCaXRyYXRlJywgJ2N1cnJlbnRSb3VuZFRyaXBUaW1lJ107XG5cbiAgICAgICAgICAgICAgICBzdGF0c1JlcG9ydC5mb3JFYWNoKChzdGF0OiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG1lZGlhVHlwZSA9IHN0YXQubWVkaWFUeXBlICE9IG51bGwgPyBzdGF0Lm1lZGlhVHlwZSA6IHN0YXQua2luZDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWRkU3RhdCA9IChkaXJlY3Rpb246IHN0cmluZywga2V5OiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0W2tleV0gIT0gbnVsbCAmJiByZXNwb25zZVtkaXJlY3Rpb25dICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1lZGlhVHlwZSAmJiB2aWRlb1RyYWNrU3RhdHMuaW5kZXhPZihrZXkpID4gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaWFUeXBlID0gJ3ZpZGVvJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRpcmVjdGlvbiAhPSBudWxsICYmIG1lZGlhVHlwZSAhPSBudWxsICYmIGtleSAhPSBudWxsICYmIHJlc3BvbnNlW2RpcmVjdGlvbl1bbWVkaWFUeXBlXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlW2RpcmVjdGlvbl1bbWVkaWFUeXBlXVtrZXldID0gTnVtYmVyKHN0YXRba2V5XSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gIT0gbnVsbCAmJiBrZXkgIT0gbnVsbCAmJiBjYW5kaWRhdGVQYWlyU3RhdHMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYW5kaWRhdGUtcGFpci1zdGF0c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZVtkaXJlY3Rpb25dW2tleV0gPSBOdW1iZXIoc3RhdFtrZXldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChzdGF0LnR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ291dGJvdW5kLXJ0cCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnb3V0Ym91bmQnLCAnYnl0ZXNTZW50Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnb3V0Ym91bmQnLCAncGFja2V0c1NlbnQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdvdXRib3VuZCcsICdmcmFtZXNFbmNvZGVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnb3V0Ym91bmQnLCAnbmFja0NvdW50Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnb3V0Ym91bmQnLCAnZmlyQ291bnQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdvdXRib3VuZCcsICdwbGlDb3VudCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ291dGJvdW5kJywgJ3FwU3VtJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdpbmJvdW5kLXJ0cCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnaW5ib3VuZCcsICdieXRlc1JlY2VpdmVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnaW5ib3VuZCcsICdwYWNrZXRzUmVjZWl2ZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdpbmJvdW5kJywgJ3BhY2tldHNMb3N0Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnaW5ib3VuZCcsICdqaXR0ZXInKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdpbmJvdW5kJywgJ2ZyYW1lc0RlY29kZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdpbmJvdW5kJywgJ25hY2tDb3VudCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ2luYm91bmQnLCAnZmlyQ291bnQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdpbmJvdW5kJywgJ3BsaUNvdW50Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICd0cmFjayc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnaW5ib3VuZCcsICdqaXR0ZXJCdWZmZXJEZWxheScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ2luYm91bmQnLCAnZnJhbWVzUmVjZWl2ZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdvdXRib3VuZCcsICdmcmFtZXNEcm9wcGVkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCgnb3V0Ym91bmQnLCAnZnJhbWVzU2VudCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQodGhpcy5zdHJlYW0uaXNMb2NhbCgpID8gJ291dGJvdW5kJyA6ICdpbmJvdW5kJywgJ2ZyYW1lSGVpZ2h0Jyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkU3RhdCh0aGlzLnN0cmVhbS5pc0xvY2FsKCkgPyAnb3V0Ym91bmQnIDogJ2luYm91bmQnLCAnZnJhbWVXaWR0aCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnY2FuZGlkYXRlLXBhaXInOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZFN0YXQoJ2NhbmRpZGF0ZXBhaXInLCAnY3VycmVudFJvdW5kVHJpcFRpbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRTdGF0KCdjYW5kaWRhdGVwYWlyJywgJ2F2YWlsYWJsZU91dGdvaW5nQml0cmF0ZScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAvLyBEZWxldGUgY2FuZGlkYXRlcGFpciBmcm9tIHJlc3BvbnNlIGlmIG51bGxcbiAgICAgICAgICAgICAgICBpZiAoIXJlc3BvbnNlPy5jYW5kaWRhdGVwYWlyIHx8IE9iamVjdC5rZXlzKDxPYmplY3Q+cmVzcG9uc2UuY2FuZGlkYXRlcGFpcikubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByZXNwb25zZS5jYW5kaWRhdGVwYWlyO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBnZXR0aW5nIGNvbW1vbiBzdGF0czogJywgZXJyb3IpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdlbmVyYXRlSlNPTlN0YXRzUmVzcG9uc2Uoc3RhdHM6IElXZWJydGNTdGF0cyk6IEpTT05TdGF0c1Jlc3BvbnNlIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICdAdGltZXN0YW1wJzogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgICAgcGFydGljaXBhbnRfaWQ6IHRoaXMuc3RyZWFtLmNvbm5lY3Rpb24uZGF0YSxcbiAgICAgICAgICAgIHNlc3Npb25faWQ6IHRoaXMuc3RyZWFtLnNlc3Npb24uc2Vzc2lvbklkLFxuICAgICAgICAgICAgcGxhdGZvcm06IHBsYXRmb3JtLmdldE5hbWUoKSxcbiAgICAgICAgICAgIHBsYXRmb3JtX2Rlc2NyaXB0aW9uOiBwbGF0Zm9ybS5nZXREZXNjcmlwdGlvbigpLFxuICAgICAgICAgICAgc3RyZWFtOiAnd2ViUlRDJyxcbiAgICAgICAgICAgIHdlYnJ0Y19zdGF0czogc3RhdHNcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFdlYlJ0Y1N0YXRzUmVzcG9uc2VPdXRsaW5lKCk6IElXZWJydGNTdGF0cyB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5pc0xvY2FsKCkpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgb3V0Ym91bmQ6IHtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW86IHt9LFxuICAgICAgICAgICAgICAgICAgICB2aWRlbzoge31cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGNhbmRpZGF0ZXBhaXI6IHt9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBpbmJvdW5kOiB7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvOiB7fSxcbiAgICAgICAgICAgICAgICAgICAgdmlkZW86IHt9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==